我被要求对两个文件(记录文件)应用双向合并排序, 该算法解释了以下步骤:
排序阶段 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 ++中应用这样的算法,我对如何在每一步中确定每次运行的大小感到有点困惑。
答案 0 :(得分:0)
正如Amdt Jonasson评论的那样,该程序需要跟踪每个文件的运行大小和数据结束。在您的示例中,初始运行大小显示为3个元素的固定运行大小。两次大小为3的合并将导致大小为6的单次运行,如步骤所示。在这种情况下,只需要跟踪运行大小的单个实例和每个文件中的数据结尾。
如果排序是一个稳定的排序(原始顺序保存在相同的键上),并且运行大小是可变的,那么将需要每个文件的运行计数数组,或某种方式来表示结束在文件中运行,例如文本文件,使用特殊字符序列作为运行结束指示符。
如果排序不需要稳定,则可以使用乱序序列(较大键值后的较小键值)来指示运行结束。这里的风险是,如果运行恰好按顺序进行,则两次或多次运行似乎是单次运行,这将失去稳定性并使文件的运行计数失去平衡。
这是使用3个文件的双向合并排序。如果您使用第4个文件,则每个运行合并可以在2个输出文件之间交替,从而无需在每次合并传递后拆分运行。
使用3个文件进行双向合并排序的另一种方法是多阶段合并排序,但它很复杂,可能超出了类分配所期望的范围,而且更多的是"遗产&# 34;在基于磁带的排序时代使用的算法。