查找算法
-
java中,常用的查找算法:
- 顺序查找(线性查找)
- 二分查找/折半查找
- 插值查找
- 斐波那契查找
-
线形查找算法
-
举例:数列{1,8,10,89,1000,1234},判断数列中是否包含此名称,如果找到了,就是提示找到,并给出下标值。
-
代码实现
-
-
二分查找
-
对一个有序数组进行查找{1,8,10,89,1000,1234},对一个一个无序数组,则不能使用有序数组查找。
-
思路分析
1.首先确定该数组中间的下标mid=(left+right)/2;
2.然后让需要查找的数findVal和arr[mid]比较
2.1 findVal>arr[mid],说明要查找数在mid的右边,因此需要向右递归查找
2.2 findVal<arr[mid],说明要查找数在mid的左边,因此需要向左递归查找
2.3 findVal==arr[mid]说明找到,就返回。
什么时候需要结束递归
1)找到结束递归
2)递归完,仍然没有找到findVal,也需要结束递归 当left>right就需要退出
-
代码实现
二分查找
-
思考:{1,8,10,89,1000,1234}当一个有序数组中,有多个相同的数组时,如何将所有的数值都查找到,比如这里1000
-
代码实现
-
-
-
插值查找算法
-
插值查找算法类似于二分查找,不同的是插值查找每次从自适应mid处开始查找。
-
插值查找算法的求mid的自适应算法,对于目标值的定位非常快,尤其是在数据量较大并且连续的情况下,优越性就会体现出来。比如二分查找,查找五次才可查找出来,插值查找1次就可定位出来,可见其优越性。
-
将折半查找中的求mid索引的公式,low表示左边索引,high表示右边索引
int mid = left+(right-left)*(findVal-arr[left])/(arr[right]-arr[left])
-
插值查找注意事项
-
对于数据量较大,关键字分布比较均匀的查找表来说,采用插值查找,数据较快。
- 关键字:数组的元素
- 均匀:前后跳跃不是太大,比如1,2,3是均匀,1,1000,2,前后跳跃度不是太大,那么分布不均匀。
-
关键字分布不均匀的情况下,该方法不一定比折半查找要好。
-
代码实现
-
-
-
斐波那契(黄金分割法)查找算法
-
黄金分割点是指把一条线段分为两部分,使其中一部分与全长之比等于另一部分与这部分之比。取其前三位的近似值是0.618。由于按此比例设计的造型十分美丽,因此称为黄金分割,也称中外比。
-
斐波那契数列
- 前两位为1,从第三个数开始,为前面另个数和相加。
- {1,1,2,3,5,8,13,21,34,55}
- 两个相邻数的比例,无限接近黄金分割值0.618
-
斐波那契原理
-
原理和二分查找和插入查找类似,仅仅改变了中间结点的位置,mid不再是中间或插值得到,而是位于黄金分割点附近即mid=low+F(k-1)-1
-
F代表斐波那契数列
如图所示,有斐波那契数列F[k]=F[k-1]+F[k-2]的性质,可以得到(F[k]-1)=(F[k-1]-1)+(F[k-2]-1)+1。该是说明,只要顺序表的长度为F[k]-1,则可以将该表分成长度为F[k-1]-1和F[k-2]-1的阶段,即如上图所示,从而中间的位置为mid = low+F(k-1)-1
-
类似的,每一子段也可以用相同的方式分割
-
但顺序表长度n不一定刚好等于F[k]-1,所以需要将原来的顺序表长度n增加至F[k]-1,。这里的k值只要能使得F[k]-1恰好大于或者等于n即可,有以下代码得到,顺序表长度递增后,新增位置(从n+1到F[k]-1位置),都赋n位置的值即可。
-
代码实现
-
-