李春葆《数据结构教程》(第4版)笔记和课后习题详解(外排序)【圣才出品】

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第11章外排序

11.1 复习笔记

一、外排序概述

文件存储在外存上,因此外排序方法与各种外存设备的特征有关。外排序的基本方法是归并排序法。它分为以下两个步骤:

1.生成若干初始归并段(顺串)

将一个文件(含待排序的数据)中的数据分段读入内存,在内存中对其进行内排序,并将经过排序的数据段(有序段)写到多个外存文件上。

2.多路归并

对这些初始归并段进行多遍归并,使得有序的归并段逐渐扩大,最后在外存上形成整个文件的单一归并段,也就完成了这个文件的外排序。

二、磁盘排序

1.磁盘排序概述

磁盘是直接存取设备,读/写一个数据块的时间与当前读/写头所处的位置关系不大,存放在磁盘中的文件的排序属典型的外排序。

磁盘排序过程如图11-1所示.

图11-1 磁盘排序过程

磁盘中的F in文件包括待排序的数据,通过相关算法将F in文件中数据一部分一部分地调入内存(每个记录被读一次)处理,产生若干个文件F1~F n(每个记录被写一次),它们都是有序的,称为顺串。然后再次将F1~F n文件中的记录调入内存(每个记录被读一次),通过相关归并算法产生一个有序的F out文件(每个记录被写一次),从而达到数据排序的目的。

可见,提高排序速度很重要的一个方面是减少对数据的扫描遍数。

2.生成初始归并段

使用置换—选择的排序算法用于生成较长的初始归并段。

采用置换—选择排序算法生成初始归并段时,内排序基于选择排序,即从若干个记录中通过关键字比较选择一个最小的记录,同时在此过程中进行记录的输入和输出,最后生成若干个长度可能各不相同的有序文件。基本步骤如下:

(1)从待排序文件F in中按内存工作区WA的容量(设为w)读入w个记录,设归并段编号i=1;

(2)从WA中选出关键字最小的记录R min;

(3)将R min 记录输出到文件F i 中,作为当前归并段的一个成员;

(4)若F in 不空,则从F in 中读入下一个记录到WA 中替代刚输出的记录;

(5)从WA 工作区中所有大于或等于R min 的记录中选择出最小记录作为新的R min ,转(3),直到选不出这样的R min ;

(6)置i=i+1,开始一个新的归并段;

(7)若WA 工作区已空,则初始归并段已全部产生,否则转(2)。

置换-选择排序算法所生成的初始归并段的长度既与内存工作区的大小有关,也与输入文件中记录的排列次序有关。

3.多路平衡归并

(1)k 路平衡归并的效率分析

归并过程基本上是二路平衡归并的过程。一般说来,如果初始归并段有m 个,那么这样的归并树就有

⎡⎤1log 2+m 层,要对数据进行⎡⎤m 2log 遍扫描。类似地,采用k 路平衡归并时,则相应的归并树有⎡⎤1log 2+m 层,要对数据进行s=⎡⎤m 2log 遍扫描,显然,k 越大,磁盘读写次数越少。

在进行内部归并时,在k 个记录中选择最小者,需要进行k-1次关键字比较。每趟归并u 个记录需要做(u-1)×(k-1)次关键字比较,则s 趟归并总共需要的关键字比较次数为:

⎡⎤⎡⎤⎡⎤k k u m k u m k u s k k 2log /)1()1(log )

1()1(log )1()1(-⨯-⨯=-⨯-⨯=-⨯-⨯

在初始归并段个数m 与记录个数u 一定时,其中的⎡⎤)1(log 2-⨯u m 是常量,而⎡⎤k k 2log /)1(-在k 增大时趋于无穷大。因此,增大归并路数k ,会使内部归并的时间增

加,若k增大到一定的程度,就会抵消掉由于减少磁盘读写次数而赢得的时间。也就是说,在k路平衡归并中,并非k越大,归并的效率就越高。

(2)k路平衡归并过程

利用败者树实现k路平衡归并的过程是,先建立败者树,然后对k个输入有序段进行k 路平衡归并。

败者树是一棵有k个叶子节点的完全二叉树,其中叶子节点存储记录,分支节点存放关键字对应的段号。对k个有序段进行k路平衡归并的方法如下:

①取每个输入有序段的第一个记录作为败者树的叶子节点,建立初始败者树:叶子节点之间两两比较,在双亲节点中记录比赛的败者(关键字较大者),而让胜者去参加更高一层的比赛,如此,在根节点上胜出的“冠军”是关键字最小者;

②胜出的记录写至输出归并段,在对应的叶子节点处,补充输入有序段的下一个记录,若该有序段变空,则补充一个关键字大(比所有记录关键字都大,设为k max)的虚记录;

③调整败者树,选择新的关键字最小的记录:从补充记录的叶子节点向上和双亲节点的关键字比较,败者留在该双亲节点,胜者继续向上,直至树的根节点,最后将胜者放在根节点的双亲节点中;

④若胜出的记录关键字等于k max,则归并结束,否则转②继续。

当采用败者树实现多路平衡归并时,只要内存空间允许,增大归并路数k,可以有效地减少归并树的深度,从而减少读写磁盘的次数,提高外排序的速度。

4.最佳归并树

归并树是描述归并过程的k次树。因为每一次做k路归并都需要有k个归并段参加,因此,归并树是只包含度为0和度为k的节点的标准k次树。

最佳归并树是带权路径长度最短的k次(阶)哈夫曼树,构造步骤如下:

(1)若(m-1)mod(k-1)≠0,则需附加(k-1)-(m-1)mod(k-1)个长度为0的虚段,以使每次归并都可以对应k个段;

(2)按照哈夫曼树的构造原则(权值越小的节点离根节点越远)构造最佳归并树。

在前面的例子中,m0=11,k=3,(11-1)mod(3-1)=0,可以不加空归并段,直接进行3路归并。

三、磁带排序

1.多路平衡归并排序

先对输入文件的各段进行内排序,生成初始归并段,再把它们写到磁带上,然后再把这些归并段进行反复的归并,直到只剩下一个归并段为止。

采用多路归并能够减少扫描的遍数,但对磁带排序来说,多路归并需要多台磁带,为了避免过多的磁带寻找时间,要归并的归并段需要放在不同的磁带上。

2.多阶段归并排序

多阶段归并排序实际上是多路非平衡归并排序,即各条带上的归并段不再保持平衡分布。它在k路归并中仅使用(k+1)条磁带,就可避免在多路平衡归并排序法中遇到的重新分布有序段的问题。开始时,初始归并段不平衡地分配在前k条磁带上,第(k+1)条磁带作为输出带,开始为空。每一步归并只是部分记录参加,归并段最少的带在本步归并完成后便成为空带,作为下一步归并的输出带。这样,(k+1)条磁带将轮流成为输出带,直到整个文件为一个排序文件为止。

11.2 课后习题详解

相关文档
最新文档