数据结构和算法:Python实现二分查找(Binary_search)
在一个列表当中我们可以进行线性查找也可以进行二分查找,即通过不同的方法找到我们想要的数字,线性查找即按照数字从列表里一个一个从左向右查找,找到之后程序停下。而二分查找的效率往往会比线性查找更高。
一.二分查找的步骤
二分查找的步骤首先是将列表进行升序或者降序排列,否则无法进行数字的比较,也就无法进行二分查找。然后找到一个列表的中间数值(mid),如果列表当中的数字和为基数,则为最中间的那个数。如果为偶数,则为最中间的那两个数的左边那一个,比如说我们有一个列表,[1,2,3,4,5,6],列表当中的数字为偶数个,那么mid则是3。找到mid之后,再和我们需要查找的数字进行比较,如果比我们需要查找的数字要小,那么就让low=mid+1,即在Mid的右边一个,如果比我们需要的数字要大,则让high=mid—1,在high的左边一个,利用夹逼法直到mid等于var的时候这个时候在返回mid的值,这个值就是我们数字所在的顺序数,在列表当中的order或称index(索引)。我们下面一张图来表示二分查找的步骤,下面是举了一个最为简单的列子,数字的个数仅为4个,且为1,2,3,4。
假设我们想要找的数字为3的index,因此首先在第一次循环当中,1=low,4=high,mid=2,我们令var=3,也就是我们想要找的数为var,发现这个数的数值是比mid的数值更大的,因此low=mid+1,此时mid所代表的数值变成了3。紧接着我们进行下一次循环,我们发现var和mid是相等的,因此返回mid的数值(并非mid所对应在列表当中的数值,而是mid自己的值),这样就可以得到var的索引值了!实现的程序如下:
# 首先咱们来看一个线性查找,这个的效率比较低
li = [1,2,3,4,0,4,2,3] # print(6 in li)# 这个就是线性查找,看6是否在里面
# print(li.index(6))# 看6在第几个index li.sort()
print("进行排序之后的列表为:{}".format(li)) def bin_search(li, var):
low = 0
high = len(li) - 1
while low<=high:# 这里不能够使用while true!!不然输入一个不存在的值的话就会导致mid做了加减法后low比high大或者high比Low小,失去了比较的意义
mid = (low + high) // 2
if li[mid] == var:
return mid
elif li[mid] < var:
low = mid + 1
else:# li[mid] > var
high = mid - 1
return -1 # 二分查找的时间复杂度为log(n)
if __name__ == "__main__":
print(bin_search(li, 3))
在程序当中需要注意的是循环while的判断条件是low<=high,因为如果在输入的值var不属于列表的情况下,运算到最后low就会大于high,这种情况下是应该直接返回-1的,而不是继续运算到无穷无尽。在这个程序当中我们设定了列表li,并通过定义二分查找函数来执行二分查找的过程。程序也很通俗易懂,和之前我们讲过的二分查找的步骤是一样的,下面我们来看一个利用二分查找的例题:
二.例题
这个例题节选自悉尼大学“Python编程”这门课的每周同步编程练习,题目是这样的:
输入一个序列,然后让整个序列变成一个有序的列表,最后找到数字8在这个列表当中的位置,我们可以使用二分查找来做这道题目,标准的Example如下:
现在我们使用二分查找算法来实现这个问题,首先是输入的字符串用input()函数来进行接收,但是接收之后的数字是字符串,我们需要使用split()函数将其每一个元素通过间隔开,由于使用了split()函数,因此就会自己动返回一个列表,不过里面每一个数字也还是string型,我们再利用一个for循环将其改变为int型,再重新灌入一个列表当中,形成interger型的列表,也就是我们第二个的输出结果,最后运用咱们刚才的二分查找法,得到数字8的index值,程序如下:
def binary_search(list, var):
low = 0
high = len(list)-1
while low <= high:
mid = (low+high)//2
if list[mid] == var:
return mid
elif list[mid] < var:
low=mid+1
else:
high=mid-1
return -1 a = input("Enter some integers:")
a = a.split(",")
print(a)
ls = []
for i in a:
b = int(i)
ls.append(b) print("我们得到的数组是:{}".format(ls))
# 将列表进行升序排列,这样才可以使用二分查找算法
ls.sort()
print(ls) if __name__ == "__main__":
print(binary_search(ls,5))
输出结果如下:
E:\conda\python.exe F:/computer/datast/T4Q6P4.py
Enter some integers:23,4456,234,67,5
['', '', '', '', '']
我们得到的数组是:[23, 4456, 234, 67, 5]
[5, 23, 67, 234, 4456]
0
今天的教程就到这里了!希望你看了之后会有收获!
数据结构和算法:Python实现二分查找(Binary_search)的更多相关文章
- golang数据结构和算法之BinarySearch二分查找法
基础语法差不多了, 就需要系统的撸一下数据结构和算法了. 没找到合适的书, 就参考github项目: https://github.com/floyernick/Data-Structures-and ...
- Python 迭代器&生成器,装饰器,递归,算法基础:二分查找、二维数组转换,正则表达式,作业:计算器开发
本节大纲 迭代器&生成器 装饰器 基本装饰器 多参数装饰器 递归 算法基础:二分查找.二维数组转换 正则表达式 常用模块学习 作业:计算器开发 实现加减乘除及拓号优先级解析 用户输入 1 - ...
- Python实现二分查找
老生常谈的算法了. #!/usr/bin/python # -*- coding:utf-8 -*- # Filename: demo.py # 用python实现二分查找 def binarySea ...
- 数据结构与算法-Python/C(目录)
第一篇 基本概念 01 什么是数据结构 02 什么是算法 03 应用实例-最大子列和问题 第二篇 线性结构 01 线性表及其实现 02 堆栈 03 队列 04 应用实例-多项式加法运算 05 小白专场 ...
- 数据结构和算法(Golang实现)(27)查找算法-二叉查找树
二叉查找树 二叉查找树,又叫二叉排序树,二叉搜索树,是一种有特定规则的二叉树,定义如下: 它是一颗二叉树,或者是空树. 左子树所有节点的值都小于它的根节点,右子树所有节点的值都大于它的根节点. 左右子 ...
- 数据结构和算法(Golang实现)(29)查找算法-2-3树和左倾红黑树
某些教程不区分普通红黑树和左倾红黑树的区别,直接将左倾红黑树拿来教学,并且称其为红黑树,因为左倾红黑树与普通的红黑树相比,实现起来较为简单,容易教学.在这里,我们区分开左倾红黑树和普通红黑树. 红黑树 ...
- 北京大学公开课《数据结构与算法Python版》
之前我分享过一个数据结构与算法的课程,很多小伙伴私信我问有没有Python版. 看了一些公开课后,今天特向大家推荐北京大学的这门课程:<数据结构与算法Python版>. 课程概述 很多同学 ...
- 数据结构和算法(Golang实现)(26)查找算法-哈希表
哈希表:散列查找 一.线性查找 我们要通过一个键key来查找相应的值value.有一种最简单的方式,就是将键值对存放在链表里,然后遍历链表来查找是否存在key,存在则更新键对应的值,不存在则将键值对链 ...
- 数据结构和算法(Golang实现)(28)查找算法-AVL树
AVL树 二叉查找树的树高度影响了查找的效率,需要尽量减小树的高度,AVL树正是这样的树. 一.AVL树介绍 AVL树是一棵严格自平衡的二叉查找树,1962年,发明者Adelson-Velsky和La ...
- 【数据结构与算法Python版学习笔记】引言
学习来源 北京大学-数据结构与算法Python版 目标 了解计算机科学.程序设计和问题解决的基本概念 计算机科学是对问题本身.问题的解决.以及问题求解过程中得出的解决方案的研究.面对一 个特定问题,计 ...
随机推荐
- 由生到死10个月!做App中的“二”有多难
十月,原本是怀胎过程的喜悦时光,但这段个时光,如今却是绝大多数App从生到死的所有时间.在App市场表面形式一片大好,彻底主宰我们生活.工作.娱乐的当下,绝大多数用户只是在App海洋中只取一瓢饮,其他 ...
- 吴裕雄--天生自然 python语言数据分析:开普勒系外行星搜索结果分析
import pandas as pd pd.DataFrame({'Yes': [50, 21], 'No': [131, 2]}) pd.DataFrame({'Bob': ['I liked i ...
- 初入 Ubuntu 的一些操作 · Lei's blog
查看系统版本 cat /etc/os-release 修改 root 密码 passwd 新建用户 新建用户: adduser username 将新用户加入 sudo 组,这样就可以用 sudo 命 ...
- Python如何让字典保持有序
问题: Python如何让字典保持有序 ? 解决方案: 使用collections.OrderedDict代替Dict. 验证程序: from collections import OrderedDi ...
- iOS多线程开发之NSOperation
一.什么是NSOperation? NSOperation是苹果提供的一套多线程解决方案.实际上NSOperation是基于GCD更高一层的封装,但是比GCD更加的面向对象.代码可读性更高.可控性更强 ...
- Android(四)-JVM与DVM区别
JVM与DVM区别 1.由来 Android是基于java的既然java已经有了java虚拟机,为什么android还要弄一个DVM了?最重要的就是版权问题,一开始就是用的 JVM,没过多久就被SUN ...
- ysoserial-调试分析总结篇(1)
前言: ysoserial很强大,花时间好好研究研究其中的利用链对于了解java语言的一些特性很有帮助,也方便打好学习java安全的基础,刚学反序列化时就分析过commoncollections,但是 ...
- jenkins-设置定时任务
前言 跑自动化用例每次用手工点击 jenkins 出发自动化用例太麻烦了,我们希望能每天固定时间 跑,这样就不用管了,坐等收测试报告结果就行. 一.定时构建语法 * * * * * (五颗星,中间用 ...
- 拿到webshell之后的事情
之前搞站都是搞到后台管理员,或者搞到webshell就宣布结束了,,今天终于有机会学习一下后面的操作了. 公司网站为php的站,已经拿到webshell.可以进行菜刀连接. 菜刀虚拟终端 php -m ...
- Java enum枚举在实际项目中的常用方法
在项目实际开发过程中,经常会遇到对某些固定的值.字典项的定义的需求,很多项目经常使用常量来定义,其实在jdk1.5就已经引入了枚举,使用枚举可以更好的解决这类需求,本文主要记录枚举的优势以及经常在项目 ...