斐波那契查找
- 斐波那契数列 {1,1,2,3,5,8,13,21,34,55,89}
- 相邻两个数之比,越来越接近于黄金比例 0.618
- 改变了mid的位置 mid = low + F(k-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
- 假如数列长度n不一定是F(k)-1 ,将n增加至f(k)-1即可 arr[right]
public class FibonacciSearch { public static int maxSize = 20; /** * @return 斐波那契数列 */ 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; } /** * 斐波那契查找 * * @param arr 待查找数列 * @param key 待查找元素 * @return 待查找元素下标 */ public static int fibSearch(int[] arr, int key) { int low = 0; int high = arr.length - 1; int k = 0;//斐波那契下标 int mid = 0;//存放mid值 int[] f = fib(); while (high > f[k] - 1) { k++; } //目前为止,不足的部分是用0来填充 int[] temp = Arrays.copyOf(arr, f[k]); //{1,1,2,3,5,8,13,21,34,55} ->{1,1,2,3,5,8,13,21,34,55,55, 55,55} for (int i = high + 1; i < temp.length; i++) { temp[i] = arr[high]; } //非递归 while (low <= high) { mid = low + f[k - 1] - 1;//核心! if (key < temp[mid]) {//小于则往左 //递归传参 high = mid - 1; //f[k]=f[k-1]+f[k-2] k--; } else if (key > temp[mid]) {//大于则往右 low = mid + 1; //f[k]=f[k-1]+f[k-2] //f[k-2]=f[k-3]+f[k-4] k -= 2; } else { if (mid <= high) { return mid; } else { return high; } } } return -1; } }