数据结构—哈希表

一、哈希表概念

哈希表(Hash Table):也叫散列表。是根据关键码值(Key Value)直接进行访问的数据结构。

哈希表通过(键 key )和(映射函数 Hash(key) )计算出对应的(值 value),把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做(哈希函数(散列函数)),存放记录的数组叫做(哈希表(散列表))。

二、哈希表的操作

关于哈希表,有两种操作:建立和查询

1.向哈希表中插入一个关键码值

        将键(key)通过哈希函数转化为 值(value)并存放在哈希表中

2. 在哈希表中搜索一个关键码值

        使用相同的哈希函数转化为 值(value)再在哈希表中查询

当处理数据为整型时,键(key)的大小通常为元素大小,再进行映射函数计算值,大致原理如下

数据结构—哈希表

 三、哈希函数

        概念:将哈希表中元素的键值映射为元素存储位置(值)的函数

哈希函数一般要满足以下条件:

 ①  易于计算,并且计算出来的值分布均匀(避免出现过多的哈希冲突)

 ②  哈希函数计算出的哈希值是一个固定长度的输出值

③  一个键值不能对应两个hash值对应:

        如果Hash(key1)!=Hash(key2) 那么key1与key2一定不相等

数据结构—哈希表

④一个hash值可以对应多个键值(哈希冲突) 

数据结构—哈希表

四、哈希函数的方法

1. 直接定址法

        取关键字本身 / 关键字的某个线性函数值作为哈希地址。

        hash(key)= key 或者 hash(key)= a * key + b

2.除留余数法

        假设哈希表的表长为 m ,取一个不大于 m 但接近或等于 m 的质数 p ,利用取模运算,将关键值转化为哈希地址(取质数可以尽量避免冲突)

        hash(key)= key % p

3.平方取中法

        先通过关键值平方的方式扩大相近数之间的差别,然后根据长度取关键值平方值的中间几位数作为哈希地址

        hash(key)= ( key * key )/ 100 % 1000  // 先计算平方,去除末尾两位数,再取最后三位数(即取中间三位数作为哈希地址)

4.基数转换法

        将关键字看成另一种进制的数再转化为原来进制的数,选其中几位作为哈希地址

五、哈希冲突

         不同的关键字通过同一个哈希函数可能得到同一哈希地址,即 key1!=key2 而 hash(key1)== hash(key2)

当出现哈希冲突时,才用以下两种方法解决哈希冲突

        1.开放地址法

        将哈希表中的(空地址)向处理冲突开放,当哈希表未满时,处理冲突时需要尝试另外的单元,直到找到空的单元为止

        发生冲突时,开放地址法按照下面方法求得新的哈希地址:H(i)= (hash(key)+ F (i) ) % m

如果H(1) 仍发生哈希冲突,则再一次通过上述操作处理出 H (2)  ……直至 H (x) 不出现冲突 

关于F(x)的计算:

        ①线性探测法:即 F(i)=i

        ②二次探测法:F(i)=1^2, -1^2, 2^2, -2^2……i^2,-i^2

        ③伪随机数序列:F(i)=rand()

数据结构—哈希表

        2.链地址法

        将具有相同哈希地址的元素(或记录)存储在同一个线性链表中

        思想:将键值通过哈希函数得到的值存储入哈希表中,当出现哈希冲突时,采用链表的方法储存相同哈希值对应的键值。

        1.每次插入键值时,最好插入表头(时间复杂度最低)

        2.查询关键值时,通过哈希函数计算出对应的哈希地址 i ,然后在对应的链表上扫描一遍即可

数据结构—哈希表

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/b3d199db88.html