参考:《数据结构(Python 语言描述)》 - 3.3 搜索算法

学习思路按照以下三个层次推进:学习算法设计思路 >> 实现算法 >> 复杂度分析

Tips:为了保持简洁,每个函数都只处理一个整数列表,并且假设列表不为空。

1. 搜索最小值

Search for the Minimum

下面这个函数会返回列表中最小项的索引,该算法的复杂度是 O(n) 。

def index_of_min(lyst):

"""返回最小项的索引"""

min_index = 0

current_index = 1

while current_index < len(lyst):

if lyst[current_index] < lyst[min_index]:

min_index = current_index

current_index += 1

return min_index

2. 顺序搜索

顺序搜索(Sequential Search),也称线性搜索(linear search)。

如果需要在对象上使用 in 进行成员测试,则需要为该对象实现 __contains__() 方法。如果对象中包含指定项,返回 True;否则返回 False 。下面这个顺序搜索函数,实现了与列表中 __contains__() 方法类的功能。

def sequential_search(target, lyst):

"""如果找到目标项,返回其索引;否则返回-1"""

position = 0

while position < len(lyst):

if target == lyst[position]:

return position

position += 1

return -1

2.1 最好情况、最坏情况、平均情况

Best-Case, Worst-Case, and Average-Case Performance Revisited

有些算法的性能与数据的排列方式有关,比如顺序搜索算法。此时,我们可以分三种情况考虑考虑该算法的性能:

最坏情况:对于"顺序搜索"而言,在最坏情况下,目标项位于列表末尾,或根本不在列表之中。此时必须访问列表中的每一项,对大小为 n 的列表要执行 n 次迭代。因此,顺序搜索在最坏的情况下复杂度为 O(n) 。

最好情况:"顺序搜索"只进行一次迭代就在第一个位置找到了目标项,复杂度为 O(1) 。

平均情况:需要把从"最好情况"到"最坏情况"间可能出现的所有情况的迭代次数相加,并除以 n。因此,算法平均执行了 (1+2+3+...+n-1+n)/n 次迭代,化简后等于 (n+1)/2 。对于很大的 n 而言,常数因子 2 的作用并不大。因此,平均情况的复杂度仍然为 O(n) 。

3. 二叉搜索

Binary Search

二叉搜索也称二分查找,该算法针对有序列表,其时间复杂度是 O(\log_{2}n) 。

假设我们需要利用二叉搜索查找某个按照升序排列的列表。首先,二叉算法会找出位于列表中间位置的中间项,并将该项与目标项进行比较:如果两者一致,便返回中间项的索引;如果目标项小于中间项,则继续搜索列表的前半部分;反之,则搜索后半部分。当找到目标,或当索引的起点值大于终点值时停止搜索。

注意,使用二叉搜索时有一个额外的整体性代价,就是必须保持列表的有序性。

下面分别使用"循环方式"和"递归方式"来实现二叉搜索。

3.1 循环方式

# -*- coding: utf-8 -*-

def binary_search_loop(sorted_list: list, target: int):

"""

二分查找,循环方式

:param sorted_list: 按升序排列的列表

:param target: 被查找的目标项

:return: 如果sorted_list中包含target,返回target的索引值,否则返回None

"""

low = 0

high = len(sorted_list) - 1

while low <= high:

mid_point = (low + high) // 2

if sorted_list[mid_point] == target:

return mid_point

elif sorted_list[mid_point] > target:

high = mid_point - 1

else:

low = mid_point + 1

return None

if __name__ == '__main__':

my_list = [1, 2, 3, 4]

assert binary_search_loop(my_list, 1) == 1

assert binary_search_loop(my_list, 2) == 1

assert binary_search_loop(my_list, 3) == 2

assert binary_search_loop(my_list, 4) == 3

assert binary_search_loop(my_list, 10) is None

3.2 递归方式

基线条件:数组只包含一个元素,如果目标值与该元素相同,便在最终的基线条件下找到了目标值,否则目标值不在数组中。

递归条件:每次把数组分成两半,并丢弃其中的一半,对剩下的一半再次执行二分查找。

# -*- coding: utf-8 -*-

def binary_search_recursive(sorted_list: list, target: int):

"""

二分查找,递归方式

:param sorted_list: 按升序排列的列表

:param target: 被查找的目标项

:return: 如果sorted_list中包含target,返回target的索引值,否则返回None

"""

mid = (len(sorted_list) - 1) // 2

if len(sorted_list) == 1: # 基线条件

if target == sorted_list[0]:

return 0

else:

return None

elif target == sorted_list[mid]: # 基线条件

return mid

# 下面的代码,通过递归逐步缩减问题规模

if target > sorted_list[mid]:

index = binary_search_recursive(sorted_list[mid + 1:], target)

if index is None:

return None

# 减半后的新列表sorted_list[mid + 1:]会重新以索引0开头,

# 这里需要保证返回的索引值包含当前sorted_list列表的索引信息,

# 因此需要重新调整index中的索引值。

# 要将index中的索引值调整到sorted_list列表中的对应位置,

# 需要为index加上(mid + 1)

return index + (mid + 1)

else:

index = binary_search_recursive(sorted_list[:mid], target)

return index

if __name__ == '__main__':

assert binary_search_recursive(my_list, 1) == 0

assert binary_search_recursive(my_list, 2) == 1

assert binary_search_recursive(my_list, 3) == 2

assert binary_search_recursive(my_list, 4) == 3

assert binary_search_recursive(my_list, 10) is None

3.3 最坏情况

