数据结构与算法Python版 顺序查找与二分查找


一、顺序查找

顺序查找 Sequential Search

  • 通过下标,我们就可以按照顺序来访问和查找数据项,这种技术称为“顺序查找
  • 如果数据项保存在如列表这样的集合中,我们会称这些数据项具有线性或者顺序关系
  • 在Python列表中,这些数据项的存储位置称为下标(index),这些下标都是有序的整数。首先从列表的第1个数据项开始,按照下标增长的顺序,逐个比对数据项,如果到最后一个都未发现要查找的项,那么查找失败。
    在这里插入图片描述

顺序查找-算法分析

  • 要对查找算法进行分析,首先要确定其中的基本计算步骤。在查找算法中,这种基本计算步骤就是进
    行数据项的比对。当前数据项等于还是不等于要查找的数据项,比对的次数决定了算法复杂度
  • 列表中的数据项是无序的,数据项在列表中各个位置出现的概率相同,顺序查找的算法复杂度是O(n)
Case最好Case最差Case平均Case
item存在1nn/2
item不存在nnn
  • 列表中的数据项是有序的,item不存在时有所不同,但顺序查找的算法复杂度也是O(n)。当数据项存在时,比对过程与无序表完全相同;如果数据项不存在,比对可以提前结束。
Case最好Case最差Case平均Case
item存在1nn/2
item不存在1nn/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
比较次数剩余项目的大致数量
1n/2
2n/4
3n/8
in/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版》专栏!关注不迷路~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值