mirror of
				https://github.com/krahets/hello-algo.git
				synced 2025-10-31 10:26:48 +08:00 
			
		
		
		
	 7ffef7e1d6
			
		
	
	7ffef7e1d6
	
	
	
		
			
			* update author information * Update index.md --------- Co-authored-by: Yudong Jin <krahets@163.com>
		
			
				
	
	
		
			162 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Zig
		
	
	
	
	
	
			
		
		
	
	
			162 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Zig
		
	
	
	
	
	
| // File: array_hash_map.zig
 | |
| // Created Time: 2023-01-15
 | |
| // Author: codingonion (coderonion@gmail.com)
 | |
| 
 | |
| const std = @import("std");
 | |
| const inc = @import("include");
 | |
| 
 | |
| // 键值对
 | |
| const Pair = struct {
 | |
|     key: usize = undefined,
 | |
|     val: []const u8 = undefined,
 | |
| 
 | |
|    pub fn init(key: usize, val: []const u8) Pair {
 | |
|         return Pair {
 | |
|             .key = key,
 | |
|             .val = val,
 | |
|         };
 | |
|     }
 | |
| };
 | |
| 
 | |
| // 基于数组实现的哈希表
 | |
| pub fn ArrayHashMap(comptime T: type) type {
 | |
|     return struct {
 | |
|         bucket: ?std.ArrayList(?T) = null,
 | |
|         mem_allocator: std.mem.Allocator = undefined,
 | |
| 
 | |
|         const Self = @This();
 | |
|         
 | |
|         // 构造函数
 | |
|         pub fn init(self: *Self, allocator: std.mem.Allocator) !void {
 | |
|             self.mem_allocator = allocator;
 | |
|             // 初始化一个长度为 100 的桶(数组)
 | |
|             self.bucket = std.ArrayList(?T).init(self.mem_allocator);
 | |
|             var i: i32 = 0;
 | |
|             while (i < 100) : (i += 1) {
 | |
|                 try self.bucket.?.append(null);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // 析构函数
 | |
|         pub fn deinit(self: *Self) void {
 | |
|             if (self.bucket != null) self.bucket.?.deinit();
 | |
|         }
 | |
| 
 | |
|         // 哈希函数
 | |
|         fn hashFunc(key: usize) usize {
 | |
|             var index = key % 100;
 | |
|             return index;
 | |
|         }
 | |
| 
 | |
|         // 查询操作
 | |
|         pub fn get(self: *Self, key: usize) []const u8 {
 | |
|             var index = hashFunc(key);
 | |
|             var pair = self.bucket.?.items[index];
 | |
|             return pair.?.val;
 | |
|         }
 | |
| 
 | |
|         // 添加操作
 | |
|         pub fn put(self: *Self, key: usize, val: []const u8) !void {
 | |
|             var pair = Pair.init(key, val);
 | |
|             var index = hashFunc(key);
 | |
|             self.bucket.?.items[index] = pair;
 | |
|         }
 | |
| 
 | |
|         // 删除操作
 | |
|         pub fn remove(self: *Self, key: usize) !void {
 | |
|             var index = hashFunc(key);
 | |
|             // 置为 null ,代表删除
 | |
|             self.bucket.?.items[index] = null;
 | |
|         }       
 | |
| 
 | |
|         // 获取所有键值对
 | |
|         pub fn pairSet(self: *Self) !std.ArrayList(T) {
 | |
|             var entry_set = std.ArrayList(T).init(self.mem_allocator);
 | |
|             for (self.bucket.?.items) |item| {
 | |
|                 if (item == null) continue;
 | |
|                 try entry_set.append(item.?);
 | |
|             }
 | |
|             return entry_set;
 | |
|         }  
 | |
| 
 | |
|         // 获取所有键
 | |
|         pub fn keySet(self: *Self) !std.ArrayList(usize) {
 | |
|             var key_set = std.ArrayList(usize).init(self.mem_allocator);
 | |
|             for (self.bucket.?.items) |item| {
 | |
|                 if (item == null) continue;
 | |
|                 try key_set.append(item.?.key);
 | |
|             }
 | |
|             return key_set;
 | |
|         }  
 | |
| 
 | |
|         // 获取所有值
 | |
|         pub fn valueSet(self: *Self) !std.ArrayList([]const u8) {
 | |
|             var value_set = std.ArrayList([]const u8).init(self.mem_allocator);
 | |
|             for (self.bucket.?.items) |item| {
 | |
|                 if (item == null) continue;
 | |
|                 try value_set.append(item.?.val);
 | |
|             }
 | |
|             return value_set;
 | |
|         }
 | |
| 
 | |
|         // 打印哈希表
 | |
|         pub fn print(self: *Self) !void {
 | |
|             var entry_set = try self.pairSet();
 | |
|             defer entry_set.deinit();
 | |
|             for (entry_set.items) |item| {
 | |
|                 std.debug.print("{} -> {s}\n", .{item.key, item.val});
 | |
|             }
 | |
|         }
 | |
|     };
 | |
| }
 | |
| 
 | |
| // Driver Code
 | |
| pub fn main() !void {
 | |
|     // 初始化哈希表
 | |
|     var map = ArrayHashMap(Pair){};
 | |
|     try map.init(std.heap.page_allocator);
 | |
|     defer map.deinit();
 | |
| 
 | |
|     // 添加操作
 | |
|     // 在哈希表中添加键值对 (key, value)
 | |
|     try map.put(12836, "小哈");
 | |
|     try map.put(15937, "小啰");
 | |
|     try map.put(16750, "小算");
 | |
|     try map.put(13276, "小法");
 | |
|     try map.put(10583, "小鸭");
 | |
|     std.debug.print("\n添加完成后,哈希表为\nKey -> Value\n", .{});
 | |
|     try map.print();
 | |
| 
 | |
|     // 查询操作
 | |
|     // 向哈希表中输入键 key ,得到值 value
 | |
|     var name = map.get(15937);
 | |
|     std.debug.print("\n输入学号 15937 ,查询到姓名 {s}\n", .{name});
 | |
| 
 | |
|     // 删除操作
 | |
|     // 在哈希表中删除键值对 (key, value)
 | |
|     try map.remove(10583);
 | |
|     std.debug.print("\n删除 10583 后,哈希表为\nKey -> Value\n", .{});
 | |
|     try map.print();
 | |
|     
 | |
|     // 遍历哈希表
 | |
|     std.debug.print("\n遍历键值对 Key->Value\n", .{});
 | |
|     var entry_set = try map.pairSet();
 | |
|     for (entry_set.items) |kv| {
 | |
|         std.debug.print("{} -> {s}\n", .{kv.key, kv.val});
 | |
|     }
 | |
|     defer entry_set.deinit();
 | |
|     std.debug.print("\n单独遍历键 Key\n", .{});
 | |
|     var key_set = try map.keySet();
 | |
|     for (key_set.items) |key| {
 | |
|         std.debug.print("{}\n", .{key});
 | |
|     }
 | |
|     defer key_set.deinit();
 | |
|     std.debug.print("\n单独遍历值 value\n", .{});
 | |
|     var value_set = try map.valueSet();
 | |
|     for (value_set.items) |val| {
 | |
|         std.debug.print("{s}\n", .{val});
 | |
|     }
 | |
|     defer value_set.deinit();
 | |
| 
 | |
|     _ = try std.io.getStdIn().reader().readByte();
 | |
| } |