• 二分查找(折半查找)


    • 定义

    •   二分查找又称折半查找,是一种高效率的数据查找方法。其思想是按比例逐步缩小需要考虑的数据范围,从而快速逼近需要查找的数据。该过程可以类比于我们中学时查字典的过程(假设 字典的索引被吃了),如果你要查询一个字“破”,那么思考下你要怎么查询?是不是首先需要根据“破”的拼音首字母“P”,找到在字典的大致位置(前半部分还是后半部分),显然“P”位于26个英文字母的后半部分,因此下一步就是在这后半部分中再分为两部分继续确定,此时“P”位于前半部分,以此类推,直到找到“P”的位置(例如在字典的350-430页)。然后次位的拼音“O”再按照这种方式,定位“PO”组合的位置。 
    • 查找过程(设顺序表元素升序排列)

    •  1)初始时,考虑的元素区间是整个顺序表

    •     2)取所考虑的元素范围内位置居中的那个元素(中间项),比较该元素和检索元素的关系,如果相等则检索结束,返回True

    •  3) 如果检索元素大,则检索范围修改为中间项之后的半区间;如果检索元素小,则检索范围修改为中间项之前的半区间

    •     4)如果区间范围内有数据就执行步骤2),否则检索元素不在顺序表中,返回False
    • 实现

    •  二分查找有递归实现和循环实现方式,如下:

    def binary_search(search_list, search_element):
        """二分查找:基于递归,返回是否存在该元素"""
        s_len = len(search_list)
        if s_len > 0:
            mid_element = s_len // 2
            # 中间元素恰好为所要查询的元素
            if search_list[mid_element] == search_element:
                return True
            # 所要查询的元素位于原序列左侧
            elif search_list[mid_element] > search_element:
                return binary_search(search_list[:mid_element], search_element)
            # 所要查询的元素位于原序列右侧
            else:
                return binary_search(search_list[mid_element+1:], search_element)
        return False
    
    
    if __name__ == "__main__":
        L1 = [1, 3, 5, 6, 12, 23, 34, 35, 43, 55, 65]
        print(binary_search(L1, 43))
        print(binary_search(L1, 5))
        print(binary_search(L1, 11))
        print(binary_search(L1, 23))
    def binary_search(search_list, search_element):
        """二分查找:基于循环,返回是否存在该元素"""
        s_len = len(search_list)
        # 利用索引值的改变,定位在原列表的查询范围
        first_idx = 0
        last_idx = s_len-1
        # 当前面索引小于等于后面索引,执行查找;需要注意等号也成立
        while first_idx <= last_idx:
            mid_idx = (first_idx + last_idx) // 2
            if search_list[mid_idx] == search_element:
                return True
            elif search_list[mid_idx] > search_element:
                last_idx = mid_idx - 1
            else:
                first_idx = mid_idx + 1
        return False
    
    
    if __name__ == "__main__":
        L1 = [1, 3, 5, 6, 12, 23, 34, 35, 43, 55, 65]
        print(binary_search(L1, 43))
        print(binary_search(L1, 5))
        print(binary_search(L1, 11))
        print(binary_search(L1, 23))
    • 复杂度

    •            最优时间复杂度:O(1)
    •            最坏时间复杂度:O(logn)
    • 优缺点

    •           优点:查找速度快,比较次数少,平均性能好
    •           缺点:要求待查表为有序表,且插入删除困难

      参考:数据结构与算法(python语言描述)裘宗燕

                      黑马python数据结构与算法系列课程

  • 相关阅读:
    【ES6】数组的扩展——扩展运算符
    【ES6】函数的扩展
    菜鸡程序员是如何写代码的?
    我是技术总监,我出来求职,竟然找不到工作!
    为什么互联网公司天天都在招人?
    这个立冬,我线下面基了一位TMD高级专家,太牛逼了!
    太可怕了!有些码农为啥写代码,写到监狱里去了?
    56岁潘石屹生日当天宣布要学编程语言Python,网友:地产商来抢码农饭碗了!
    如何写出让同事无法维护的代码?
    hdu 1037 Keep on Truckin'
  • 原文地址:https://www.cnblogs.com/pjsdly-NLP/p/12633566.html
Copyright © 2020-2023  润新知