数据结构与算法python—11.查找及python实现与leetcode总结

本文详细介绍了查找的基础知识,包括顺序查找、二分查找、插值查找、斐波那契查找和线性索引查找。重点讨论了二分查找的原理和在LeetCode中的应用,如面试题中的相关问题,强调了不同查找算法的时间复杂度和适用场景。
摘要由CSDN通过智能技术生成

一、查找(搜索)基础

  我们常用的搜索引擎的原理如下:
在这里插入图片描述
下面介绍一些概念:

  1. 查找(Searching)
    就是根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录)。
  2. 查找表(Search Table)
    由同一类型的数据元素((或记录)构成的集合
  3. 关键字(Key)
    数据元素中某个数据项的值,又称为键值。
  4. 主键(Primary Key)
    可唯一地标识某个数据元素或记录的关键字。

查找表按照操作方式可分为:

  1. 静态查找表(Static Search Table):只做查找操作的查找表。
    它的主要操作是:查询某个“特定的”数据元素是否在表中、检索某个“特定的”数据元素和各种属性
  2. 动态查找表(Dynamic Search Table):在查找中同时进行插入或删除等操作
    查找时插入数据、查找时删除数据

1.顺序查找

  顺序查找也称为线性查找,属于无序查找算法,顺序查找适合于存储结构为顺序存储或链接存储的线性表。其基本思想是:从数据结构线形表的一端开始,顺序扫描,依次将扫描到的结点关键字与给定值k相比较,若相等则表示查找成功;若扫描结束仍没有找到关键字等于k的结点,表示查找失败。

时间复杂度分析:查找成功时的平均查找长度为 n + 1 2 \frac{n+1}2 2n+1
查找失败时,查找长度为 n n n
所以顺序查找的时间复杂度为 O ( n ) O(n) O(n)

# 最基础的遍历无序列表的查找算法,时间复杂度为O(n)
def sequential_search(lis, key):
    length = len(lis)
    for i in range(length):
        if lis[i] == key:
            return i
    else:
        return False


if __name__ == '__main__':
    nums = [1, 2, 3, 4, 5, 6, 7, 8]
    target = 6
    result = sequential_search(nums, target)
    print(result)
def sequential_search(lis, key):
    i = 0
    # 往列表末尾防止哨兵,省去了遍历时判断查找是否越界的过程,数据量大时,效果显著
    lis.append(key)
    while lis[i] != key:
        i += 1
    # 如果i等于列表长度(最后一个元素索引+1),说明查找失败,否则查找成功
    return i


if __name__ == '__main__':
    nums = [1, 2, 3, 4, 5, 6, 7, 8]
    target = 6
    result = sequential_search(nums, target)
    print(result)

2.二分查找

  二分查找也称折半查找(Binary Search),是一种在有序数组中查找某一特定元素的搜索算法。我们可以从定义可知,运用二分搜索的前提是数组必须是有序的,这里需要注意的是,我们的输入不一定是数组,也可以是数组中某一区间的起始位置和终止位置。

二分查找要注重代码细节,容易出错

二分查找的执行过程如下:

  1. 从已经排好序的数组或区间中,取出中间位置的元素,将其与我们的目标值进行比较,判断是否相等,如果相等则返回。
  2. 如果nums[mid]target不相等,则对nums[mid]target值进行比较大小,通过比较结果决定是从mid的左半部分还是右半部分继续搜索。
    如果target > nums[mid]右半区间继续进行搜索,即left = mid + 1;
    target < nums[mid]则在左半区间继续进行搜索,即right = mid -1

二分查找过程举例:target = 8
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

# 针对有序查找表的二分查找算法
# 时间复杂度为O(log(n))
def binary_serach(lis, key):
    low = 0
    high = len(lis) - 1
    # 这里如果low<high,mid会移到12后,low = high = 8,此时跳出循环,返回False
    while low <= high:
        mid = int(low + (high - low) / 2)
        if lis[mid] == key:
            return mid
        elif lis[mid] > key:
            high = mid - 1
        elif lis[mid] < key:
            low = mid + 1
    # 循环结束时,low > high,上面的mid-1,smid+1是为了避免出现死循环
    
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值