From 8726934f94079ee87252281fe1bf3ad7470c8a9b Mon Sep 17 00:00:00 2001 From: sjinzh <99076655+sjinzh@users.noreply.github.com> Date: Thu, 12 Jan 2023 21:51:11 +0800 Subject: [PATCH] add zig codes for Section 'Stack', 'Bubble Sort' and 'Insertion Sort' --- codes/zig/build.zig | 68 ++++++++++ codes/zig/chapter_sorting/bubble_sort.zig | 62 +++++++++ codes/zig/chapter_sorting/insertion_sort.zig | 33 +++++ .../chapter_stack_and_queue/array_stack.zig | 99 +++++++++++++++ .../linkedlist_stack.zig | 120 ++++++++++++++++++ codes/zig/chapter_stack_and_queue/stack.zig | 44 +++++++ 6 files changed, 426 insertions(+) create mode 100644 codes/zig/chapter_sorting/bubble_sort.zig create mode 100644 codes/zig/chapter_sorting/insertion_sort.zig create mode 100644 codes/zig/chapter_stack_and_queue/array_stack.zig create mode 100644 codes/zig/chapter_stack_and_queue/linkedlist_stack.zig create mode 100644 codes/zig/chapter_stack_and_queue/stack.zig diff --git a/codes/zig/build.zig b/codes/zig/build.zig index b9bbddce0..a8738fae9 100644 --- a/codes/zig/build.zig +++ b/codes/zig/build.zig @@ -119,4 +119,72 @@ pub fn build(b: *std.build.Builder) void { if (b.args) |args| run_cmd_my_list.addArgs(args); const run_step_my_list = b.step("run_my_list", "Run my_list"); 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); } diff --git a/codes/zig/chapter_sorting/bubble_sort.zig b/codes/zig/chapter_sorting/bubble_sort.zig new file mode 100644 index 000000000..863190963 --- /dev/null +++ b/codes/zig/chapter_sorting/bubble_sort.zig @@ -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; +} + diff --git a/codes/zig/chapter_sorting/insertion_sort.zig b/codes/zig/chapter_sorting/insertion_sort.zig new file mode 100644 index 000000000..3c7594c24 --- /dev/null +++ b/codes/zig/chapter_sorting/insertion_sort.zig @@ -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; +} + diff --git a/codes/zig/chapter_stack_and_queue/array_stack.zig b/codes/zig/chapter_stack_and_queue/array_stack.zig new file mode 100644 index 000000000..868d9d94d --- /dev/null +++ b/codes/zig/chapter_stack_and_queue/array_stack.zig @@ -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; +} diff --git a/codes/zig/chapter_stack_and_queue/linkedlist_stack.zig b/codes/zig/chapter_stack_and_queue/linkedlist_stack.zig new file mode 100644 index 000000000..633583b45 --- /dev/null +++ b/codes/zig/chapter_stack_and_queue/linkedlist_stack.zig @@ -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; +} + diff --git a/codes/zig/chapter_stack_and_queue/stack.zig b/codes/zig/chapter_stack_and_queue/stack.zig new file mode 100644 index 000000000..95ed427b0 --- /dev/null +++ b/codes/zig/chapter_stack_and_queue/stack.zig @@ -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; +}