在討論費氏搜尋之前,要先了解一下費氏數列。
費氏數列 (Fibonacci numbers),又稱費波那契數列,是指在一串數字中,每一項是前兩項的和。數學上的定義為:
公式為:f(n) = f(n-1) + f(n-2), n >= 2
直接列出前十項,觀察一下就能了解了。
| f[0] | f[1] | f[2] | f[3] | f[4] | f[5] | f[6] | f[7] | f[8] | f[9] | f[10] | 
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 | 
| 用程式碼來寫一下,怎麼算出費氏數列。 | ||||||||||
| 時間複雜度為 O(2^n) | 
def fibonacci(n):
    if n == 0:
        return 0;
    elif n == 1:
        return 1;
    return fibonacci(n-1) + fibonacci(n-2)
    
print(fibonacci(7))
在大致了解費氏數列後,那費氏搜尋法又是如何運作呢?
假設我們要在已經排序好的數列中找到數字:
費氏數列 fib = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]
查找資料 data = [10, 22, 30, 44, 56, 58, 60, 70, 100, 110, 130]
搜尋值 key = 60
(真的要用不同的資料多試幾次,才會慢慢了解查找的概念...真的蠻繞的,但只要了解,會發現速度很快)
import sys
# 產生費氏數列
def fibo(max):
    fib = [sys.maxsize] * max
    fib[0] = 0
    fib[1] = 1
    for i in range(2, max):
        fib[i] = fib[i - 1] + fib[i - 2]
    return fib
def getY(fib, n):
    i = 0
    while fib[i] <= n:
        i += 1
    return i - 1
def search(data, key):
    fib = fibo(len(data))
    max = len(data) - 1  # data的最大索引值
    y = getY(fib, max + 1) # 在費氏數列裡的值,如果比data的最大索引值還大,回傳費氏數列索引值的前一個
    m = max - fib[y] 
    x = y - 1  #找到在data搜尋的起始索引值
    print("\nx=%d, m=%d, fib[x]=%d" % (x, m, fib[x]))
    i = x
    if data[i] < key:
        i += m
    while fib[x] > 0:
        if data[i] < key:
            x -= 1
            i += fib[x]
        elif data[i] > key:
            x -= 1
            i -= fib[x]
        else:
            return i
    return -1
number = [10, 22, 30, 44, 56, 58, 60, 70, 100, 110, 130]
find = search(number, 60)
print("找到數值於索引 " + str(find) if find >= 0 else "找不到數值")