一、散列函数:无论你给它什么数据,它都还你一个数字。
要求:
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.散列表可以用于缓存数据、模拟映射关系、防止冲突。