1.散列法的性能分析
-
由于冲突的存在,散列法在进行搜索的时候,实际上也要进行关键码的比较。
散列法的搜索过程:给定一个待查数据项的关键码,通过散列函数得到该数据项在表当中的散列地址,如果该地址没有冲突,那么在该地址上就可以访问相应的数据项,而不需要关键码的比较,若存在冲突,则需要进一步的探查,实际上在进一步的探查过程中也要进行关键码的比较 -
用平均搜索长度ASL (Averagy Search Length)衡量散列方法的搜索性能。
-
根据搜索成功与否,它又有搜索成功的平均搜索长度ASLsucc和搜索不成功的平均搜索长度ASLunsucc之分。
-
搜索成功的平均搜索长度 ASLsucc 是指能搜索到待查表项的平均探查次数。
它是找到表中各个已有表项的探查次数的平均值。 -
搜索不成功的平均搜索长度 ASLunsucc 是指在表中搜索不到待查的表项,但找到插入位置的平均探查次数。
它是表中所有可能散列到的位置上要插入新元素时为找到空桶的探查次数的平均值。
能找到插入位置说明表未满,表满的探测计数是不计入计算的 -
使用线性探测法来解决冲突,计算ASL
ASLsucc中1✖6的含义,经过1次探测计数的个数为6个,以此类推,下面的红色的数字代表的探测的次数
ASLunsucc中的9的含义是:要插入一个新元素,从0地址开始,因为0-7的位置都有元素了,所以空的位置是8,需要探查9次,如果是在1这个地址插入,如果是在2这个地址插入,以此类推 -
使用链地址法来解决冲突,计算ASL
先将表项映射到表空间中;
ASLsucc中1✖7的含义:如果需要搜索26这个表项,需要探测几次呢?首先26这个表项被映射到了0这个位置,发现这个位置的指针,即指向链表的头指针不为空,则需要在链表中进行探测,只需要探测一次即可,41,68,等都是通过一次探测就可以找到;
ASLunsucc中的1的含义:假设给定一个关键码映射到了0这个地址,但是关键码又不等于26(比较一次),然后在26后面插入一个新的表项,所以需要探测的次数是一次,如果在1这个位置插入一个新元素,因为这个位置的指针是空的,则不需要任何的比较即可插入,所以是0,如果是在2这个地址,以此类推,不论是在头部插入还是在尾部插入,都需要先探测 -
线性探测法和链地址法的散列法性能分析
2.哈希法性能分析
-
哈希查找过程仍是一个给定值与关键字进行比较的过程。
-
评价哈希查找效率仍要用ASL
-
哈希法中影响关键字比较次数的因素有三个:
-
哈希函数、处理冲突的方法以及哈希表的装填因子。哈希表的装填因子α的定义如下:
(1)散列表的装填因子α表明了表中的装满程度。越大,说明表越满,再插入新元素时发生冲突的可能性就越大。
(2)与顺序搜索不同,表越大,搜索性能越低,O(n);
二分查找,二叉树查找类似,与表空间的长度也有关,O( l o g 2 n log_2n log2n)
散列表的查找,表空间越大,搜索效率越高 -
(1)当装填因子α较高时,选择的散列函数不同,散列表的搜索性能差别很大。在一般情况下多选用除留余数法,其中的除数在实用上应选择不含有20以下的质因数的质数。
(2)对散列表技术进行的实验评估表明,它具有很好的平均性能,优于一些传统的技术,如平衡树。
(3)但散列表在最坏情况下性能很不好。如果对一 个有 n 个关键码的散列表执行一次搜索或插入操作,最坏情况下需要 O(n) 的时间。
(4)Knuth对不同的溢出处理方法进行了概率分析。Donald Ervin Knuth(高德纳)对不同的冲突处理方法进行了概率分析,如图下所示:这是理论分析
-
实验分析分析:
(1)下图给出一些实验结果,列出在采用不同的散列函数和不同的处理溢出的方法时,搜索关键码所需的对桶访问的平均次数。实验数据为 { 33575, 24050, 4909, 3072, 2241, 930, 762, 500 }
(2)从图中可以看出,链地址法优于开地址法;在散列函数中,用除留余数法作散列函数优于其它类型的散列函数,最差的是折叠法。
-
结论:除留余数法+链地址法组合后的效率最高
散列函数使用:除留余数法,除留余数法最后要模上桶的大小(XXX%桶的大小,XXXX是经过运算得到的,运算最好要与关键码的相关性强一些,比如字符串的哈希函数,最好与字符串的每一个字符都发生关系,得到一个值,然后再进行除留余数)
处理冲突的方法:链地址法
3.几种查找方法对比
- 时间复杂度
- 后三种效率都比较快,哈希查找是最快的。二分查找要求数据是已经排序过的,二叉树查找与哈希查找没有此问题
- 二叉树查找效率虽不及哈希查找,但是它在进行遍历的时候能将顺便将数据排好序。而哈希查找很难找到一种方法按顺序遍历表空间。