mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-05 20:24:19 +00:00
Number the H1 and H2 headings.
This commit is contained in:
@@ -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)$ 。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user