斐波那契数列:
{1,1,2,3,5,8,13,21,34,55…} 相邻两个数的比例很接近0.618
思想:
仍然是改变mid的值来找到最佳索引位置==》mid = left+F[k-1]-1
数组中记录的个数为某个斐波那契数小1,即n=F(k)-1;(总长度F[k]-1 == F[k-1]-1 + F[k-2]-1)
如果数组长度不够,那么要进行扩容(增加到F[k]-1,扩容部分为源数组末尾值),满足斐波那契,才能进行斐波那契查找。
代码实现:
package chazhao;
import java.util.Arrays;
public class FibonacciSerach {
public static int maxSize = 20;
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 15};
int i = fibSearch(arr, 10);
System.out.println(i);
}
//返回一个斐波那契数列
public static int[] fib() {
int[] fib = new int[maxSize];
fib[0] = 1;
fib[1] = 1;
for (int i = 2; i < maxSize; i++) {
fib[i] = fib[i - 1] + fib[i - 2];
}
return fib;
}
//查找方法 非递归
public static int fibSearch(int[] arr, int num) {
int left = 0;
int right = arr.length - 1;
//斐波那契分割数值的下标
int k = 0;
//存放mid值
int mid = 0;
//获取斐波那契数列
int[] f = fib();
//获取到斐波那契数值的下标
while (right > f[k] - 1) {
k++;
}
//因为f[k]值可能大于arr数组长度,把arr填满,不足部分补0
int[] temp = Arrays.copyOf(arr, f[k]);
//把temp补齐的0换成temp的末尾值
for (int i = right + 1; i < temp.length; i++) {
temp[i] = arr[right];
}
//找值
while (left <= right) {
mid = left + f[k - 1] - 1;
if (num < temp[mid]) {
//左
right = mid - 1;
k--;
} else if (num > temp[mid]) {
left = mid + 1;
k -= 2;
} else {
//找到
if (mid <= right) {
return mid;
} else {
return right;
}
}
}
return -1;
}
}
结果