Python实现的数据结构与算法之基本搜索详解


Posted in Python onApril 22, 2015

本文实例讲述了Python实现的数据结构与算法之基本搜索。分享给大家供大家参考。具体分析如下:

一、顺序搜索

顺序搜索 是最简单直观的搜索方法:从列表开头到末尾,逐个比较待搜索项与列表中的项,直到找到目标项(搜索成功)或者 超出搜索范围 (搜索失败)。

根据列表中的项是否按顺序排列,可以将列表分为 无序列表有序列表。对于 无序列表,超出搜索范围 是指越过列表的末尾;对于 有序列表,超过搜索范围 是指进入列表中大于目标项的区域(发生在目标项小于列表末尾项时)或者指越过列表的末尾(发生在目标项大于列表末尾项时)。

1、无序列表

在无序列表中进行顺序搜索的情况如图所示:

Python实现的数据结构与算法之基本搜索详解

def sequentialSearch(items, target):
  for item in items:
    if item == target:
      return True
  return False

2、有序列表

在有序列表中进行顺序搜索的情况如图所示:

Python实现的数据结构与算法之基本搜索详解

def orderedSequentialSearch(items, target):
  for item in items:
    if item == target:
      return True
    elif item > target:
      break
  return False

二、二分搜索

实际上,上述orderedSequentialSearch算法并没有很好地利用有序列表的特点。

二分搜索 充分利用了有序列表的优势,该算法的思路非常巧妙:在原列表中,将目标项(target)与列表中间项(middle)进行对比,如果target等于middle,则搜索成功;如果target小于middle,则在middle的左半列表中继续搜索;如果target大于middle,则在middle的右半列表中继续搜索。

在有序列表中进行二分搜索的情况如图所示:

Python实现的数据结构与算法之基本搜索详解

根据实现方式的不同,二分搜索算法可以分为迭代版本和递归版本两种:

1、迭代版本

def iterativeBinarySearch(items, target):
  first = 0
  last = len(items) - 1
  while first <= last:
    middle = (first + last) // 2
    if target == items[middle]:
      return True
    elif target < items[middle]:
      last = middle - 1
    else:
      first = middle + 1
  return False

2、递归版本

def recursiveBinarySearch(items, target):
  if len(items) == 0:
    return False
  else:
    middle = len(items) // 2
    if target == items[middle]:
      return True
    elif target < items[middle]:
      return recursiveBinarySearch(items[:middle], target)
    else:
      return recursiveBinarySearch(items[middle+1:], target)

三、性能比较

上述搜索算法的时间复杂度如下所示:

搜索算法          时间复杂度
-----------------------------------
sequentialSearch      O(n)
-----------------------------------
orderedSequentialSearch  O(n) 
-----------------------------------
iterativeBinarySearch   O(log n)
-----------------------------------
recursiveBinarySearch   O(log n)
-----------------------------------
in             O(n)

可以看出,二分搜索 的性能要优于 顺序搜索

值得注意的是,Python的成员操作符 in 的时间复杂度是O(n),不难猜出,操作符 in 实际采用的是 顺序搜索 算法。

四、算法测试

#!/usr/bin/env python
# -*- coding: utf-8 -*-
def test_print(algorithm, listname, target):
  print(' %d is%s in %s' % (target, '' if algorithm(eval(listname), target) else ' not', listname))
if __name__ == '__main__':
  testlist = [1, 2, 32, 8, 17, 19, 42, 13, 0]
  orderedlist = sorted(testlist)
  print('sequentialSearch:')
  test_print(sequentialSearch, 'testlist', 3)
  test_print(sequentialSearch, 'testlist', 13)
  print('orderedSequentialSearch:')
  test_print(orderedSequentialSearch, 'orderedlist', 3)
  test_print(orderedSequentialSearch, 'orderedlist', 13)
  print('iterativeBinarySearch:')
  test_print(iterativeBinarySearch, 'orderedlist', 3)
  test_print(iterativeBinarySearch, 'orderedlist', 13)
  print('recursiveBinarySearch:')
  test_print(recursiveBinarySearch, 'orderedlist', 3)
  test_print(recursiveBinarySearch, 'orderedlist', 13)

运行结果:

$ python testbasicsearch.py
sequentialSearch:
 3 is not in testlist
 13 is in testlist
orderedSequentialSearch:
 3 is not in orderedlist
 13 is in orderedlist
