二分查找(递归)----针对“有序”的数组
public static int search(int[] arr,int left,int right,int findv){
if(left>right||findv<arr[0]||findv>arr[arr.length-1]){//没有找到个数,结束递归
return -1;
}
int mid=(left+right)/2;
int midv=arr[mid];
if(findv<midv){//向左递归
return search(arr,left,mid-1,findv);
}else if(findv>midv){//向右递归
return search(arr,mid+1,right,findv);
}else{//找到了这个数,就返回相应的索引
return mid;
}
}
差值查找—自适应的二分查找&有局限性
//差值查找(针对间隔均匀)
public static int insertsearch(int[] arr,int left,int right,int findv){
if(left>right||findv<arr[0]||findv>arr[arr.length-1]){//没有找到个数,结束递归
return -1;
}
//防止mid越界,判断合法性
int mid=left+(right-left)*(findv-arr[left])/(arr[right]-arr[left]);
if(mid<0 || mid>(arr.length-1)){
return -1;
}
int midv=arr[mid];
if(findv<midv){//向左递归
return search(arr,left,mid-1,findv);
}else if(findv>midv){//向右递归
return search(arr,mid+1,right,findv);
}else{//找到了这个数,就返回相应的索引
return mid;
}
}
斐波那契(黄金分割)查找算法
step1:首先借助斐波那契数列,将原始的数组扩充为能够找到黄金分割点的临时数组temp
step2:借助斐波那契数列,开始循环分割查找数据(类似二分查找:只是mid=low+f[k-1]-1)
//创建斐波那契数列
public static int[] fib(){
int[] arr=new int[maxsize];
arr[0]=1;
arr[1]=1;
for (int i = 2; i <maxsize ; i++) {
arr[i]=arr[i-1]+arr[i-2];
}
return arr;
}
//斐波那契(黄金分割)查找
public static int fibsearch(int[] arr,int findv){
int low=0;
int high=arr.length-1;//有效的最高索引
int k=0;//斐波那契数列的下标
int mid=0;//arr数组的mid值
int[] f=fib();
//构造长度满足f[i]-1=(f[i-1]-1)+(f[i-2]-1)+1的临时数组temp
while(high>f[k]-1){
k++;
}
int[] temp= Arrays.copyOf(arr,f[k]);//超出high长度的部分使用0来填充
for(int i=high+1;i<temp.length;i++){
temp[i]=arr[high];
}
//开始循环斐波那查找(temp的长度满足)
//f[i]-1=(f[i-1]-1)+(f[i-2]-1)+1,显然这个多余的1恰好作为mid位置
while(low<=high){
mid=low+f[k-1]-1;
if(findv<temp[mid]){//向左边查找
high=mid-1;
k--;//位于左半端的长度
}else if(findv>temp[mid]){//向右查找
low=mid+1;
k=k-2;//位于右半段的长度
}else{
if(mid<high){
return mid;//相当于找的不是最后一个数
}else{
return high;//找的是最后一个数
}
}
}
return -1;//相当于没有找到任何一个数
}
}