查找算法之斐波那契查找


 

斐波那契(黃金分割法)查找算法

斐波那契算法基本介紹:

1.黃金分割點是把一條線段分割為兩部分,是其中一部分與全長之比等於另一部分與這部分之比,取其前三位數的近似值為0.618。由於按此比例設計的造型十分美麗,因此稱為黃金分割

2.斐波那契數列{1,1,2,3,5,8,13,21,34,55}發現斐波那契數列的相鄰兩個數的比例,無限接近黃金分格值0.618

3.斐波那契工作原理:斐波那契查找與二分查找和插入查找原理非常相似,僅僅改變了中間節點(mid)的位置,mid不在是中間或者是插值得到,而是位於黃金分割點附近,即mid=low=F(k-1)-1(F代表斐波那契數列)

 

 

對F(k-1)-1的理解:

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]-1和F[k-2]-1的兩端。從而中間位置為 mid=low=F(k-1)-1

2.類似的每個子段也可以使用相同的方式分割

3.但是順序表的長度n不一定剛好等於F[k]-1,所以需要將原來的順序表長度n增加至F[k]-1。這里的k值只要能 使得F[k]-1恰好大於或等於n即可

代碼:

package com.gcy.searcch;

import java.util.Arrays;

/**
* 斐波那契查找算法
* @author Administrator
*
*/
public class FeibonaqiSearch {
public static int maxSize=20;
public static void main(String[] args) {
int[] arr= {1,8,10,89,1000,1234};
System.out.println("所要查找的數據的下標值index="+feiSearch(arr,1234));
}
/**
* 得到一個斐波那契數列
* 使用非遞歸方式
* @return
*/
public static int[] fei() {
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 arr
* @param key要查找的關鍵字
* @return返回對應 的下標值
* */
public static int feiSearch(int[] arr,int key) {
int low=0;
int high=arr.length-1;
int k=0;//表示斐波那契數分割數的下標值
int mid=0;
int[] f=fei();//調用斐波那契數列
//獲取斐波那契分割數值的下標
while(high>(f[k]-1)) {
k++;
}
//因為f[k]值可能大於a的長度,因此需要使用Arrays工具類,構造一個新法數組,並指向temp[],不足的部分會使用0補齊
int[] temp=Arrays.copyOf(arr, f[k]);
//實際需要使用arr數組的最后一個數來填充不足的部分
for(int i=high+1;i<temp.length;i++) {
temp[i]=arr[high];
}
//使用while循環處理,找到key值
while(low<=high) {
mid=low+f[k-1]-1;
if(key<temp[mid]) {//向數組的前面部分進行查找
high=mid-1;
/*
* 對k--進行理解
* 1.全部元素=前面的元素+后面的元素
* 2.f[k]=k[k-1]+f[k-2]
* 因為前面有k-1個元素沒所以可以繼續分為f[k-1]=f[k-2]+f[k-3]
* 即在f[k-1]的前面繼續查找k--
* 即下次循環,mid=f[k-1-1]-1
*/
k--;
}else if(key>temp[mid]) {//向數組的后面的部分進行查找
low=mid+1;
/**
* 對k-=2理解
* 1.全部元素=前面的元素+后面的元素
* 2.f[k]=k[k-1]+f[k-2]
* 3.因為后面有k-2個元素,所以可以繼續拆分f[k-2]=f[k-3]+f[k-4]
* 4.即在f[k-2]前面進行查找k-=2
* 5.即在下次循環mid=[k-1-2]-1
*/
k-=2;

}else {//找到了
//需要確定返回的是哪個下標
if(mid<=high) {
return mid;
}else {
return high;
}
}
}
return -1;
}

}

結果截圖:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM