斐波那契查找
黄金比例又称黄金分割,是指事物各部分间一定的数学比例关系,即将整体一分为二,较大部分与较小部分之比等于整体与较大部分之比,其比值约为1:0.618或1.618:1。
斐波那契查找也是二分查找的一种提升算法,通过运用黄金比例的概念在数列中选择查找点进行查找,提高查找效率。同样地,斐波那契查找也属于一种有序查找算法。其核心也是如何优化那个缩减速率,使得查找次数尽量降低。
原理:
斐波那契查找与折半查找很相似,是根据斐波那契序列的特点对有序表进行分割的。要求开始表中记录的个数为某个斐波那契数小1,及n = F(k)-1
斐波那契查找的核心是:
- 当key=a[mid]时,查找成功;
- 当key<a[mid]时,新的查找范围是第low个到第mid-1个,此时范围个数为F[k-1] - 1个,即数组左边的长度,所以要在[low, F[k - 1] - 1]范围内查找;
- 当key>a[mid]时,新的查找范围是第mid+1个到第high个,此时范围个数为F[k-2] - 1个,即数组右边的长度,所以要在[F[k - 2] - 1]范围内查找。
代码实现:
def fibonacciSearch(data, length, key):
F = [0, 1]
count = 1
low = 0
high = length - 1
if (key < data[low] or key > data[high]): # 索引超出范围返回错误
print("Error!!! The ", key, " is not in the data!!!")
return -1
while F[count] < length: # 生成斐波那契数列
F.append(F[count - 1] + F[count])
count = count + 1
low = F[0]
high = F[count]
while length - 1 < F[count - 1]: # 将数据个数补全
data.append(data[length - 1])
length = length + 1
while (low <= high):
mid = low + F[count - 1] # 计算当前分割下标
if (data[mid] > key): # 若查找记录小于当前分割记录
high = mid - 1 # 调整分割记录
count = count - 1
elif (data[mid] < key): # 若查找记录大于当前分割记录
low = mid + 1
count = count - 2
else: # 若查找记录等于当前分割记录
return mid
时间复杂度:
斐波那契查找的整体时间复杂度也为O(log(n))。但就平均性能,要优于二分查找。但是在最坏情况下,比如这里如果key为1,则始终处于左侧半区查找,此时其效率要低于二分查找。