mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-06 20:54:19 +00:00
build
This commit is contained in:
@@ -4,7 +4,7 @@ comments: true
|
||||
|
||||
# 6.1. 二分查找
|
||||
|
||||
「二分查找 Binary Search」是一种基于分治思想的高效搜索算法。它利用数据的有序性,每轮减少一半搜索范围,实现定位目标元素。
|
||||
「二分查找 Binary Search」是一种基于分治思想的高效搜索算法。它利用数据的有序性,每轮减少一半搜索范围,直至找到目标元素或搜索区间为空为止。
|
||||
|
||||
我们先来求解一个简单的二分查找问题。
|
||||
|
||||
@@ -22,7 +22,7 @@ comments: true
|
||||
|
||||
**若数组不包含目标元素,搜索区间最终会缩小为空**,即达到 $i > j$ 。此时,终止循环并返回 $-1$ 即可。
|
||||
|
||||
为了更清晰地表示区间,我们在下图中以折线图的形式表示数组。
|
||||
如下图所示,为了更清晰地表示区间,我们以折线图的形式表示数组。
|
||||
|
||||
=== "<0>"
|
||||

|
||||
@@ -50,8 +50,6 @@ comments: true
|
||||
|
||||
值得注意的是,**当数组长度 $n$ 很大时,加法 $i + j$ 的结果可能会超出 `int` 类型的取值范围**。为了避免大数越界,我们通常采用公式 $m = \lfloor {i + (j - i) / 2} \rfloor$ 来计算中点。
|
||||
|
||||
有趣的是,理论上 Python 的数字可以无限大(取决于内存大小),因此无需考虑大数越界问题。
|
||||
|
||||
=== "Java"
|
||||
|
||||
```java title="binary_search.java"
|
||||
@@ -105,6 +103,7 @@ comments: true
|
||||
i, j = 0, len(nums) - 1
|
||||
# 循环,当搜索区间为空时跳出(当 i > j 时为空)
|
||||
while i <= j:
|
||||
# 理论上 Python 的数字可以无限大(取决于内存大小),无需考虑大数越界问题
|
||||
m = (i + j) // 2 # 计算中点索引 m
|
||||
if nums[m] < target:
|
||||
i = m + 1 # 此情况说明 target 在区间 [m+1, j] 中
|
||||
@@ -533,12 +532,12 @@ comments: true
|
||||
|
||||
## 6.1.2. 优点与局限性
|
||||
|
||||
二分查找效率很高,主要体现在:
|
||||
二分查找在时间和空间方面都有较好的性能:
|
||||
|
||||
- **二分查找的时间复杂度较低**。对数阶在大数据量情况下具有显著优势。例如,当数据大小 $n = 2^{20}$ 时,线性查找需要 $2^{20} = 1048576$ 轮循环,而二分查找仅需 $\log_2 2^{20} = 20$ 轮循环。
|
||||
- **二分查找无需额外空间**。与哈希查找相比,二分查找更加节省空间。
|
||||
- **二分查找的时间效率高**。在大数据量下,对数阶的时间复杂度具有显著优势。例如,当数据大小 $n = 2^{20}$ 时,线性查找需要 $2^{20} = 1048576$ 轮循环,而二分查找仅需 $\log_2 2^{20} = 20$ 轮循环。
|
||||
- **二分查找无需额外空间**。相较于需要借助额外空间的搜索算法(例如哈希查找),二分查找更加节省空间。
|
||||
|
||||
然而,并非所有情况下都可使用二分查找,原因如下:
|
||||
然而,二分查找并非适用于所有情况,原因如下:
|
||||
|
||||
- **二分查找仅适用于有序数据**。若输入数据无序,为了使用二分查找而专门进行排序,得不偿失。因为排序算法的时间复杂度通常为 $O(n \log n)$ ,比线性查找和二分查找都更高。对于频繁插入元素的场景,为保持数组有序性,需要将元素插入到特定位置,时间复杂度为 $O(n)$ ,也是非常昂贵的。
|
||||
- **二分查找仅适用于数组**。二分查找需要跳跃式(非连续地)访问元素,而在链表中执行跳跃式访问的效率较低,因此不适合应用在链表或基于链表实现的数据结构。
|
||||
|
||||
Reference in New Issue
Block a user