『算法』——静态查找——线性表查找——二分查找(折半查找/对分查找)
发布日期:2021-05-07 08:51:55 浏览次数:20 分类:原创文章

本文共 1972 字,大约阅读时间需要 6 分钟。

二分查找

引言

  • 二分查找是顺序表或线性链表表示的静态查找表
  • 表内元素有序

1、定义

\quad \quad 二分查找针对的是一个有序的数据集合,每次通过跟区间中间的元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间缩小为0。

2、思想

\quad \quad 假设表中元素是有序的,将表的中间位置的关键字与所需的关键字比较,相等则成功,否则分为前后两个子表,若所需的值大于中间元素,则在后半部分查找,否则在前半部分查找。不断重复这个过程,直到查找成功。否则查找失败。需要两个移动指针p,r,分别指向列表的上界与下界。

3、算法

伪代码

在这里插入图片描述

python:

#非递归实现import numpy as npdef binary_search(A,x):    A=np.sort(A)#先将A排序    n=len(A)    #搜索区间范围:左闭右闭[left,right]    p=0#p:头指针    r=n-1#r:尾指针    while p<=r:        q=(p+r)//2#//符号:商取整        #或q=p+(r-p)//2,防止溢出,最好使用这种取中值的方法        if A[q]==x:            return q        elif A[q]>x:            r=q-1        else:            p=q+1    return print("NOT FOUND")

另一种非递归模板:

import numpy as npdef binary_search(A,x):    A=np.sort(A)#先将A排序    n=len(A)    #区间范围:左闭右开[left,right)    p=0#p:头指针    r=n#r:尾指针    while p<r:        q=(p+r)//2#//符号:商取整        #或q=p+(r-p)//2,防止溢出,最好使用这种取中值的方法        if A[q]==x:            return q        elif A[q]>x:            r=q        else:            p=q+1    return print("NOT FOUND")
#递归实现(p,r)一般刚开始是(0,len(A)-1)也就是列表中第一个与最后一个位置def recursive_binary_search(A,p,r,x):    A=np.sort(A)#先将A排序    if p>r:        return print("NOT FOUND")    else:        q=(p+r)//2        if A[q]==x:            return q        elif A[q]>x:            return recursive_binary_search(A,p,q-1,x)        else:            return recursive_binary_search(A,q+1,r,x)   

中位数的计算方法:

1、mid = (left + right) / 2; 是初级写法,是有 bug 的:有可能会溢出。

2、 mid = left + (right - left) / 2; 是正确的写法,考虑到了整型溢出的风险;

3、mid = (low + high) >> 1; 右移运算符>>,运算结果正好能对应一个整数的二分之一值,这就正好能代替数学上的除2运算,但是比除2运算要快。

4、查找性能(ASL)

在这里插入图片描述

【时间复杂度】: O ( l o g 2 n ) O(log_2n) O(log2n)
【空间复杂度】:

  • 递归实现: O ( l o g 2 n ) O(log_2n) O(log2n)
  • 非递实现: O ( 1 ) O(1) O(1)

5、特点

优点:比较次数少,时间性能相对于顺序查找要好,效率要快

缺点:要求待查表为有序表,且限于顺序存储结构(对线性链表无效)。

局限性:

1.二分查找依赖的是顺序表结构,即数组。
2.二分查找针对的是有序数据,因此只能用在插入、删除操作不频繁,一次排序多次查找的场景中。
3.数据量太小不适合二分查找,与直接遍历相比效率提升不明显。但有一个例外,就是数据之间的比较操作非常费时,比如数组中存储的都是长度超过300的字符串,那这是还是尽量减少比较操作使用二分查找吧。
4.数据量太大也不是适合用二分查找,因为数组需要连续的空间,若数据量太大,往往找不到存储如此大规模数据的连续内存空间。

上一篇:python中的map( )函数及lambda()函数简介
下一篇:2020.5.14-力扣刷刷1-4.寻找两个正序数组的中位数(数组类型)

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2025年04月13日 03时18分53秒