1. 程式人生 > >python演算法9.19——斐波那契查詢

python演算法9.19——斐波那契查詢

# 二分查詢的改進,運用斐波那契數列設定分隔數
# 基本原理:
# 1.黃金分割比1:0.618,斐波那契數列:1,1,2,3,5,8,13……(兩數比接近0.618且和為後一個數)
# 2.查詢序列有序,且長度為某斐波那契數-1,即len = F[k] -1,(不足可複製最後一個元素)
# 3.分割點F[k-1],前F{k-1]-1、後F[k-2]-1,共F[k] -1
# 4.確定查詢點位置,在前半部分則k=k-1,在後半部分則k=k-2,3中關係仍然成立

import random
Range = 10
Length = 7
flag = 0
pos = -1

list = random.sample(range(Range),Length)
goal = random.randint(0,Range)
# list =  [0, 2, 3, 4, 5, 6, 8, 9, 10, 12, 13, 14]
# goal = 8

# 氣泡排序處理
for i in range(Length-1):
    for j in range(Length-i-1):
        if list[j] > list[j + 1]:
            list[j + 1], list[j] = list[j], list[j + 1]
print('search ',goal,', in list:',list)

# 建立斐波那契數列
F = [0,1]
while True:
    F.append(F[len(F)-1] + F[len(F)-2])
    if F[len(F)-1]>Length:
        break

k = len(F)-1
min = F[1] - 1                          # 0
max = F[k] - 2                          # 陣列長度-1
mid = F[k-1] - 1                        # mid位置

if goal>list[max] or goal<list[min]:   # 預篩選
    pass
else:
    while min<max:
        if goal == list[mid]:
            pos = mid
            flag = 1
            break
        elif goal<list[mid]:            # 前半部分則k=k-1
            max = mid
            k -= 1
        elif goal>list[mid]:            # 後半部分則k=k-2
            min = mid
            k -= 2
        mid = min + F[k-1] - 1           # 更新mid
        if k < 2:                       # 防止下標異常,k為3時,list[min]與list[max]至多相差一個下標
            if goal == list[min]:
                pos = min
                flag = 1
            elif goal == list[max]:
                pos = max
                flag = 1
            elif goal == list[min+1]:
                pos = min+1
                flag = 1
            break

if flag:
    print('find in ',pos+1,'th place')
else:
    print('not found')