散列表

可以模拟映射关系:根据key查找value

散列函数

不管输入是什么,总是返回一个数字
对于相同的输入,返回的数字总是相同。例如,输入apple,总是返回0
对于不同的输入,理想情况下,返回的数字总是不同的(实际上,这样的理想情况几乎不可能实现,所以要处理冲突)。例如,输入apple返回0;输入banana返回1。
散列函数只返回有效的索引。例如数组长度为10,它只会返回10以内的数字,不会返回100。

散列表可以用数组+散列函数实现

例如,实现商品和价格的对应关系。apple的价格是0.67,milk的价格是1.49,egg的价格是2.49。
key(商品):value(价格)

首先创建一个长度为5个数组。

存储:散列函数根据key计算出索引位置,将value存储在数组索引处。
例如,f(apple)=0,f(milk)=2,f(egg)=3,则对应的散列表为[0.67, , 1.49, 2.49, ](其中,索引位置为1和4的值为空)

查找:散列函数根据key计算出索引位置,在数组索引处找到value。
例如,查找商品apple的价格,散列函数输入apple返回0,数组[0]=0.67

冲突

实际情况下,散列函数几乎很难实现【对于不同的输入,返回的数字总是不同】
比如散列函数【将字符串首字母作为索引】,则apple的索引为0,banana的索引为1,但是avocados的索引也为0。此时如果将avocados的价格存储到索引位置,那么根据apple查找时,预期得到的应该是apple的价格,却得到了avocados的价格。

解决冲突最简单的方式,是在数组冲突的位置存储一个链表。
如果没有冲突,则在散列表中查找元素等同于在数组中根据索引获取元素,速度为O(1)
如果有冲突,且散列函数很糟糕,将所有元素都匹配到了同一个索引位置,则相当于将散列表的所有元素都存储在了一个链表中,那么在散列表中查找元素等同于在链表中查找元素,速度为O(n)
所以为了提高散列表的查找性能,应该尽量减少冲突


使用链表解决冲突.png

减少冲突

降低填装因子
填装因子=散列表的元素总数/位置总数
比如有100个元素,而散列表有100个位置,则填装因子等于1,此时理想情况下,每个元素都可以匹配到一个不同的位置;
如果散列表只有50个位置,则填装因子为2,此时不可能让每个元素都有自己的位置,因为位置总数不够。

良好的散列函数
良好的散列函数总是将元素均匀的分布到散列表中。

散列表的应用案例

模拟映射关系:根据key获取value
防止重复:判断key在散列表中是否已存在
缓存:根据key获取缓存内容

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容