标签:python 字典 hashmap 快速 区间 算法 标记 适用于 规则
python中的字典底层依靠哈希表(hash table)实现, 使用开放寻址法解决冲突,
哈希表是key-value类型的数据结构, 可以理解为一个键值需要按照一定规则存放的数组, 而哈希函数就是这个规则
字典本质上是一个散列表(总有空白元素的数组, python至少保证1/3的数组是空的), 字典中的每个键都占用一个单元, 一个单元分为两部分, 分别是对键的引用和对值的引用, 使用hash函数获得键的散列值, 散列值对数组长度取余, 取得的值就是存放位置的索引
哈希冲突(数组的索引相同), 使用开放寻址法解决
这也是python中要求字典的key必须可hash的原因
数组中1/3的位置为空, 增加元素可能会导致扩容, 引发新的散列冲突, 导致新的散列表中键的次序发生变化, 这也是字典遍历时不能添加和删除的原因
字典在内存中开销很大, 实际上是以空间换时间
根据设定的哈希函数H(key)和处理冲突方法将一组关键字映象到一个有限的地址区间上的算法。也称为散列算法、杂凑算法。
数据经过哈希算法之后得到的集合。这样关键字和数据在集合中的位置存在一定的关系,可以根据这种关系快速查询。
与哈希表相对应,集合中的 数据和其存放位置没任何关联关系的集合。
由此可见,哈希算法是一种特殊的算法,能将任意数据散列后映射到有限的空间上,通常计算机软件中用作快速查找或加密使用。
由于哈希算法被计算的数据是无限的,而计算后的结果范围有限,因此总会存在不同的数据经过计算后得到的值相同,这就是哈希冲突。
解决哈希冲突的方法一般有:开放定址法、链地址法(拉链法)、再哈希法、建立公共溢出区等方法。
从发生冲突的那个单元起,按照一定的次序,从哈希表中找到一个空闲的单元。然后把发生冲突的元素存入到该单元的一种方法。开放定址法需要的表长度要大于等于所需要存放的元素。
在开放定址法中解决冲突的方法有:线行探查法、平方探查法、双散列函数探查法。
开放定址法的缺点在于删除元素的时候不能真的删除,否则会引起查找错误,只能做一个特殊标记。只到有下个元素插入才能真正删除该元素。
链接地址法的思路是将哈希值相同的元素构成一个同义词的单链表,并将单链表的头指针存放在哈希表的第i个单元中,查找、插入和删除主要在同义词链表中进行。链表法适用于经常进行插入和删除的情况。
如下一组数字,(32、40、36、53、16、46、71、27、42、24、49、64)哈希表长度为13,哈希函数为H(key)=key%13,则链表法结果如下:
0
1 -> 40 -> 27 -> 53
2
3 -> 16 -> 42
4
5
6 -> 32 -> 71
7 -> 46
8
9
10 -> 36 -> 49
11 -> 24
12 -> 64
注:在java中,链接地址法也是HashMap解决哈希冲突的方法之一,jdk1.7完全采用单链表来存储同义词,jdk1.8则采用了一种混合模式,对于链表长度大于8的,会转换为红黑树存储。
就是同时构造多个不同的哈希函数:
Hi = RHi(key) i= 1,2,3 ... k;
当H1 = RH1(key) 发生冲突时,再用H2 = RH2(key) 进行计算,直到冲突不再产生,这种方法不易产生聚集,但是增加了计算时间。
将哈希表分为公共表和溢出表,当溢出发生时,将所有溢出数据统一放到溢出区。
标签:python 字典 hashmap 快速 区间 算法 标记 适用于 规则
原文地址:https://www.cnblogs.com/zyyhxbs/p/12408604.html