文章目录
一、顺序查找
顺序查找 Sequential Search
- 通过下标,我们就可以按照顺序来访问和查找数据项,这种技术称为“顺序查找”
- 如果数据项保存在如列表这样的集合中,我们会称这些数据项具有线性或者顺序关系
- 在Python列表中,这些数据项的存储位置称为下标(index),这些下标都是有序的整数。首先从列表的第1个数据项开始,按照下标增长的顺序,逐个比对数据项,如果到最后一个都未发现要查找的项,那么查找失败。
顺序查找-算法分析
- 要对查找算法进行分析,首先要确定其中的基本计算步骤。在查找算法中,这种基本计算步骤就是进
行数据项的比对。当前数据项等于还是不等于要查找的数据项,比对的次数决定了算法复杂度 - 列表中的数据项是无序的,数据项在列表中各个位置出现的概率相同,顺序查找的算法复杂度是O(n)
Case | 最好Case | 最差Case | 平均Case |
---|---|---|---|
item存在 | 1 | n | n/2 |
item不存在 | n | n | n |
- 列表中的数据项是有序的,item不存在时有所不同,但顺序查找的算法复杂度也是O(n)。当数据项存在时,比对过程与无序表完全相同;如果数据项不存在,比对可以提前结束。
Case | 最好Case | 最差Case | 平均Case |
---|---|---|---|
item存在 | 1 | n | n/2 |
item不存在 | 1 | n | n/2 |
示例:查找数据项50,当看到54时,可知道后面不可能存在50,可以提前退出
def sequential_search(lst, item):
"""顺序查找无序数据项"""
for i in lst:
if i == item:
return True
# 找不到时返回False
return False
test_list = [50, 88, 76, 65, 74, 16]
print(sequential_search(test_list, 74))
print(sequential_search(test_list, 50))
print(sequential_search(test_list, 22))
### 输出结果
True
True
False
二、二分查找
二分查找Binary Search
- 对于有序表(约定:数据项由小到大排列),从列表中间开始比对!如果列表中间的项匹配查找项,则查找结束;如果不匹配,那么就有两种情况:
- 列表中间项比查找项大,那么查找项只可能出现在前半部分
- 列表中间项比查找项小,那么查找项只可能出现在后半部分
- 重复采用上面的方法查找,无论如何,我们都会将比对范围缩小到原来的一半:n/2
比较次数 | 剩余项目的大致数量 |
---|---|
1 | n/2 |
2 | n/4 |
3 | n/8 |
… | … |
i | n/2^i |
def binary_search(sequence_list, item):
begin = 0
end = len(sequence_list) - 1
while begin <= end:
middle = (begin + end) // 2
if sequence_list[middle] == item: # 查找成功
return True
elif item < sequence_list[middle]:
end = middle - 1 # 在左半部分查找
else:
begin = middle + 1 # 在右半部分查找
# 查找失败
return False
test_list = [2, 3, 4, 7, 9, 33, 88]
print(binary_search(test_list, 33))
print(binary_search(test_list, 2))
print(binary_search(test_list, 22))
### 输出结果
True
True
False
二分查找-递归形式
def binary_search_recursion(sequence_list, item):
if len(sequence_list) == 0:
return False
else:
middle = len(sequence_list) // 2
if sequence_list[middle] == item:
return True
elif item < sequence_list[middle]:
return binary_search_recursion(sequence_list[:middle], item)
else:
return binary_search_recursion(sequence_list[middle + 1 :], item)
test_list = [2, 3, 4, 7, 9, 33, 88]
print(binary_search_recursion(test_list, 33))
print(binary_search_recursion(test_list, 2))
print(binary_search_recursion(test_list, 22))
### 输出结果
True
True
False
二分查找- 算法分析
- 二分查找,每次比对都将下一步的比对范围缩小一半。当比对次数足够多以后,比对范围内就会仅剩余1个数据项,即
n/2^i=1
。所以二分法查找的算法复杂度是O(log n)。 - 一个系统在算法选择问题上,要综合考虑多种因素
- 二分查找在时间复杂度上优于顺序查找,但前提是数据项是有序的。如果一次排序后可以进行多次查找,那么排序的开销就可以摊薄;否则,排序所占成本高,导致总体算法开销大。
- 二分查找算法中,除了对比,还对列表进行切片操作带来额外开销。也可以不切片,传入起始和结束的索引值即可
- 二分查找体现了解决问题的策略:分而治之
您正在阅读的是《数据结构与算法Python版》专栏!关注不迷路~
标签:数据项,search,Python,list,item,算法,查找,数据结构 From: https://blog.csdn.net/zljgzw/article/details/144565194