斐波那契数列,又称黄金分割数列,指的是这样一个数列:一、一、二、三、五、八、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); } }