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

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

# 先创建一个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. Python自动发送邮件(可带附件)

    Python内置对SMTP的支持,可以发送纯文本邮件.HTML邮件以及带附件的邮件. Python对SMTP支持有smtplib和email两个模块,email负责构造邮件,smtplib负责发送邮件 ...

  2. BNUOJ 1207 滑雪

    滑雪 Time Limit: 1000ms Memory Limit: 65536KB   This problem will be judged on PKU. Original ID: 10886 ...

  3. 【HTML/XML 1】HTML 速成总结

    导读:反反复复的看完了HTML的速成材料,前面学习了牛腩,所以这块知识只能是作为一种旧知识的复习.和机房重构时的SQLHelper一样,刚开始都是稀里糊涂的用了,后面系统的学习后,才知道为什么要那样用 ...

  4. BZOJ 1419 Red is good ——期望DP

    定义f[i][j]表示还剩i张红牌,j张黑牌的时候能取得的期望最大值 显然有$f[i][j]=max(0,\frac {i}{i+j}(f[i-1][j]+1)+ \frac {j}{i+j}(f[i ...

  5. 算法复习——莫队算法(bzoj1878)

    题目: Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一 段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此他的 ...

  6. BZOJ [P2124] 等差子序列

    线段树维护哈希值 要求出现长度大于三的等差子序列,我们只要找到长度等于三的就可以了 初看本题没有思路,只能暴力枚举,O(n^4) 后来发现,这个序列是n的一个排列,那么每个数字都只会出现一次 我们可以 ...

  7. NOJ 1111 保险箱的密码 【大红】 [区间dp]

    传送门 保险箱的密码 [大红] 时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65536 KByte总提交 : 118            测 ...

  8. python--爬取http://www.kuaidaili.com/并保存为xls

    代码如下: 复制在python3上先试试吧^_^ # -*- coding: utf-8 -*- """ Created on Mon Jun 12 13:27:59 2 ...

  9. kail Linux 安装Parallels Tools

    网上好多都是Parallels8的 针对Parallels 9 的还真不好找..... 自己捣鼓了一阵 终于可以安装了,但还是有错误,因为公司网络太不给力....回家再测试吧 1.在桌面新建一个文件夹 ...

  10. C# 读写bat文件

    读: var batFile = "D:\\test.bat"; if (File.Exists(batFile)) { using (var sr = new StreamRea ...