目录
查找算法
1、线性查找
线性查找是一种非常简单的查找方式。查找思路是:从数组的一个元素出发,一个个地和要查找的值进行比较,如果发现有相同的元素就返回该元素的下标。反之返回-1(未找到)
2、二分查找
时间复杂度O(logn)
二分查找首先要求的是该数组已经有序了
-
设置一个指向中间元素下标的变量mid,mid=(left + right)/2
-
让要查找的元素和数组mid下标的元素进行比较
-
如果查找的元素大于arr[mid],则left变为mid后面一个元素的下标
-
如果查找的元素小于arr[mid],则right变为mid前一个元素的下标
-
如果查找的元素等于arr[mid],则mid就是要查找元素所在的位置
-
-
当left > rigth时,说明元素不在该数组中
改进:但是有可能要查找的元素有多个。这时就需要在找到一个元素后,不要立即返回,而是扫描其左边和右边的元素,将所有相同元素的下标保存到一个数组中,然后一起返回
public class BinarySearch {
public static ArrayList<Integer> Binary(int[] array, int target, int left, int right){
ArrayList<Integer> Indexlist = new ArrayList<Integer>();
int mid = (right + left)/2;
if(left > right){
Indexlist.add(-1);
return Indexlist;
}
if(array[mid] == target){
Indexlist.add(mid);
int tmp = mid - 1;
while(array[tmp] == target){
Indexlist.add(tmp);
tmp--;
}
tmp = mid + 1;
while(array[tmp] == target){
Indexlist.add(tmp);
tmp++;
}
return Indexlist;
}else if(array[mid] > target){
return Binary(array, target, left, mid-1);
}else{
return Binary(array, target, mid+1, right);
}
}
public static void main(String[] args) {
int[] array = {1,2,3,3,4,4,4,4,5,6,7,8,9};
ArrayList<Integer> index = Binary(array, 4, 0, array.length - 1);
for(int i = 0; i < index.size(); i++){
System.out.print(index.get(i)+" ");
}
}
}
3、插值查找
在二分查找中,如果我们 要找的元素位于数组的最前端或者最后段,这时的查找效率是很低的。所以在二分查找至上,引入了插值查找,也是一种基于有序数组的查找方式
插值查找与二分查找的区别是:插值查找使用了一种自适应算法,用这种算法来计算mid。
mid的值在两种查找算法中的求法:
-
二分查找:mid = (left + right)/2
-
插值查找:
mid = left + (right - left) * (num - arr[left]) / (arr[right] - arr[left])
-
其中num为要查找的那个值
-
相当于增加一个权值
4、斐波那契(黄金分割法)查找
黄金分割点是指把一条线段分割为两部分,使其中一部分与全长之比等于另一部分与这一部分之比。取其前三位数字的近似值0.618。
斐波那契数列{1,1,2,3,5,8,13,21,34,55}两个相邻数的比例,无限接近黄金分割点。
斐波拉去查找原理与前两种相似,仅仅改变了中间结点(mid)的位置,mid=left + F(k-1)- 1