• 查找算法-斐波那契查找法(Fibonacci Search)


    目录

      查找算法-斐波那契查找法(Fibonacci Search)

    1、说明

    2、算法分析

    3、C++代码 


      查找算法-斐波那契查找法(Fibonacci Search)

    1、说明

    斐波那契查找法又称为斐氏查找法,此查找法和二分法一样都是以分割范围来进行查找的,不同的是斐波那契查找法不是按对半方式来分割的,而是以斐波那契级数的方式来分割的。

    斐波那契级数F(n)的定义如下:

            F_{0} = 0; F_{1} = 1;

            F_{i} = F_{i-1} + F_{i-2}

    斐波那契级数:0、1、1、2、3、5、8、13、21、34、55、89、...。也就是除了第0个和第1个元素外,级数中的每个元素值都是前两个元素值的和。

    斐波那契查找法的好处是只需要用到加减运算而不需要用到乘除运算,这从计算机运算的过程来看效率会高于前两种查找法。在尚未介绍斐波那契查找法之前,我们先来认识斐波那契树。所谓斐波那契树,是以斐波那契级数的特性来建立的二叉树,其建立的原则如下:

    1. 斐波那契树的左右子树均为斐波那契树。
    2. 当数据个数n确定时,若想确定斐波那契树的层数k值是多少,我们必须找到一个最小的k值,使得斐波那契层数的Fib(k+1)\geqslant n+1
    3. 斐波那契树的树根一定是一个斐波那契树,且子节点与父节点差值的绝对值为斐波那契数。
    4. k\geqslant 2时,斐波那契树的树根为Fib(k),左子树为(k-1)层斐波那契树(其树根为Fib(k-1)),右子树为(k-2)层斐波那契树(其树根为Fib(k)+Fib(k-2))。
    5. n+1值不是斐波那契树的值,则可以找出一个m,使得Fib(k+1)-m=n+1m=Fib(k+1)-(n+1),再按斐波那契树的建立原则完成斐波那契树的建立,最后斐波那契树的各节点再减去差值m即可,并把小于1的节点去掉。

    2、算法分析

    1. 斐波那契查找法的平均比较次数少于二分查找法,但在最坏的情况下二分查找法较快,其平均时间复杂度为O(log_{2}n)
    2. 斐波那契查找法较为复杂,需额外产生斐波那契树。

    3、C++代码 

    1. #include
    2. using namespace std;
    3. void SetData(int* Data, int Size) {
    4. for (int i = 0; i < Size; i++) {
    5. Data[i] = rand() % 150 + 1;
    6. }
    7. }
    8. void Sort(int* Data, int Size) {
    9. for (int i = 0; i < Size; i++) {
    10. for (int j = i + 1; j < Size; j++) {
    11. if (Data[i] > Data[j]) {
    12. int temp = Data[i];
    13. Data[i] = Data[j];
    14. Data[j] = temp;
    15. }
    16. }
    17. }
    18. }
    19. void Print(int* Data, int Size) {
    20. for (int i = 0; i < Size ; i++) {
    21. cout << Data[i] << " ";
    22. }
    23. cout << endl;
    24. }
    25. int* Fibonacci(int Size) {
    26. int* fib = new int[Size];
    27. fib[0] = 0;
    28. fib[1] = 1;
    29. for (int i = 2; i < Size; i++) {
    30. fib[i] = fib[i - 1] + fib[i - 2];
    31. }
    32. return fib;
    33. }
    34. int FibonacciSearch(int* Data, int Size, int Value) {
    35. int low = 0;
    36. int high = Size - 1;
    37. int k = 0;
    38. int mid = 0;
    39. int* fib = Fibonacci(Size);
    40. while (high > fib[k] - 1) {
    41. k++;
    42. }
    43. int* temp = new int[fib[k]];
    44. for (int i = 0; i < Size; i++) {
    45. temp[i] = Data[i];
    46. }
    47. for (int i = Size; i < fib[k]; i++) {
    48. temp[i] = Data[high];
    49. }
    50. while (low <= high) {
    51. mid = low + fib[k - 1] - 1;
    52. if (Value < temp[mid]) {
    53. high = mid - 1;
    54. k--;
    55. }
    56. else if (Value > temp[mid]) {
    57. low = mid + 1;
    58. k -= 2;
    59. }
    60. else
    61. return mid <= high ? mid : high;
    62. }
    63. return -1;
    64. }
    65. int main() {
    66. int Size = 20;
    67. int* Data = new int[Size] {0};
    68. SetData(Data, Size);
    69. Sort(Data, Size);
    70. cout << "原始数据:" << endl;
    71. Print(Data, Size);
    72. cout << "---------------------" << endl;
    73. int num = 0;
    74. cout << "请输入想要查找的数据:";
    75. cin >> num;
    76. int index = -1;
    77. index = FibonacciSearch(Data, Size, num);
    78. if (index != -1)
    79. cout << "查找的数据在数据库的第[ " << index + 1 << " ]位" << endl;
    80. else
    81. cout << "在数据库中没有找到该数据" << endl;
    82. return 0;
    83. }

    输出结果 

  • 相关阅读:
    棱镜七彩参编!开源领域4项团体标准正式发布
    【踩坑篇】代码中使用 Long 作为 Map的Key存在的问题
    Lumion和Enscape渲染器有什么区别?哪个适合你
    springboot证书管理系统的设计与实现毕业设计源码162317
    Python时间模块(datetime)
    Go使用Gin+mysql实现增删改查
    除了增删改查你对MySQL还了解多少?
    Java_集合泛型、Collection接口
    pb:导入EXCEL,提示“不能连接EXCEL”
    驻波在物理上的应用与魅力
  • 原文地址:https://blog.csdn.net/qq_40660998/article/details/134033754