- ✨本文收录于《Python数据结构与算法》专栏,此专栏主要记录如何python学习数据结构与算法笔记。
- 个人主页:JoJo的数据分析历险记
- 个人介绍:小编大四统计在读,目前保研到统计学top3高校继续攻读统计研究生
- 如果文章对你有帮助,欢迎✌
关注
、点赞
、✌收藏
、订阅
专栏
查找
是在一个项目集合中找到一个特定项目的算法过程,判断该项目是否存在,并返回其索引。 查找的几种常见方法:顺序查找、二分法查找、二叉树查找、哈希查找。本章主要介绍一下顺序查找
和二分查找
当数据没有排序时,使用顺序查找,它的主要思想是从按顺序搜索列表,如果找到,则返回下标标,如果没有找到,返回
None
。接下来我们来看一个小的案例,假设有一个数据,如下所示,我们要找54是否在当中
可以看到,我们需要对这个数据列表进行遍历,判断是否等于我们要查找的值,首先,
17
不等于54
,向右移,直到搜索到54
为止。顺序查找的代码很简单,下面我们来看看具体的代码是如何实现的:
'''
顺序查找基本思路:按顺序搜索列表.如果找到,返回索引,如果没找到,返回None
'''
def linear_search(val,li):
"""
:param li:要搜索的数据列表
:param val: 要查找的值
:return: 返回索引
"""
for i in range(len(li)):#遍历列表
if li[i] == val:#查找是否等于查找值
return i
return None
li = [17,20,26,31,44,54,55,65,77,93]
print(linear_search(54,li))
5
可以看出,
54
找到了!返回的索引结果为5
。为了更容易的理解顺序排序的过程,我们来看下面这张动态图,我们要找到128
:
可以看出线性查找相当于一个遍历数据的过程,下面我们来分析一下它的时间复杂度。
如果查找的元素存在 |
- 最好的情况:
1
,可能第一个就查找到了- 最差的情况:
n
,可能最后一个才查到- 平均情况: n 2 \frac{n}{2} 2n
如果查找的元素不存在: |
- 最好的情况:
n
- 最坏的情况:
n
- 平均情况:
n
因为如果元素不存在的话,无论是哪种情况,我们都要遍历完整个数据列表。
接下来我们介绍一下二分查找。二分法每次查找后,查找范围折半。从有序列表的候选区开始,首先,定义以下三个点:
left:
最小的值的索引right
:最大值索引mid
: 中间值索引(left + right)/2
- 然后,比较目标值所在的位置。如果目标值在
left
和mid
之间:right = mid-1
- 如果目标值在
mid
和right
之间:left = mid+1
二分查找要求我们的列表首先是一个有序的。具体的实现过程如下所示,我们还是要找128:
接下来我们思考一下,具体代码如何写。可以看出,我们也需要一个循环处理,并且我们不知道循环次数,因此使用while循环,那么结束条件如何确定呢。不难分析得到,如果left>right,那么肯定没有找到。因此,当left
时,我们就进行循环。下面我们来看一下具体的代码写法:
方法一:使用循环 |
def binary_search(val,li):
"""
:param li:要搜索的数据列表
:param val: 要查找的值
:return: 返回索引
"""
left = 0
right = len(li)-1
while left < right:
mid = (left+right)//2
if li[mid] == val:
return mid
elif li[mid] < val:#目标值大于中间值
left = mid + 1#取右半部分进行搜索
else:
right = mid-1#取左半部分进行搜索
return None
li = [17,20,26,31,44,54,55,65,77,93]
print(binary_search(54,li))
5
方法二:使用递归 |
- 结束条件为:left>right
- 调用关系为:如果目标值<中间值,右边界为mid+1,如果目标值>中间值,左边界为mid-1
具体代码如下:
def binary_search2(val,li):#主函数
def bi_search(left, right):#定义搜索范围
if left > right:#结束条件
return None
mid = (left + right)
if li[mid] == val:
return mid
elif li[mid] < val:
bi_search(mid+1,right)
elif li[mid] > val:
bi_search(left, mid-1)
接下来我们来思考一下它的时间复杂度。
每次搜索范围都减半,因此根据之前第一章介绍的,不难分析得到其时间复杂度为 O ( l o g N ) O(logN) O(logN)。
根据主项定理:
T ( n ) = T ( n ) / 2 + 1 T(n) = T(n)/2+1 T(n)=T(n)/2+1
a = 1 , b = 2 , n l o g 2 1 = 1 a=1,b=2,n^{log_21}=1 a=1,b=2,nlog21=1,因此,时间复杂度为 O ( l o g N ) O(logN) O(logN).
本文介绍了查找最基本的两个方法,线性查找和二分查找。其中线性查找的时间复杂度为 O ( n ) O(n) O(n),二分查找的时间复杂度为 O ( l o g N ) O(logN) O(logN),后续还会介绍哈希查找等方法。
本章的介绍到此介绍,如果文章对你有帮助,请多多点赞、收藏、评论、关注支持!!