在討論費氏搜尋之前,要先了解一下費氏數列。
費氏數列 (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 "找不到數值")