diff --git a/codes/zig/build.zig b/codes/zig/build.zig index 4ba9bea82..52d2103c7 100644 --- a/codes/zig/build.zig +++ b/codes/zig/build.zig @@ -242,6 +242,34 @@ pub fn build(b: *std.build.Builder) void { const run_step_linear_search= b.step("run_linear_search", "Run linear_search"); run_step_linear_search.dependOn(&run_cmd_linear_search.step); + // Section: "Binary Search" + // Source File: "chapter_searching/binary_search.zig" + // Run Command: zig build run_binary_search + const exe_binary_search = b.addExecutable("binary_search", "chapter_searching/binary_search.zig"); + exe_binary_search.addPackagePath("include", "include/include.zig"); + exe_binary_search.setTarget(target); + exe_binary_search.setBuildMode(mode); + exe_binary_search.install(); + const run_cmd_binary_search = exe_binary_search.run(); + run_cmd_binary_search.step.dependOn(b.getInstallStep()); + if (b.args) |args| run_cmd_binary_search.addArgs(args); + const run_step_binary_search= b.step("run_binary_search", "Run binary_search"); + run_step_binary_search.dependOn(&run_cmd_binary_search.step); + + // Section: "Hash Search" + // Source File: "chapter_searching/hashing_search.zig" + // Run Command: zig build run_hashing_search + const exe_hashing_search = b.addExecutable("hashing_search", "chapter_searching/hashing_search.zig"); + exe_hashing_search.addPackagePath("include", "include/include.zig"); + exe_hashing_search.setTarget(target); + exe_hashing_search.setBuildMode(mode); + exe_hashing_search.install(); + const run_cmd_hashing_search = exe_hashing_search.run(); + run_cmd_hashing_search.step.dependOn(b.getInstallStep()); + if (b.args) |args| run_cmd_hashing_search.addArgs(args); + const run_step_hashing_search= b.step("run_hashing_search", "Run hashing_search"); + run_step_hashing_search.dependOn(&run_cmd_hashing_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_searching/binary_search.zig b/codes/zig/chapter_searching/binary_search.zig new file mode 100644 index 000000000..0a2f754f4 --- /dev/null +++ b/codes/zig/chapter_searching/binary_search.zig @@ -0,0 +1,65 @@ +// File: binary_search.zig +// Created Time: 2023-01-15 +// Author: sjinzh (sjinzh@gmail.com) + +const std = @import("std"); +const inc = @import("include"); + +// 二分查找(双闭区间) +fn binarySearch(comptime T: type, nums: std.ArrayList(T), target: T) T { + // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素 + var i: usize = 0; + var j: usize = nums.items.len - 1; + // 循环,当搜索区间为空时跳出(当 i > j 时为空) + while (i <= j) { + var m = (i + j) / 2; // 计算中点索引 m + if (nums.items[m] < target) { // 此情况说明 target 在区间 [m+1, j] 中 + i = m + 1; + } else if (nums.items[m] > target) { // 此情况说明 target 在区间 [i, m-1] 中 + j = m - 1; + } else { // 找到目标元素,返回其索引 + return @intCast(T, m); + } + } + // 未找到目标元素,返回 -1 + return -1; +} + +// 二分查找(左闭右开) +fn binarySearch1(comptime T: type, nums: std.ArrayList(T), target: T) T { + // 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1 + var i: usize = 0; + var j: usize = nums.items.len; + // 循环,当搜索区间为空时跳出(当 i = j 时为空) + while (i <= j) { + var m = (i + j) / 2; // 计算中点索引 m + if (nums.items[m] < target) { // 此情况说明 target 在区间 [m+1, j) 中 + i = m + 1; + } else if (nums.items[m] > target) { // 此情况说明 target 在区间 [i, m) 中 + j = m; + } else { // 找到目标元素,返回其索引 + return @intCast(T, m); + } + } + // 未找到目标元素,返回 -1 + return -1; +} + +// Driver Code +pub fn main() !void { + var target: i32 = 6; + var nums = std.ArrayList(i32).init(std.heap.page_allocator); + defer nums.deinit(); + try nums.appendSlice(&[_]i32{ 1, 3, 6, 8, 12, 15, 23, 67, 70, 92 }); + + // 二分查找(双闭区间) + var index = binarySearch(i32, nums, target); + std.debug.print("目标元素 6 的索引 = {}\n", .{index}); + + // 二分查找(左闭右开) + index = binarySearch1(i32, nums, target); + std.debug.print("目标元素 6 的索引 = {}\n", .{index}); + + _ = try std.io.getStdIn().reader().readByte(); +} + diff --git a/codes/zig/chapter_searching/hashing_search.zig b/codes/zig/chapter_searching/hashing_search.zig new file mode 100644 index 000000000..b6f1a5552 --- /dev/null +++ b/codes/zig/chapter_searching/hashing_search.zig @@ -0,0 +1,57 @@ +// File: hashing_search.zig +// Created Time: 2023-01-15 +// Author: sjinzh (sjinzh@gmail.com) + +const std = @import("std"); +const inc = @import("include"); + +// 哈希查找(数组) +fn hashingSearch(comptime T: type, map: std.AutoHashMap(T, T), target: T) T { + // 哈希表的 key: 目标元素,value: 索引 + // 若哈希表中无此 key ,返回 -1 + if (map.getKey(target) == null) return -1; + return map.get(target).?; +} + +// 哈希查找(数组) +fn hashingSearch1(comptime T: type, map: std.AutoHashMap(T, *inc.ListNode(T)), target: T) ?*inc.ListNode(T) { + // 哈希表的 key: 目标结点值,value: 结点对象 + // 若哈希表中无此 key ,返回 null + if (map.getKey(target) == null) return null; + return map.get(target); +} + +// Driver Code +pub fn main() !void { + var target: i32 = 3; + + // 哈希查找(数组) + var nums = [_]i32{ 1, 5, 3, 2, 4, 7, 5, 9, 10, 8 }; + // 初始化哈希表 + var map = std.AutoHashMap(i32, i32).init(std.heap.page_allocator); + defer map.deinit(); + for (nums) |num, i| { + try map.put(num, @intCast(i32, i)); // key: 元素,value: 索引 + } + var index = hashingSearch(i32, map, 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.arrToLinkedList(i32, mem_allocator, &nums); + // 初始化哈希表 + var map1 = std.AutoHashMap(i32, *inc.ListNode(i32)).init(std.heap.page_allocator); + defer map1.deinit(); + while (head != null) { + try map1.put(head.?.val, head.?); + head = head.?.next; + } + var node = hashingSearch1(i32, map1, target); + std.debug.print("目标结点值 3 的对应结点对象为 ", .{}); + try inc.PrintUtil.printLinkedList(i32, node); + + _ = try std.io.getStdIn().reader().readByte(); +} + diff --git a/codes/zig/include/ListNode.zig b/codes/zig/include/ListNode.zig index da7e667c0..19ece1174 100644 --- a/codes/zig/include/ListNode.zig +++ b/codes/zig/include/ListNode.zig @@ -33,4 +33,18 @@ pub fn listToLinkedList(comptime T: type, mem_allocator: std.mem.Allocator, list head = head.next.?; } return dum.next; +} + +// Generate a linked list with an array +pub fn arrToLinkedList(comptime T: type, mem_allocator: std.mem.Allocator, arr: []T) !?*ListNode(T) { + var dum = try mem_allocator.create(ListNode(T)); + dum.init(0); + var head = dum; + for (arr) |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