二分查找算法(加法方式:斐波那契查找)

二分查找算法比较熟悉的是折半查找,但是折半查找中计算mid时,有加法和除法。下面介绍仅有加法方式的二分查找算法

核心思想利用斐波那契表达式来实现加法方式的折半查找
技巧点:
1)将数组中数的个数(f(n)-1)分成 f(n-1) -1和 f(n-2)
2):f(n) - 1 = (f(n-1)-1 )+ (f(n-2)-1)
在数组中因为要用到一个mid数(中间位置的数) 故总共要减掉1,故上述表达式成立。

  1 #-*-coding: UTF-8 -*-
  2
  3
  4 #
  5 # 时间复杂度O(log(n))
  6
  7 def fibonacci_search_F1(lis, key):
  8     print("---F1---")
  9     # 需要一个现成的斐波那契列表。其最大元素的值必须超过查找表中元素个数的数值。
 10     F = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144,
 11          233, 377, 610, 987, 1597, 2584, 4181, 6765,
 12          10946, 17711, 28657, 46368]
 13     low = 0
 14     high = len(lis) - 1
 15
 16     # 为了使得查找表满足斐波那契特性,在表的最后添加几个同样的值
 17     # 这个值是原查找表的最后那个元素的值
 18     # 添加的个数由F[k]-1-high决定
 19     k = 0
 20     while high > F[k]-1:
 21         k += 1
 22     print(k)
 23     i = high
 24     while F[k]-1 > i:
 25         lis.append(lis[high])
 26         i += 1
 27     print(lis)
 28
 29     # 算法主逻辑。time用于展示循环的次数。
 30     time = 0
 31     while low <= high:
 32         time += 1
 33         # 为了防止F列表下标溢出,设置if和else
 34         if k < 2:
 35             mid = low
 36         else:
 37             #利用F[k-1]来计算中间位置的数
 38             mid = low + F[k-1]-1
 39
 40         print("low=%s, mid=%s, high=%s" % (low, mid, high))
 41         if key < lis[mid]:
 42             high = mid - 1
 43             k -= 1
 44         elif key > lis[mid]:
 45             low = mid + 1
 46             k -= 2
 47         else:
 48             if mid <= high:
 49                 # 打印查找的次数
 50                 print("times: %s" % time)
 51                 return mid
 52             else:
 53                 print("times: %s" % time)
 54                 return high
 55     print("times: %s" % time)
 56     return False
 57
 58 def fibonacci_search_F2(lis, key):
 59     print("---F2---")
 60     # 需要一个现成的斐波那契列表。其最大元素的值必须超过查找表中元素个数的数值。
 61     F = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144,
 62          233, 377, 610, 987, 1597, 2584, 4181, 6765,
 63          10946, 17711, 28657, 46368]
 64     low = 0
 65     high = len(lis) - 1
 66
 67     # 为了使得查找表满足斐波那契特性,在表的最后添加几个同样的值
 68     # 这个值是原查找表的最后那个元素的值
 69     # 添加的个数由F[k]-1-high决定
 70     k = 0
 71     while high > F[k]-1:
 72         k += 1
 73     print(k)
 74     i = high
 75     while F[k]-1 > i:
 76         lis.append(lis[high])
 77         i += 1
 78     print(lis)
 79
 80     # 算法主逻辑。time用于展示循环的次数。
 81     time = 0
 82     while low <= high:
 83         time += 1
 84         # 为了防止F列表下标溢出,设置if和else
 85         if k < 2:
 86             mid = low
 87         else:
 88             mid = low + F[k-2]-1
 89
 90         print("low=%s, mid=%s, high=%s" % (low, mid, high))
 91         if key < lis[mid]:
 92             high = mid - 1
 93             k -= 2
 94         elif key > lis[mid]:
 95             low = mid + 1
 96             k -= 1
 97         else:
 98             if mid <= high:
 99                 # 打印查找的次数
100                 print("times: %s" % time)
101                 return mid
102             else:
103                 print("times: %s" % time)
104                 return high
105     print("times: %s" % time)
106     return False
107
108 if __name__ == ‘__main__‘:
109     LIST = [1,2,3,4, 5,6, 7, 8,9,10,11,12,13,14,15,16,17,18,19,20]
110     print("F1:%d" % fibonacci_search_F1(LIST, 15))
111     print("F2:%d" % fibonacci_search_F2(LIST, 15))

以上用两种方式查找mid的值,主要思想是 mid 既可以由f(n-1) 获得 又可以由f(n-2) 获得。

F1:     f(n-1) + f(n-2) = f(n)

F2:     f(n-2) + f(n-1) = f(n)

原文地址:https://www.cnblogs.com/hoojjack/p/10952202.html

时间: 2024-07-29 23:35:44

二分查找算法(加法方式:斐波那契查找)的相关文章

