mirror of
https://github.com/krahets/hello-algo.git
synced 2024-12-26 10:16:29 +08:00
Merge pull request #247 from sjinzh/master
add zig codes for Section 'Stack', 'Bubble Sort' and 'Insertion Sort'
This commit is contained in:
commit
32a8abdb4e
6 changed files with 426 additions and 0 deletions
|
@ -119,4 +119,72 @@ pub fn build(b: *std.build.Builder) void {
|
||||||
if (b.args) |args| run_cmd_my_list.addArgs(args);
|
if (b.args) |args| run_cmd_my_list.addArgs(args);
|
||||||
const run_step_my_list = b.step("run_my_list", "Run my_list");
|
const run_step_my_list = b.step("run_my_list", "Run my_list");
|
||||||
run_step_my_list.dependOn(&run_cmd_my_list.step);
|
run_step_my_list.dependOn(&run_cmd_my_list.step);
|
||||||
|
|
||||||
|
// Section: "Stack"
|
||||||
|
// Source File: "chapter_stack_and_queue/stack.zig"
|
||||||
|
// Run Command: zig build run_stack
|
||||||
|
const exe_stack = b.addExecutable("stack", "chapter_stack_and_queue/stack.zig");
|
||||||
|
exe_stack.addPackagePath("include", "include/include.zig");
|
||||||
|
exe_stack.setTarget(target);
|
||||||
|
exe_stack.setBuildMode(mode);
|
||||||
|
exe_stack.install();
|
||||||
|
const run_cmd_stack = exe_stack.run();
|
||||||
|
run_cmd_stack.step.dependOn(b.getInstallStep());
|
||||||
|
if (b.args) |args| run_cmd_stack.addArgs(args);
|
||||||
|
const run_step_stack = b.step("run_stack", "Run stack");
|
||||||
|
run_step_stack.dependOn(&run_cmd_stack.step);
|
||||||
|
|
||||||
|
// Source File: "chapter_stack_and_queue/linkedlist_stack.zig"
|
||||||
|
// Run Command: zig build run_linkedlist_stack
|
||||||
|
const exe_linkedlist_stack = b.addExecutable("linkedlist_stack", "chapter_stack_and_queue/linkedlist_stack.zig");
|
||||||
|
exe_linkedlist_stack.addPackagePath("include", "include/include.zig");
|
||||||
|
exe_linkedlist_stack.setTarget(target);
|
||||||
|
exe_linkedlist_stack.setBuildMode(mode);
|
||||||
|
exe_linkedlist_stack.install();
|
||||||
|
const run_cmd_linkedlist_stack = exe_linkedlist_stack.run();
|
||||||
|
run_cmd_linkedlist_stack.step.dependOn(b.getInstallStep());
|
||||||
|
if (b.args) |args| run_cmd_linkedlist_stack.addArgs(args);
|
||||||
|
const run_step_linkedlist_stack = b.step("run_linkedlist_stack", "Run linkedlist_stack");
|
||||||
|
run_step_linkedlist_stack.dependOn(&run_cmd_linkedlist_stack.step);
|
||||||
|
|
||||||
|
// Source File: "chapter_stack_and_queue/array_stack.zig"
|
||||||
|
// Run Command: zig build run_array_stack
|
||||||
|
const exe_array_stack = b.addExecutable("array_stack", "chapter_stack_and_queue/array_stack.zig");
|
||||||
|
exe_array_stack.addPackagePath("include", "include/include.zig");
|
||||||
|
exe_array_stack.setTarget(target);
|
||||||
|
exe_array_stack.setBuildMode(mode);
|
||||||
|
exe_array_stack.install();
|
||||||
|
const run_cmd_array_stack = exe_linkedlist_stack.run();
|
||||||
|
run_cmd_array_stack.step.dependOn(b.getInstallStep());
|
||||||
|
if (b.args) |args| run_cmd_array_stack.addArgs(args);
|
||||||
|
const run_step_array_stack = b.step("run_array_stack", "Run array_stack");
|
||||||
|
run_step_array_stack.dependOn(&run_cmd_array_stack.step);
|
||||||
|
|
||||||
|
// Section: "Bubble Sort"
|
||||||
|
// Source File: "chapter_sorting/bubble_sort.zig"
|
||||||
|
// Run Command: zig build run_bubble_sort
|
||||||
|
const exe_bubble_sort = b.addExecutable("bubble_sort", "chapter_sorting/bubble_sort.zig");
|
||||||
|
exe_bubble_sort.addPackagePath("include", "include/include.zig");
|
||||||
|
exe_bubble_sort.setTarget(target);
|
||||||
|
exe_bubble_sort.setBuildMode(mode);
|
||||||
|
exe_bubble_sort.install();
|
||||||
|
const run_cmd_bubble_sort = exe_bubble_sort.run();
|
||||||
|
run_cmd_bubble_sort.step.dependOn(b.getInstallStep());
|
||||||
|
if (b.args) |args| run_cmd_bubble_sort.addArgs(args);
|
||||||
|
const run_step_bubble_sort = b.step("run_bubble_sort", "Run bubble_sort");
|
||||||
|
run_step_bubble_sort.dependOn(&run_cmd_bubble_sort.step);
|
||||||
|
|
||||||
|
// Section: "Insertion Sort"
|
||||||
|
// Source File: "chapter_sorting/insertion_sort.zig"
|
||||||
|
// Run Command: zig build run_insertion_sort
|
||||||
|
const exe_insertion_sort = b.addExecutable("insertion_sort", "chapter_sorting/insertion_sort.zig");
|
||||||
|
exe_insertion_sort.addPackagePath("include", "include/include.zig");
|
||||||
|
exe_insertion_sort.setTarget(target);
|
||||||
|
exe_insertion_sort.setBuildMode(mode);
|
||||||
|
exe_insertion_sort.install();
|
||||||
|
const run_cmd_insertion_sort = exe_insertion_sort.run();
|
||||||
|
run_cmd_insertion_sort.step.dependOn(b.getInstallStep());
|
||||||
|
if (b.args) |args| run_cmd_insertion_sort.addArgs(args);
|
||||||
|
const run_step_insertion_sort = b.step("run_insertion_sort", "Run insertion_sort");
|
||||||
|
run_step_insertion_sort.dependOn(&run_cmd_insertion_sort.step);
|
||||||
}
|
}
|
||||||
|
|
62
codes/zig/chapter_sorting/bubble_sort.zig
Normal file
62
codes/zig/chapter_sorting/bubble_sort.zig
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
// File: time_complexity.zig
|
||||||
|
// Created Time: 2023-01-08
|
||||||
|
// Author: sjinzh (sjinzh@gmail.com)
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const inc = @import("include");
|
||||||
|
|
||||||
|
// 冒泡排序
|
||||||
|
fn bubbleSort(nums: []i32) void {
|
||||||
|
// 外循环:待排序元素数量为 n-1, n-2, ..., 1
|
||||||
|
var i: usize = nums.len - 1;
|
||||||
|
while (i > 0) : (i -= 1) {
|
||||||
|
var j: usize = 0;
|
||||||
|
// 内循环:冒泡操作
|
||||||
|
while (j < i) : (j += 1) {
|
||||||
|
if (nums[j] > nums[j + 1]) {
|
||||||
|
// 交换 nums[j] 与 nums[j + 1]
|
||||||
|
var tmp = nums[j];
|
||||||
|
nums[j] = nums[j + 1];
|
||||||
|
nums[j + 1] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 冒泡排序(标志优化)
|
||||||
|
fn bubbleSortWithFlag(nums: []i32) void {
|
||||||
|
// 外循环:待排序元素数量为 n-1, n-2, ..., 1
|
||||||
|
var i: usize = nums.len - 1;
|
||||||
|
while (i > 0) : (i -= 1) {
|
||||||
|
var flag = false; // 初始化标志位
|
||||||
|
var j: usize = 0;
|
||||||
|
// 内循环:冒泡操作
|
||||||
|
while (j < i) : (j += 1) {
|
||||||
|
if (nums[j] > nums[j + 1]) {
|
||||||
|
// 交换 nums[j] 与 nums[j + 1]
|
||||||
|
var tmp = nums[j];
|
||||||
|
nums[j] = nums[j + 1];
|
||||||
|
nums[j + 1] = tmp;
|
||||||
|
flag = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!flag) break; // 此轮冒泡未交换任何元素,直接跳出
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Driver Code
|
||||||
|
pub fn main() !void {
|
||||||
|
var nums = [_]i32{ 4, 1, 3, 1, 5, 2 };
|
||||||
|
bubbleSort(&nums);
|
||||||
|
std.debug.print("冒泡排序完成后 nums = ", .{});
|
||||||
|
inc.PrintUtil.printArray(i32, &nums);
|
||||||
|
|
||||||
|
var nums1 = [_]i32{ 4, 1, 3, 1, 5, 2 };
|
||||||
|
bubbleSortWithFlag(&nums1);
|
||||||
|
std.debug.print("\n冒泡排序完成后 nums1 = ", .{});
|
||||||
|
inc.PrintUtil.printArray(i32, &nums1);
|
||||||
|
|
||||||
|
const getchar = try std.io.getStdIn().reader().readByte();
|
||||||
|
_ = getchar;
|
||||||
|
}
|
||||||
|
|
33
codes/zig/chapter_sorting/insertion_sort.zig
Normal file
33
codes/zig/chapter_sorting/insertion_sort.zig
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// File: time_complexity.zig
|
||||||
|
// Created Time: 2023-01-08
|
||||||
|
// Author: sjinzh (sjinzh@gmail.com)
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const inc = @import("include");
|
||||||
|
|
||||||
|
// 插入排序
|
||||||
|
fn insertionSort(nums: []i32) void {
|
||||||
|
// 外循环:base = nums[1], nums[2], ..., nums[n-1]
|
||||||
|
var i: usize = 1;
|
||||||
|
while (i < nums.len) : (i += 1) {
|
||||||
|
var base = nums[i];
|
||||||
|
var j: usize = i;
|
||||||
|
// 内循环:将 base 插入到左边的正确位置
|
||||||
|
while (j >= 1 and nums[j - 1] > base) : (j -= 1) {
|
||||||
|
nums[j] = nums[j - 1]; // 1. 将 nums[j] 向右移动一位
|
||||||
|
}
|
||||||
|
nums[j] = base; // 2. 将 base 赋值到正确位置
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Driver Code
|
||||||
|
pub fn main() !void {
|
||||||
|
var nums = [_]i32{ 4, 1, 3, 1, 5, 2 };
|
||||||
|
insertionSort(&nums);
|
||||||
|
std.debug.print("插入排序完成后 nums = ", .{});
|
||||||
|
inc.PrintUtil.printArray(i32, &nums);
|
||||||
|
|
||||||
|
const getchar = try std.io.getStdIn().reader().readByte();
|
||||||
|
_ = getchar;
|
||||||
|
}
|
||||||
|
|
99
codes/zig/chapter_stack_and_queue/array_stack.zig
Normal file
99
codes/zig/chapter_stack_and_queue/array_stack.zig
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
// File: stack.zig
|
||||||
|
// Created Time: 2023-01-08
|
||||||
|
// Author: sjinzh (sjinzh@gmail.com)
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const inc = @import("include");
|
||||||
|
|
||||||
|
// 基于数组实现的栈
|
||||||
|
// 编译期泛型
|
||||||
|
pub fn ArrayStack(comptime T: type) type {
|
||||||
|
return struct {
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
stack: ?std.ArrayList(T) = null,
|
||||||
|
|
||||||
|
// 构造函数(分配内存+初始化栈)
|
||||||
|
pub fn init(self: *Self, allocator: std.mem.Allocator) void {
|
||||||
|
if (self.stack == null) {
|
||||||
|
self.stack = std.ArrayList(T).init(allocator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 析构函数(释放内存)
|
||||||
|
pub fn deinit(self: *Self) void {
|
||||||
|
if (self.stack == null) return;
|
||||||
|
self.stack.?.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取栈的长度
|
||||||
|
pub fn size(self: *Self) usize {
|
||||||
|
return self.stack.?.items.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断栈是否为空
|
||||||
|
pub fn empty(self: *Self) bool {
|
||||||
|
return self.size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 访问栈顶元素
|
||||||
|
pub fn top(self: *Self) T {
|
||||||
|
if (self.size() == 0) @panic("栈为空");
|
||||||
|
return self.stack.?.items[self.size() - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 入栈
|
||||||
|
pub fn push(self: *Self, num: T) !void {
|
||||||
|
try self.stack.?.append(num);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 出栈
|
||||||
|
pub fn pop(self: *Self) T {
|
||||||
|
var num = self.stack.?.pop();
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回 ArrayList
|
||||||
|
pub fn toList(self: *Self) std.ArrayList(T) {
|
||||||
|
return self.stack.?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Driver Code
|
||||||
|
pub fn main() !void {
|
||||||
|
// 初始化栈
|
||||||
|
var stack = ArrayStack(i32){};
|
||||||
|
stack.init(std.heap.page_allocator);
|
||||||
|
// 延迟释放内存
|
||||||
|
defer stack.deinit();
|
||||||
|
|
||||||
|
// 元素入栈
|
||||||
|
try stack.push(1);
|
||||||
|
try stack.push(3);
|
||||||
|
try stack.push(2);
|
||||||
|
try stack.push(5);
|
||||||
|
try stack.push(4);
|
||||||
|
std.debug.print("栈 stack = ", .{});
|
||||||
|
inc.PrintUtil.printList(i32, stack.toList());
|
||||||
|
|
||||||
|
// 访问栈顶元素
|
||||||
|
var top = stack.top();
|
||||||
|
std.debug.print("\n栈顶元素 top = {}", .{top});
|
||||||
|
|
||||||
|
// 元素出栈
|
||||||
|
top = stack.pop();
|
||||||
|
std.debug.print("\n出栈元素 pop = {},出栈后 stack = ", .{top});
|
||||||
|
inc.PrintUtil.printList(i32, stack.toList());
|
||||||
|
|
||||||
|
// 获取栈的长度
|
||||||
|
var size = stack.size();
|
||||||
|
std.debug.print("\n栈的长度 size = {}", .{size});
|
||||||
|
|
||||||
|
// 判断栈是否为空
|
||||||
|
var empty = stack.empty();
|
||||||
|
std.debug.print("\n栈是否为空 = {}", .{empty});
|
||||||
|
|
||||||
|
const getchar = try std.io.getStdIn().reader().readByte();
|
||||||
|
_ = getchar;
|
||||||
|
}
|
120
codes/zig/chapter_stack_and_queue/linkedlist_stack.zig
Normal file
120
codes/zig/chapter_stack_and_queue/linkedlist_stack.zig
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
// File: linkedlist_stack.zig
|
||||||
|
// Created Time: 2023-01-08
|
||||||
|
// Author: sjinzh (sjinzh@gmail.com)
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const inc = @import("include");
|
||||||
|
|
||||||
|
// 基于链表实现的栈
|
||||||
|
// 编译期泛型
|
||||||
|
pub fn LinkedListStack(comptime T: type) type {
|
||||||
|
return struct {
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
stackTop: ?*inc.ListNode(T) = null, // 将头结点作为栈顶
|
||||||
|
stkSize: usize = 0, // 栈的长度
|
||||||
|
mem_arena: ?std.heap.ArenaAllocator = null,
|
||||||
|
mem_allocator: std.mem.Allocator = undefined, // 内存分配器
|
||||||
|
|
||||||
|
// 构造函数(分配内存+初始化栈)
|
||||||
|
pub fn init(self: *Self, allocator: std.mem.Allocator) !void {
|
||||||
|
if (self.mem_arena == null) {
|
||||||
|
self.mem_arena = std.heap.ArenaAllocator.init(allocator);
|
||||||
|
self.mem_allocator = self.mem_arena.?.allocator();
|
||||||
|
}
|
||||||
|
self.stackTop = null;
|
||||||
|
self.stkSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 析构函数(释放内存)
|
||||||
|
pub fn deinit(self: *Self) void {
|
||||||
|
if (self.mem_arena == null) return;
|
||||||
|
self.mem_arena.?.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取栈的长度
|
||||||
|
pub fn size(self: *Self) usize {
|
||||||
|
return self.stkSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断栈是否为空
|
||||||
|
pub fn empty(self: *Self) bool {
|
||||||
|
return self.size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 访问栈顶元素
|
||||||
|
pub fn top(self: *Self) T {
|
||||||
|
if (self.size() == 0) @panic("栈为空");
|
||||||
|
return self.stackTop.?.val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 入栈
|
||||||
|
pub fn push(self: *Self, num: T) !void {
|
||||||
|
var node = try self.mem_allocator.create(inc.ListNode(T));
|
||||||
|
node.init(num);
|
||||||
|
node.next = self.stackTop;
|
||||||
|
self.stackTop = node;
|
||||||
|
self.stkSize += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 出栈
|
||||||
|
pub fn pop(self: *Self) T {
|
||||||
|
var num = self.top();
|
||||||
|
self.stackTop = self.stackTop.?.next;
|
||||||
|
self.stkSize -= 1;
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将栈转换为数组
|
||||||
|
pub fn toArray(self: *Self) ![]T {
|
||||||
|
var node = self.stackTop;
|
||||||
|
var res = try self.mem_allocator.alloc(T, self.size());
|
||||||
|
std.mem.set(T, res, @as(T, 0));
|
||||||
|
var i: usize = 0;
|
||||||
|
while (i < res.len) : (i += 1) {
|
||||||
|
res[res.len - i - 1] = node.?.val;
|
||||||
|
node = node.?.next;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Driver Code
|
||||||
|
pub fn main() !void {
|
||||||
|
// 初始化栈
|
||||||
|
var stack = LinkedListStack(i32){};
|
||||||
|
try stack.init(std.heap.page_allocator);
|
||||||
|
// 延迟释放内存
|
||||||
|
defer stack.deinit();
|
||||||
|
|
||||||
|
// 元素入栈
|
||||||
|
try stack.push(1);
|
||||||
|
try stack.push(3);
|
||||||
|
try stack.push(2);
|
||||||
|
try stack.push(5);
|
||||||
|
try stack.push(4);
|
||||||
|
std.debug.print("栈 stack = ", .{});
|
||||||
|
inc.PrintUtil.printArray(i32, try stack.toArray());
|
||||||
|
|
||||||
|
// 访问栈顶元素
|
||||||
|
var top = stack.top();
|
||||||
|
std.debug.print("\n栈顶元素 top = {}", .{top});
|
||||||
|
|
||||||
|
// 元素出栈
|
||||||
|
top = stack.pop();
|
||||||
|
std.debug.print("\n出栈元素 pop = {},出栈后 stack = ", .{top});
|
||||||
|
inc.PrintUtil.printArray(i32, try stack.toArray());
|
||||||
|
|
||||||
|
// 获取栈的长度
|
||||||
|
var size = stack.size();
|
||||||
|
std.debug.print("\n栈的长度 size = {}", .{size});
|
||||||
|
|
||||||
|
// 判断栈是否为空
|
||||||
|
var empty = stack.empty();
|
||||||
|
std.debug.print("\n栈是否为空 = {}", .{empty});
|
||||||
|
|
||||||
|
const getchar = try std.io.getStdIn().reader().readByte();
|
||||||
|
_ = getchar;
|
||||||
|
}
|
||||||
|
|
44
codes/zig/chapter_stack_and_queue/stack.zig
Normal file
44
codes/zig/chapter_stack_and_queue/stack.zig
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// File: stack.zig
|
||||||
|
// Created Time: 2023-01-08
|
||||||
|
// Author: sjinzh (sjinzh@gmail.com)
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const inc = @import("include");
|
||||||
|
|
||||||
|
// Driver Code
|
||||||
|
pub fn main() !void {
|
||||||
|
// 初始化栈
|
||||||
|
// 在 zig 中,推荐将 ArrayList 当作栈来使用
|
||||||
|
var stack = std.ArrayList(i32).init(std.heap.page_allocator);
|
||||||
|
// 延迟释放内存
|
||||||
|
defer stack.deinit();
|
||||||
|
|
||||||
|
// 元素入栈
|
||||||
|
try stack.append(1);
|
||||||
|
try stack.append(3);
|
||||||
|
try stack.append(2);
|
||||||
|
try stack.append(5);
|
||||||
|
try stack.append(4);
|
||||||
|
std.debug.print("栈 stack = ", .{});
|
||||||
|
inc.PrintUtil.printList(i32, stack);
|
||||||
|
|
||||||
|
// 访问栈顶元素
|
||||||
|
var top = stack.items[stack.items.len - 1];
|
||||||
|
std.debug.print("\n栈顶元素 top = {}", .{top});
|
||||||
|
|
||||||
|
// 元素出栈
|
||||||
|
top = stack.pop();
|
||||||
|
std.debug.print("\n出栈元素 pop = {},出栈后 stack = ", .{top});
|
||||||
|
inc.PrintUtil.printList(i32, stack);
|
||||||
|
|
||||||
|
// 获取栈的长度
|
||||||
|
var size = stack.items.len;
|
||||||
|
std.debug.print("\n栈的长度 size = {}", .{size});
|
||||||
|
|
||||||
|
// 判断栈是否为空
|
||||||
|
var empty = if (stack.items.len == 0) true else false;
|
||||||
|
std.debug.print("\n栈是否为空 = {}", .{empty});
|
||||||
|
|
||||||
|
const getchar = try std.io.getStdIn().reader().readByte();
|
||||||
|
_ = getchar;
|
||||||
|
}
|
Loading…
Reference in a new issue