#源于搜索的学习#
目前为止学到的搜索有两个:1,python中自带的搜索 2,顺序搜索
其中顺序搜索又有:1,无序表的顺序搜索 2,有序表的顺序搜索
今天,我们的学习同样也涉及到有序表,利用其有序性,发挥它的最大功能。
它就是-----二分搜索
原理:从中间的元素着手。如果这个元素就是目标元素,那就立即停止搜索;如果不是,则可以利用列表有序的特性,排除一半的元素。如果目标元素比中间元素大,就可以直接排除列表的左半部分和中间的元素。 如果还没有找到目标元素,则继续二分,缩小范围直到找到,或是列表不可以再进行缩小时。
这么说,肯定还是懵懵的,直接上代码,带你一步步地去分析
首先要确定一些必要的条件
1,参数 根据题目可知,我们所需要的参数: 1,list(目标列表) 2,item(目标元素)
2,变量的设置 1,first(首) 2,last(尾)这里是用来指代我们待会要进行搜索的范围 3,还有一个found这是后面将返回是否找到的布尔值。 这个可以看搜索的定义处便可以理解了
那么,我们上源代码:
def binarySearch(alist,item):
first = 0
last = len(alist) - 1
found = False
while first <= last and not found: #若目标还未找到,则直到列表中没元素时也会停止
midpoint = (first + last) // 2
if alist[midpoint] == item: #中间项比对
found = True
else:
if item < alist[midpoint]: #当目标在中间值左边时
last = midpoint - 1 #这是为了往左边缩小
else: #当目标值在中间值右边时
first = midpoint + 1 #为了往右边进行缩小范围
return found
在求整的时候,万一除数的结果为浮点数的时候,它的值其实会便小,那么这里的midpoint + 1就是为弥补这个。
这个原因下面的递归二分也会用到。
现在来看一下---二分法递归
def binarySearch(alist,item):
if len(alist) == 0:
return False
#这里是设置递归中的基本条件类型,如果找不到元素,则返回错误
else:
midpoint = len(alist) // 2
#此处使用整除,向下取整
if alist[midpoint] == item:
return True
else:
if item < alist[midpoint]:
return binarySearch(alist[:midponit],item)
#这里进行中值比较,目标值偏小,用切片的方式缩小
else:
return binarySearch(alist[midpoint+1:],item)
#这里一定要注意,midponit+1
#因为有一个向下取整的操作,我们加上1,抵消它
#不然在某些特定情况下会报错
这里通过列表的切片操作,来不断地缩小它的范围,当遇到了目标值的时候,return函数便结束该函数的递归,并返回布尔值---True
对于该二分搜索的时间复杂度是---O(logn) 因为比较次数的最大值与列表元素的元素个数是对数关系。但是它的所需空间增加,因为递归会用到系统自带的栈,运行时会占用一定的空间,需要我们根据具体情况来选择使用。
最后,感谢各位的观看,可能有些地方还未讲出,如果有任何疑问,欢迎来到评论区留下你的疑问。