python中的二分法实现

#源于搜索的学习#

目前为止学到的搜索有两个: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)   因为比较次数的最大值与列表元素的元素个数是对数关系。但是它的所需空间增加,因为递归会用到系统自带的栈,运行时会占用一定的空间,需要我们根据具体情况来选择使用。

最后,感谢各位的观看,可能有些地方还未讲出,如果有任何疑问,欢迎来到评论区留下你的疑问。

你可能感兴趣的:(python,开发语言)