zoukankan      html  css  js  c++  java
  • 二分查找算法(加法方式:斐波那契查找)

    二分查找算法比较熟悉的是折半查找,但是折半查找中计算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)

  • 相关阅读:
    C#编程总结(三)线程同步 多线程
    配置 Spring.NET
    C# Redis
    WPF MvvmLight RelayCommand 绑定Command 的使用
    WCF编程系列(一)初识WCF
    C#/WPF程序开机自动启动
    C# 创建Windows Service(Windows服务)程序
    前端Js框架汇总
    列式存储和行式存储
    llvm-3.4.2 编译失败 解决方案
  • 原文地址:https://www.cnblogs.com/hoojjack/p/10952202.html
Copyright © 2011-2022 走看看