数据结构-----哈希表

来源:互联网 发布:网络购彩何时恢复 编辑:程序博客网 时间:2024/06/05 09:35

      哈希表的基本思想:

         以结点的关键字k为自变量,通过一个确定的函数关系f,计算出对应的函数值,并把这个值解释为结点的存储地址,最后将结点存入f(k)所指示的存储位置上。查找时再根据要查找的关键字,用同样的函数计算地址,然后从相应的单元中读取。函数f称为哈希函数,f(k)的值称为哈希地址,用于存储结点的数据结构称为哈希表。

           几个概念:如果有哈希表的空间大小为m,填入表的结点数为n。则称alpha=n/m为装填因子。

                               若对于某个哈希函数,关键字k1和k2得到相同的哈希地址,则称该现象为冲突。

          例子:

              关键字集合:S={abc,def,ghe,cba,bca,egh};

              哈希表: char  hash[26][4]

              我们选取关键字key的第一个字母作为哈希函数的变量,选取哈希函数为f(key)=key[0]-'a'。              

                    哈希地址                   关键字                         0                        abc                         1                         bca                          2                         cba                            3                         def                         4                         egh                          5                          6                                         ghe                                               7                          8                      ......                        .....            

       哈希函数的构造

             哈希函数的构造是处理哈希表的关键之处,一般的要尽可能使函数简单,尽量减少冲突发生。

            1. 平方取中法:

                   先对关键字的进行平方运算,扩大差别,然后再取关键字的几位或者组合作为哈希地址。

                  如:关键字(0100,0110,1010,1001)

                          平方得到:(0010000,0012100,1020100,1002001)

                          如果哈希表表长为1000,则取中间三位为哈希地址。地址集为(100,121,201,020).

             2.折叠法

                 在关键字位数较多时,也可将关键字分割成位数相同的几段,段的长度取决于哈希表的地址位数,然后叠加求和(舍弃进位)作为哈希地址。

            3.除留余数法

                 选择适当的正整数p,用p取除关键字,所得余数作为哈希地址。

                                             f(key)=key%p

             4.基数转换法

                  把关键看成另一种进制的数后,再把它转换成原来的进制的数,取其中若干位作为散列地址。一般取大于原来的数作为转换的基数,并且两个数要互为素数。

                  如:十进制的数(210485),看成十三进制的数。再把它转换成十进制的数,有新的十进制数(771932).假设哈希表长度为10000,可以取低四位1932作为哈希地址。

             5.随机数法

                 选择一个随机数,去关键字的随机值作为散列地址,通常用于关键字长度不同的场合。

           解决冲突的方法

             A.开放地址法

                      当发生冲突时,使用某种方法在散列表中形成一个探查序列,沿着这个序列逐个单元的查找,直到找到一个空的单元格时将新的结点放入为止,固在造表时应该先把表置空。探查序列的构造有以下三种方法:

                      1.线性探查法。设表长为m,关键字个数为n。基本思想是:将哈希表看成是一个环形表,若发生冲突的地址是d,则依次探查d+1,d+2,d+3....m-1,0,1...d-1.直至找到一个空的单元为止。

                      开放地址公式为:

                                                   d(i)=(d+i)%m,   1<=i<m,d=f(key).

                       如,一组关键字(26,36,41,38,44,15,68,12,06,51,25),用线性探查法解决冲突问题。

                          假设构造时,哈希表为hash[15],用除留余数法构造哈希函数,p=13.(没有特定要求,只是举例子)

                    关键字2636413844156812065125 余数0102125231261212                               我们按顺序把关键字放入到哈希表中,26,36,41,38,44,很简单的放入就行。在放入15时要注意,因为地址2中已经放入了41,按照线性探查法的要求,地址后移直至找到空地址,把41放入,则15放在地址3上,同理68将会放在4上,12放在13上,51放在14上,25放在1上。

                                                         线性探查法构造哈希表哈希表地址01234567891011121314 关键字26254115684406   36 381251  

                       2.二次探查法

                                原理和线性探查法差不多,每次探查空地址时,按d+(1,-1,2^2,-2^2,3^2,-3^2....).探查.

                                                     d'=(d+i^2)%m或者d‘=(d-i^2)%m.

                       3.随机探查法

                                采用一个随机数作为地址位移计算下一个单元地址。

                                                 d'=(d+random)%m.

                  B.拉链法

                       将所有关键字为同地址的结点,链接到同一个单链表中.如上面描述的例子,余数为12的数,以地址12构成链表,相连着。  


                   

0 0