二分查找 python 非递归,python二分排序算法
Python的list内部实现是数组或者线性表。若要在列表中查找元素,请使用list.index(方法)。时间复杂度为o(n)。当有大量数据时,可以通过二分搜索法进行优化。子搜索要求对象必须是有序的,其基本原理如下。
1.从数组的中间元素开始。如果中间的元素恰好是你要找的元素,检索过程结束;
2.如果一个特定的元素比中间的元素大或者小,就按比中间的元素大或者小的数组的一半来搜索,然后像第一个一样从中间的元素开始比较。
3.如果某一步数组为空,说明找不到。
二分搜索法也是五五开。每比较一次算法,搜索范围会缩小一半,其时间复杂度为o(logn)。
二分搜索法是通过递归和循环实现的:
defbinary_search_recursion(lst,value,low,high):ifhighlow:returnnonemid=(low high)/2if lst[mid]vvalue 3360 mid-1)elif lst[mid]value:returnbinary _ search _ recursion(lst,value,mid 1,high)else:returnmiddefbindef value):low,high=0,len(lst)-1 while low=high:mid(low high)/2if lst[
没有人回答“”这个问题?建立Python学习交流QQ群:找到拥有778463939杂志的小伙伴,互相帮助。群里有很好的视频学习教程和PDF电子书! if _ _ name _= _ _ main _ :importrandomlst=[random . randint(0,10000)for _ inx range(100000)[lst . sort]def test _ recursion(:binary _ search _ recursion)lst,999,len 999)importtimeittt 1=time it . timer))test _)timer setup= from _ main _ import test _ recursion )T2=time it
在递归中:3.12596702576循环:2.08254289627,可以看出循环方案比递归效率高。
Python二分法模块用于维护有序列表。等分模块实现了将元素插入有序列表的算法。在某些情况下,这比重复排序列表或创建一个大列表进行排序更有效。二等分的意思是二分法,这里用于排序。该元素被插入到有序列表中的适当位置,因此不需要在每次调用排序时维护有序列表。
下面显示了的一个简单使用示例。
没有人回答“”这个问题?建立Python学习交流QQ群:找到拥有778463939杂志的小伙伴,互相帮助。群里有很好的视频学习教程和PDF电子书! importsectionimportrandomrandom . seed(1)print new pos contents print -l=[]for iiid
新位置内容- 14 - 14 (14 ) 85 ) 77 (14,77,85 ) 26 (14,26,77,85 ) 50 ) 14
0, 77, 85] 45 2 [14, 26, 45, 50, 77, 85] 66 4 [14, 26, 45, 50, 66, 77, 85] 79 6 [14, 26, 45, 50, 66, 77, 79, 85] 10 0 [10, 14, 26, 45, 50, 66, 77, 79, 85] 3 0 [3, 10, 14, 26, 45, 50, 66, 77, 79, 85] 84 9 [3, 10, 14, 26, 45, 50, 66, 77, 79, 84, 85] 44 4 [3, 10, 14, 26, 44, 45, 50, 66, 77, 79, 84, 85] 77 9 [3, 10, 14, 26, 44, 45, 50, 66, 77, 77, 79, 84, 85] 1 0 [1, 3, 10, 14, 26, 44, 45, 50, 66, 77
二等分.二等分_左(a,x,lo=0,hi=len (a)):在有序列表a中查找x插入的索引,lo和hi用于指定列表的区间,默认使用整个列表。如果X已经存在,将它插入到它的左边。返回值是index。
平分。平分_ RIGHT (a,x,lo=0,hi=len (a))平分。二等分(a,x,lo=0,hi=len (a)):这两个函数类似于二等分_左,但是如果x已经存在,就把它插入到它的右边。
二等分. insort _ left (a,x,lo=0,hi=len (a)):在有序列表a中插入x .和a. insert(二等分.二等分_ left (a,x,lo,hi),x)作用相同。
平分。INSORT _ RIGHT (a,x,lo=0,hi=len (a))二等分。INSORT (a,x,lo=0,hi=len (a)):类似于insort_left,但是如果x已经存在,就插入到它的右边。
二分模块提供的功能可以分为两类:二分*只用于查找索引,没有实际插入;而insort*用于实际插入。该模块的典型应用是计算分数等级:
def grade(score,breakpoints=[60,70,80,90],grades=FDCBA): i=平分。平分(断点、得分)返回grades[I]print[grade(score)for score in[33,99,77,70,89,90,100]]执行结果:
[F , A , C , B , A , A]同样,我们可以用把…分为两个部分模块实现二分查找:
遇到问题没人解答?小编创建了一个计算机编程语言学习交流即时通信软件群:778463939寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和便携文档格式电子书! def binary _ search _ bi section(lst,x):from bi section import bi section _ left I=bi section _ left(lst,x) if i!=len(lst)和lst[I]=x:return I返回None我们再来测试一下它与递归和循环实现的二分查找的性能:
递归:4.00940990448循环:2.658484841可以看到其比循环实现略快,比递归实现差不多要快一半。
计算机编程语言著名的数据处理zjdlc也有一个用于二分查找的函数numpy.searchsorted,用法与把…分为两个部分基本相同,只不过如果要右边插入时,需要设置参数side=右,例如:
import numpy as NP from bi section import bi section _ left,bi section _ right data=[2,4,7,9]bi section _ left(data,4)1 np.searchsorted(data,4)1 bi section _ right(data,4)2 np.searchsorted(data,4,side=right)2那么,我们再来比较一下性能:
In [20]: %timeit -n 100等分_左(数据,99999)100次循环,每次循环3:670 ns in[21]:% time it-n 100 NP。搜索排序(数据,99999)100次循环,每次循环3:56.9毫秒在[22]:%时间它-n 100等分_左(数据,8888)100次循环,每次循环3分961秒可以发现numpy.searchsorted效率是很低的,跟把…分为两个部分根本不在一个数量级上。因此搜索排序不适合用于搜索普通的数组,但是它用来搜索numpy.ndarray是相当快的:
在[30]中:data _ ndarray=NP。[31]中的arange(0,1000000):% time it NP。搜索排序(data _ ndarray,99999)最慢的运行比最快的运行花费的时间长16.04倍。这可能意味着正在缓存中间结果。1000000次循环,每次循环的最佳时间为3:996 ns in[32]:% time it NP。搜索排序(data _ ndarray,8888)最慢的运行时间比最快的运行时间长18.22倍。这可能意味着正在缓存中间结果。1000000次循环,每次循环的最佳时间为3:994 ns in[33]:% time it NP。搜索排序(data _ ndarray,777777)最慢的运行时间比最快的运行时间长31.32倍。这可能意味着正在缓存中间结果。1000000个循环,最好为3:990纳秒/循环numpy.searchsorted可以同时搜索多个值:
np.searchsorted([1,2,3,4,5],3)2 np.searchsorted([1,2,3,4,5),3,side= right )3 NP .搜索排序([1,2,3,4,5],[-10,10,2,3])数组([0,5,1,2])
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。