29.数据结构 - 查找

查找在我们平时的使用中是非常频繁的,查找的算法也比较多。查找算法的优劣将影响到计算机的使用效率,应根据应用场合选择相应的查找算法

 

常见的查找方法有顺序查找、折半查找、分块查找、Hash表查找等等。效率最高,应用较多的是哈希表查找,我们也是重点学习,但是别的查找我们也要知道怎么应用。

一.查找方法

1.顺序查找

应用:顺序查找适合于存储结构为顺序存储或链接存储的线性表,最基本的查找技术

基本思想:顺序查找也称为线形查找,属于无序查找算法。从数据结构线形表的一端开始,顺序扫描,依次将扫描到的结点关键字与给定值k相比较,若相等则表示查找成功;若扫描结束仍没有找到关键字等于k的结点,表示查找失败。

顺序查找的时间复杂度为O(n)。

 

明显顺序表的查找是非常费时的,在顺序查找的基础上进行优化就有了二分查找。

 

2.二分查找(折半查找)

应用:折半查找的前提条件是需要有序表顺序存储,对于静态查找表,一次排序后不再变化,折半查找能得到不错的效率。但对于需要频繁执行插入或删除操作的数据集来说,维护有序的排序会带来不小的工作量,那就不建议使用

 

说明:元素必须是有序的,如果是无序的则要先进行排序操作。

基本思想:也称为是折半查找,属于有序查找算法。用给定值k先与中间结点的关键字比较,中间结点把线形表分成两个子表,若相等则查找成功;若不相等,再根据k与该中间结点关键字的比较结果确定下一步查找哪个子表,这样递归进行,直到查找到或查找结束发现表中没有这样的结点。

简单理解其实就像电视中的看物品猜价格,先取个值,然后说大了小了,然后逐渐缩小范围,得到最后的物品价格。

 

复杂度分析:最坏情况下,关键词比较次数为log2(n+1),且期望时间复杂度为O(log2n)

例:

 

3.分块查找

说明:分块查找又称索引顺序查找,它是顺序查找的一种改进方法。在块内还能再使用折半查找,方法是灵活的。

算法思想:将n个数据元素"按块有序"划分为m块(m ≤ n)。每一块中的结点不必有序,但块与块之间必须"按块有序";即第1块中任一元素的关键字都必须小于第2块中任一元素的关键字;而第2块中任一元素又都必须小于第3块中的任一元素,……
算法流程:
step1 先选取各块中的最大关键字构成一个索引表;
step2 查找分两个部分:先对索引表进行二分查找或顺序查找,以确定待查记录在哪一块中;然后,在已确定的块中用顺序法进行查找。

 

 

4.哈希表查找(效率高)

我们的重点来啦,哈希表查找,它的效率是比较高,应用的也比较多。

"直接定址"与"解决冲突"是哈希表的两大特点

Hash是一种典型以空间换时间的算法

 

那么哈希函数到底是什么呢?

官方话语太难理解了,简单说,我们通过一些算法和公式,得到许多的虚拟地址,我们查找的时候,只需要相同的公式就能找到该元素。但是有个问题就是不同元素通过一个公式计算的地址可能相同,就产生冲突

 

算法流程:

  1. hash函数的选取
  2. 用给定的哈希函数构造哈希表
  3. 根据选择的冲突处理方法解决地址冲突
  4. 在哈希表的基础上执行哈希查找

 

那么我们的疑问就来了?哈希函数怎么选?冲突怎么解决?

直接举个例子,例子讲完了,所有的一些零碎的概念就能串起来了。

例:

k={23,34,14,38,46,16,68,15,07,31,26};

我们要存储这么一串数据,他的记录数也就存储个数n=11;那么我们怎么存呢,就需要构造一个hash函数。

 

常用的构造hash函数的方法有很多,直接地址法,平方取中法,叠加法,随机函数法

保留除数法,用的最多的是保留除数法,那么我们就选择这个方法。

 

那么什么是保留除数法?

又称质数除余法,设Hash表空间长度为m,选取一个不大于m的最大质数p,令:      H(key)=key%p。质数的选取(越大越好)

有了公式,但是我们的空间长度m和质数p我们都不知道。

m的选取涉及到一个概念表的装填因子α

α=n/m,其中m为表长,n为表中记录(存储)个数。一般α在0.7~0.8之间,使表保持一定的空闲余量,以减少冲突和聚积现象

根据存储个数,得到M,根据m又可以得到质数p。

令装填因子α=0.75,取表长m= én/αù =15。

用“保留余数法”选取Hash函数(p=13): H(key)=key%13

根据这个公式我们就可以得到地址了,然后将数据存到指定的位置,但是这时候问题就来了,不同的数据却计算出了相同的地址,也就是产生了冲突。

那么怎么解决冲突?

这里主要用了两种方法一个是开放地址法,一个是链地址的方法。

开放地址法:

 Hi=(H(key)+di)%m

原来hash函数基础上,在它的附近找空间

但是出现一直冲突就聚集了,这种方法就不太灵了。

 

那就用链地址的方法

链地址法解决冲突的优点:无聚积现象;删除表中记录容易实现

那么一个完整的hash表的建立过程就完成了。

特殊说明:

哈希表是一个在时间和空间上做出权衡的经典例子。如果没有内存限制,那么可以直接将键作为数组的索引。那么所有的查找时间复杂度为O(1);如果没有时间限制,那么我们可以使用无序数组并进行顺序查找,这样只需要很少的内存。哈希表使用了适度的时间和空间来在这两个极端之间找到了平衡。只需要调整哈希函数算法即可在时间和空间上做出取舍。

Hash是一种典型以空间换时间的算法

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章