你不知道的:哈希表(Hash table)
哈希表(Hash table),是最有用的数据结构,Python中的字典(Dict)就是基于哈希表实现的。用哈希表实现查找的时间复杂度为O(1),所以在需要频繁查找的应用中,常常使用哈希表。通常情况下,哈希表的查找元素时间跟数组一样快,插入和删除元素的时间跟链表一样快。
比较项 | 数组 | 链表 | 哈希表 |
---|---|---|---|
随机访问(读/写) | O(1) | O(N) | O(1) |
插入 | O(N) | O(1) | O(1) |
删除当前元素 | O(N) | O(1) | O(1) |
假设有一张勘误表,当项目比较少时,从头到尾依次查看,还能接受;但当项目比较多时,例如,超过100项,要从中找出自己关心的内容,就比较费力了。这是,我们希望输入一个关键词,然后迅速获得期望的内容。
从数学的视角看,哈希表(hash table)是从一个集合A到另一个集合B的映射(mapping),集合A中的元素称为键(Key),集合B中的元素称为值(Value),映射的过程由哈希函数(Hash function)实现。
哈希函数(Hash function)必须满足一些要求:
- 一致性:对于同样的输入,必须保证返回同样的输出
- 散列性:应该将不同的输入映射到不同的输出,若不同的输入都映射到相同的输出,那么这个哈希函数设计是失败的
- 冲突:即相同的输入映射到了同一位置;出现冲突后,则需要在冲突位置,建立起链表,用于储存不同的输入。好的哈希函数不会导致冲突,即便导致冲突,其同一位置的链表也很短,不会影响访问性能。
- 填装因子:又称负载因子(Load Factor),定义为哈希表包含的元素个数÷位置总数,通常不要超过0.7,一旦超过0.7,就该调整哈希表的长度;填装因子越小,查询性能越高,但占用的空间越大。在查询性能和占用空间之间,用填装因子做折中。
- 任何优秀的语言都提供哈希表的实现,不需要手动写了。只需要理解,会用即可。
由此,哈希表也被称为:散列表、散列映射、映射、字典或关联数组。总之,其查询元素的速度非常快,输入键(key),就可以获得值(value)。
哈希表应用: - DNS域名解析,即把方便人阅读的网址映射为计算机能理解的IP地址,就是用哈希表实现的
- 鉴别是否有重复,例如,希望把orange的价格添加到价格表中,但忘记是否已经添加过,可以先查阅orange是否存在
- 实现缓存,先在哈希表中查找被查询内容是否在缓存(cache)中,若在,直接从缓存中提取;若不在,在从其它地方请求。