1.斐波那契数列的简单介绍(摘自百度)
斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)
2.斐波那契数列和斐波那契查找算法之间的关系
前面我们谈过了二分查找算法和插值查找算法,也说过了二分查找算法和插值算法中存在着很多相似的地方,唯一不同的地方就是它们对于mid的定位不同,二分查找算法(mid=(low+high)/2), 插值算法(mid=low+(key-arr[low])/(high-low))
对于斐波那契查找算法而言,实现的方式和上述代码类似,唯一不同的也是对于mid的定位方式,在这里使用的是基于斐波那契数列的方式对mid进行定位
mid=low+F(k-1)-1 F表示斐波那契数列
3.如何推导公式
首先可以知道斐波那契数列公式如下: 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进行分割
所以可以得到mid的值为 low+F[k-1]-1
注:相当于把左段向后平移low个单位得到mid
4.斐波那契查找算法思路一览
(1)准备斐波那契数列
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;
}
(2) 在编写具体的算法之前,需要进行原搜索数组和斐波那契数组的适应工作
*F(k)-1的值要大于等于原数组的长度
//将顺序表的长度和斐波那契数列进行自适应
while (high > f[k] - 1) {
k++;
}
*修改之后将原数组进行拓展,将原数组的长度和斐波那契数列的值进行匹配
//因为f[K]可能大于数组的长度,因此需要使用Arrays构造一个新的数组,并指向a[],不足的部分会使用0去填充
int[] temp = Arrays.copyOf(a, f[k]);
//temp={1,8,10,89,1000,1234,0,0,0}->{1,8,10,89,1000,1234,1234,1234}
//新构建的数组用最后数进行填充
for (int i = high + 1; i < temp.length; i++) {
temp[i] = a[high];
}
注: 在这次变化之后 原顺序数组变成了{1,8,10,89,1000,1234,1234,1234} 斐波那契数列变成了 f[6]={1,1,2,3,5,8}
已经做到了 7(high)<=f[6]-1 arr[f[6]]={1,8,10,89,1000,1234,1234,1234}
(3) 开始喜闻乐见的查找(这次咱们玩玩非递归的方式)
while (low <= high) {
//借助斐波那契数列对mid进行定位
mid = low + f[k - 1] - 1;
if (key < temp[mid]) {//向左查找
high = mid - 1;
/**
* 全部元素 = 前面元素+后面元素
* f[k]=f[k-1]+f[k-2]
* 前面有f[k-1]个元素可以继续进行拆分
* 本次循环条件mid = low+f[k-1]-1
* 下次循环条件mid= low+f[k-1-1]-1
* */
k--;
} else if (key > temp[mid]) {
low = mid + 1;
//下次循环为 mid= f[k-1-2]-1
k -= 2; //!!! 注意这里不是K+=1 而是k-=2
} else {
if (mid <= high) {
return mid;
} else {
return high;
}
}
}
(4) 主函数
public static void main(String[] args) {
int[] arr = {1, 8, 10, 89, 1000, 1234};
System.out.println(fibSearch(arr, 1000));
}
(5) 结果
完整代码:https://github.com/Lzin/search_algor/tree/master/src/com/liz/fibonacci_search