【Python数据结构与算法】(四):二分查找和顺序查找(含代码实现)

【Python数据结构与算法】(四):二分查找和顺序查找

  • ✨本文收录于《Python数据结构与算法》专栏,此专栏主要记录如何python学习数据结构与算法笔记。
  • 个人主页:JoJo的数据分析历险记
  • 个人介绍:小编大四统计在读,目前保研到统计学top3高校继续攻读统计研究生
  • 如果文章对你有帮助,欢迎✌关注点赞、✌收藏订阅专栏

文章目录

  • 【Python数据结构与算法】(四):二分查找和顺序查找
  • 写在前面
  • 1.顺序查找
    • 1.1 基本理论
    • 1.2 代码
    • 1.3 时间复杂度
  • 2.二分查找
    • 2.1 基础理论
    • 2.2 代码
    • 2.3 时间复杂度
  • 3.总结

写在前面

查找是在一个项目集合中找到一个特定项目的算法过程,判断该项目是否存在,并返回其索引。 查找的几种常见方法:顺序查找、二分法查找、二叉树查找、哈希查找。本章主要介绍一下顺序查找二分查找

1.顺序查找

1.1 基本理论

当数据没有排序时,使用顺序查找,它的主要思想是从按顺序搜索列表,如果找到,则返回下标标,如果没有找到,返回None。接下来我们来看一个小的案例,假设有一个数据,如下所示,我们要找54是否在当中

image-20220602172252849

可以看到,我们需要对这个数据列表进行遍历,判断是否等于我们要查找的值,首先,17不等于54,向右移,直到搜索到54为止。顺序查找的代码很简单,下面我们来看看具体的代码是如何实现的:

1.2 代码

'''
顺序查找基本思路:按顺序搜索列表.如果找到,返回索引,如果没找到,返回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

【Python数据结构与算法】(四):二分查找和顺序查找(含代码实现)_第1张图片

1.3 时间复杂度

可以看出线性查找相当于一个遍历数据的过程,下面我们来分析一下它的时间复杂度。

如果查找的元素存在
  • 最好的情况:1,可能第一个就查找到了
  • 最差的情况:n,可能最后一个才查到
  • 平均情况: n 2 \frac{n}{2} 2n
如果查找的元素不存在:
  • 最好的情况:n
  • 最坏的情况:n
  • 平均情况:n

因为如果元素不存在的话,无论是哪种情况,我们都要遍历完整个数据列表。

具体时间复杂度如下表所示:
image-20220602172306640

2.二分查找

2.1 基础理论

接下来我们介绍一下二分查找。二分法每次查找后,查找范围折半。从有序列表的候选区开始,首先,定义以下三个点:

  • left:最小的值的索引
  • right:最大值索引
  • mid: 中间值索引(left + right)/2
  • 然后,比较目标值所在的位置。如果目标值在leftmid之间:
  • right = mid-1
  • 如果目标值在midright之间:
  • left = mid+1

二分查找要求我们的列表首先是一个有序的。具体的实现过程如下所示,我们还是要找128:

接下来我们思考一下,具体代码如何写。可以看出,我们也需要一个循环处理,并且我们不知道循环次数,因此使用while循环,那么结束条件如何确定呢。不难分析得到,如果left>right,那么肯定没有找到。因此,当left时,我们就进行循环。下面我们来看一下具体的代码写法:

2.2 代码

方法一:使用循环
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)

2.3 时间复杂度

接下来我们来思考一下它的时间复杂度。
每次搜索范围都减半,因此根据之前第一章介绍的,不难分析得到其时间复杂度为 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).

3.总结

本文介绍了查找最基本的两个方法,线性查找和二分查找。其中线性查找的时间复杂度为 O ( n ) O(n) O(n),二分查找的时间复杂度为 O ( l o g N ) O(logN) O(logN),后续还会介绍哈希查找等方法。

在这里插入图片描述

本章的介绍到此介绍,如果文章对你有帮助,请多多点赞、收藏、评论、关注支持!!

你可能感兴趣的:(Python数据结构与算法,算法,二分查找,python,数据结构,顺序查找)