diff --git a/codes/zig/build.zig b/codes/zig/build.zig index a8738fae9..4299c60f2 100644 --- a/codes/zig/build.zig +++ b/codes/zig/build.zig @@ -160,6 +160,48 @@ pub fn build(b: *std.build.Builder) void { const run_step_array_stack = b.step("run_array_stack", "Run array_stack"); run_step_array_stack.dependOn(&run_cmd_array_stack.step); + // Section: "Hash Map" + // Source File: "chapter_hashing/hash_map.zig" + // Run Command: zig build run_hash_map + const exe_hash_map = b.addExecutable("hash_map", "chapter_hashing/hash_map.zig"); + exe_hash_map.addPackagePath("include", "include/include.zig"); + exe_hash_map.setTarget(target); + exe_hash_map.setBuildMode(mode); + exe_hash_map.install(); + const run_cmd_hash_map = exe_hash_map.run(); + run_cmd_hash_map.step.dependOn(b.getInstallStep()); + if (b.args) |args| run_cmd_hash_map.addArgs(args); + const run_step_hash_map= b.step("run_hash_map", "Run hash_map"); + run_step_hash_map.dependOn(&run_cmd_hash_map.step); + + // Section: "Binary Tree" + // Source File: "chapter_tree/binary_tree.zig" + // Run Command: zig build run_binary_tree + const exe_binary_tree = b.addExecutable("hash_map", "chapter_tree/binary_tree.zig"); + exe_binary_tree.addPackagePath("include", "include/include.zig"); + exe_binary_tree.setTarget(target); + exe_binary_tree.setBuildMode(mode); + exe_binary_tree.install(); + const run_cmd_binary_tree = exe_binary_tree.run(); + run_cmd_binary_tree.step.dependOn(b.getInstallStep()); + if (b.args) |args| run_cmd_binary_tree.addArgs(args); + const run_step_binary_tree= b.step("run_binary_tree", "Run binary_tree"); + run_step_binary_tree.dependOn(&run_cmd_binary_tree.step); + + // Section: "Linear Search" + // Source File: "chapter_searching/linear_search.zig" + // Run Command: zig build run_linear_search + const exe_linear_search = b.addExecutable("linear_search", "chapter_searching/linear_search.zig"); + exe_linear_search.addPackagePath("include", "include/include.zig"); + exe_linear_search.setTarget(target); + exe_linear_search.setBuildMode(mode); + exe_linear_search.install(); + const run_cmd_linear_search = exe_linear_search.run(); + run_cmd_linear_search.step.dependOn(b.getInstallStep()); + if (b.args) |args| run_cmd_linear_search.addArgs(args); + const run_step_linear_search= b.step("run_linear_search", "Run linear_search"); + run_step_linear_search.dependOn(&run_cmd_linear_search.step); + // Section: "Bubble Sort" // Source File: "chapter_sorting/bubble_sort.zig" // Run Command: zig build run_bubble_sort diff --git a/codes/zig/chapter_hashing/hash_map.zig b/codes/zig/chapter_hashing/hash_map.zig new file mode 100644 index 000000000..1e217c43c --- /dev/null +++ b/codes/zig/chapter_hashing/hash_map.zig @@ -0,0 +1,55 @@ +// File: hash_map.zig +// Created Time: 2023-01-13 +// Author: sjinzh (sjinzh@gmail.com) + +const std = @import("std"); +const inc = @import("include"); + +// Driver Code +pub fn main() !void { + // 初始化哈希表 + var map = std.AutoHashMap(i32, []const u8).init(std.heap.page_allocator); + // 延迟释放内存 + defer map.deinit(); + + // 添加操作 + // 在哈希表中添加键值对 (key, value) + try map.put(12836, "小哈"); + try map.put(15937, "小啰"); + try map.put(16750, "小算"); + try map.put(13276, "小法"); + try map.put(10583, "小鸭"); + std.debug.print("\n添加完成后,哈希表为\nKey -> Value\n", .{}); + inc.PrintUtil.printHashMap(i32, []const u8, map); + + // 查询操作 + // 向哈希表输入键 key ,得到值 value + var name = map.get(15937).?; + std.debug.print("\n输入学号 15937 ,查询到姓名 {s}\n", .{name}); + + // 删除操作 + // 在哈希表中删除键值对 (key, value) + _ = map.remove(10583); + std.debug.print("\n删除 10583 后,哈希表为\nKey -> Value\n", .{}); + inc.PrintUtil.printHashMap(i32, []const u8, map); + + // 遍历哈希表 + std.debug.print("\n遍历键值对 Key->Value\n", .{}); + inc.PrintUtil.printHashMap(i32, []const u8, map); + + std.debug.print("\n单独遍历键 Key\n", .{}); + var it = map.iterator(); + while (it.next()) |kv| { + std.debug.print("{}\n", .{kv.key_ptr.*}); + } + + std.debug.print("\n单独遍历值 value\n", .{}); + it = map.iterator(); + while (it.next()) |kv| { + std.debug.print("{s}\n", .{kv.value_ptr.*}); + } + + const getchar = try std.io.getStdIn().reader().readByte(); + _ = getchar; +} + diff --git a/codes/zig/chapter_searching/linear_search.zig b/codes/zig/chapter_searching/linear_search.zig new file mode 100644 index 000000000..3ba21313b --- /dev/null +++ b/codes/zig/chapter_searching/linear_search.zig @@ -0,0 +1,56 @@ +// File: linear_search.zig +// Created Time: 2023-01-13 +// Author: sjinzh (sjinzh@gmail.com) + +const std = @import("std"); +const inc = @import("include"); + +// 线性查找(数组) +fn linearSearchList(comptime T: type, nums: std.ArrayList(T), target: T) T { + // 遍历数组 + for (nums.items) |num, i| { + // 找到目标元素, 返回其索引 + if (num == target) { + return @intCast(T, i); + } + } + // 未找到目标元素,返回 -1 + return -1; +} + +// 线性查找(链表) +pub fn linearSearchLinkedList(comptime T: type, node: ?*inc.ListNode(T), target: T) ?*inc.ListNode(T) { + var head = node; + // 遍历链表 + while (head != null) { + // 找到目标结点,返回之 + if (head.?.val == target) return head; + head = head.?.next; + } + return null; +} + +// Driver Code +pub fn main() !void { + var target: i32 = 3; + + // 在数组中执行线性查找 + var nums = std.ArrayList(i32).init(std.heap.page_allocator); + defer nums.deinit(); + try nums.appendSlice(&[_]i32{ 1, 5, 3, 2, 4, 7, 5, 9, 10, 8 }); + var index = linearSearchList(i32, nums, target); + std.debug.print("目标元素 3 的索引 = {}\n", .{index}); + + // 在链表中执行线性查找 + var mem_arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer mem_arena.deinit(); + const mem_allocator = mem_arena.allocator(); + var head = try inc.ListUtil.listToLinkedList(i32, mem_allocator, nums); + var node = linearSearchLinkedList(i32, head, target); + std.debug.print("目标结点值 3 的对应结点对象为 ", .{}); + try inc.PrintUtil.printLinkedList(i32, node); + + const getchar = try std.io.getStdIn().reader().readByte(); + _ = getchar; +} + diff --git a/codes/zig/chapter_sorting/bubble_sort.zig b/codes/zig/chapter_sorting/bubble_sort.zig index 863190963..17cb0d973 100644 --- a/codes/zig/chapter_sorting/bubble_sort.zig +++ b/codes/zig/chapter_sorting/bubble_sort.zig @@ -1,4 +1,4 @@ -// File: time_complexity.zig +// File: bubble_sort.zig // Created Time: 2023-01-08 // Author: sjinzh (sjinzh@gmail.com) diff --git a/codes/zig/chapter_sorting/insertion_sort.zig b/codes/zig/chapter_sorting/insertion_sort.zig index 3c7594c24..5c9547911 100644 --- a/codes/zig/chapter_sorting/insertion_sort.zig +++ b/codes/zig/chapter_sorting/insertion_sort.zig @@ -1,4 +1,4 @@ -// File: time_complexity.zig +// File: insertion_sort.zig // Created Time: 2023-01-08 // Author: sjinzh (sjinzh@gmail.com) diff --git a/codes/zig/chapter_stack_and_queue/array_stack.zig b/codes/zig/chapter_stack_and_queue/array_stack.zig index 868d9d94d..36b1c7ca3 100644 --- a/codes/zig/chapter_stack_and_queue/array_stack.zig +++ b/codes/zig/chapter_stack_and_queue/array_stack.zig @@ -1,4 +1,4 @@ -// File: stack.zig +// File: array_stack.zig // Created Time: 2023-01-08 // Author: sjinzh (sjinzh@gmail.com) diff --git a/codes/zig/chapter_tree/binary_tree.zig b/codes/zig/chapter_tree/binary_tree.zig new file mode 100644 index 000000000..b2cb9a960 --- /dev/null +++ b/codes/zig/chapter_tree/binary_tree.zig @@ -0,0 +1,40 @@ +// File: binary_tree.zig +// Created Time: 2023-01-14 +// Author: sjinzh (sjinzh@gmail.com) + +const std = @import("std"); +const inc = @import("include"); + +// Driver Code +pub fn main() !void { + // 初始化二叉树 + // 初始化结点 + var n1 = inc.TreeNode(i32){ .val = 1 }; + var n2 = inc.TreeNode(i32){ .val = 2 }; + var n3 = inc.TreeNode(i32){ .val = 3 }; + var n4 = inc.TreeNode(i32){ .val = 4 }; + var n5 = inc.TreeNode(i32){ .val = 5 }; + // 构建引用指向(即指针) + n1.left = &n2; + n1.right = &n3; + n2.left = &n4; + n2.right = &n5; + std.debug.print("初始化二叉树\n", .{}); + try inc.PrintUtil.printTree(&n1, null, false); + + // 插入与删除结点 + var p = inc.TreeNode(i32){ .val = 0 }; + // 在 n1 -> n2 中间插入结点 P + n1.left = &p; + p.left = &n2; + std.debug.print("插入结点 P 后\n", .{}); + try inc.PrintUtil.printTree(&n1, null, false); + // 删除结点 + n1.left = &n2; + std.debug.print("删除结点 P 后\n", .{}); + try inc.PrintUtil.printTree(&n1, null, false); + + const getchar = try std.io.getStdIn().reader().readByte(); + _ = getchar; +} + diff --git a/codes/zig/include/ListNode.zig b/codes/zig/include/ListNode.zig index ae0246c09..da7e667c0 100644 --- a/codes/zig/include/ListNode.zig +++ b/codes/zig/include/ListNode.zig @@ -16,6 +16,21 @@ pub fn ListNode(comptime T: type) type { // Initialize a list node with specific value pub fn init(self: *Self, x: i32) void { self.val = x; + self.next = null; } }; +} + +// Generate a linked list with a list +pub fn listToLinkedList(comptime T: type, mem_allocator: std.mem.Allocator, list: std.ArrayList(T)) !?*ListNode(T) { + var dum = try mem_allocator.create(ListNode(T)); + dum.init(0); + var head = dum; + for (list.items) |val| { + var tmp = try mem_allocator.create(ListNode(T)); + tmp.init(val); + head.next = tmp; + head = head.next.?; + } + return dum.next; } \ No newline at end of file diff --git a/codes/zig/include/PrintUtil.zig b/codes/zig/include/PrintUtil.zig index 4d2d20893..d126acb32 100644 --- a/codes/zig/include/PrintUtil.zig +++ b/codes/zig/include/PrintUtil.zig @@ -3,8 +3,10 @@ // Author: sjinzh (sjinzh@gmail.com) const std = @import("std"); -const ListNode = @import("ListNode.zig").ListNode; -const TreeNode = @import("TreeNode.zig").TreeNode; +pub const ListUtil = @import("ListNode.zig"); +pub const ListNode = ListUtil.ListNode; +pub const TreeUtil = @import("TreeNode.zig"); +pub const TreeNode = TreeUtil.TreeNode; // Print an array pub fn printArray(comptime T: type, nums: []T) void { @@ -46,6 +48,27 @@ pub fn printLinkedList(comptime T: type, node: ?*ListNode(T)) !void { } } +// Print a HashMap +pub fn printHashMap(comptime TKey: type, comptime TValue: type, map: std.AutoHashMap(TKey, TValue)) void { + var it = map.iterator(); + while (it.next()) |kv| { + var key = kv.key_ptr.*; + var value = kv.value_ptr.*; + std.debug.print("{} -> {s}\n", .{key, value}); + } +} + +// print a heap (PriorityQueue) +pub fn printHeap(comptime T: type, mem_allocator: std.mem.Allocator, queue: anytype) !void { + var arr = queue.items; + var len = queue.len; + std.debug.print("堆的数组表示:", .{}); + printArray(T, arr[0..len]); + std.debug.print("\n堆的树状表示:\n", .{}); + var root = try TreeUtil.arrToTree(T, mem_allocator, arr[0..len]); + try printTree(root, null, false); +} + // This tree printer is borrowed from TECHIE DELIGHT // https://www.techiedelight.com/c-program-print-binary-tree/ const Trunk = struct { diff --git a/codes/zig/include/TreeNode.zig b/codes/zig/include/TreeNode.zig index 12af9e8f3..7c1e2ad22 100644 --- a/codes/zig/include/TreeNode.zig +++ b/codes/zig/include/TreeNode.zig @@ -17,6 +17,44 @@ pub fn TreeNode(comptime T: type) type { // Initialize a tree node with specific value pub fn init(self: *Self, x: i32) void { self.val = x; + self.left = null; + self.right = null; } }; +} + +// Generate a binary tree with an array +pub fn arrToTree(comptime T: type, mem_allocator: std.mem.Allocator, list: []T) !?*TreeNode(T) { + if (list.len == 0) return null; + var root = try mem_allocator.create(TreeNode(T)); + root.init(list[0]); + + const TailQueue = std.TailQueue(?*TreeNode(T)); + const TailQueueNode = std.TailQueue(?*TreeNode(T)).Node; + var que = TailQueue{}; + var node_root = TailQueueNode{ .data = root }; + que.append(&node_root); + var index: usize = 0; + while (que.len > 0) { + var node = que.popFirst(); + index += 1; + if (index >= list.len) break; + if (index < list.len) { + var tmp = try mem_allocator.create(TreeNode(T)); + tmp.init(list[index]); + node.?.data.?.left = tmp; + var a = TailQueueNode{ .data = node.?.data.?.left }; + que.append(&a); + } + index += 1; + if (index >= list.len) break; + if (index < list.len) { + var tmp = try mem_allocator.create(TreeNode(T)); + tmp.init(list[index]); + node.?.data.?.right = tmp; + var a = TailQueueNode{ .data = node.?.data.?.right }; + que.append(&a); + } + } + return root; } \ No newline at end of file diff --git a/codes/zig/include/include.zig b/codes/zig/include/include.zig index 20dfca90f..42cd76cf1 100644 --- a/codes/zig/include/include.zig +++ b/codes/zig/include/include.zig @@ -3,5 +3,7 @@ // Author: sjinzh (sjinzh@gmail.com) pub const PrintUtil = @import("PrintUtil.zig"); -pub const ListNode = @import("ListNode.zig").ListNode; -pub const TreeNode = @import("TreeNode.zig").TreeNode; \ No newline at end of file +pub const ListUtil = @import("ListNode.zig"); +pub const ListNode = ListUtil.ListNode; +pub const TreeUtil = @import("TreeNode.zig"); +pub const TreeNode = TreeUtil.TreeNode; \ No newline at end of file