"二分查找(Binary Search)"与"斐波那契查找(Fibonacci Search)"

首先,我们来看一个笔者的拙作,一段二分查找代码 //返回值是key的下标,如果A中不存在key则返回-1 template <class T> int BinSearch(T* A, const T &key, int lo, int hi) {     int mid;     while(lo<hi)     {         mid = lo + (hi-lo)/2;         if(key < A[mid])             hi = mid-1;

数据结构之---C语言实现斐波那契查找

斐波那契查找的核心思想是: 1)当key=a[mid]时,查找成功: 2)当key<a[mid]时,新的查找范围是第low个到第mid-1个,此时范围个数为F[k-1] - 1个,即数组左边的长度,所以要在[low, F[k - 1] - 1]范围内查找: 3)当key>a[mid]时,新的查找范围是第mid+1个到第high个,此时范围个数为F[k-2] - 1个,即数组右边的长度,所以要在[F[k - 2] - 1]范围内查找. 代码: //斐波那契查找 //杨鑫 #include <

【算法】先生,您点的查找套餐到了(二分、插入和斐波那契查找)

参考资料 <算法(java)>                           — — Robert Sedgewick, Kevin Wayne <数据结构>                                  — — 严蔚敏 Interpolation Search[插值查找]     — —  维基百科 Fibonacci Search[斐波那契查找]   — —  GeeksforGeeks 根据输入的一个关键字(Key),  在一个有序数组内查找与该关键

数据结构(六)查找---有序表查找(三种查找方式:折半,插值,斐波拉契查找)

前提 有序表查找要求我们的数据是有序的,是排序好的,我们只需要进行查找即可 我们下面将介绍折半查找(二分查找),插值查找,斐波那契查找 一:折半查找 (一)定义 二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法.但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列. (二)查找过程 首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关

看数据结构写代码(53) 静态查找表(线性查找,二分查找,斐波那契查找,插值查找)

查找定义:根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录). 查找表分类:静态查找表和动态查找表. 静态查找表:只查找,而不进行插入,删除. 动态查找表:在查找过程中同时插入查找表中不存在的数据元素,或者从查找表中删除已经存在的某个数据元素. 静态表的 查找 大致 四种 算法: 线性查找,二分查找,斐波那契查找和插值查找. 其中 在线性查找之前,对表 无要求.对于 其余三种 需要 在查找之前 排序.插值查找 除了 需要 排序,还需要 均匀分布. 下面 给出代码: 线性查

二分查找和斐波那契查找

二分查找 说明:查找的数组或列表必须是有序的,若无序,先进行排序 复杂度:时间复杂度 O(log2n),空间复杂度O(n) C++源码(递归和非递归两个版本) #include <iostream> using namespace std; int a[] = { 1, 2, 3, 4, 5, 6, 8 }; int BinarySearch1(int l, int r, int value) { int mid = (l + r) / 2; if (l == r && a[l

分治法--二分查找、乘方、斐波那契数

1.二分查找 常见错误: 死循环:循环体外的初始化条件,与循环体内的迭代步骤, 都必须遵守一致的区间规则,也就是说,如果循环体初始化时,是以左闭右开区间为边界的,那么循环体内部的迭代也应该如此.如果两者不一致,会造成程序的错误. 溢出:middle = left + (right - left) / 2 终止条件:一般来说,如果左闭右闭,则left<=right: 如果一开一闭,则left<right: 关键看left能不能等于right,而且要考虑实际情况,有时不能这样简单终结,会出现死循环

斐波那契查找算法 -数据结构

这个是我本人写的斐波那契查找算法,和网上的其他思路略有不同,特贴出来: 1)没有预先存储斐波那契的数组,整个的搜索数据长度可以变动: 2)mid索引的变动是动态变化的,根据斐波那契的回退方法: #include<stdlib.h>#include<stdio.h> #define INF 32767#define SIZE 92int Feibinaci(int str[],int n,int key){ int F0 = 1; int F1 = 1; int temp; int

斐波那契查找算法完整C代码

/* 斐波那契查找法 */ #include <stdio.h> #include <stdlib.h> int Fib( int k ) { if( 1 == k || 2 == k ) return 1; else return Fib(k-1)+Fib(k-2); } int FibSearch( int *a, int n, int key ) { int k = 1; int nFib; int *b; int low, mid, high; while( Fib(k)

斐波那契查找(超详解)

// 斐波那契查找.cpp #include <iostream> #include <string.h> using namespace std; const int max_size=20;//斐波那契数组的长度 /*构造一个斐波那契数组*/ void Fibonacci(int * F) { F[0]=0; F[1]=1; for(int i=2;i<max_size;++i) F[i]=F[i-1]+F[i-2]; } /*定义斐波那契查找法*/ int Fibona