一·顺序查找
# 最基础的遍历无序列表的查找算法
# 时间复杂度O(n)
def sequential_search(lis,key):
length=len(lis)
for i in range(length):
if lis[i]==key:
return i
return False
二·二分查找
# 针对有序查找表的二分查找算法
def binary_search(lis,key):
low=0
high=len(lis)-1
time=0
while low<high:
time+=1
mid=int((low+high)/2)
if key<lis[mid]:
high=mid-1
elif key>lis[mid]:
low=mid+1
else:
return mid
return False
三·插值查找
思想: 基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率。当然,差值查找也属于有序查找。改进就在于mid的计算上。
注:对于表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能比折半查找要好的多。反之,数组中如果分布非常不均匀,那么插值查找未必是很合适的选择。
def insert_search(lis,key):
low=0
high=len(lis)-1
while low<high:
mid=low+int((high-low)*(key-lis[low])/(lis[high]-lis[low]))
if key<lis[mid]:
high=mid-1
elif key>lis[mid]:
low=mid+1
else:
return mid
return False
四·斐波那契查找
斐波那契数列,又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、····,在数学上,斐波那契被递归方法如下定义:F(1)=1,F(2)=1,F(n)=f(n-1)+F(n-2) (n>=2)。该数列越往后相邻的两个数的比值越趋向于黄金比例值(0.618)。
思路: 它要求数据是有序的(升序或降序)。斐波那契查找采用和二分查找/插值查找相似的区间分割策略,都是通过不断的分割区间缩小搜索的范围。
- 构建斐波那契数列;
- 计算数组长度对应的斐波那契数列元素个数;
- 对数组进行填充;
- 循环进行区间分割,查找中间值;
- 判断中间值和目标值的关系,确定更新策略;
复杂度分析: 最坏情况下,时间复杂度为O(log2n),且其期望复杂度也为O(log2n)。
import copy
def fibonacci_search(lis,key,max_size):
#首先深度复制数据
D = copy.deepcopy(lis)
# 构建斐波那契数列
F = [0, 1] + [fibonacci_sequence(i) for i in range(2, max_size)]
#计算数据长度对应斐波那契数列元素
index=0
while F[index]<len(D):
index+=1
#对数据进行填充
for i in range(len(D),F[index]):
D.append(D[-1])
#不断分割区间
left=0
right=F[index]
while left<right and index>0:
mid=left+F[index-1]-1
if key==D[mid]:
# 判断搜索到的目标值是否为填充的值
if mid>len(lis):
return len(lis)-1
else:
return mid
elif key<D[mid]:
right=mid-1
index-=1
elif key>D[mid]:
left=mid+1
index-=2
return False
def fibonacci_sequence(num: int): # 按照待查找数列的大小,动态生成斐波那契数列
a, b = 0, 1
while a <= num - 1:
a, b = b, a + b
return a