斐波那契數列,又稱黃金分割數列,指的是這樣一個數列:一、一、二、三、五、八、1三、2一、····,在數學上,斐波那契被遞歸方法以下定義:F(1)=1,F(2)=1,F(n)=f(n-1)+F(n-2) (n>=2)。該數列越日後相鄰的兩個數的比值越趨向於黃金比例值(0.618)。 java
斐波那契查找就是在二分查找的基礎上根據斐波那契數列進行分割的。在斐波那契數列找一個等於略大於查找表中元素個數的數F[n],將原查找表擴展爲長度爲F[n](若是要補充元素,則補充重複最後一個元素,直到知足F[n]個元素),完成後進行斐波那契分割,即F[n]個元素分割爲前半部分F[n-1]個元素,後半部分F[n-2]個元素,找出要查找的元素在那一部分並遞歸,直到找到。 數組
package test.algorithm.FastSlowPointer; /** * 斐波那契查找(黃金分割法查找) * @author serenity * */ public class FibonacciSearch { public final static int MAXSIZE = 20; /** * 斐波那契數列 * @return */ public static int[] fibonacci(){ int[] f = new int[20]; int i =0; f[0] = 1; f[1] = 1; for(i=2;i<MAXSIZE;i++){ f[i] = f[i-1]+f[i-2]; } return f; } public static int fibonacciSearch(int[] data,int key){ int low = 0; int high = data.length-1; int mid = 0; //斐波那契分割數值下標 int k = 0; //序列元素個數 int i=0; // 獲取斐波那契數列 int[] f = fibonacci(); //獲取斐波那契分割數值下標 while(data.length>f[k]-1){ k++; } //建立臨時數組 int[] temp = new int[f[k]-1]; for(int j=0;j<data.length;j++){ temp[j] = data[j]; } //序列補充至f[k]個元素 //補充的元素值爲最後一個元素的值 for(i=data.length;i<f[k]-1;i++){ temp[i]=temp[high]; } for(int j:temp){ System.out.print(j+" "); } System.out.println(); while( low <= high ) { // low:起始位置 // 前半部分有f[k-1]個元素,因爲下標從0開始 // 則-1 獲取 黃金分割位置元素的下標 mid = low + f[k-1] - 1; if( temp[mid] > key ) { // 查找前半部分,高位指針移動 high = mid - 1; // (所有元素) = (前半部分)+(後半部分) // f[k] = f[k-1] + f[k-1] // 由於前半部分有f[k-1]個元素,因此 k = k-1 k = k - 1; }else if( temp[mid] < key ) { // 查找後半部分,高位指針移動 low = mid + 1; // (所有元素) = (前半部分)+(後半部分) // f[k] = f[k-1] + f[k-1] // 由於後半部分有f[k-1]個元素,因此 k = k-2 k = k - 2; }else{ //若是爲真則找到相應的位置 if( mid <= high ) { return mid; }else{ //出現這種狀況是查找到補充的元素 //而補充的元素與high位置的元素同樣 return high; } } } return -1; } public static void main(String[] args) { int[] f = fibonacci(); for(int i:f){ System.out.print(i+" "); } System.out.println(); int[] data = {1, 5, 15, 22, 25, 31, 39, 42, 47, 49, 59, 68, 88}; int search = 39; int position = fibonacciSearch(data,search); System.out.println("值"+search+"的元素位置爲:"+position); } }