""" File: hash_map_chaining.py Created Time: 2023-06-13 Author: Krahets (krahets@163.com) """ import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) from chapter_hashing.array_hash_map import Pair class HashMapChaining: """链式地址哈希表""" def __init__(self): """构造方法""" self.size = 0 # 键值对数量 self.capacity = 4 # 哈希表容量 self.load_thres = 2 / 3 # 触发扩容的负载因子阈值 self.extend_ratio = 2 # 扩容倍数 self.buckets = [[] for _ in range(self.capacity)] # 桶数组 def hash_func(self, key: int) -> int: """哈希函数""" return key % self.capacity def load_factor(self) -> float: """负载因子""" return self.size / self.capacity def get(self, key: int) -> str: """查询操作""" index = self.hash_func(key) bucket = self.buckets[index] # 遍历桶,若找到 key 则返回对应 val for pair in bucket: if pair.key == key: return pair.val # 若未找到 key 则返回 None return None def put(self, key: int, val: str): """添加操作""" # 当负载因子超过阈值时,执行扩容 if self.load_factor() > self.load_thres: self.extend() index = self.hash_func(key) bucket = self.buckets[index] # 遍历桶,若遇到指定 key ,则更新对应 val 并返回 for pair in bucket: if pair.key == key: pair.val = val return # 若无该 key ,则将键值对添加至尾部 pair = Pair(key, val) bucket.append(pair) self.size += 1 def remove(self, key: int): """删除操作""" index = self.hash_func(key) bucket = self.buckets[index] # 遍历桶,从中删除键值对 for pair in bucket: if pair.key == key: bucket.remove(pair) self.size -= 1 break def extend(self): """扩容哈希表""" # 暂存原哈希表 buckets = self.buckets # 初始化扩容后的新哈希表 self.capacity *= self.extend_ratio self.buckets = [[] for _ in range(self.capacity)] self.size = 0 # 将键值对从原哈希表搬运至新哈希表 for bucket in buckets: for pair in bucket: self.put(pair.key, pair.val) def print(self): """打印哈希表""" for bucket in self.buckets: res = [] for pair in bucket: res.append(str(pair.key) + " -> " + pair.val) print(res) """Driver Code""" if __name__ == "__main__": # 初始化哈希表 hashmap = HashMapChaining() # 添加操作 # 在哈希表中添加键值对 (key, value) hashmap.put(12836, "小哈") hashmap.put(15937, "小啰") hashmap.put(16750, "小算") hashmap.put(13276, "小法") hashmap.put(10583, "小鸭") print("\n添加完成后,哈希表为\n[Key1 -> Value1, Key2 -> Value2, ...]") hashmap.print() # 查询操作 # 向哈希表输入键 key ,得到值 value name = hashmap.get(13276) print("\n输入学号 13276 ,查询到姓名 " + name) # 删除操作 # 在哈希表中删除键值对 (key, value) hashmap.remove(12836) print("\n删除 12836 后,哈希表为\n[Key1 -> Value1, Key2 -> Value2, ...]") hashmap.print()