【数据结构】课堂复习笔记6——排序
【数据结构】课堂复习笔记6——排序
Kendal学习的网课是青岛大学-王卓的数据结构与算法基础系列课程,可在bilibili上观看。并配合zjut课堂笔记整理,仅用于学习和复习
七、排序
7.1 排序概述
- 内部排序和外部排序
- 若待排序记录都在内存中,称为内部排序
- 若待排序记录一部分在内存,一部分在外存,则称为外部排序。
- 规则不同:
- 插入排序
- 交换排序
- 选择排序
- 归并排序
- 稳定性:A和B的关键字相等,排序后A、B的先后次序保持不变,则称这种排序算法是稳定的。
- 时间复杂度:
- 简单排序
- 先进排序
- 简单排序
记录序列以顺序表存储
|
7.2 插入排序
每步将一个待排序的对象,按其关键码大小,插入到前面已经排好序的一组对象的适当位置上,直到对象全部插入为止。
7.2.1 直接插入排序
顺序查找法
void InsertSort(SqList &L) |
算法分析:
- 最好情况下:
- 每趟只需比较 1 次,不移动
- 总比较次数为 n-1
- 最坏情况下:第 i 趟比较i次,移动i+1次
- 时间复杂度:
- 时间复杂度:
7.2.2 折半插入排序
void BInsertSort ( SqList &L ) |
算法分析:
- 折半查找比顺序查找快,所以折半插入排序就平均性能来说比直接插入排序要快。
- 它所需要的关键码比较次数与待排序对象序列的初始排列无关,仅依赖于对象个数。在插入第
i 个对象时,需要经过
次关键码比较,才能确定它应插入的位置 。 - 当 n 较大时,总关键码比较次数比直接插入排序的最坏情况要好得多,但比其最好情况要差
- 在对象的初始排列已经按关键码排好序或接近有序时,直接插入排序比折半插入排序执行的关键码比较次数要少
- 折半插入排序的对象移动次数与直接插入排序相同,依赖于对象的初始排列
- 减少了比较次数,但没有减少移动次数
- 平均性能优于直接插入排序
- 时间复杂度:
- 空间复杂度为
- 稳定的排序
7.2.3 希尔排序
先将整个待排记录序列分割成若干子序列,分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。
void ShellSort(SqList &L,int dlta[ ],int t){ |
算法分析:
- 如何选择最佳d序列,目前尚未解决
- 最后一个增量值必须为1,无除1以外的公因子
- 不宜在链式存储结构上实现
- 空间复杂度为 O(1)
- 是一种不稳定的排序方法
7.3 交换排序
7.3.1 冒泡排序
void main() |
- 优点:
- 每趟结束时,不仅能挤出一个最大值到最后面位置,还能同时部分理顺其他元素:一旦下趟没有交换,还可提前结束排序
void bubble_sort(SqList &L) |
- 时间复杂度为
- 空间复杂度为
- 是一种稳定的排序方法
- 最坏情况下:需 n-1趟排序,第i趟比较n-i次,移动3(n-i)次
7.3.2 快速排序
void main ( ) |
算法分析:
- 可以证明,平均计算时间是
- 实验结果表明:就平均计算时间而言,快速排序是我们所讨论的所有内排序方法中最好的一个。
- 快速排序是递归的,需要有一个栈存放每层递归调用时参数(新的low和high)
- 最大递归调用层次数与递归树的深度一致,因此,要求存储开销为
。
- 最大递归调用层次数与递归树的深度一致,因此,要求存储开销为
- 空间效率:
递归要用到栈空间 - 不稳定
7.4 选择排序
7.4.1 简单选择排序
void SelectSort(SqList &K) |
算法分析:
- 移动次数:
- 最好情况:0
- 最坏情况:3(n-1)
- 时间复杂度:O(n²)
- 空间复杂度:O(1)
- 不稳定
7.4.2 堆排序
满足:
如果将序列看成一个完全二叉树,非终端结点的值均小于或大于左右子结点的值。
- 堆的调整:
- 输出堆顶元素后,以堆中最后一个元素替代之
- 将根结点与左、右子树根结点比较,并与小者交换
- 重复直至叶子结点,得到新的堆
- 算法分析:
- 时间效率:
- 空间效率:
- 稳 定 性:不稳定
- 适用于n 较大的情况
- 时间效率:
7.5 归并排序
归并:将两个或两个以上的有序表组合成一个新有序表
- 算法分析:
- 时间效率:
- 空间效率:
- 稳定
- 时间效率:
7.6 基数排序
算法分析:
- 时间效率:
- 空间效率:
- 稳 定 性:稳定

