mirror of
				https://github.com/krahets/hello-algo.git
				synced 2025-11-04 14:18:20 +08:00 
			
		
		
		
	Merge pull request #256 from sjinzh/master
add zig codes for Section 'Heap' (heap.zig)
This commit is contained in:
		@ -1,5 +1,5 @@
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * File: my_heap.java
 | 
					 * File: heap.java
 | 
				
			||||||
 * Created Time: 2023-01-07
 | 
					 * Created Time: 2023-01-07
 | 
				
			||||||
 * Author: Krahets (krahets@163.com)
 | 
					 * Author: Krahets (krahets@163.com)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
				
			|||||||
@ -188,6 +188,20 @@ pub fn build(b: *std.build.Builder) void {
 | 
				
			|||||||
        const run_step_binary_tree= b.step("run_binary_tree", "Run binary_tree");
 | 
					        const run_step_binary_tree= b.step("run_binary_tree", "Run binary_tree");
 | 
				
			||||||
        run_step_binary_tree.dependOn(&run_cmd_binary_tree.step);
 | 
					        run_step_binary_tree.dependOn(&run_cmd_binary_tree.step);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Section: "Heap"
 | 
				
			||||||
 | 
					        // Source File: "chapter_heap/heap.zig"
 | 
				
			||||||
 | 
					        // Run Command: zig build run_heap
 | 
				
			||||||
 | 
					        const exe_heap = b.addExecutable("heap", "chapter_heap/heap.zig");
 | 
				
			||||||
 | 
					        exe_heap.addPackagePath("include", "include/include.zig");
 | 
				
			||||||
 | 
					        exe_heap.setTarget(target);
 | 
				
			||||||
 | 
					        exe_heap.setBuildMode(mode);
 | 
				
			||||||
 | 
					        exe_heap.install();
 | 
				
			||||||
 | 
					        const run_cmd_heap = exe_heap.run();
 | 
				
			||||||
 | 
					        run_cmd_heap.step.dependOn(b.getInstallStep());
 | 
				
			||||||
 | 
					        if (b.args) |args| run_cmd_heap.addArgs(args);
 | 
				
			||||||
 | 
					        const run_step_heap = b.step("run_heap", "Run heap");
 | 
				
			||||||
 | 
					        run_step_heap.dependOn(&run_cmd_heap.step);
 | 
				
			||||||
 | 
					             
 | 
				
			||||||
    // Section: "Linear Search"
 | 
					    // Section: "Linear Search"
 | 
				
			||||||
        // Source File: "chapter_searching/linear_search.zig"
 | 
					        // Source File: "chapter_searching/linear_search.zig"
 | 
				
			||||||
        // Run Command: zig build run_linear_search
 | 
					        // Run Command: zig build run_linear_search
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										81
									
								
								codes/zig/chapter_heap/heap.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								codes/zig/chapter_heap/heap.zig
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,81 @@
 | 
				
			|||||||
 | 
					// File: heap.zig
 | 
				
			||||||
 | 
					// Created Time: 2023-01-14
 | 
				
			||||||
 | 
					// Author: sjinzh (sjinzh@gmail.com)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const std = @import("std");
 | 
				
			||||||
 | 
					const inc = @import("include");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn lessThan(context: void, a: i32, b: i32) std.math.Order {
 | 
				
			||||||
 | 
					    _ = context;
 | 
				
			||||||
 | 
					    return std.math.order(a, b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn greaterThan(context: void, a: i32, b: i32) std.math.Order {
 | 
				
			||||||
 | 
					    return lessThan(context, a, b).invert();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn testPush(comptime T: type, mem_allocator: std.mem.Allocator, heap: anytype, val: T) !void {
 | 
				
			||||||
 | 
					    try heap.add(val);  //元素入堆
 | 
				
			||||||
 | 
					    std.debug.print("\n元素 {} 入堆后\n", .{val});
 | 
				
			||||||
 | 
					    try inc.PrintUtil.printHeap(T, mem_allocator, heap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn testPop(comptime T: type, mem_allocator: std.mem.Allocator, heap: anytype) !void {
 | 
				
			||||||
 | 
					    var val = heap.remove();    //堆顶元素出堆
 | 
				
			||||||
 | 
					    std.debug.print("\n堆顶元素 {} 出堆后\n", .{val});
 | 
				
			||||||
 | 
					    try inc.PrintUtil.printHeap(T, mem_allocator, heap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Driver Code
 | 
				
			||||||
 | 
					pub fn main() !void {
 | 
				
			||||||
 | 
					    // 初始化内存分配器
 | 
				
			||||||
 | 
					    var mem_arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
 | 
				
			||||||
 | 
					    defer mem_arena.deinit();
 | 
				
			||||||
 | 
					    const mem_allocator = mem_arena.allocator();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 初始化堆
 | 
				
			||||||
 | 
					    // 初始化小顶堆
 | 
				
			||||||
 | 
					    const PQlt = std.PriorityQueue(i32, void, lessThan);
 | 
				
			||||||
 | 
					    var minHeap = PQlt.init(std.heap.page_allocator, {});
 | 
				
			||||||
 | 
					    defer minHeap.deinit();
 | 
				
			||||||
 | 
					    // 初始化大顶堆
 | 
				
			||||||
 | 
					    const PQgt = std.PriorityQueue(i32, void, greaterThan);
 | 
				
			||||||
 | 
					    var maxHeap = PQgt.init(std.heap.page_allocator, {});
 | 
				
			||||||
 | 
					    defer maxHeap.deinit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std.debug.print("\n以下测试样例为大顶堆", .{});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 元素入堆
 | 
				
			||||||
 | 
					    try testPush(i32, mem_allocator, &maxHeap, 1);
 | 
				
			||||||
 | 
					    try testPush(i32, mem_allocator, &maxHeap, 3);
 | 
				
			||||||
 | 
					    try testPush(i32, mem_allocator, &maxHeap, 2);
 | 
				
			||||||
 | 
					    try testPush(i32, mem_allocator, &maxHeap, 5);
 | 
				
			||||||
 | 
					    try testPush(i32, mem_allocator, &maxHeap, 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 获取堆顶元素
 | 
				
			||||||
 | 
					    var peek = maxHeap.peek().?;
 | 
				
			||||||
 | 
					    std.debug.print("\n堆顶元素为 {}\n", .{peek});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 堆顶元素出堆
 | 
				
			||||||
 | 
					    try testPop(i32, mem_allocator, &maxHeap);
 | 
				
			||||||
 | 
					    try testPop(i32, mem_allocator, &maxHeap);
 | 
				
			||||||
 | 
					    try testPop(i32, mem_allocator, &maxHeap);
 | 
				
			||||||
 | 
					    try testPop(i32, mem_allocator, &maxHeap);
 | 
				
			||||||
 | 
					    try testPop(i32, mem_allocator, &maxHeap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 获取堆的大小
 | 
				
			||||||
 | 
					    var size = maxHeap.len;
 | 
				
			||||||
 | 
					    std.debug.print("\n堆元素数量为 {}\n", .{size});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 判断堆是否为空
 | 
				
			||||||
 | 
					    var isEmpty = if (maxHeap.len == 0) true else false;
 | 
				
			||||||
 | 
					    std.debug.print("\n堆是否为空 {}\n", .{isEmpty});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 输入列表并建堆
 | 
				
			||||||
 | 
					    try minHeap.addSlice(&[_]i32{ 1, 3, 2, 5, 4 });
 | 
				
			||||||
 | 
					    std.debug.print("\n输入列表并建立小顶堆后\n", .{});
 | 
				
			||||||
 | 
					    try inc.PrintUtil.printHeap(i32, mem_allocator, minHeap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const getchar = try std.io.getStdIn().reader().readByte();
 | 
				
			||||||
 | 
					    _ = getchar;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -24,36 +24,38 @@ pub fn TreeNode(comptime T: type) type {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Generate a binary tree with an array
 | 
					// Generate a binary tree with an array
 | 
				
			||||||
pub fn arrToTree(comptime T: type, mem_allocator: std.mem.Allocator, list: []T) !?*TreeNode(T) {
 | 
					pub fn arrToTree(comptime T: type, mem_allocator: std.mem.Allocator, arr: []T) !?*TreeNode(T) {
 | 
				
			||||||
    if (list.len == 0) return null;
 | 
					    if (arr.len == 0) return null;
 | 
				
			||||||
    var root = try mem_allocator.create(TreeNode(T));
 | 
					    var root = try mem_allocator.create(TreeNode(T));
 | 
				
			||||||
    root.init(list[0]);
 | 
					    root.init(arr[0]);
 | 
				
			||||||
 | 
					    const L = std.TailQueue(*TreeNode(T));
 | 
				
			||||||
    const TailQueue = std.TailQueue(?*TreeNode(T));
 | 
					    var que = L{};
 | 
				
			||||||
    const TailQueueNode = std.TailQueue(?*TreeNode(T)).Node;
 | 
					    var root_node = try mem_allocator.create(L.Node);
 | 
				
			||||||
    var que = TailQueue{};
 | 
					    root_node.data = root;
 | 
				
			||||||
    var node_root = TailQueueNode{ .data = root };
 | 
					    que.append(root_node); 
 | 
				
			||||||
    que.append(&node_root); 
 | 
					 | 
				
			||||||
    var index: usize = 0;
 | 
					    var index: usize = 0;
 | 
				
			||||||
    while (que.len > 0) {
 | 
					    while (que.len > 0) {
 | 
				
			||||||
        var node = que.popFirst();
 | 
					        var que_node = que.popFirst().?;
 | 
				
			||||||
 | 
					        var node = que_node.data;
 | 
				
			||||||
        index += 1;
 | 
					        index += 1;
 | 
				
			||||||
        if (index >= list.len) break;
 | 
					        if (index >= arr.len) break;
 | 
				
			||||||
        if (index < list.len) {
 | 
					        if (index < arr.len) {
 | 
				
			||||||
            var tmp = try mem_allocator.create(TreeNode(T));
 | 
					            var tmp = try mem_allocator.create(TreeNode(T));
 | 
				
			||||||
            tmp.init(list[index]);
 | 
					            tmp.init(arr[index]);
 | 
				
			||||||
            node.?.data.?.left = tmp;
 | 
					            node.left = tmp;
 | 
				
			||||||
            var a = TailQueueNode{ .data = node.?.data.?.left };
 | 
					            var tmp_node = try mem_allocator.create(L.Node);
 | 
				
			||||||
            que.append(&a);
 | 
					            tmp_node.data = node.left.?;
 | 
				
			||||||
 | 
					            que.append(tmp_node);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        index += 1;
 | 
					        index += 1;
 | 
				
			||||||
        if (index >= list.len) break;
 | 
					        if (index >= arr.len) break;
 | 
				
			||||||
        if (index < list.len) {
 | 
					        if (index < arr.len) {
 | 
				
			||||||
            var tmp = try mem_allocator.create(TreeNode(T));
 | 
					            var tmp = try mem_allocator.create(TreeNode(T));
 | 
				
			||||||
            tmp.init(list[index]);
 | 
					            tmp.init(arr[index]);
 | 
				
			||||||
            node.?.data.?.right = tmp;
 | 
					            node.right = tmp;
 | 
				
			||||||
            var a = TailQueueNode{ .data = node.?.data.?.right };
 | 
					            var tmp_node = try mem_allocator.create(L.Node);
 | 
				
			||||||
            que.append(&a);
 | 
					            tmp_node.data = node.right.?;
 | 
				
			||||||
 | 
					            que.append(tmp_node);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return root;
 | 
					    return root;
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user