斐波那契查找算法
什么是斐波那契查找算法?
1.黃金分割點是把一條線段分割成兩個部分,使得一部分與全長之比等於另一部分與這一部分之比,取其前三位的近似值大概是0.618。
2.斐波那契數列{1,1,2,3,5,8,13,...}兩個相鄰數的比例無限接近0.618
斐波那契思想
1.斐波那契思想與二分法相類似,不過中間點不再是中點,而變成了黃金分割點的附近mid=low+F(k-1)-1,F代表斐波那契數列
對於F(k-1)-1的含義的理解
1.F代表的斐波那契數列
2.k代表斐波那契數列的第k個元素
3.由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)兩段,另外一個1就是
mid位置的元素
4.類似的每一個子段也可以用同樣的方式來進行分隔
5.但是順序表的長度不一定是恰好等於F[k]-1,所以需要將原來的順序表的長度增加到F[k]-1,這里的k值僅僅需要恰好使得F[k]-1恰好大於或者等於n,新增位置,都賦值為下標為n-1位置的值就可以了
代碼實現
package search;
import java.util.Arrays;
public class FibonacciSearch {
public static int maxSize=20;
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] a= {1,2,3,4,5,6,7,8};
int index=fibonacciSearch(a, 5);
System.out.println(index);
}
public static int[] fib() {//返回一個斐波那契數組
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 fibonacciSearch(int[] a,int key)
{
int low=0;
int high=a.length-1;
int k=0;//表示斐波那契分割值的下標
int[] f=fib();//獲取斐波那契分割數值的下標
while(high>f[k]-1)
{
k++;
}
//因為f[k]這個值可能大於數組a的長度,因此需要使用Arrays類,構造一個新的數組並指向a
int[] temp=Arrays.copyOf(a, f[k]);//不足的部分會使用0填充
//用數組的最后一個數來填充
for(int i=high+1;i<temp.length;i++)
{
temp[i]=a[high];
}
while(low<=high)
{
int mid=low+f[k-1]-1;
if(key<temp[mid])//應當向前面進行查找
{
high=mid-1;
k--;//全部元素=前面的元素+后面的元素
//f[k]=f[k-1]+f[k-2]
//因為前面有f[k-1]個元素所以可以繼續拆分分配f[k-1]=f[k-2]+f[k-3]
//即f[k-1]的前面繼續查找k--
//下次訓話mid=f[k-1-1]-1
}
else if(k>temp[mid])//后面查找,右邊查找
{
low=mid+1;
k-=2;
}
else
{
if(mid<=high)
{
return mid;
}
else
{
return high;
}
}
}
return -1;
}
}