From 5e17778f69efd028a5d358c92e04b38beec903ca Mon Sep 17 00:00:00 2001 From: sjinzh <99076655+sjinzh@users.noreply.github.com> Date: Sun, 15 Jan 2023 20:39:46 +0800 Subject: [PATCH] update zig codes for Section 'Heap' (heap.zig) --- codes/zig/chapter_heap/heap.zig | 11 +++--- codes/zig/include/PrintUtil.zig | 7 +++- codes/zig/include/TreeNode.zig | 70 +++++++++++++++++++++++++-------- 3 files changed, 64 insertions(+), 24 deletions(-) diff --git a/codes/zig/chapter_heap/heap.zig b/codes/zig/chapter_heap/heap.zig index 1f4162a53..d6e8f3e05 100644 --- a/codes/zig/chapter_heap/heap.zig +++ b/codes/zig/chapter_heap/heap.zig @@ -18,13 +18,13 @@ fn testPush(comptime T: type, mem_allocator: std.mem.Allocator, heap_push: anyty var heap = heap_push; try heap.add(val); //元素入堆 std.debug.print("\n元素 {} 入堆后\n", .{val}); - try inc.PrintUtil.printHeap(T, mem_allocator, heap); + try inc.PrintUtil.printHeap(T, mem_allocator, heap, true); } fn testPop(comptime T: type, mem_allocator: std.mem.Allocator, heap_pop: anytype) !void { var val = heap_pop.remove(); //堆顶元素出堆 std.debug.print("\n堆顶元素 {} 出堆后\n", .{val}); - try inc.PrintUtil.printHeap(T, mem_allocator, heap_pop); + try inc.PrintUtil.printHeap(T, mem_allocator, heap_pop, true); } // Driver Code @@ -74,11 +74,10 @@ pub fn main() !void { // 输入列表并建堆 // 时间复杂度为 O(n) ,而非 O(nlogn) - try minHeap.addSlice(&[_]i32{ 1, 3, 2, 5, 4 }); + try minHeap.addSlice(&[_]i32{ 1, 3, 2, 5, 4, 8, 9 }); std.debug.print("\n输入列表并建立小顶堆后\n", .{}); - try inc.PrintUtil.printHeap(i32, mem_allocator, minHeap); + try inc.PrintUtil.printHeap(i32, mem_allocator, minHeap, true); const getchar = try std.io.getStdIn().reader().readByte(); _ = getchar; -} - +} \ No newline at end of file diff --git a/codes/zig/include/PrintUtil.zig b/codes/zig/include/PrintUtil.zig index d126acb32..9858797c4 100644 --- a/codes/zig/include/PrintUtil.zig +++ b/codes/zig/include/PrintUtil.zig @@ -59,13 +59,16 @@ pub fn printHashMap(comptime TKey: type, comptime TValue: type, map: std.AutoHas } // print a heap (PriorityQueue) -pub fn printHeap(comptime T: type, mem_allocator: std.mem.Allocator, queue: anytype) !void { +pub fn printHeap(comptime T: type, mem_allocator: std.mem.Allocator, queue: anytype, queue_flag: bool) !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]); + var root = if (queue_flag) + try TreeUtil.arrQueToTree(T, mem_allocator, arr[0..len]) // through TailQueue + else + try TreeUtil.arrListToTree(T, mem_allocator, arr[0..len]); // through ArrayList to work as queue try printTree(root, null, false); } diff --git a/codes/zig/include/TreeNode.zig b/codes/zig/include/TreeNode.zig index a3715dbdf..b2498fb1f 100644 --- a/codes/zig/include/TreeNode.zig +++ b/codes/zig/include/TreeNode.zig @@ -23,31 +23,69 @@ pub fn TreeNode(comptime T: type) type { }; } -// 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; +// Generate a binary tree with an array (through ArrayList to work as queue) +pub fn arrListToTree(comptime T: type, mem_allocator: std.mem.Allocator, arr: []T) !?*TreeNode(T) { + if (arr.len == 0) return null; var root = try mem_allocator.create(TreeNode(T)); - root.init(list[0]); - var que = std.ArrayList(*TreeNode(T)).init(std.heap.page_allocator); - try que.append(root); + root.init(arr[0]); + var list = std.ArrayList(*TreeNode(T)).init(std.heap.page_allocator); + try list.append(root); var index: usize = 0; - while (que.items.len > 0) { - var node = que.orderedRemove(0); + while (list.items.len > 0) { + var node = list.orderedRemove(0); index += 1; - if (index >= list.len) break; - if (index < list.len) { + if (index >= arr.len) break; + if (index < arr.len) { var tmp = try mem_allocator.create(TreeNode(T)); - tmp.init(list[index]); + tmp.init(arr[index]); node.left = tmp; - try que.append(node.left.?); + try list.append(node.left.?); } index += 1; - if (index >= list.len) break; - if (index < list.len) { + if (index >= arr.len) break; + if (index < arr.len) { var tmp = try mem_allocator.create(TreeNode(T)); - tmp.init(list[index]); + tmp.init(arr[index]); node.right = tmp; - try que.append(node.right.?); + try list.append(node.right.?); + } + } + return root; +} + +// Generate a binary tree with an array (through TailQueue) +pub fn arrQueToTree(comptime T: type, mem_allocator: std.mem.Allocator, arr: []T) !?*TreeNode(T) { + if (arr.len == 0) return null; + var root = try mem_allocator.create(TreeNode(T)); + root.init(arr[0]); + const L = std.TailQueue(*TreeNode(T)); + var que = L{}; + var root_node = try mem_allocator.create(L.Node); + root_node.data = root; + que.append(root_node); + var index: usize = 0; + while (que.len > 0) { + var que_node = que.popFirst().?; + var node = que_node.data; + index += 1; + if (index >= arr.len) break; + if (index < arr.len) { + var tmp = try mem_allocator.create(TreeNode(T)); + tmp.init(arr[index]); + node.left = tmp; + var tmp_node = try mem_allocator.create(L.Node); + tmp_node.data = node.left.?; + que.append(tmp_node); + } + index += 1; + if (index >= arr.len) break; + if (index < arr.len) { + var tmp = try mem_allocator.create(TreeNode(T)); + tmp.init(arr[index]); + node.right = tmp; + var tmp_node = try mem_allocator.create(L.Node); + tmp_node.data = node.right.?; + que.append(tmp_node); } } return root;