zoukankan      html  css  js  c++  java
  • python中两种方法实现二分法查找,细致分析二分法查找算法

    之前分析了好多排序算法,可难理解了呢!!(泣不成声)
    这次我要把二分查找总结一下,这个算法不算难度特别大,欢迎大家参考借鉴

    我不喜欢太官方的定义,太晦涩的语言,让人看了就头晕。我希望加入我自己的理解,能帮助大家更好的理解算法的原理
    同时也欢迎大家批评指正

    二分查找:
    我们手里有一个长度为n的正序数列,当我们想查找一个数 x是否在这个数列当中的时候
    1 取数列正中间的数mid,
    如果mid和x相等,则找到结果,查找成功 返回True
    如果mid比x大,则x应该在mid的左侧,我们把mid左侧当作一个新的数列li
    如果mid比x小,则x应该在mid的右侧,我们把mid右侧当作一个新的数列li
    2 对于新的数列li 进行1的查找工作

    3 一直重复上面查找,生成新的数列li为空的时候则 数列当中没有数x 返回False

    时间复杂度:最优O(1) 我们取第一次中间数mid 找到了 这种概率很低
    最坏O(log n) 假设n个数的数列,每次把数列分成两半,n除以多少次2 等于1 呢? log n次


    首先我们用递归的方式实现二分查找算法:
     1 #递归实现二分查找 li是列表   item是要查找的元素
     2 def merge_search( li ,item ):
     3     #传来的列表每次都是新生成的,如果发现里面没有元素,则是查找到尽头都没找到
     4     if not li :
     5         return False
     6 
     7     mid = len(li)//2   #mid记录li的中间位置
     8     #检查一下 如果中间这个数就是要找的元素 返回真
     9     if li[mid] == item :
    10         return True
    11     # 如果mid比item大,说明item可能会出现在mid左边,对左边再查找
    12     elif li[mid]> item :
    13         return merge_search( li[:mid] ,item )
    14     # mid 比item小,说明item有可能在mid右边,对右边再查找
    15     else :
    16         return merge_search( li[mid+1:] , item )
    17 
    18 if __name__ == '__main__':
    19     li = [1,2,3,4,5,6,7]
    20     print( merge_search(li , 0) )   #False
    21     print( merge_search(li , 1) )   #True

    下面我们尝试用while循环去实现二分查找:

     1 def merge_search( li , item ):
     2     #获取li的开始 结束
     3     start = 0
     4     end = len(li)-1
     5 
     6     #只要start和end 还没错开 就一直找
     7     while start <= end :
     8         #通过计算获取当前查找范围的中间位置
     9         mid = (start + end)//2
    10         #如果中间数就是item则返回True
    11         if li[mid] == item :
    12             return True
    13         #如果mid比item大,说明item可能会出现在mid左边,对左边再查找
    14         elif li[mid]> item :
    15             end = mid - 1
    16         # mid 比item小,说明item有可能在mid右边,对右边再查找
    17         else :
    18             start = mid + 1
    19     #跳出循环说明没找到 返回错误
    20     return False
    21 
    22 if __name__ == '__main__':
    23     li = [1,2,3,4,5,6,7,8]
    24     print( merge_search(li , 8) ) #True
    25     print( merge_search(li , 0) ) #False

    OK 以上就是两种实现二分查找的方法。

    因为思想相同,他们的时间复杂度是一样的。

    但是递归的方式,每次都要开新的列表,实际上空间复杂度会更大一些。



    谢谢你的观赏~欢迎大家批评指正!


  • 相关阅读:
    [记录] 原生JS 的常用方法封装
    [记录] JavaScript 中的DOM操作
    [记录] JavaScript 中的正则表达式(案例分析)
    图片查看器插件(带缩略图) viewer.js
    (二) 美化滚动条 JScrollPane.js
    关于数据库存储过程管理的一点建议
    根据属性名称来改变XML节点值
    hdu 3911 Black And White
    poj 3667 Hotel
    hdu 4217 Data Structure?
  • 原文地址:https://www.cnblogs.com/Lin-Yi/p/7309288.html
Copyright © 2011-2022 走看看