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

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

# 先创建一个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. Android ScrollView嵌套GridView导致GridView只显示一行item

    Android ScrollView嵌套GridView导致GridView只显示一行item Android ScrollView在嵌套GridView时候,会导致一个问题发生:GridView只显 ...

  2. 【java基础 11】java集合框架学习

    导读:本篇博客主要是从整体上了解java的集合框架,然后主要介绍几个自己在项目中用到的结构,比如说:hashtable.hashmap.hashset.arraylist等! 一.宏观预览 从宏观上看 ...

  3. LINQ-内部联接

    一.简单键联接 下面的示例创建两个集合,其中包含两种用户定义类型 Person 和 Pet 的对象. 查询使用 C# 中的 join 子句将 Person 对象与 Owner 是该 Person 的  ...

  4. 九度oj 题目1450:产生冠军

    题目描述: 有一群人,打乒乓球比赛,两两捉对撕杀,每两个人之间最多打一场比赛. 球赛的规则如下: 如果A打败了B,B又打败了C,而A与C之间没有进行过比赛,那么就认定,A一定能打败C. 如果A打败了B ...

  5. mysql5.7.23版本安装教程

    亲身实践安装mysql,用时居然花费了三个小时,在有那么多教程的情况下,依然在不该花费时间的路上浪费了太多时间.希望这篇文章能够帮助大家少走弯路~~ 1.下载我下载的是64位. 2.解压下载之后,我选 ...

  6. BZOJ 1855 [Scoi2010]股票交易 ——动态规划

    DP方程是比较简单的,主要有三种:什么都不做.买入.卖出. 发现买入卖出都是$\Theta (n^3)$但是转移方程都是线性的,而且决策和当前的情况是分开的. 所以可以单调队列优化. 复杂度$\The ...

  7. annotation之@Autowired、@Inject、@Resource三者区别

    一.@Autowired 1.@Autowired是spring自带的注解,通过‘AutowiredAnnotationBeanPostProcessor’ 类实现的依赖注入: 2.@Autowire ...

  8. 转载:shell中awk printf的用法

    转载:http://www.linuxawk.com/jiaocheng/83.html 6. printf函数   打印输出时,可能需要指定字段间的空格数,从而把列排整齐.在print函数中使用制表 ...

  9. python和python-dev

    问:python-dev是什么?为什么安装了python后有时还要安装python-dev? 答: linux发行版通常会把类库的头文件和相关的pkg-config分拆成一个单独的xxx-dev(el ...

  10. Codeforces 961 E Tufurama

    Discription One day Polycarp decided to rewatch his absolute favourite episode of well-known TV seri ...