一、何为哈希表
HashTable-散列表/哈希表,是根据关键字(key)来直接访问在内存存储位置的数据结构。
它通过一个关键值的函数将所需的数据映射到表中的位置来访问数据,这个映射函数叫做散列函数,存放记录的数组叫做散列表。
二、哈希表的构造方法
- 直接定址法–取关键字的某个线性函数为散列地址,Hash(Key)= Key 或 Hash(Key)= A*Key + B,A、B为常数。
- 除留余数法–取关键值被某个不大于散列表长m的数p除后的所得的余数为散列地址。Hash(Key)= Key % P。
- 平方取中法
- 折叠法
- 随机数法
- 数学分析法
前两种为较常用的。
三、哈希冲突
不同的Key值经过哈希函数Hash(Key)处理以后可能产生相同的值哈希地址,我们称这种情况为哈希冲突。任意的散列函数都不能避免产生冲突。
散列表的载荷因子:a=表中的元素个数/表的长度;
当载荷因子变大的时候冲突的概率变高,因此要控制载荷因子的值在一定的范围内。对于开放定址法,一般是0.7到0.8。拉链法就是1
四、哈希冲突的解决方法
1、开放定址法
(1)线性探测法:当出现哈希冲突的时候,按顺序往后探测,增量为1,直到找到元素为空的位置或找到该元素为止;
(2)二次探测法:当出现哈希冲突的时候,按顺序往后探测,增量为i^2,i逐步递增,直到找到元素为空的位置或找到该元素为止;
代码连接:https://github.com/lvjiabao/C-Cplusplus-Datastruct/tree/master/哈希表
2、拉链法
定义一个指针数组,然后把节点挂在数组下面:
代码连接:https://github.com/lvjiabao/C-Cplusplus-Datastruct/tree/master/哈希表
五、开放定制法和拉链法的比较
(1)开放定址法的查找相对要慢,因为它的元素之间会相互影响。比如你连续来好几个映射位置相同的数,就会一直有冲突。而拉链法不会出现这样的情况,它数字映射到某一位置上,然后直接头插挂在上面。效率更高。
(2)开放定址法的利用率要低,因为它的载荷因子最高为0.7到0.8,这时候就必须要扩容了,而拉链法中载荷因子可以为1。
综上,拉链法应用起来更好一些。
六、哈希表和平衡搜索树的比较
哈希表和平衡搜索树同为搜索的数据结构,到底谁的效率更高一些呢?
1、哈希表(拉链法):
(1)哈希表的时间复杂度为O(1)(这里不采取最坏的情况O(n),它是个例外),但是也不会冲突地太厉害,因为做了很多优化,比如采用素数集,以及载荷因子。
(2)哈希表比较不稳定,因为如果出现相同映射地址的元素,效率势必要降低。因此Java就此做了优化,当某一个位置下元素个数超过长度的一半,该位置下面挂的就是红黑树,借此提高效率。
(3)哈希表会浪费空间
2、平衡搜索树(红黑,AVL)的时间复杂度为O(log2n)
综上,哈希表和平衡搜索树的时间复杂度差不多,实际测出来是哈希稍微高效一些。各有各的应用场景。
1088

被折叠的 条评论
为什么被折叠?



