什么是排序
- 排序就是对数据元素的逻辑顺序或物理顺序的一种重新排列。
- 排成非递减(递增)顺序称作正序,排成非递增(递减)顺序称作逆序。
- 排序的依据是排序码(可重复),即元素或记录中的用于作为排序依据的项。
排序的确切定义如下:
假设含
n
n
n个记录的序列为
{
R
1
,
R
2
,
.
.
.
,
R
n
}
\{R_1,\ R_2,\ ... \ ,\ R_n\}
{R1, R2, ... , Rn},其相应的关键字序列为
{
K
1
,
K
2
,
.
.
.
,
K
n
}
\{K_1,\ K_2,\ ...\ ,\ K_n\}
{K1, K2, ... , Kn}。
需要确定一种排列
p
1
,
p
2
,
.
.
.
,
p
n
p_1, p_2, ..., p_n
p1,p2,...,pn,使其相应的关键字满足如下非递减(或非递增)的关系
K
p
1
≤
K
p
2
≤
.
.
.
≤
K
p
n
K_{p_1}≤ K_{p_2}≤ ... ≤K_{p_n}
Kp1≤Kp2≤...≤Kpn
即原序列成为一个按关键字有序的序列
{
R
p
1
,
R
p
2
,
.
.
.
,
R
p
n
}
\{R_{p_1}, \ R_{p_2},\ ...\ ,\ R_{p_n}\}
{Rp1, Rp2, ... , Rpn}
排序算法的稳定性
若待排表中有两个元素 R i R_i Ri和 R j R_j Rj,其对应的关键字 k e y i = k e y j key_i = key_j keyi=keyj,且在排序前 R i R_i Ri在 R j R_j Rj前面,若使用某一排序算法排序后, R i R_i Ri仍然在 R j R_j Rj前面,则称这个排序算法是稳定的,否则称排序算法是不稳定的。
需要注意的是,算法是否具有稳定性并不能衡量一个算法的优劣,它主要是对算法的性质进行描述。
排序算法的时间代价和空间代价
排序算法的时间代价包括两类:
- 排序过程中关键码的比较次数
- 元素移动次数
一般数据移动比关键码比较需花费更多的时间。
各种排序算法的基本存储空间都是
n
n
n (假定待排元素有
n
n
n个)。
算法空间代价分析主要考虑附加空间的数量,即排序过程需要多少额外的存储空间。
- 附加空间使用多的排序算法将占用更多的存储资源
- 原地排序的算法在排序过程中只需 O ( 1 ) O(1) O(1)的附加存储空间,结果仍在原来存储。
排序的分类
在排序过程中,根据元素是否完全在内存中,可将排序算法分为两类:内部排序和外部排序。
- 内部排序:是指在排序期间元素全部存放在内存中的排序
- 外部排序:是指在排序期间元素无法全部同时存放在内存中,必须在排序的过程中根据要求不断地在内、外存之间移动的排序。
一般情况下,内部排序算法在执行过程中都要进行两种操作:比较和移动。
排 序 { 内 部 排 序 { 插 入 排 序 { 直 接 插 入 排 序 折 半 插 入 排 序 希 尔 排 序 交 换 排 序 { 冒 泡 排 序 快 速 排 序 选 择 排 序 { 简 单 选 择 排 序 堆 排 序 归 并 排 序 基 数 排 序 外 部 排 序 — — 多 路 归 并 排 序 排序\begin{cases} 内部排序 \begin{cases} 插入排序 \begin{cases} 直接插入排序\\ 折半插入排序\\ 希尔排序\\ \end{cases}\\ \\ 交换排序 \begin{cases} 冒泡排序\\ 快速排序\\ \end{cases}\\ \\ 选择排序 \begin{cases} 简单选择排序\\ 堆排序\\ \end{cases}\\ \\ 归并排序\\ \\ 基数排序\\ \end{cases}\\ \\ 外部排序——多路归并排序\\ \end{cases} 排序⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧内部排序⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧插入排序⎩⎪⎨⎪⎧直接插入排序折半插入排序希尔排序交换排序{冒泡排序快速排序选择排序{简单选择排序堆排序归并排序基数排序外部排序——多路归并排序