斐波那契数列:1,1,2,3,5,8,13…
可以发现相邻的两个数无限接近黄金分割点。
中间值:mid=low+F(k-1)+1
F代表斐波那契数列
理解:
1.斐波那契数列: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)和F(k-2)两部分。
从而中间位置为 mid=low+F(k-1)+1;
2.所以k值要使F(k)-1大于等于n,但是 n不一定够,这时,就需要将n增加,从新增位置到F(k)-1都赋为n的值即可。
public static int maxSize=20;
//后面需要使用到斐波那契数列,所及先建立一个
public static int[] Fibonacci(){
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;
}
//非递归方法
public static int search(int[] a,int key){
int low=0;
int high=a.length-1;
int k=0; //表示斐波那契分割数值对应的下标
int mid=0;
int []f=Fibonacci();
//不够
while(high>f[k]-1){
k++;
}
//多了
int []temp= Arrays.copyOf(a,f[k]); //这里表示不足部分用0填充
//但是实际上需要用a数组最后的数来填充
for(int i=high+1;i<temp.length;i++){
temp[i]=a[high];
}
//使用while循环,来找到key
while(low<=high){
mid=low+f[k-1]+1;
if(key<temp[mid]){
high=mid-1;
k--;
}else if(key>temp[mid]){
low=mid+1;
k-=2;
}else{
//找到
if(mid<=high){
return mid;
}else{
return high;
}
}
}
return -1;
}