mirror of
				https://github.com/krahets/hello-algo.git
				synced 2025-11-04 22:28:40 +08:00 
			
		
		
		
	Merge pull request #228 from sjinzh/master
add zig codes for Section 'Space Complexity' and 'Space Time Tradeoff'
This commit is contained in:
		@ -56,6 +56,7 @@ int bubbleSort(int *nums, int n) {
 | 
			
		||||
    for (int i = n - 1; i > 0; i--) {
 | 
			
		||||
        // 内循环:冒泡操作
 | 
			
		||||
        for (int j = 0; j < i; j++) {
 | 
			
		||||
            if (nums[j] > nums[j + 1]) {
 | 
			
		||||
                // 交换 nums[j] 与 nums[j + 1]
 | 
			
		||||
                int tmp = nums[j];
 | 
			
		||||
                nums[j] = nums[j + 1];
 | 
			
		||||
@ -63,6 +64,7 @@ int bubbleSort(int *nums, int n) {
 | 
			
		||||
                count += 3;  // 元素交换包含 3 个单元操作
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,17 @@
 | 
			
		||||
// File: build.zig
 | 
			
		||||
// Created Time: 2023-01-07
 | 
			
		||||
// Author: sjinzh (sjinzh@gmail.com)
 | 
			
		||||
 | 
			
		||||
const std = @import("std");
 | 
			
		||||
 | 
			
		||||
// zig version 0.10.0
 | 
			
		||||
// Zig Version: 0.10.0
 | 
			
		||||
// Build Command: zig build
 | 
			
		||||
pub fn build(b: *std.build.Builder) void {
 | 
			
		||||
    const target = b.standardTargetOptions(.{});
 | 
			
		||||
    const mode = b.standardReleaseOptions();
 | 
			
		||||
 | 
			
		||||
    // "chapter_computational_complexity/time_complexity.zig"
 | 
			
		||||
    // Section: "Time Complexity"
 | 
			
		||||
        // Source File: "chapter_computational_complexity/time_complexity.zig"
 | 
			
		||||
        // Run Command: zig build run_time_complexity
 | 
			
		||||
        const exe_time_complexity = b.addExecutable("time_complexity", "chapter_computational_complexity/time_complexity.zig");
 | 
			
		||||
        exe_time_complexity.addPackagePath("include", "include/include.zig");
 | 
			
		||||
@ -18,7 +24,7 @@ pub fn build(b: *std.build.Builder) void {
 | 
			
		||||
        const run_step_time_complexity = b.step("run_time_complexity", "Run time_complexity");
 | 
			
		||||
        run_step_time_complexity.dependOn(&run_cmd_time_complexity.step);
 | 
			
		||||
 | 
			
		||||
    // "chapter_computational_complexity/worst_best_time_complexity.zig"
 | 
			
		||||
        // Source File: "chapter_computational_complexity/worst_best_time_complexity.zig"
 | 
			
		||||
        // Run Command: zig build run_worst_best_time_complexity
 | 
			
		||||
        const exe_worst_best_time_complexity = b.addExecutable("worst_best_time_complexity", "chapter_computational_complexity/worst_best_time_complexity.zig");
 | 
			
		||||
        exe_worst_best_time_complexity.addPackagePath("include", "include/include.zig");
 | 
			
		||||
@ -31,7 +37,22 @@ pub fn build(b: *std.build.Builder) void {
 | 
			
		||||
        const run_step_worst_best_time_complexity = b.step("run_worst_best_time_complexity", "Run worst_best_time_complexity");
 | 
			
		||||
        run_step_worst_best_time_complexity.dependOn(&run_cmd_worst_best_time_complexity.step);
 | 
			
		||||
 | 
			
		||||
    // "chapter_computational_complexity/leetcode_two_sum.zig"
 | 
			
		||||
    // Section: "Space Complexity"
 | 
			
		||||
        // Source File: "chapter_computational_complexity/space_complexity.zig"
 | 
			
		||||
        // Run Command: zig build run_space_complexity
 | 
			
		||||
        const exe_space_complexity = b.addExecutable("space_complexity", "chapter_computational_complexity/space_complexity.zig");
 | 
			
		||||
        exe_space_complexity.addPackagePath("include", "include/include.zig");
 | 
			
		||||
        exe_space_complexity.setTarget(target);
 | 
			
		||||
        exe_space_complexity.setBuildMode(mode);
 | 
			
		||||
        exe_space_complexity.install();
 | 
			
		||||
        const run_cmd_space_complexity = exe_space_complexity.run();
 | 
			
		||||
        run_cmd_space_complexity.step.dependOn(b.getInstallStep());
 | 
			
		||||
        if (b.args) |args| run_cmd_space_complexity.addArgs(args);
 | 
			
		||||
        const run_step_space_complexity = b.step("run_space_complexity", "Run space_complexity");
 | 
			
		||||
        run_step_space_complexity.dependOn(&run_cmd_space_complexity.step);
 | 
			
		||||
 | 
			
		||||
    // Section: "Space Time Tradeoff"
 | 
			
		||||
        // Source File: "chapter_computational_complexity/leetcode_two_sum.zig"
 | 
			
		||||
        // Run Command: zig build run_leetcode_two_sum
 | 
			
		||||
        const exe_leetcode_two_sum = b.addExecutable("leetcode_two_sum", "chapter_computational_complexity/leetcode_two_sum.zig");
 | 
			
		||||
        exe_leetcode_two_sum.addPackagePath("include", "include/include.zig");
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										125
									
								
								codes/zig/chapter_computational_complexity/space_complexity.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								codes/zig/chapter_computational_complexity/space_complexity.zig
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,125 @@
 | 
			
		||||
// File: space_complexity.zig
 | 
			
		||||
// Created Time: 2023-01-07
 | 
			
		||||
// Author: sjinzh (sjinzh@gmail.com)
 | 
			
		||||
 | 
			
		||||
const std = @import("std");
 | 
			
		||||
const inc = @import("include");
 | 
			
		||||
 | 
			
		||||
// 函数
 | 
			
		||||
fn function() i32 {
 | 
			
		||||
    // do something
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 常数阶
 | 
			
		||||
fn constant(n: i32) void {
 | 
			
		||||
    // 常量、变量、对象占用 O(1) 空间
 | 
			
		||||
    const a: i32 = 0;
 | 
			
		||||
    var b: i32 = 0;
 | 
			
		||||
    var nums = [_]i32{0}**10000;
 | 
			
		||||
    var node = inc.ListNode(i32){.val = 0};
 | 
			
		||||
    var i: i32 = 0;
 | 
			
		||||
    // 循环中的变量占用 O(1) 空间
 | 
			
		||||
    while (i < n) : (i += 1) {
 | 
			
		||||
        var c: i32 = 0;
 | 
			
		||||
        _ = c;
 | 
			
		||||
    }
 | 
			
		||||
    // 循环中的函数占用 O(1) 空间
 | 
			
		||||
    i = 0;
 | 
			
		||||
    while (i < n) : (i += 1) {
 | 
			
		||||
        _ = function();
 | 
			
		||||
    }
 | 
			
		||||
    _ = a;
 | 
			
		||||
    _ = b;
 | 
			
		||||
    _ = nums;
 | 
			
		||||
    _ = node;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 线性阶
 | 
			
		||||
fn linear(comptime n: i32) !void {
 | 
			
		||||
    // 长度为 n 的数组占用 O(n) 空间
 | 
			
		||||
    var nums = [_]i32{0}**n;
 | 
			
		||||
    // 长度为 n 的列表占用 O(n) 空间
 | 
			
		||||
    var nodes = std.ArrayList(i32).init(std.heap.page_allocator);
 | 
			
		||||
    defer nodes.deinit();
 | 
			
		||||
    var i: i32 = 0;
 | 
			
		||||
    while (i < n) : (i += 1) {
 | 
			
		||||
        try nodes.append(i);
 | 
			
		||||
    }
 | 
			
		||||
    // 长度为 n 的哈希表占用 O(n) 空间
 | 
			
		||||
    var map = std.AutoArrayHashMap(i32, []const u8).init(std.heap.page_allocator);
 | 
			
		||||
    defer map.deinit();
 | 
			
		||||
    var j: i32 = 0;
 | 
			
		||||
    while (j < n) : (j += 1) {
 | 
			
		||||
        const string = try std.fmt.allocPrint(std.heap.page_allocator, "{d}", .{j});
 | 
			
		||||
        defer std.heap.page_allocator.free(string);
 | 
			
		||||
        try map.put(i, string);
 | 
			
		||||
    }
 | 
			
		||||
    _ = nums;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 线性阶(递归实现)
 | 
			
		||||
fn linearRecur(comptime n: i32) void {
 | 
			
		||||
    std.debug.print("递归 n = {}\n", .{n});
 | 
			
		||||
    if (n == 1) return;
 | 
			
		||||
    linearRecur(n - 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 平方阶
 | 
			
		||||
fn quadratic(n: i32) !void {
 | 
			
		||||
    // 二维列表占用 O(n^2) 空间
 | 
			
		||||
    var nodes = std.ArrayList(std.ArrayList(i32)).init(std.heap.page_allocator);
 | 
			
		||||
    defer nodes.deinit();
 | 
			
		||||
    var i: i32 = 0;
 | 
			
		||||
    while (i < n) : (i += 1) {
 | 
			
		||||
        var tmp = std.ArrayList(i32).init(std.heap.page_allocator);
 | 
			
		||||
        defer tmp.deinit();
 | 
			
		||||
        var j: i32 = 0;
 | 
			
		||||
        while (j < n) : (j += 1) {
 | 
			
		||||
            try tmp.append(0);
 | 
			
		||||
        }
 | 
			
		||||
        try nodes.append(tmp);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 平方阶(递归实现)
 | 
			
		||||
fn quadraticRecur(comptime n: i32) i32 {
 | 
			
		||||
    if (n <= 0) return 0;
 | 
			
		||||
    var nums = [_]i32{0}**n;
 | 
			
		||||
    std.debug.print("递归 n = {} 中的 nums 长度 = {}\n", .{n, nums.len});
 | 
			
		||||
    return quadraticRecur(n - 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 指数阶(建立满二叉树)
 | 
			
		||||
fn buildTree(mem_allocator: std.mem.Allocator, n: i32) !?*inc.TreeNode(i32) {
 | 
			
		||||
    if (n == 0) return null;
 | 
			
		||||
    const root = try mem_allocator.create(inc.TreeNode(i32));
 | 
			
		||||
    root.init(0);
 | 
			
		||||
    root.left = try buildTree(mem_allocator, n - 1);
 | 
			
		||||
    root.right = try buildTree(mem_allocator, n - 1);
 | 
			
		||||
    return root;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Driver Code
 | 
			
		||||
pub fn main() !void {
 | 
			
		||||
    const n: i32 = 5;
 | 
			
		||||
    // 常数阶
 | 
			
		||||
    constant(n);
 | 
			
		||||
    // 线性阶
 | 
			
		||||
    try linear(n);
 | 
			
		||||
    linearRecur(n);
 | 
			
		||||
    // 平方阶
 | 
			
		||||
    try quadratic(n);
 | 
			
		||||
    _ = quadraticRecur(n);
 | 
			
		||||
    // 指数阶
 | 
			
		||||
    var mem_arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
 | 
			
		||||
    defer mem_arena.deinit();
 | 
			
		||||
    var root = blk_root: {
 | 
			
		||||
        const mem_allocator = mem_arena.allocator();
 | 
			
		||||
        break :blk_root try buildTree(mem_allocator, n);
 | 
			
		||||
    };
 | 
			
		||||
    try inc.PrintUtil.printTree(root, null, false);
 | 
			
		||||
 | 
			
		||||
    const getchar = try std.io.getStdIn().reader().readByte();
 | 
			
		||||
    _ = getchar;
 | 
			
		||||
}
 | 
			
		||||
@ -59,6 +59,7 @@ fn bubbleSort(nums: []i32) i32 {
 | 
			
		||||
        var j: usize = 0;
 | 
			
		||||
        // 内循环:冒泡操作
 | 
			
		||||
        while (j < i) : (j += 1) {
 | 
			
		||||
            if (nums[j] > nums[j + 1]) {
 | 
			
		||||
                // 交换 nums[j] 与 nums[j + 1]
 | 
			
		||||
                var tmp = nums[j];
 | 
			
		||||
                nums[j] = nums[j + 1];
 | 
			
		||||
@ -66,6 +67,7 @@ fn bubbleSort(nums: []i32) i32 {
 | 
			
		||||
                count += 3;  // 元素交换包含 3 个单元操作
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -138,7 +140,7 @@ fn factorialRecur(n: i32) i32 {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Driver Code
 | 
			
		||||
pub fn main() void {
 | 
			
		||||
pub fn main() !void {
 | 
			
		||||
    // 可以修改 n 运行,体会一下各种复杂度的操作数量变化趋势
 | 
			
		||||
    const n: i32 = 8;
 | 
			
		||||
    std.debug.print("输入数据大小 n = {}\n", .{n});
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ pub fn findOne(nums: []i32) i32 {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Driver Code
 | 
			
		||||
pub fn main() void {
 | 
			
		||||
pub fn main() !void {
 | 
			
		||||
    var i: i32 = 0;
 | 
			
		||||
    while (i < 10) : (i += 1) {
 | 
			
		||||
        const n: usize = 100;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										21
									
								
								codes/zig/include/ListNode.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								codes/zig/include/ListNode.zig
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
			
		||||
// File: ListNode.zig
 | 
			
		||||
// Created Time: 2023-01-07
 | 
			
		||||
// Author: sjinzh (sjinzh@gmail.com)
 | 
			
		||||
 | 
			
		||||
const std = @import("std");
 | 
			
		||||
 | 
			
		||||
// Definition for a singly-linked list node
 | 
			
		||||
// 编译期泛型
 | 
			
		||||
pub fn ListNode(comptime T: type) type {
 | 
			
		||||
    return struct {
 | 
			
		||||
        const Self = @This();
 | 
			
		||||
        
 | 
			
		||||
        val: T = 0,
 | 
			
		||||
        next: ?*Self = null,
 | 
			
		||||
 | 
			
		||||
        // Initialize a list node with specific value
 | 
			
		||||
        pub fn init(self: *Self, x: i32) void {
 | 
			
		||||
            self.val = x;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
@ -1,13 +1,73 @@
 | 
			
		||||
// File: TreeNode.zig
 | 
			
		||||
// File: PrintUtil.zig
 | 
			
		||||
// Created Time: 2023-01-07
 | 
			
		||||
// Author: sjinzh (sjinzh@gmail.com)
 | 
			
		||||
 | 
			
		||||
const std = @import("std");
 | 
			
		||||
const ListNode = @import("ListNode.zig").ListNode;
 | 
			
		||||
const TreeNode = @import("TreeNode.zig").TreeNode;
 | 
			
		||||
 | 
			
		||||
// Print an Array
 | 
			
		||||
// Print an array
 | 
			
		||||
// 编译期泛型
 | 
			
		||||
pub fn printArray(comptime T: type, nums: []T) void {
 | 
			
		||||
    std.debug.print("[", .{});
 | 
			
		||||
    if (nums.len > 0) {
 | 
			
		||||
        for (nums) |num, j| {
 | 
			
		||||
            std.debug.print("{}{s}", .{num, if (j == nums.len-1) "]\n" else ", " });
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        std.debug.print("]", .{});
 | 
			
		||||
        std.debug.print("\n", .{});
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This tree printer is borrowed from TECHIE DELIGHT
 | 
			
		||||
// https://www.techiedelight.com/c-program-print-binary-tree/
 | 
			
		||||
const Trunk = struct {
 | 
			
		||||
    prev: ?*Trunk = null,
 | 
			
		||||
    str: []const u8 = undefined,
 | 
			
		||||
    
 | 
			
		||||
    pub fn init(self: *Trunk, prev: ?*Trunk, str: []const u8) void {
 | 
			
		||||
        self.prev = prev;
 | 
			
		||||
        self.str = str;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Helper function to print branches of the binary tree
 | 
			
		||||
pub fn showTrunks(p: ?*Trunk) void {
 | 
			
		||||
    if (p == null) return;
 | 
			
		||||
    showTrunks(p.?.prev);
 | 
			
		||||
    std.debug.print("{s}", .{p.?.str});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// The interface of the tree printer
 | 
			
		||||
// Print a binary tree
 | 
			
		||||
pub fn printTree(root: ?*TreeNode(i32), prev: ?*Trunk, isLeft: bool) !void {
 | 
			
		||||
    if (root == null) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var prev_str = "    ";
 | 
			
		||||
    var trunk = Trunk{.prev = prev, .str = prev_str};
 | 
			
		||||
 | 
			
		||||
    try printTree(root.?.right, &trunk, true);
 | 
			
		||||
   
 | 
			
		||||
    if (prev == null) {
 | 
			
		||||
        trunk.str = "———";
 | 
			
		||||
    } else if (isLeft) {
 | 
			
		||||
        trunk.str = "/———";
 | 
			
		||||
        prev_str = "   |";
 | 
			
		||||
    } else {
 | 
			
		||||
        trunk.str = "\\———";
 | 
			
		||||
        prev.?.str = prev_str;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    showTrunks(&trunk);
 | 
			
		||||
    std.debug.print(" {}\n", .{root.?.val});
 | 
			
		||||
 | 
			
		||||
    if (prev) |_| {
 | 
			
		||||
        prev.?.str = prev_str;
 | 
			
		||||
    }
 | 
			
		||||
    trunk.str = "   |";
 | 
			
		||||
 | 
			
		||||
    try printTree(root.?.left, &trunk, false);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								codes/zig/include/TreeNode.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								codes/zig/include/TreeNode.zig
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
// File: TreeNode.zig
 | 
			
		||||
// Created Time: 2023-01-07
 | 
			
		||||
// Author: sjinzh (sjinzh@gmail.com)
 | 
			
		||||
 | 
			
		||||
const std = @import("std");
 | 
			
		||||
 | 
			
		||||
// Definition for a binary tree node
 | 
			
		||||
// 编译期泛型
 | 
			
		||||
pub fn TreeNode(comptime T: type) type {
 | 
			
		||||
    return struct {
 | 
			
		||||
        const Self = @This();
 | 
			
		||||
 | 
			
		||||
        val: T = undefined,
 | 
			
		||||
        left: ?*Self = null,
 | 
			
		||||
        right: ?*Self = null,
 | 
			
		||||
 | 
			
		||||
        // Initialize a tree node with specific value
 | 
			
		||||
        pub fn init(self: *Self, x: i32) void {
 | 
			
		||||
            self.val = x;
 | 
			
		||||
        }
 | 
			
		||||
    };   
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,7 @@
 | 
			
		||||
// File: include.zig
 | 
			
		||||
// Created Time: 2023-01-04
 | 
			
		||||
// Created Time: 2023-01-07
 | 
			
		||||
// 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;
 | 
			
		||||
		Reference in New Issue
	
	Block a user