排序(数据结构)
同样是复习总结。
基本概念
概念:就是重新排列列表中的元素,使表中的元素满足按关键字递增或递减的过程。
算法的稳定性:简单来说就是原本列表中的两个相同元素经过排序算法后,如果没有发生位置变化,则称该算法是稳定的;反之则不稳定。
注:
1.算法是否具有稳定性并不能衡量一个算法的优劣,它主要是对算法的性质进行描述。
2.对于不稳定的排序算法,只需举出一组关键字的实例,说明它的不稳定性即可。
排序根据数据元素是否完全在内存中,可分为内部排序和外部排序。
内部排序:在排序期间元素全部存放在内存中的排序。
外部排序:在排序期间元素无法全部同时存放在内存中,必须在排序过程中根据要求不断地在内、外存之间移动的排序。
在今天只是对内部排序进行复习。
- 内部排序的操作:比较和移动。(并不是所有的内部排序算法都要基于比较,例如:基数排序)
- 内部排序算法的性能却决于算法的时间复杂度和空间复杂度,而时间复杂度一般是由移动的次数来决定的。
直接插入排序(插入排序)
算法
1 | //直接插入排序 |
性能分析
- 空间效率:
O(1)
- 时间效率:
O(n²)
- 稳定性:稳定
- 适用性:顺序储存和链式储存
折半插入排序(插入排序)
算法
1 | //折半插入排序 |
性能分析
- 空间效率:
O(1)
- 时间效率:
O(n²)
- 稳定性:稳定
- 适用性:顺序储存
希尔排序(插入排序)
算法
1 | //希尔排序 |
性能分析
- 空间效率:
O(1)
- 时间效率:
O(n²)
- 稳定性:不稳定
- 适用性:顺序储存
冒泡排序(交换排序)
算法
1 | //冒泡排序 |
性能分析
- 空间效率:
O(1)
- 时间效率:
O(n²)
- 稳定性:稳定
- 适用性:顺序储存
- 特点:每一趟排序都会将一个元素放置到其最终的位置上。
快速排序(交换排序)
算法
1 | //快速排序 |
性能分析
- 空间效率:最坏情况
O(n)
;平均情况O(log2n)
- 时间效率:
O(n²)
- 稳定性:不稳定
- 适用性:顺序储存
- 特点:每一趟排序都会将一个元素放置到其最终的位置上。
简单选择排序(选择排序)
算法
1 | //简单选择排序 |
性能分析
- 空间效率:
O(1)
- 时间效率:
O(n²)
- 稳定性:不稳定
- 适用性:顺序储存
堆排序(选择排序)
- 这是一种树形选择排序方法,特点:子啊排序过程中,将L[1…n]看成是一棵完全二叉树的顺序储存结构,利用完全二叉树中双亲结点和孩子节点之间的内在关系,在当前无序区中选择关键字最大(或最小)的元素。
- 小根堆(小定堆)
- 大根堆(大定堆)
建立大根堆的算法
1 | //建立大根堆 |
向下调整算法
1 | //向下调整算法 |
向上调整算法
1 | //向上调整算法 |
堆排序的算法
1 | // 堆排序算法 |
性能分析
- 空间效率:
O(1)
- 时间效率:
O(nlog2n)
- 稳定性:不稳定
- 适用性:顺序储存
归并排序
Merge算法
1 | //Merge函数 |
排序算法
1 | //排序算法(2路) |
性能分析
- 空间效率:
O(n)
- 时间效率:
O(nlog2n)
- 稳定性:稳定
- 适用性:顺序储存
基数排序
性能分析
- 空间效率:
O(r)
(r是队列的个数) - 时间效率:
O(d(n+r))
(特点:跟序列的初始状态无关) - 稳定性:稳定
- 适用性:顺序储存
各种排序的比较及应用
各种排序算法的性质
算法种类 | 时间复杂度 | 空间复杂度 | 是否稳定 | ||
最好情况 | 平均情况 | 最坏情况 | |||
直接插入排序 | O(n) | O(n²) | O(n²) | O(1) | 是 |
冒泡排序 | O(n) | O(n²) | O(n²) | O(1) | 是 |
简单选择排序 | O(n²) | O(n²) | O(n²) | O(1) | 否 |
希尔排序 | O(n²) | O(n²) | O(n²) | O(1) | 否 |
快速排序 | O(nlog2n) | O(nlog2n) | O(n²) | O(log2n) | 否 |
堆排序 | O(nlog2n) | O(nlog2n) | O(nlog2n) | O(1) | 否 |
2-路归并排序 | O(nlog2n) | O(nlog2n) | O(nlog2n) | O(n) | 是 |
基数排序 | O(d(n+r)) | O(d(n+r)) | O(d(n+r)) | O(r) | 是 |
排序算法的应用
(1)选取排序方法需要考虑的因素:
- 待排序的元素数目n
- 元素本身信息量的大小
- 关键自结构及其分布情况
- 稳定性的要求
- 语言工具的条件,存储结构及辅助空间的大小
(2)排序算法小结:
若n(n<=50)较小,则可以采用直接插入排序和简单选择排序。当记录本身信息量较大的时候,用简单选择排序较好。
若文件的初始状态已关键字基本有序,则选用直接插入或冒泡排序为宜。
若n较大,则采用时间复杂度为
O(nlog2n)
的排序方法:快速排序、堆排序、归并排序。快速排序被认为是目前基于比骄傲的每部排序法中最好的方法。(不稳定)
堆排序所需的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况。(稳定)
当追求稳定时,可以采用归并排序。但通常不提倡2-路归并,而是将它和直接插入排序结合在一起使用。直接插入排序是稳定的,因此改进后的归并排序仍是稳定的。
当文件的n个关键字随机分布时,任何借助“比较”的排序算法,至少需要
O(nlog2n)
的时间。当n很大,记录的关键字位数较少且可以分解时,采用基数排序较好。
当记录本身信息量较大时,为避免耗费大量时间移动记录,可用链表作为存储结构。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 人间一趟!
评论