CS415 数据结构与算法

Chapter 8 Sorting

| 关于   «  8. 希尔排序   ::   目录   ::   10. 实现归并排序  »

9. 归并排序概念

9.1. 归并排序概念

解决问题的一种自然方法是分治。 在排序时运用分治,我们可以考虑把待排序的线性表拆成若干片段, 分别处理,然后再以某种方式把它们重新组合起来。 一个简单的做法是把线性表一分为二,对两半分别排序,再把排好序的 两半归并起来。 这就是 归并排序 背后的思想。

从概念上讲,归并排序是最简单的排序算法之一, 无论是在渐近意义下还是在实验运行时间上都表现良好。 遗憾的是,尽管它基于一个简单的概念, 在实践中实现起来却相对困难。 下面是归并排序的伪代码梗概:

List mergesort(List inlist) {
  if (inlist.length() <= 1) return inlist;; List L1 = inlist 中一半的项;List L2 = inlist 中另一半的项;return merge(mergesort(L1), mergesort(L2));
}

下面这个可视化演示了归并排序的工作原理。

归并排序中最难理解的一步是归并函数。 归并函数先检查每个子线性表的首条记录, 并挑出较小的值作为整体上最小的记录。 这个较小的值从其子线性表中取出,放入输出线性表。 归并就这样继续下去:比较各子线性表的首记录, 不断把较小的那条追加到输出线性表,直到不再有输入记录为止。

下面是对线性表执行归并的伪代码:

List merge(List L1, List L2) {
  List answer = new List(); while (L1 != NULL || L2 != NULL) {
    if (L1 == NULL) { // 已完成 L1
      answer.append(L2); L2 = NULL;
    } else if (L2 == NULL) { // 已完成 L2
      answer.append(L1); L1 = NULL;
    } else if (L1.value() <= L2.value()) {
      answer.append(L1.value()); L1 = L1.next();
    } else {
      answer.append(L2.value()); L2 = L2.next();
    }
  } return answer;
}

下面是对归并操作的可视化。

Settings

Proficient Saving... Error Saving
Server Error
Resubmit

下面是一个归并排序热身练习,用来练习归并。

9.2. 归并排序练习

现在给出一个完整的熟练度练习,把所有内容综合起来。

这个可视化给出了归并排序的运行时间分析。

Settings

Proficient Saving... Error Saving
Server Error
Resubmit

   «  8. 希尔排序   ::   目录   ::   10. 实现归并排序  »

关闭窗口