# 二分查找的改进,运用斐波那契数列设置分隔数
# 基本原理:
# 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')