Java编程内功-数据结构与算法「斐波那契查找」

开发 后端 算法
斐波那契是指把一条线段分割成两部分,使其中一部分与全长之比等于另一部分与这部分之比。取其前三位数字的近似值是0.618。由于按此比例设计的造型十分美丽,因此也称为黄金分割,也称中外比。

[[398011]]

基本介绍

  1. 斐波那契是指把一条线段分割成两部分,使其中一部分与全长之比等于另一部分与这部分之比。取其前三位数字的近似值是0.618。由于按此比例设计的造型十分美丽,因此也称为黄金分割,也称中外比。
  2. 斐波那契数列{1,1,2,3,5,8,13,21,34,55}发现斐波那契数列的两个相邻数的比例,无限接近黄金分割值0.618.

斐波那契查找原理

斐波那契查找原理与二分查找和插值查找相似,仅仅改变了中间点(mid)的位置,mid不再是中间或插值得到的,而是位于黄金分割点附近,即mid = low+F(k-1)-1,F代表斐波那契数列,如下图

对F(k-1)-1的理解:

  1. 由于斐波那契数列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]和F[k-2]**的两段,即如上图所示。从而中间位置为:mid = low+F(k-1)-1。
  2. 类似的,每个字段也可以才用相似的方式分割。
  3. 但顺序表长度n不一定刚好等于F[k]-1,所以需要将原来的顺序表长度n增加至F[k]-1。这里的k值只要能使得F[k]-1恰好大于等于n即可,由以下代码得到,顺序表长度增加后,新增的位置(从n+1到F[k]-1),都赋为n位置的值即可.
  1. while(n>fib(k)-1){ 
  2.    k++; 

 代码案例

  1. package com.xie.search; 
  2.  
  3. public class Fibonacci { 
  4.  
  5.     public static void main(String[] args) { 
  6.         int arr[] = {1, 8, 10, 89, 1000, 1234}; 
  7.         int n = 6; 
  8.         int x = 1; 
  9.  
  10. //        int[] arr = new int[100]; 
  11. //        for (int i = 0; i < 100; i++) { 
  12. //            arr[i] = i; 
  13. //        } 
  14. //        int n = 100; 
  15. //        int x = 1; 
  16.  
  17.         System.out.println("Found at index: " + 
  18.                 fibMonaccianSearch(arr, x, n)); 
  19.     } 
  20.  
  21.     /** 
  22.      * 返回x和y最小的数 
  23.      * 
  24.      * @param x 
  25.      * @param y 
  26.      * @return 
  27.      */ 
  28.     public static int min(int x, int y) { 
  29.         return (x <= y) ? x : y; 
  30.     } 
  31.  
  32.     /** 
  33.      * 斐波那契搜索x的索引,找到就返回索引位置,否则返回-1 
  34.      * <p> 
  35.      * 算法说明: 
  36.      * 令arr[0..n-1]为输入数组,要搜索的元素为x。 
  37.      * 1.找到大于或等于n的最小斐波那契数。将此数字设为fibM [第m个斐波纳契数], 
  38.      * 设其前面的两个斐波那契数为fibMm1 [第(m-1)个斐波那契数]和fibMm2 [第(m-2)个斐波那契数]。 
  39.      * 2.当数组中有要检查的元素时: 
  40.      *  a.将x与fibMm2覆盖范围的最后一个元素进行比较,如果x匹配,则返回索引; 
  41.      *  b.如果x小于元素,则将三个Fibonacci变量向前移动两个Fibonacci,表示消除了剩余数组的大约后三分之二; 
  42.      *  c.如果x大于元素,则将三个斐波那契变量向后移动一个斐波那契。将偏移量重置为索引。这些加在一起表明消除了其余阵列的大约三分之一; 
  43.      * 3.由于可能还有一个元素需要比较,因此请检查fibMm1是否为1。如果是,则将x与该剩余元素进行比较。如果匹配,则返回索引。 
  44.      * 
  45.      * @param arr 数组 
  46.      * @param x   查找的值 
  47.      * @param n   数组的长度 
  48.      * @return x索引位置或者-1 
  49.      */ 
  50.     public static int fibMonaccianSearch(int arr[], int x, int n) { 
  51.         // 初始化斐波那契数 
  52.         //第(m-2)个斐波那契编号 
  53.         int fibMMm2 = 0; 
  54.         //第(m-1)个斐波那契编号 
  55.         int fibMMm1 = 1; 
  56.         //第 m个斐波那契数 
  57.         int fibM = fibMMm2 + fibMMm1; 
  58.  
  59.         /* fibM将存储最小的斐波那契数大于或等于n*/ 
  60.         while (fibM < n) { 
  61.             fibMMm2 = fibMMm1; 
  62.             fibMMm1 = fibM; 
  63.             fibM = fibMMm2 + fibMMm1; 
  64.         } 
  65.  
  66.         // 从前面标记消除的范围 
  67.         int offset = -1; 
  68.  
  69.         /* 循环检查元素,注意,我们将arr[fibMm2]与x进行了比较,当fibM变为1时,fibMm2变为0 */ 
  70.         while (fibM > 1) { 
  71.             // 检查fibMm2是否为有效位置 
  72.             int i = min(offset + fibMMm2, n - 1); 
  73.  
  74.             /* 如果x大于索引fibMm2处的值,则将从offset到i切割为子数组 */ 
  75.             if (arr[i] < x) { 
  76.                 fibM = fibMMm1; 
  77.                 fibMMm1 = fibMMm2; 
  78.                 fibMMm2 = fibM - fibMMm1; 
  79.                 offset = i; 
  80.             } else if (arr[i] > x) { 
  81.                 /*如果小于索引fibMm2处的值,则将从i+1到arr.length-1进行切割数组*/ 
  82.                 fibM = fibMMm2; 
  83.                 fibMMm1 = fibMMm1 - fibMMm2; 
  84.                 fibMMm2 = fibM - fibMMm1; 
  85.             } else { 
  86.                 /*找到了,就返回索引*/ 
  87.                 return i; 
  88.             } 
  89.         } 
  90.  
  91.         /* 将最后一个元素与x比较 */ 
  92.         if (fibMMm1 == 1 && arr[offset + 1] == x) { 
  93.             return offset + 1; 
  94.         } 
  95.  
  96.         /*没有找打,返回-1 */ 
  97.         return -1; 
  98.     } 

 【编辑推荐】

 

责任编辑:姜华 来源: 今日头条
相关推荐

2021-04-07 09:26:37

Java数据结构算法

2021-04-23 09:12:09

Java数据结构算法

2021-05-12 09:07:09

Java数据结构算法

2021-04-13 09:37:41

Java数据结构算法

2021-03-09 06:30:32

JAVA数据结构算法

2021-03-18 08:44:20

Java数据结构算法

2021-03-26 08:40:28

Java数据结构算法

2021-03-12 09:13:47

Java数据结构算法

2021-03-23 08:33:22

Java数据结构算法

2021-04-27 06:21:29

Java数据结构算法

2012-02-22 10:14:44

Java

2021-03-10 08:42:19

Java数据结构算法

2021-03-08 06:28:57

JAVA数据结构与算法稀疏数组

2021-03-17 09:27:36

Java数据结构算法

2021-04-16 09:40:52

Java数据结构算法

2021-04-15 09:36:44

Java数据结构算法

2021-04-22 10:07:45

Java数据结构算法

2021-03-14 08:27:40

Java数据结构算法

2021-03-11 08:53:20

Java数据结构算法

2021-12-28 07:20:44

斐波那契数算法数字
点赞
收藏

51CTO技术栈公众号