归并排序
-
基本思想:将两个或两个以上的有序子序列“归并”为一个有序序列。
-
在内部排序中,常采用2-路归并排序。
- 即,将两个位置相邻的有序子序列R[l…m]和R[m+1…n]归并为一个有序序列R[l…n]。
-
例子:初始序列为{48,34,60,80,75,12,26,48*}
方法:
上图是一个倒着的树(归并树),总共需要 ⌈ log 2 n ⌉ \left\lceil {\log _2^n} \right\rceil ⌈log2n⌉趟(树的深度)。 -
关键问题:如何将两个有序序列合并成一个有序序列?
方法:可以参考前面线性表合并有关内容。有序表合并。
但在归并排序中,有序表的合并有特殊性,因为归并排序里需要合并的两个有序表是连续的,即有序表R[low]-R[mid]和R[mid+1]-R[high]相邻,归并成一个有序序列的步骤如下图,
-
性能分析
- 时间效率: O ( n l o g 2 n ) O(nlog2n) O(nlog2n)。
- 空间效率: O ( n ) O(n) O(n),因为需要一个与原始序列同样大小的辅助序列,这也正是此算法的缺点。
- 稳定性:稳定。
基数排序
-
基本思想:分配+收集
也叫桶排序或箱排序:设置若干个箱子,将关键字为k的记录放入第k个箱子(分配),然后再按序号将非空的连接(收集)。 -
基数排序:数字是有范围的,均由0-9这十个数字组成,则只需设置十个箱子,相继按个、十、百…进行排序。
-
例子:对如下序列排序{614,738,921,485,637,101,215,530,790,306}
方法:
1.第一趟分配(按个位排) 和第一趟收集如下图,
此时,个位就已经变的有序了。
2.第二趟分配(按十位排)和第二趟收集如下图,
此时,十位就已经变的有序了。
3.第三趟分配(按百位排)和第三趟收集如下图,
此时,百位就已经变的有序了,结束。 -
性能分析
- 时间效率:
O
(
k
∗
(
n
+
m
)
)
O(k*(n+m))
O(k∗(n+m))
其中,k:关键字个数;m:关键字取值范围为m个值。 - 空间效率: O ( n + m ) O(n+m) O(n+m)
- 稳定性:稳定
- 时间效率:
O
(
k
∗
(
n
+
m
)
)
O(k*(n+m))
O(k∗(n+m))