算法学习(一)

来源:互联网 发布:淘宝搜不到以前的订单 编辑:程序博客网 时间:2024/06/09 15:15

1.散列表:一个数组,它的每个下标与该单元所存储的数据元素的关键字是相互映射的关系。数据元素的关键字k作为输入,经过散列函数hash(k)计算后,得到对应的存储位置的下标;并且,有可能多个数据元素映射到散列表的同一位置,从而使得散列表的存储位置个数要比数据元素的个数少。散列表采用了其他的方法解决这种多个元素映射到同一地址的冲突问题,实现了一定的存储空间容纳更多的数据元素,同时又一定程度上保留了对数组进行随机访问的时间的高效性,也就是实现了高效的存储和读取速度。

    读取(查找)的速度:链接法散列,即用一个双向链表解决映射到同一下标的冲突问题,链接法散列表的性能可以用装载因子n/m来衡量,n是可能存放的元素数量,m是散列表的存储位置个数。无论是查找成功还是查找不成功,链接法散列表的查找时间复杂度都是O(1+n/m),所以当存储位置数目与待存储数据元素的数量成正比增长时,链接法散列表的读取(查找)速度(时间复杂度)一直保持在O(1)的数量级。


除数散列法: 散列函数是一个取余函数mod m,将所有的数据元素映射到m个纯存储单元。一个用所有元素个数除以装载因子得到的附近的不太接近2的整数幂的素数,是通常对m的好的选择。

乘法散列法: 原理是将k放大s倍之后取k*s的低w位上的一部分数位上的值作为散列地址(下标),其中w是关键字k的存储单元的长度(位数),比如计算机的字长,而p则是目标散列表长度的位数(比如散列表长2的14次方,即可以存储16384个数据元素,那么p就是14)。用公式表示则是先乘以一个分数s/(2的w次方),然后截取得到小数部分,再乘以m,并且向下取整得到最终散列值。(略复杂)


开放寻址法:与链接法散列相比较,它不能将所有数据元素都存入到存储散列表中,当待存元素个数超过散列表的长度时,就无法存入,也使得散列表的装载因子总是小于等于1。开放寻址法的散列函数有两个输入:一是待存元素的关键字,而是探查号(一般地,探查号有m个,m是散列表的长度)。散列函数一般有三种:(一)线性探查,(二)二次探查,(三)双重探查。线性探查最简单,就是在辅助散列函数(比如出发散列函数或者乘法散列函数)的基础上,向后逐个探查后续的位置。但是这会导致一次群集的发生,严重影响查找的性能。二次探查是对一次探查的改进,但是不能避免二次群集的发生,它使用了一个简单二次多项式而不是直接线性的向后探查(公式:h(k, j) = ( h'(k) + c1*i + c2*i^2 ) mod m。双重散列:引入了两个辅助散列函数,使的散列的位置更加随机,公式:h(k, i) = (h1(k) + i*h2(k)) mod m,对于第二个辅助散列函数以及散列表长度的选择,h2(k) 产生的散列值必须和表长度m互质;最一般的双重散列函数:h1(k) = k mod m, h2(k) = 1 + (k mod m'),m是一个素数,m'是比m略小的数。不成功的探查次数最多为1/(1-a),a是装载因子。



0 0
原创粉丝点击