算法图解(三)

一、散列函数:无论你给它什么数据,它都还你一个数字。

要求:

1.一致:输入apple时得到的是4,那么每次输入apple时,得到的必须都是4。 

2.将不同的输入映射到不同的数字。

结合散列函数(输出为索引)和数组创建散列表(hash table)的数据结构。python提供的散列表实现为字典

二、散列表应用:查找、防止重复、用作缓存

1 cache = {}
2 
3 def get_page(url):
4     if cache.get("url"):
5         return cache["url"]       #返回缓存中的数据
6     else:
7         data = get_data_from_server(url)
8         cache["url"] = data       #将数据保存到缓存中
9         return data

 三、冲突

由于散列函数的关系:不能将不同的键映射到不同的位置,就可能会发生冲突。

 以上情况发生了“冲突”,按字母表顺序进行分配时,两个都为A打头的数据都要存储在数组的第一个位置。

解决办法:

 在同一个位置处存储一个链表。

散列函数很重要!!!最理想的情况是:散列函数将“键”均匀地映射到散列表的不同位置。避免发生冲突。

如果散列表存储的链表很长,散列表的速度将急速下降(和普通的链表没什么区别)。然而,如果散列函数很好,这些链表就不会很长!

四、性能:散列表平均情况下(均匀分布)的性能为常量时间O(1)

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

填装因子越小,发生冲突的可能性就越小,散列表的性能就越高。一旦填装因子大于0.7就调整散列表的长度。

良好的散列函数让数组中的值呈均匀分布。糟糕的散列函数让值扎堆,导致大量的冲突。

五、小结

1.可以结合散列函数和数组来创建散列表;

2.使用可以最大限度降低冲突的散列函数;

3.散列表查找、删除、插入速度都非常快;

4.散列表可以用于缓存数据、模拟映射关系、防止冲突。

原文地址:https://www.cnblogs.com/direwolf22/p/12671185.html