背景
众里寻他千百度,那人却在灯火燃珊处。怎样在一堆混乱的数据中查找到需要的数据呢?查找算法就显得很重要了,常见的查找有多种,以下是其中的一些,看实现的完整代码请用随意门~

一,顺序查找
- Sequence Search
- 说明:顺序查找适合于存储结构为顺序存储或链接存储的线性表。
(一)基本思想
- 顺序查找也称为线形查找,属于无序查找算法。
- 从数据结构线形表的一端开始,顺序扫描,依次将扫描到的结点关键字与给定值k相比较,若相等则表示查找成功;若扫描结束仍没有找到关键字等于k的结点,表示查找失败。
(二)复杂度分析
- 查找成功时的平均查找长度为:(假设每个数据元素的概率相等) ASL = 1/n(1+2+3+…+n) = (n+1)/2 ;
- 当查找不成功时,需要n+1次比较,时间复杂度为O(n);
- 所以,顺序查找的时间复杂度为O(n)。
(三)代码实现
1 | int SequenceSort(int *arr, int value) |
二,折半查找
- Binary Search
- 说明:元素必须是有序的,如果是无序的则要先进行排序操作。
(一)基本思想
- 也称为是折半查找,属于有序查找算法。
- 用给定值k先与中间结点的关键字比较,中间结点把线形表分成两个子表,若相等则查找成功;若不相等,再根据k与该中间结点关键字的比较结果确定下一步查找哪个子表,这样递归进行,直到查找到或查找结束发现表中没有这样的结点。
(二)复杂度分析
- 最坏情况下,关键词比较次数为log2(n+1),且期望时间复杂度为O(log2n)。
(三)代码实现
1 | /*** 非递归版本 ***/ |
三,插值查找
(一)基本思想
- 基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率。当然,差值查找也属于有序查找。
- mid=low+(key-a[low])/(a[high]-a[low])*(high-low)
- 将上述的比例参数1/2改进为自适应的,根据关键字在整个有序表中所处的位置,让mid值的变化更靠近关键字key,这样也就间接地减少了比较次数。
(二)复杂度分析
- 查找成功或者失败的时间复杂度均为:O(log2(log2n))。
(三)代码实现
1 | /*** 非递归版本 ***/ |
四,分块查找
(一)基本思想
- 也叫索引顺序查找,算法实现除了需要查找表本身之外,还需要根据查找表建立一个索引表。
- 建立的索引表要求按照关键字进行升序排序,查找表要么整体有序,要么分块有序。 分块有序指的是第二个子表中所有关键字都要大于第一个子表中的最大关键字,第三个子表的所有关键字都要大于第二个子表中 的最大关键字,依次类推。
(二)复杂度分析
- 分块查找算法的运行效率受两部分影响:查找块的操作和块内查找的操作。
- 查找块的操作可以采用顺序查找,也可以采用折半查 找(更优);块内查找的操作采用顺序查找的方式。
- 相比于折半查找,分块查找时间效率上更低一些;相比于顺序查找,由于在子表中进行,比较的子表个数会不同程度的减少,所有分块查找算法会更优
- 总体来说,分块查找算法的效率介于顺序查找和折半查找之间。
(三)代码实现
1 | int search(int key, int a[]) |
五,斐波那契查找
(一)基本思想
- 也是二分查找的一种提升算法,通过运用黄金比例的概念在数列中选择查找点进行查找,提高查找效率。同样地,斐波那契查找也属于一种有序查找算法。
斐波那契查找与折半查找很相似,他是根据斐波那契序列的特点对有序表进行分割的。他要求开始表中记录的个数为某个斐波那契数小1,及n=F(k)-1;
- 开始将k值与第F(k-1)位置的记录进行比较(及mid=low+F(k-1)-1),比较结果也分为三种:
- 1)相等,mid位置的元素即为所求
- 2)>,low=mid+1,k-=2;
- 说明:low=mid+1说明待查找的元素在[mid+1,high]范围内,k-=2 说明范围[mid+1,high]内的元素个数为n-(F(k-1))= Fk-1-F(k-1)=Fk-F(k-1)-1=F(k-2)-1个,所以可以递归的应用斐波那契查找。
- 3)<,high=mid-1,k-=1。
- 说明:low=mid+1说明待查找的元素在[low,mid-1]范围内,k-=1 说明范围[low,mid-1]内的元素个数为F(k-1)-1个,所以可以递归 的应用斐波那契查找。
(二)复杂度分析
- 最坏情况下,时间复杂度为O(log 2 n),且其期望复杂度也为O(log 2 n)。
(三)代码实现
1 | /*构造一个斐波那契数组*/ |