1、斐波那契查找算法
- Fibonacci Search:算法核心思想与二分法相同,只是mid点是黄金分割点;
- 黄金分割点是把一条线段分割成两个部分,使得一部分与全长之比等于另一部分与这一部分之比,取其前三位的近似值大概是0.618;
- 斐波那契数列{1,1,2,3,5,8,13,...}两个相邻数的比例无限接近0.618;
2、Java代码
package Algorithm.Search;
import java.util.Arrays;
/**
* @author yhx
* @date 2020/10/11
*/
public class FibonacciSearch {
public static void main(String[] args) {
int[] arr = {1, 8, 10, 89, 1000, 1234};
Fibonacci fibonacci = new Fibonacci();
int res = fibonacci.fibSearch(arr, 10);
if (res == -1) {
System.out.println("没有查找到!");
} else {
System.out.println("所查数在的位置是:" + res);
}
}
}
class Fibonacci {
public static final int MAXSIZE = 20;
/**
* 使用非递归的方式得到一个斐波那契数列
*
* @return 返回斐波那契数列
*/
public 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;
}
/**
* 斐波那契查找算法
*
* @param arr 查找数组
* @param key 待查找数
* @return 返回待查找数下标
*/
public int fibSearch(int[] arr, int key) {
int low = 0;
int high = arr.length - 1;
// 表示斐波那契分割数值的下标
int k = 0;
int mid;
int[] f = fib();
// 获取斐波那契分割值的下标
while (high > f[k] - 1) {
k++;
}
/*
因为f[k]可能大于arr[]的长度,因此需要Arrays类构造一个新的数组,并指向arr[]
不足的部分先用0填充,然后使用arr[]数组的最后一个值替换
举例:
arr[] = {1, 8, 10, 89, 1000, 1234}
temp[] = {1, 8, 10, 89, 1000, 1234, 0, 0, 0} => temp[] = {1, 8, 10, 89, 1000, 1234, 1234, 1234, 1234}
*/
int[] temp = Arrays.copyOf(arr, f[k]);
for (int i = high + 1; i < temp.length; i++) {
temp[i] = arr[high];
}
// 使用while来循环处理,找到查找数key
while (low <= high) {
mid = low + f[k - 1] - 1;
if (key < temp[mid]) {
high = mid - 1;
k--;
} else if (key > temp[mid]) {
low = mid + 1;
// 对于斐波那契数列,f[k] = f[k-1] + f[k-2]
k -= 2;
} else {
return Math.min(mid, high);
}
}
return -1;
}
}
3、运行结果
所查数在的位置是:2