2文件c ++的双向合并排序

时间:2018-04-06 13:29:51

标签: c++ sorting merge mergesort

我被要求对两个文件(记录文件)应用双向合并排序, 该算法解释了以下步骤:

  

排序阶段   1)要排序的文件上的记录分为几组。   每个组称为运行,每个运行都适合主存。   2)对每次运行应用内部排序,3)并将生成的排序运行分发到两个外部文件。

     

合并排序:1)从排序阶段创建的每个外部文件中运行一次,合并为更大的排序记录。   2)结果存储在第三个文件中。   3)数据被分发回前两个文件,并且合并继续,直到所有记录都在一个大的运行中。

我只能应用Sort Phase,所以当前文件是: (假设运行只包含3个键)

  

文件1:   50 95 110 | 40 120 153 | 22 80 140

     

文件2:   10 36 100 | 60 70 130

这里是合并阶段的步骤 所以如果我能解决它理论上会执行以下操作:

合并阶段:

第1步:

文件3:  10 36 50 95 100 110 | 40 60 70 120 130 153 | 22 80 140

文件1: 10 36 50 95 100 100 | 22 80 140

文件2: 40 60 70 120 130 153

第2步:

文件3: 10 36 40 50 60 70 95 100 110 120 130 135 | 22 80 140

文件1: 10 36 40 50 60 70 95 100 110 120 130 135

文件2:  22 80 140

第3步:

文件3: 10 22 36 40 50 60 70 80 95 100 110 120 130 135 140

一次停止排序完成

现在我需要应用合并阶段,以便每个文件中的每个密钥相互比较并输出较小的文件3,并在步骤2中将文件3重新分配到两个文件中然后合并并排序,直到有一个排序运行

我如何在c ++中应用这样的算法,我对如何在每一步中确定每次运行的大小感到有点困惑。

1 个答案:

答案 0 :(得分:0)

正如Amdt Jonasson评论的那样,该程序需要跟踪每个文件的运行大小和数据结束。在您的示例中,初始运行大小显示为3个元素的固定运行大小。两次大小为3的合并将导致大小为6的单次运行,如步骤所示。在这种情况下,只需要跟踪运行大小的单个实例和每个文件中的数据结尾。

如果排序是一个稳定的排序(原始顺序保存在相同的键上),并且运行大小是可变的,那么将需要每个文件的运行计数数组,或某种方式来表示结束在文件中运行,例如文本文件,使用特殊字符序列作为运行结束指示符。

如果排序不需要稳定,则可以使用乱序序列(较大键值后的较小键值)来指示运行结束。这里的风险是,如果运行恰好按顺序进行,则两次或多次运行似乎是单次运行,这将失去稳定性并使文件的运行计数失去平衡。

这是使用3个文件的双向合并排序。如果您使用第4个文件,则每个运行合并可以在2个输出文件之间交替,从而无需在每次合并传递后拆分运行。

使用3个文件进行双向合并排序的另一种方法是多阶段合并排序,但它很复杂,可能超出了类分配所期望的范围,而且更多的是"遗产&# 34;在基于磁带的排序时代使用的算法。