通过在网上找教程解释和看书,总结出一套比较简单易懂的代码实现。

斐波那契查找和二分查找一样,针对的是有序序列,在此前提下:

# 先创建一个Fibonacci函数
fib = lambda n: n if n < 2 else fib(n-1) + fib(n-2)

斐波那契查找,是通过利用斐波那契数列的值作为分割点,然后二分查找,相对于普通的二分查找,性能更优秀

def fib_search(arr, x):
    left = 0
    right = len(arr) - 1

    # 计算fib的值,这个值是大于等于arr的长度的,所以使用时要对key-1
    key = 0
    while fib(key) < len(arr):
        key += 1

    while left <= right:
        # 当x在分隔的后半部分时,fib计算的mid值可能大于arr长度
        # 因为mid是索引位置,这里要取arr长度-1
        mid = min(left + fib(key - 1), len(arr) - 1)
        if x < arr[mid]:
            right = mid - 1
            key -= 1
        elif x > arr[mid]:
            left = mid + 1
            key -= 2
        else:
            return mid
    return "Not Found"

若x的值刚好是arr[0],那么则会出现一种情况,即按照fibonacci数列的值依次对比,其中会出现如8,5,3,2,1,1,0这种索引,两个1就是重复了,所以大家看到的很多例子里,mid的计算是left + fib(key -1) - 1,这里最后的-1其实就是去掉索引重复值。

# 举个例子
arr = [0, 1, 16, 24, 35, 47, 59, 62, 73, 88, 99]
x = 0
# 不加-1的mid值依次是8,5,3,2,1,1,0
# 加了-1的mid值依次是7,4,2,1,0

有兴趣的可以测试下代码

fib = lambda n: n if n < 2 else fib(n-1) + fib(n-2)

def fib_search(arr, x):
    if len(arr) == 0:
        return 'arr is None'

    left = 0
    right = len(arr) - 1

    # 计算fib的值,这个值是大于等于arr的长度的,所以使用时要对key-1
    key = 0
    while fib(key) < len(arr):
        key += 1

    while left <= right:
        # 当x在分隔的后半部分时,fib计算的mid值可能大于arr长度
        # 因为mid是索引位置,这里要取arr长度-1
        mid = min(left + fib(key - 1) - 1, len(arr) - 1)
        if x < arr[mid]:
            right = mid - 1
            key -= 1
        elif x > arr[mid]:
            left = mid + 1
            key -= 2
        else:
            return mid
    return "Not Found"

def test_fib_search():
    arr = [0, 1, 16, 24, 35, 47, 59, 62, 73, 88, 99]
    x = 0    print(fib_search(arr, x))

if __name__ == '__main__':
    test_fib_search()

python实现斐波那契查找的更多相关文章

  1. python实现斐波那契数列(Fibonacci sequence)

    使用Python实现斐波那契数列(Fibonacci sequence) 斐波那契数列形如 1,1,2,3,5,8,13,等等.也就是说,下一个值是序列中前两个值之和.写一个函数,给定N,返回第N个斐 ...

  2. 【Java】 大话数据结构(10) 查找算法(1)(顺序、二分、插值、斐波那契查找)

    本文根据<大话数据结构>一书,实现了Java版的顺序查找.折半查找.插值查找.斐波那契查找. 注:为与书一致,记录均从下标为1开始. 顺序表查找 顺序查找  顺序查找(Sequential ...

  3. Python中斐波那契数列的四种写法

    在这些时候,我可以附和着笑,项目经理是决不责备的.而且项目经理见了孔乙己,也每每这样问他,引人发笑.孔乙己自己知道不能和他们谈天,便只好向新人说话.有一回对我说道,“你学过数据结构吗?”我略略点一点头 ...

  4. 斐波那契查找(Fibonacci Search)

    斐波那契查找 斐波那契查找就是在二分查找的基础上根据斐波那契数列进行分割的.   在斐波那契数列找一个等于略大于查找表中元素个数的数F[n],将原查找表扩展为长度为F[n](如果要补充元素,则补充重复 ...

  5. python基础----斐波那契数列

    python实现斐波那契数列的三种方法 """ 斐波那契数列 0,1,1,2,3,5,8,13,21,... """ # 方法一:while ...

  6. Python中斐波那契数列的赋值逻辑

    斐波那契数列 斐波那契数列又称费氏数列,是数学家Leonardoda Fibonacci发现的.指的是0.1.1.2.3.5.8.13.21.34.······这样的数列.即从0和1开始,第n项等于第 ...

  7. python实现斐波那契数列

    https://www.cnblogs.com/wolfshining/p/7662453.html 斐波那契数列即著名的兔子数列:1.1.2.3.5.8.13.21.34.…… 数列特点:该数列从第 ...

  8. python实现斐波那契数列笔记

    斐波那契数列即著名的兔子数列:1.1.2.3.5.8.13.21.34.…… 数列特点:该数列从第三项开始,每个数的值为其前两个数之和,用python实现起来很简单: a=0 b=1 while b ...

  9. [Python3.X]python 实现斐波那契数列

    斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一 ...

随机推荐

  1. pycharm下多个工程项目并存显示

    问题:使用pycharm新建一个工程时,出现如下提示: 无论选择哪一个,都会发现之前已经建立的工程没有并存显示 解决办法: 1. 找到file->settings: 2.点击project st ...

  2. Nmap手册

    转自:http://drops.xmd5.com/static/drops/tips-4333.html 0x00:说明 只是一个快速查询手册,理论的东西都没有补充,欢迎大家积极在评论区补充自己常用的 ...

  3. Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). For example: Given binary tree {3,9,20,#,#,15,7}, 3 / \ 9 20 / \

    class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { vector<vect ...

  4. C# 字符串型转数字型

    // 当需要将字符串格式的数字转为数字时候,我们会用到的函数为Convert.ToDouble(),// 然而当你的字符串为49,9时,由于包含了逗号,函数会将逗号忽略,直接转为499,// 所以我们 ...

  5. [BZOJ4994] [Usaco2017 Feb]Why Did the Cow Cross the Road III(树状数组)

    传送门 1.每个数的左右位置预处理出来,按照左端点排序,因为左端点是从小到大的,我们只需要知道每条线段包含了多少个前面线段的右端点即可,可以用树状数组 2.如果 ai < bj < bi, ...

  6. py 爬取页面http://m.sohu.com 并存储

             usage()               opts,args = getopt.getopt(sys.argv[1:],                        usage( ...

  7. cf550D Regular Bridge

    Regular Bridge An undirected graph is called k-regular, if the degrees of all its vertices are equal ...

  8. PHP中的验证码类(准备篇)

    <!--code.php内容--> <?php //开启session session_start(); include "vcode.class.php"; / ...

  9. Yii 之控制器创建使用

    在根目录下的controllers目录下创建控制器HelloController.php: <?php namespace app\controllers; use yii\web\Contro ...

  10. BZOJ——3296: [USACO2011 Open] Learning Languages

    http://www.lydsy.com/JudgeOnline/problem.php?id=3296 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit:  ...