[数据结构] hash表
哈希表
哈希表是一种比较特殊的数据结构,它遵循函数映射的思想,以Key: Value的方式存储数据。哈希表最大的特点是可以快速定位到要查找的数据,查询的时间复杂度接近O(1).
Python的内置数据结构--字典dict, 就是基于哈希表实现的.
根据数据特点选定合适的表大小和哈希函数是哈希表这种数据结构实现的关键.
[几种通用的哈希函数]:
- 除留取余法 -- 最常用的哈希定址方法
H(x) = x % p
假定哈希表长度为s,则p一般取不超过s的最大质数
- 直接定址法 -- 比较常用的方法
H(x) = a * x + b
- 折叠法
假设有数据 2053 1352,要求key值为两位数,可以计算地址为20 + 53 = 73, 13 + 52 = 65
折叠法有多种实现方法,应根据实际问题选择
- 平方取中法 -- 计算数据的平方,然后从平方数中选出中间几位来作为存储的地址。
299 * 922 = 275678 ->>56 866 * 688 = 595808 ->> 58
- 数字分析法 -- 完全通过观察数据规律来确定相应key的方法
111299 112399 113499 通过观察这组数据,发现开头和结尾都一样,那么可以选择中间两位来确定key值
冲突
哈希表还要解决的一个问题就是冲突,当选择了一个哈希函数之后,有可能不同的数据会计算出相同的key, 需要解决这种冲突.
[解决collision的方法] :
链接地址法 -- 将映射到同一个slot中的元素做成链表
开放定址法 -- 最具代表性的一种是线性探测法. 线性探测法最大的问题是冲突累计,解决一个冲突的同时会占据别的key的位置,又造成了新的冲突。
[用python实现一个简单的哈希表]
class HashTable(object): def __init__(self, size): self.elem = [None for i in range(size)] #使用线性表保存哈希表的元素 self.size = size def hash(self, key): return key % self.size # 假设采用除留取余法 '''哈希表的插入操作''' def hash_insert(self, key, value): address = self.hash(key) # 对应分配的散列地址 while self.elem[address]: address = (address + 1) % self.size #若冲突, 线性探测下一地址 self.elem[address] = value '''查找hash表是否有某个值''' def search(self, key): address = self.hash(key) value = self.hash(key) while self.elem[address] != key: address = (address + 1) % self.size if not self.elem[address] or address == value: # 没找到或者循环到了开始的位置 return False return True
🔚👋