2025-01-19 斐波那契查找法

This commit is contained in:
liangjinglin 2025-01-19 14:51:08 +08:00
parent 7a02e2ae09
commit daf6e6b989

View File

@ -0,0 +1,81 @@
package Search;
import SortAlgori.MergeSort;
import java.util.Arrays;
public class FibonacciSearch {
private int[] arr;
// 斐波那契数列
private int[] fibonacci;
public FibonacciSearch(int[] arr){
this.arr = arr;
this.fibonacci = new int[20];
fibonacci[0] = 1;
fibonacci[1] = 1;
for (int i = 2; i < fibonacci.length; i++) {
fibonacci[i] = fibonacci[i-1] + fibonacci[i-2];
}
}
//{1,1,2,3,5,8,13,21,34,55}
//{1,8,10,89,1000,1234}
private int fibSearch(int key){
int low = 0;
int high = arr.length-1;
int k = 0;
int mid = 0;
// 让数组的长度去匹配斐波那契数列直到找到数组长度大于斐波那契数组中的某个数为止
while(high > fibonacci[k]-1){
k++;
}
// 拓展原数组让原数组长度等于获取到的斐波那契数组的值f[k]
int[] temp = Arrays.copyOf(arr, fibonacci[k]);
// 拓展的部分用原数组的最后的元素进行填充
for(int i = high+1; i < temp.length; i++){
temp[i] = arr[high];
}
while(low <= high){
//获取斐波那契分割点的下标
//根据斐波那契数组的特性,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=low+F[K-1]-1
mid = low + fibonacci[k-1] - 1;
if(key < temp[mid]){
high = mid - 1;
// 全部元素 = 前面元素 + 后面元素
// f[k] = f[k-1] + f[k-2]
// 所以mid值前面的数列实际上就是f[k-1]
k--;
} else if (key > temp[mid]){
low = mid + 1;
// 全部元素 = 前面元素 + 后面元素
// f[k] = f[k-1] + f[k-2]
// 所以mid值后面的数列实际上就是f[k-2]
k = k -2;
} else {
if (mid <= high){
return mid;
} else {
// 因为high以后的坐标是拓展队列
return high;
}
}
}
return -1;
}
public static void main(String[] args) {
int[] arr = new int[]{1,8,10,89,1000,1234};
System.out.println("排序后的序列:");
FibonacciSearch fibonacciSearch = new FibonacciSearch(arr);
long startTime = System.currentTimeMillis();
int search = fibonacciSearch.fibSearch(1000);
long endTime = System.currentTimeMillis();
System.out.println("查找到的下标是:" + search);
System.out.println("查找所花费的时间:" + (endTime - startTime) + "ms");
}
}