iterativeBinarySearch:
 3 is not in orderedlist
 13 is in orderedlist
recursiveBinarySearch:
 3 is not in orderedlist
 13 is in orderedlist

希望本文所述对大家的Python程序设计有所帮助。

Python 相关文章推荐
python uuid模块使用实例
Apr 08 Python
Scrapy-redis爬虫分布式爬取的分析和实现
Feb 07 Python
浅析Git版本控制器使用
Dec 10 Python
Python定时任务sched模块用法示例
Jul 16 Python
python实现汉诺塔算法
Mar 01 Python
详解如何设置Python环境变量?
May 13 Python
python如何实现代码检查
Jun 28 Python
Python scrapy增量爬取实例及实现过程解析
Dec 24 Python
手把手教你从PyCharm安装到激活(最新激活码),亲测有效可激活至2089年
Nov 25 Python
python中print格式化输出的问题
Apr 16 Python
一文搞懂Python Sklearn库使用
Aug 23 Python
python模板入门教程之flask Jinja
Apr 11 Python
Python实现的数据结构与算法之链表详解
Apr 22 #Python
Python实现的数据结构与算法之双端队列详解
Apr 22 #Python
Python实现的数据结构与算法之队列详解
Apr 22 #Python
详尽讲述用Python的Django框架测试驱动开发的教程
Apr 22 #Python
Hadoop中的Python框架的使用指南
Apr 22 #Python
Python实现提取文章摘要的方法
Apr 21 #Python
python中map、any、all函数用法分析
Apr 21 #Python
You might like
转生史莱姆:萌王第一次撸串开心到飞起,哥布塔撸串却神似界王神
2018/11/30 日漫
关于zend studio 出现乱码问题的总结
2013/06/23 PHP
Thinkphp实现MySQL读写分离操作示例
2014/06/25 PHP
PHP/HTML混写的四种方式总结
2017/02/27 PHP
form自动提交实例讲解
2017/07/10 PHP
JavaScript中关于indexOf的使用方法与问题小结
2010/08/05 Javascript
javascript关于运动的各种问题经典总结
2015/04/27 Javascript
正则表达式替换html元素属性的方法
2016/11/26 Javascript
JavaScript使用正则表达式获取全部分组内容的方法示例
2017/01/17 Javascript
jquery请求servlet实现ajax异步请求的示例
2017/06/03 jQuery
vue.js项目打包上线的图文教程
2017/11/16 Javascript
AngularJS实现的生成随机数与猜数字大小功能示例
2017/12/25 Javascript
解决webpack多页面内存溢出的方法示例
2019/10/08 Javascript
vue登录以及权限验证相关的实现
2019/10/25 Javascript
JavaScript鼠标悬停事件用法解析
2020/05/15 Javascript
vue实现编辑器键盘抬起时内容跟随光标距顶位置向上滚动效果
2020/05/28 Javascript
vscode中的vue项目报错Property ‘xxx‘ does not exist on type ‘CombinedVueInstance<{ readyOnly...Vetur(2339)
2020/09/11 Javascript
[44:26]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#4EG VS Fnatic第二局
2016/03/03 DOTA
python两种遍历字典(dict)的方法比较
2014/05/29 Python
深入浅析Python中的yield关键字
2018/01/24 Python
python使用knn实现特征向量分类
2018/12/26 Python
python之pyqt5通过按钮改变Label的背景颜色方法
2019/06/13 Python
浅谈Python3多线程之间的执行顺序问题
2020/05/02 Python
CSS3颜色值RGBA与渐变色使用介绍
2020/03/06 HTML / CSS
浅谈Html5多线程开发之WebWorkers
2018/05/02 HTML / CSS
美国定制钻石订婚戒指:Ritani
2017/12/08 全球购物
分解成质因数(如435234=251*17*17*3*2,据说是华为笔试题)
2014/07/16 面试题
校长先进事迹材料
2014/02/01 职场文书
疾病防治方案
2014/05/31 职场文书
计算机实训报告总结
2014/11/05 职场文书
六一亲子活动感想
2015/08/07 职场文书
安全生产协议书
2016/03/22 职场文书
如何书写授权委托书?
2019/06/25 职场文书
智慧人生:永远不需要向任何人解释你自己
2019/08/20 职场文书
超详细Python解释器新手安装教程
2021/05/10 Python
pytorch中的numel函数用法说明
2021/05/13 Python