使用K方式合并

时间:2017-12-22 04:32:44

标签: algorithm sorting data-structures mergesort external-sorting

有关于合并已排序文件或合并K个已排序文件的体面文献。他们都在理论上将每个文件的第一个元素放在一个堆中,然后直到堆为空轮询该元素,从该元素所在的文件中获取另一个元素。只要每个文件的一条记录可以放在堆中,就可以正常工作。

现在让我们说我有N个已排序的文件但我只能在堆中携带K个记录并且K< N,让我们说N = Kc,其中" c"是乘数意味着N是如此之大,以至于它是c的某个倍数。显然,它需要反复进行K方式合并,直到我们只剩下K个文件,然后我们将它们最后一次合并到最终排序中。我如何实现这一点以及这将是什么复杂性?

2 个答案:

答案 0 :(得分:2)

用Java编写的k-way merge有多个例子。一个是http://www.sanfoundry.com/java-program-k-way-merge-algorithm/

要实现合并,您只需编写一个简单的包装器,不断扫描您的目录,提供事物文件,直到只剩下一个。基本思路是:

while number of files > 1
    fileList = Load all file names
    i = 0
    while i < fileList.length
        filesToMerge = copy files i through i+k-1 from file list
        merge(filesToMerge, output file name)
        i += k
    end while
end while

复杂性分析

如果我们假设每个文件包含相同数量的项目,则更容易思考。

您必须合并M个文件,每个文件包含n个项目,但您一次只能合并k个文件。所以你必须做log k (M)次传球。也就是说,如果您有1,024个文件,并且一次只能合并16个文件,那么您将一次合并16个文件,共创建64个文件。然后你将创建另一个一次合并16个文件的传递,创建四个文件,最后一个传递将合并这四个文件以创建输出。

如果你有k个文件,每个文件包含n个项目,那么合并它们的复杂性是O(n * k log 2 k)。

所以在第一遍中你做了M / k合并,每个合并都有复杂度O(nk log k)。那是O((M / k)* n * k * log 2 k),或O(Mn log k)。

现在,您的每个文件都包含n k k个项目,并且每个文件都会进行M / k / k合并。因此,第二遍复杂度是O((M / k 2 )n * k 2 * log 2 k)。简化,这也是O(Mn log k)。

在第二遍中,你做k合并,每个合并都有复杂度O(nk)。 请注意,在每次传递中,您都使用M * n个项目。所以你做的每一次传球都是O(Mn log k)。你正在做log k (M)次传球。因此总复杂度为:O(log k (M)*(Mn log k))或

O((Mn log k) log M)

假设每个文件包含相同数量的项目不会影响渐近分析,因为正如我所示,每个传递操作相同数量的项目:M * n。

答案 1 :(得分:-1)

这是我的全部想法

我会在迭代中完成。首先,我会去p = floor(n / k)迭代来获得p排序文件。然后继续对p + n%k项执行此操作,直到p + n%k变得小于k。最后将获得已排序的文件。

有意义吗?