《算法图解》系列笔记(五)—— 散列表

本文介绍了散列函数的工作原理及其在散列表中的应用。解释了如何通过散列函数将输入映射到数字,以及如何利用散列表进行高效查找、防止重复和缓存等操作。同时讨论了冲突处理及性能问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

散列函数(散列映射、映射、字典、关联数组)

散列函数是这样的函数,即无论你给它什么数据,它都还你一个数字。即散列函数“将输入映射到数字”,散列函数必须满足一些要求:

  • ①它必须是一致的。
  • ②它应将不同的输入映射到不同的数字。

以下一个商品价格的图例说明了散列表的结构:

012345
1.490.67
→milk→apple

将商品名称作为输入给散列函数,散列函数给出对应的索引值,将商品对应的价格放入索引值对应的数组位置。为何可以在O(1)的时间复杂度下找到相应的结果,主要得益于以下几点:


  • ①散列函数总是将同样的输入映射到相同的索引。
  • ②散列函数将不同的输入映射到不同的索引。(这里实际是一种理想的状态,见下文 冲突 部分)
  • ③散列函数知道数组有多大,只返回有效的索引。

散列表是一种包含额外逻辑的数据结果(散列函数),与数组和链表被直接映射到内存不同。python提供dict{}创建散列表(键值对)。
散列表的应用
  1. 用于查找(类似手机的电话薄功能、DNS解析等)
  2. 防止重复(投票等)
  3. 用于缓存(站点数据访问等)
  4. 还有更多的列举…
冲突(collision)

给两个键分配的位置相同就是冲突,如何处理?
可取的一个办法是,如果两个键映射到了同一个位置,就在这个位置储存一个链表。糟糕的情况下,就像下面这样子了:

--
A→(apple<>0.67) →(almonds<>0.98)
B
C
D

链表太长,而其它的分配的空间又浪费掉了。因此,散列函数很重要。

性能

在平均情况下,散列表执行各种操作的时间都为O(1),O(1)被称为常量时间。
而要避免上述呈现的最糟的情况,就要避免冲突,那么就需要做好下面两点:
①较低的填装因子

填装因子=散列表包含的元素数 / 位置总数

一个不错的经验规则:当大于0.7时,就要调整散列表的长度。
②良好的散列函数
扩展:SHA函数1 了解一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值