From daf6e6b989bcf85ebc614c4a7c559cfdb2bc7839 Mon Sep 17 00:00:00 2001 From: liangjinglin Date: Sun, 19 Jan 2025 14:51:08 +0800 Subject: [PATCH] =?UTF-8?q?2025-01-19=20=E6=96=90=E6=B3=A2=E9=82=A3?= =?UTF-8?q?=E5=A5=91=E6=9F=A5=E6=89=BE=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/Search/FibonacciSearch.java | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/dataANDcalc/java/Search/FibonacciSearch.java diff --git a/src/dataANDcalc/java/Search/FibonacciSearch.java b/src/dataANDcalc/java/Search/FibonacciSearch.java new file mode 100644 index 0000000..5f65fa7 --- /dev/null +++ b/src/dataANDcalc/java/Search/FibonacciSearch.java @@ -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"); + } +}