二分查找(折半查找)

  • 定义

  •   二分查找又称折半查找,是一种高效率的数据查找方法。其思想是按比例逐步缩小需要考虑的数据范围,从而快速逼近需要查找的数据。该过程可以类比于我们中学时查字典的过程(假设 字典的索引被吃了),如果你要查询一个字“破”,那么思考下你要怎么查询?是不是首先需要根据“破”的拼音首字母“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数据结构与算法系列课程

原文地址:https://www.cnblogs.com/pjsdly-NLP/p/12633566.html