// File: heap.zig // Created Time: 2023-01-14 // Author: codingonion (coderonion@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 min_heap = PQlt.init(std.heap.page_allocator, {}); defer min_heap.deinit(); // 最大ヒープを初期化 const PQgt = std.PriorityQueue(i32, void, greaterThan); var max_heap = PQgt.init(std.heap.page_allocator, {}); defer max_heap.deinit(); std.debug.print("\n以下のテストケースは最大ヒープ", .{}); // 要素をヒープに追加 try testPush(i32, mem_allocator, &max_heap, 1); try testPush(i32, mem_allocator, &max_heap, 3); try testPush(i32, mem_allocator, &max_heap, 2); try testPush(i32, mem_allocator, &max_heap, 5); try testPush(i32, mem_allocator, &max_heap, 4); // ヒープ頂点の要素を取得 var peek = max_heap.peek().?; std.debug.print("\nヒープの先頭要素は {}\n", .{peek}); // ヒープ頂点の要素を取り出す try testPop(i32, mem_allocator, &max_heap); try testPop(i32, mem_allocator, &max_heap); try testPop(i32, mem_allocator, &max_heap); try testPop(i32, mem_allocator, &max_heap); try testPop(i32, mem_allocator, &max_heap); // ヒープのサイズを取得 var size = max_heap.len; std.debug.print("\nヒープ要素数は {}\n", .{size}); // ヒープが空かどうかを判定 var is_empty = if (max_heap.len == 0) true else false; std.debug.print("\nヒープが空かどうか {}\n", .{is_empty}); // リストを入力してヒープを構築 try min_heap.addSlice(&[_]i32{ 1, 3, 2, 5, 4 }); std.debug.print("\nリストを入力して最小ヒープを構築した後\n", .{}); try inc.PrintUtil.printHeap(i32, mem_allocator, min_heap); _ = try std.io.getStdIn().reader().readByte(); }