二分
//二分查找
//前提:先需进行排序
//关键:递归查找
//递归退出条件:1.找到2.递归完整个数组,仍然没有找到,也需结束递归,条件:left>right
public static List binarySearch(int[]arr, int left, int right, int findVal){
//递归整个数组,没找到
//条件left>right
if (left>right){
return new ArrayList();
}
int mid =(left+right)/2;
int midVal =arr[mid];
if (findVal>midVal){
return binarySearch(arr,mid+1,right,findVal);
} else if (findVal resIndexlist = new ArrayList();
//向左扫描
int temp = mid-1;
while (true){
if (temp<0||arr[temp]!=findVal){
break;//退出
}
//否则就将temp放入到resIndexlist
resIndexlist.add(temp);
temp-=1;//temp左移
}
resIndexlist.add(mid);
//向右扫描
temp=mid+1;
while (true){
if (temp>arr.length-1||arr[temp]!=findVal){
break;
}
//否则就将temp放入到resIndexlist
resIndexlist.add(temp);
temp+=1;
}
return resIndexlist;
}
}
插值
key:
Low+(High-Low)*(findVal-arr[Low])/(arr[High]-arr[Low])//其中arr[Low]<=findVal<=arr[High]
//插值查找
//前提:先需进行排序
//关键1:递归查找
//关键2:mid自适应求解算法:Low+(High-Low)*(findVal-arr[Low])/(arr[High]-arr[Low])//其中arr[Low]<=findVal<=arr[High]
//递归退出条件:1.找到2.递归完整个数组,仍然没有找到,也需结束递归,条件:left>right
public static List InterpSearch(int[]arr, int left, int right, int findVal){
//递归整个数组,没找到
if (left>right||findValarr[arr.length-1]){
return new ArrayList();
}
int mid =left+(right-left)*(findVal-arr[left])/(arr[right]-arr[left]);
int midVal =arr[mid];
if (findVal>midVal){
return InterpSearch(arr,mid+1,right,findVal);
} else if (findVal resIndexlist = new ArrayList();
//向左扫描
int temp = mid-1;
while (true){
if (temp<0||arr[temp]!=findVal){
break;//退出
}
//否则就将temp放入到resIndexlist
resIndexlist.add(temp);
temp-=1;//temp左移
}
resIndexlist.add(mid);
//向右扫描
temp=mid+1;
while (true){
if (temp>arr.length-1||arr[temp]!=findVal){
break;
}
//否则就将temp放入到resIndexlist
resIndexlist.add(temp);
temp+=1;
}
return resIndexlist;
}
}
斐波那契查找算法
public class FibonacciSearch {
//因为后面我们mid=low+F(k-1)-1,需要使用到斐波那契数列,因此我们需要先获取到一个斐波那契数列
// 非递归方法得到一个斐波那契数列
public static int[] fib(int maxSize){
int [] f =new int[maxSize];
f[0]=1;
f[1]=1;
for (int i = 2; i < maxSize; i++) {
f[i]=f[i-1]+f[i-2];
}
return f;
}
//编写斐波那契查找算法
//使用非递归的方式编写算法
/**
*
* @param a 数组
* @param key
* @return 返回对应下标,如果没有-1
*/
public static int fibSearch(int[] a,int key){
int low = 0;
int high =a.length-1;
int k = 0;//表示斐波那契分割数值的下标
int mid = 0;//存放mid值
int f[]=fib(20);
//获取到斐波那契分割数值的下标
while (high>f[k]-1){
k++;
}
//因为f[k]值可能大于a的长度,因此我们需要使用Arrays类,构造一个新的数组,并指向temp[]
//不足的部分会使用0填充
int[] temp = Arrays.copyOf(a,f[k]);
//实际上需求使用a数组最后的数填充temp
// 举例:
//temp= {1,8,10,89,1000,1234,0,0}=>{1,8,10,89,1000,1234,1234,1234,}
for (int i = high+1; i temp[mid]) {
//向右边继续查找
low=mid+1;
//*为什么是k-2
//说明
//1.全部元素=前面的元素+后边元素
// 2.f[k]=f[k-1]+ f[k-2]
//3.因为后面我们有f[k-2]所以可以继续拆分f[k-2]= f[k-3]+ f[k-4]
// 4.即在f[k-2]的前面进行查找k -=2
//5.即下次循环mid= f[k-1-2]- 1
k-=2;
}else {
//找到
if (mid<=high){
return mid;
}else {
return high;
}
}
}
return -1;
}