zoukankan      html  css  js  c++  java
  • 初级算法:二分查找

    二分查找算法

     

    如果有这样一个列表,让你从这个列表中找到66的位置,你要怎么做?

    l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]

    你说,so easy!

    l.index(66)...

    我们之所以用index方法可以找到,是因为python帮我们实现了查找方法。如果,index方法不给你用了。。。你还能找到这个66么?

    l = [2,3,5,10,15,16,18,22,26,30,32,35,41,
    42,43,55,56,66,67,69,72,76,82,83,88]
    def index(l,aim):
        count = -1
        for i in l:
            count += 1
            if i == aim:
                return count
        return '没有此值'
    print(index(l,84))

    上面这个方法就实现了从一个列表中找到66所在的位置了。

    但我们现在是怎么找到这个数的呀?是不是循环这个列表,一个一个的找的呀?假如我们这个列表特别长,里面好好几十万个数,那我们找一个数如果运气不好的话是不是要对比十几万次?这样效率太低了,我们得想一个新办法。

    二分查找算法

    l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]

    你观察这个列表,这是不是一个从小到大排序的有序列表呀?

    如果这样,假如我要找的数比列表中间的数还大,是不是我直接在列表的后半边找就行了?

    这就是二分查找算法

    那么落实到代码上我们应该怎么实现呢? 

    简单版二分法 

    原列表发生改变,导致索引改变.
    li = [2, 3, 5, 10, 15, 16, 18, 19]
    def two_find(l,aim):
        mid_index = len(l) // 2
        if aim > l[mid_index]:
            return two_find(l[mid_index+1:],aim)
        elif aim < l[mid_index]:
            return two_find(l[:mid_index], aim)
        elif aim == l[mid_index]:
            return mid_index
        else:
            return None
    print(two_find(li,18))
    print(two_find(li,3))
    print(two_find(li,10))

    升级版二分法

    原列表不发生改变,你的min_index = (end - start) // 2 + start
    l1 = [1,2,3,4,5,6,7,8,9,11,12,14,15,16,17,21,22,23,24,25,26,27,28,29]
    
    def two_find(l,aim,start=0,end=None):
        end = len(l) - 1 if end is None else end
        mid_index = (end - start) // 2 + start
        if start <= end:
            if aim > l[mid_index]:
                return two_find(l, aim, start=mid_index+1, end=end)
            elif aim < l[mid_index]:
                return two_find(l, aim, start=start, end=mid_index)
            elif aim == l[mid_index]:
                return mid_index
            else:
                return None
        else:
            return None
    print(two_find(l1,22))
  • 相关阅读:
    15. DML, DDL, LOGON 触发器
    5. 跟踪标记 (Trace Flag) 834, 845 对内存页行为的影响
    4. 跟踪标记 (Trace Flag) 610 对索引组织表(IOT)最小化日志
    14. 类似正则表达式的字符处理问题
    01. SELECT显示和PRINT打印超长的字符
    3. 跟踪标记 (Trace Flag) 1204, 1222 抓取死锁信息
    2. 跟踪标记 (Trace Flag) 3604, 3605 输出DBCC命令结果
    1. 跟踪标记 (Trace Flag) 1117, 1118 文件增长及空间分配方式
    0. 跟踪标记 (Trace Flag) 简介
    SpringBoot + Redis + Shiro 实现权限管理(转)
  • 原文地址:https://www.cnblogs.com/while-number/p/9251964.html
Copyright © 2011-2022 走看看