Number the H1 and H2 headings.

This commit is contained in:
Yudong Jin
2023-01-31 03:37:50 +08:00
parent dbbc1adc4f
commit eb0afc98ec
44 changed files with 263 additions and 257 deletions
+6 -6
View File
@@ -2,7 +2,7 @@
comments: true
---
# 快速排序
# 11.4. 快速排序
「快速排序 Quick Sort」是一种基于“分治思想”的排序算法,速度很快、应用很广。
@@ -263,7 +263,7 @@ comments: true
哨兵划分的实质是将 **一个长数组的排序问题** 简化为 **两个短数组的排序问题**。
## 算法流程
## 11.4.1. 算法流程
1. 首先,对数组执行一次「哨兵划分」,得到待排序的 **左子数组** 和 **右子数组**;
2. 接下来,对 **左子数组** 和 **右子数组** 分别 **递归执行**「哨兵划分」……
@@ -412,7 +412,7 @@ comments: true
}
```
## 算法特性
## 11.4.2. 算法特性
**平均时间复杂度 $O(n \log n)$** :平均情况下,哨兵划分的递归层数为 $\log n$ ,每层中的总循环数为 $n$ ,总体使用 $O(n \log n)$ 时间。
@@ -426,7 +426,7 @@ comments: true
**自适应排序**:最差情况下,时间复杂度劣化至 $O(n^2)$ 。
## 快排为什么快?
## 11.4.3. 快排为什么快?
从命名能够看出,快速排序在效率方面一定“有两把刷子”。快速排序的平均时间复杂度虽然与「归并排序」和「堆排序」一致,但实际 **效率更高**,这是因为:
@@ -434,7 +434,7 @@ comments: true
- **缓存使用效率高**:哨兵划分操作时,将整个子数组加载入缓存中,访问元素效率很高。而诸如「堆排序」需要跳跃式访问元素,因此不具有此特性。
- **复杂度的常数系数低**:在提及的三种算法中,快速排序的 **比较**、**赋值**、**交换** 三种操作的总体数量最少(类似于「插入排序」快于「冒泡排序」的原因)。
## 基准数优化
## 11.4.4. 基准数优化
**普通快速排序在某些输入下的时间效率变差**。举个极端例子,假设输入数组是完全倒序的,由于我们选取最左端元素为基准数,那么在哨兵划分完成后,基准数被交换至数组最右端,从而 **左子数组长度为 $n - 1$、右子数组长度为 $0$** 。这样进一步递归下去,**每轮哨兵划分后的右子数组长度都为 $0$** ,分治策略失效,快速排序退化为「冒泡排序」了。
@@ -652,7 +652,7 @@ comments: true
}
```
## 尾递归优化
## 11.4.5. 尾递归优化
**普通快速排序在某些输入下的空间效率变差**。仍然以完全倒序的输入数组为例,由于每轮哨兵划分后右子数组长度为 0 ,那么将形成一个高度为 $n - 1$ 的递归树,此时使用的栈帧空间大小劣化至 $O(n)$ 。