二分算法 原理 及 复杂度 详解

本文深入解析了二分搜索算法,包括其基本原理、示例演示和时间、空间复杂度。二分搜索适用于有序数组,通过每次迭代将查找范围减半来高效定位目标值。其时间复杂度为O(log(n)),空间复杂度为O(1)。文章通过一个具体的案例详细阐述了二分搜索的过程,并分析了算法的复杂度。
摘要由CSDN通过智能技术生成

binary search,常见的翻译有二分查找、二分搜索、折半搜索(这用的名词是 half-interval search)、对数搜索(这里用的名词是 logarithmic search),是一种非常常见并且应用范围也比较广泛的搜索算法。

之前曾看到过一个说法:凡是有序,皆是二分,大概也能说明二分搜索的应用之广泛了。

二分搜索的基础原理

二分可以被用于查找 有序数组 中的某一个特定元素,其工作原理是查找一个 既定值,target数组, arr中点,mid 开始查找,判断 a r r [ m i d ] arr[mid] arr[mid] 的值,存在以下三种情况:

  1. 如果 t a r g e t = a r r [ m i d ] target = arr[mid] target=arr[mid],则找到 target,直接返回 mid
  2. 如果 t a r g e t < a r r [ m i d ] target < arr[mid] target<arr[mid],则代表 target 坐落于 [ 0... m i d ) [0...mid) [0...mid) 区间
  3. 如果 t a r g e t > a r r [ m i d ] target > arr[mid] target>arr[mid],则代表 target 坐落于 ( m i d . . . a r r . l e n g t h ) (mid...arr.length) (mid...arr.length) 区间

这种每迭代一次就会将可选项的数量折半,也是折半搜索名词的来源。

这里也会应用到双指针去确认搜索的区间,关于双指针的知识点细节可以看这里:双指针总结

二分的基础案例

以一个数组作为案例去进行二分查找的步骤,目标值 target 为 1,数组为:

14101217182125
  1. 确认 最大值最小值中点

    这里最大值 a r r . l e n g t h − 1 arr.length - 1 arr.length1,也就是 7,最小值 是数组的起点长度,也就是 0,中点 的计算稍微麻烦一些—— ( 0 + 7 ) ÷ 2 = 3.5 (0+7) \div 2 = 3.5 (0+7)÷2=3.5,这里会进行向下取整,所以 中点 为 3。

    14101217182125

    对比 target a r r [ m i d ] arr[mid] arr[mid],明显能够看出 1 < 12 1 < 12 1<12,所以在下一个迭代中可以将最大值更新为 m i d − 1 mid - 1 mid1

  2. 更新 最大值最小值中点

    这里最大值 m i d − 1 mid - 1 mid1,也就是 2,最小值 依旧是数组的起点长度,也就是 0,中点 就为 1。

    14101217182125

    对比 target a r r [ m i d ] arr[mid] arr[mid],明显能够看出 1 < 4 1 < 4 1<4,所以在下一个迭代中可以将最大值更新为 m i d − 1 mid - 1 mid1

  3. 更新 最大值最小值中点

    这里最大值 m i d − 1 mid - 1 mid1,也就是 1,最小值 依旧是数组的起点长度,也就是 0,中点 就为 0.5 向下取整,还是 0。

    14101217182125

    鉴于 红+蓝=紫,所以这里将 1 的颜色更新成紫色,表示这既是起点,也是中点。

    继续对比 target a r r [ m i d ] arr[mid] arr[mid],已经找到了对应值,便可以直接返回 mid 作为 index 了。

这就是一个完整的二分搜索的流程。

二分搜索的复杂度

接下来会对时间复杂度和空间复杂度进行分析。

空间复杂度

空间复杂度是很简单的,根据上面的流程可以得知,在整个二分搜索的过程中,只需要额外存储三个变量:最大值最小值中点,也因此,空间复杂度是常量 O ( 1 ) O(1) O(1)

时间复杂度

时间复杂度是 O ( l o g ( n ) ) O(log(n)) O(log(n)),其计算方法会稍微复杂一些,现在就开始从头分析。

已知数组的长度为 n n n,每一次数组的长度都会折半,一直到数组长度为 1:

n , n 2 , n 4 , . . . 1 n, \frac{n} {2}, \frac{n} {4}, ... 1 n,2n,4n,...1

所以又可以理解成:

n × ( 1 2 ) k = 1 n \times (\frac{1}{2})^k = 1 n×(21)k=1

即, n n n 乘以 1 2 \frac{1}{2} 21 k k k 次方后的值为 1。这个方程式再简化一下就能得到:

n × 1 2 k = 1 n \times \frac{1}{2^k} = 1 n×2k1=1

最后得出:

n = 2 k n = 2^k n=2k

最后应用对数公式,自然能够得出:

k = log ⁡ 2 n k = \log_2n k=log2n

而在算法中计算空间复杂度和时间复杂度时,是可以忽略掉对数的底的这些常数的,因此时间复杂度也就可以缩写成 l o g ( n ) log(n) log(n)

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值