Merge branch 'krahets:master' into master

This commit is contained in:
Daniel
2023-01-09 11:05:01 +11:00
committed by GitHub
93 changed files with 2147 additions and 1124 deletions

View File

@@ -210,6 +210,12 @@ $$
}
```
=== "Swift"
```swift title="binary_search.swift"
```
### “左闭右开”实现
当然,我们也可以使用“左闭右开”的表示方法,写出相同功能的二分查找代码。
@@ -374,6 +380,12 @@ $$
}
```
=== "Swift"
```swift title="binary_search.swift"
```
### 两种表示对比
对比下来,两种表示的代码写法有以下不同点:
@@ -460,6 +472,12 @@ $$
int m = i + (j - i) / 2;
```
=== "Swift"
```swift title=""
```
## 复杂度分析
**时间复杂度 $O(\log n)$ ** 其中 $n$ 为数组或链表长度;每轮排除一半的区间,因此循环轮数为 $\log_2 n$ ,使用 $O(\log n)$ 时间。
@@ -470,11 +488,11 @@ $$
二分查找效率很高,体现在:
- **二分查找时间复杂度低** 对数阶在数据量很大时具有巨大优势,例如,当数据大小 $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)$ ,也是非常昂贵的。
- **二分查找仅适用于数组** 由于在二分查找中,访问索引是 ”非连续“ 的,因此链表或者基于链表实现的数据结构都无法使用。
- **在小数据量下,线性查找的性能更好** 在线性查找中,每轮只需要 1 次判断操作;而在二分查找中,需要 1 次加法、1 次除法、1 ~ 3 次判断操作、1 次加法(减法),共 4 ~ 6 个单元操作;因此,在数据量 $n$ 较小时,线性查找反而比二分查找更快。
- **二分查找仅适用于有序数据**如果输入数据是无序的,为了使用二分查找而专门执行数据排序,那么是得不偿失的,因为排序算法的时间复杂度一般为 $O(n \log n)$ ,比线性查找和二分查找都更差。再例如,对于频繁插入元素的场景,为了保持数组的有序性,需要将元素插入到特定位置,时间复杂度为 $O(n)$ ,也是非常昂贵的。
- **二分查找仅适用于数组**由于在二分查找中,访问索引是 ”非连续“ 的,因此链表或者基于链表实现的数据结构都无法使用。
- **在小数据量下,线性查找的性能更好**在线性查找中,每轮只需要 1 次判断操作;而在二分查找中,需要 1 次加法、1 次除法、1 ~ 3 次判断操作、1 次加法(减法),共 4 ~ 6 个单元操作;因此,在数据量 $n$ 较小时,线性查找反而比二分查找更快。

View File

@@ -95,6 +95,12 @@ comments: true
}
```
=== "Swift"
```swift title="hashing_search.swift"
```
再比如,如果我们想要给定一个目标结点值 `target` ,获取对应的链表结点对象,那么也可以使用哈希查找实现。
![hash_search_listnode](hashing_search.assets/hash_search_listnode.png)
@@ -179,6 +185,12 @@ comments: true
}
```
=== "Swift"
```swift title="hashing_search.swift"
```
## 复杂度分析
**时间复杂度:** $O(1)$ ,哈希表的查找操作使用 $O(1)$ 时间。

View File

@@ -133,6 +133,12 @@ comments: true
```
=== "Swift"
```swift title="linear_search.swift"
```
再比如,我们想要在给定一个目标结点值 `target` ,返回此结点对象,也可以在链表中进行线性查找。
=== "Java"
@@ -261,6 +267,12 @@ comments: true
}
```
=== "Swift"
```swift title="linear_search.swift"
```
## 复杂度分析
**时间复杂度 $O(n)$ ** 其中 $n$ 为数组或链表长度。
@@ -269,6 +281,6 @@ comments: true
## 优点与缺点
**线性查找的通用性极佳** 由于线性查找是依次访问元素的,即没有跳跃访问元素,因此数组或链表皆适用。
**线性查找的通用性极佳**由于线性查找是依次访问元素的,即没有跳跃访问元素,因此数组或链表皆适用。
**线性查找的时间复杂度太高** 在数据量 $n$ 很大时,查找效率很低。
**线性查找的时间复杂度太高**在数据量 $n$ 很大时,查找效率很低。