当前位置: 首页 > article >正文

大白话“讲”哈希表

一、哈希表:像快递柜一样存取数据的神器

想象你有一个能秒找快递的智能柜子:

  1. 每个包裹都有唯一取件码(哈希函数生成)
  2. 柜子分成1000个小格子(数组存储)
  3. 取件码=格子编号(如9527号包裹放在527格)
  4. 偶尔多个包裹挤一个格子(哈希碰撞)
  5. 解决方法:要么在隔壁找空位(开放寻址),要么在格子里挂多个挂钩(链式存储)

这就是哈希表!它让数据存取快到飞起,平均只要1步就能找到目标,比翻字典快N倍。


二、三大核心部件白话解读

1. 哈希函数:数据界的身份证生成器
  • 把各种类型数据变成数字
# 比如字符串转数字 
"张三" ➔ 2598(假设哈希值)
"李四" ➔ 7365 
  • 好函数的标准:
    • 不同数据尽量不同号(少撞号)
    • 算得快(像扫码枪一样"滴"就出结果)
2. 数组:整齐排列的快递柜

场景:用Python字典统计水果销量

三、真实世界中的哈希表演示

  • 提前准备N个格子(数组长度)
  • 哈希值对N取余就是格子号
    2598号数据 ➔ 2598%1000=598号格子 
    3. 冲突处理:格子满了怎么办?
  • 链式法(格子挂挂钩)
  • 开放寻址法(找隔壁空位)
        1.场景:用Python字典统计水果销量

    fruit_sales = {}
     
    # 存数据(自动计算哈希)
    fruit_sales["apple"] = 50    # "apple"的哈希假设是2837 
    fruit_sales["banana"] = 30   # 哈希值假设是6654 
    fruit_sales["orange"] = 20   # 哈希值假设是2837(碰撞了!)
     
    # 底层实际存储示意图 
    [
     ..., 
     2837: [("apple",50), ("orange",20)],  # 链表存储 
     6654: ("banana",30),
     ...
    ]

    四、为什么说哈希表是万金油?

    1. 查的快:直接从格子拿数据
    • 数组下标访问 → O(1)时间复杂度
    • 比遍历数组(O(n))、二分查找(O(logn))快得多
    2. 用的广:程序员必备技能
    • 去重:快速判断元素是否存在
    • 缓存:Redis的核心数据结构
    • 计数:统计词频/点击量
    • 索引:数据库加速查询
    3. 内存省:按需分配空间
    • 传统数组要预分配超大空间
    • 哈希表动态扩容(负载因子超0.75自动翻倍)

    五、使用时必须知道的坑

    1. 哈希碰撞攻击
    • 恶意制造大量碰撞 → 查询退化为链表 → 服务器瘫痪
    • 防御:改用更安全的哈希算法(如SHA-256)
    2. 对象修改导致失踪
    Map<User, Integer> scores = new HashMap<>();
    User u = new User("张三");  // 哈希值=1234 
    scores.put(u,  95);
     
    u.setName(" 李四");         // 哈希值变成5678 
    scores.get(u);             // 找不到!因为去5678格子找了 
    3. 线程安全问题
    • 多线程同时修改可能丢数据
    • 解决方案:用ConcurrentHashMap(分段锁技术)

    六、手把手实现迷你哈希表 

    class SimpleHashTable:
        def __init__(self):
            self.size  = 8          # 初始8个格子 
            self.table  = [[] for _ in range(self.size)]   # 每个格子是列表 
        
        def _hash(self, key):
            return hash(key) % self.size   # Python内置哈希函数 
        
        def put(self, key, value):
            idx = self._hash(key)
            for item in self.table[idx]:   # 遍历链表 
                if item[0] == key:
                    item[1] = value      # 更新已有键 
                    return 
            self.table[idx].append([key,  value])  # 新增键值对 
        
        def get(self, key):
            idx = self._hash(key)
            for item in self.table[idx]: 
                if item[0] == key:
                    return item[1]
            return None 
     
    # 测试我们的迷你哈希表 
    ht = SimpleHashTable()
    ht.put("apple",  10)
    ht.put("banana",  20)
    print(ht.get("apple"))   # 输出10 

    七、哈希表的七十二变

    1. 布隆过滤器:用多个哈希函数实现低内存去重
    2. 一致性哈希:分布式系统数据分片神器
    3. 彩虹表:黑客破解密码的哈希字典
    4. 默克尔树:区块链验证数据完整性的核心结构

    总结

    哈希表就像数据世界的智能快递柜:

    • :存取操作平均O(1)时间复杂度
    • :按需使用内存空间
    • :经过40多年验证的经典结构
    • :各种魔改版本满足特殊需求

     


    http://www.kler.cn/a/558953.html

    相关文章:

  • 数据结构与算法-搜索-双向搜索 和 A*算法(字串变换,八数码,第k短路)
  • 【Vue3+Tres 三维开发】03 - 基本操作
  • 习题解答 | 一维差分与等差数列差分
  • 如何通过 Docker 在没有域名的情况下快速上线客服系统
  • Unity for Python —— 强大的 Python 脚本支持提升 Unity 编辑器效率
  • C语言递归——青蛙跳台阶问题和汉诺塔问题
  • 辗转相除法(欧几里得算法)
  • transformer架构嵌入层位置编码之RoPE旋转位置编码及简单实现示例
  • go-zero学习笔记(五)
  • Windows系统第一次运行C语言程序,环境配置,软件安装等遇到的坑及解决方法
  • 嵌入式之内存管理
  • 【2025.2最新版】从零开始的HTML网页开发学习笔记(包含网页基础概念 HTML语法 前端工具VsCode介绍)
  • mysql之B+ 树索引 (InnoDB 存储引擎)机制
  • 反射和注解
  • 自制操作系统前置知识汇编学习
  • 实验-安装Proteus
  • ZLMediaKi集群设置
  • 简说spring 的设计模式
  • Python项目源码33:待办事项列表应用2.0(命令行界面+Json+类)
  • Java基础常见的面试题(易错!!)