当目标项不在列表中的时候,便会出现最坏情况。在最坏情况下,对于大小为 n 的列表,会持续将列表长度除以 2,直至商为 1 时停止(如, n//2//...//2 = 1 )——其中除法执行的次数便是循环执行的总次数。假设除法执行的次数为 k ,那么便有 n/2^k=1 ,可得 k=log_2n 。因此,二叉搜索最坏情况的复杂度为 O(log_2n) 。

下图展示了在仅含 1~9 的整数列表中,用二叉搜索查找整数 10 的过程。灰色项表示中间项,用于和目标项进行比较,也就是会被访问的项。另外,位于初始列表前半部分的项,实际上并不会被访问。

二叉搜索.png

python搜索算法_搜索算法(Python)相关推荐

  1. 第一章 第一节:Python基础_认识Python

    Python基础入门(全套保姆级教程) 第一章 第一节:Python基础_认识Python 1. 什么是编程 通俗易懂,编程就是用代码编写程序,编写程序有很多种办法,像c语言,javaPython语言 ...

  2. java python算法_用Python,Java和C ++示例解释的排序算法

    java python算法 什么是排序算法? (What is a Sorting Algorithm?) Sorting algorithms are a set of instructions t ...

  3. excel python插件_利用 Python 插件 xlwings 读写 Excel

    Python 通过 xlwings 读取 Excel 数据 去年底公司让我做设备管理,多次委婉拒绝,最终还是做了.其实我比较喜欢技术.做管理后发现现场没有停机率统计,而原始数据有,每次要自己在Exce ...

  4. 网络安全用python吗_使用Python进行网络安全渗透——密码攻击测试器

    相关文章: 本篇将会涉及: HTTP 基本认证 对HTTP Basic认证进行密码暴力攻击测试 什么是HTTP 基本认证 HTTP基本认证(HTTP Basic Authentication)是HTT ...

  5. 动态照片墙 python 实现_利用python生成照片墙的示例代码

    这篇文章主要介绍了利用python生成照片墙的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 PIL(Python Im ...

  6. python字符串_(Python基础教程之七)Python字符串操作

    Python基础教程 在SublimeEditor中配置Python环境 Python代码中添加注释 Python中的变量的使用 Python中的数据类型 Python中的关键字 Python字符串操 ...

  7. python 字符识别_使用python进行光学字符识别入门

    python 字符识别 语言模型设计 (Language Model Designing) Optical Character Recognition is the conversion of 2-D ...

  8. 类的继承python事例_【Python五篇慢慢弹(5)】类的继承案例解析,python相关知识延伸...

    作者:白宁超 2016年10月10日22:36:57 摘要:继一文之后,笔者又将python官方文档认真学习下.官方给出的pythondoc入门资料包含了基本要点.本文是对文档常用核心要点进行梳理,简 ...

  9. 【100天精通python】Day1:python入门_初识python,搭建python环境,运行第一个python小程序

    目录 专栏导读 1 初始python python 概述 python的应用领域 应用python的公司 2 搭建python 开发环境 2.1 安装python(以windows 系统为例)(1)下 ...

  10. python计算机_基础python计算机知识

    1.计算机基础知识 计算机基础 :组成---输入输出设备 储存器 CPU 内存 cpu 中央处理器 :处理各种数据的 内存 存储数据 硬盘 存储数据的 什么是操作系统:控制计算机的工作流程 软件 什么 ...

最新文章

  1. IO中的阻塞、非阻塞、同步、异步概念分析详解
  2. 3月3日发布!realme V25正式官宣:超大内存的国潮手机
  3. C#中图片单击旋转事件
  4. java wsdl接口地址_java如何实现webservice中wsdlLocation访问地址的可配置化
  5. 解决nginx端口占用问题
  6. (转)策略回测的框架、实现、测试
  7. js 让鼠标右下角有一排小字_JavaScript+css代码实现漂亮的右下角弹窗提示
  8. NLP之人机对话系统
  9. mac的python怎么打中文空格_中英文排版空格问题解决方案
  10. File Storage:文件存储
  11. echart vue
  12. 打印机服务器属性添加哪个文件,如何设置打印机服务器属性如何找到打印机服务器属性...
  13. 【涂鸦物联网足迹】涂鸦云平台接口列表—万能红外遥控器
  14. phpstudy不能启动mysql_phpStudy启动后为什么MYSQL无法启动
  15. android ios 重力感应器,iOS实时获取当前的屏幕方向之重力感应
  16. android程序出现了奇怪的错误 Field requires API level 5 (current min is 1): ......
  17. 设顺序表va中的数据元素递增有序。先实现将x插入到顺序表的适当位置上,保存该表的有序性。
  18. python生日祝福短信_python-定时发送生日邮件祝福
  19. 芯片IC附近为什么放0.1uF的电容?难道1uF不行吗?
  20. F5浏览器请求html资源超时,F5刷新网页时,出现了“如要再次显示该网页,web浏览器需要重新发送你以前提交的信息...要点击重试,如何不让出现这个对话框的解决方案...

热门文章

  1. 【180929】仙剑卡牌游戏源码
  2. 【Linux】Mysql忘记密码怎么办?
  3. 学习随记四十五——希尔排序
  4. python--Tkinter学习笔记之Button
  5. 如何在vue中实现文件预览功能
  6. python 1到10000的累加和_Python练习题 020:累积累加
  7. 出色的 SQL 编码师成长进阶路线
  8. 个人养老金账户来了|关于养老三支柱
  9. Centos:Xshell 修改Nginx配置文件
  10. [iOS开发]——熟悉Objective-C