证明优化mergesort的运行时间是theta(NK + Nlog(N / K))?

时间:2011-01-31 07:04:12

标签: java performance mergesort recurrence

好的,我知道Mergesort的最佳情况是theta(NlogN),但它的开销很高,并且显示在递归树底部附近进行合并。有人建议我们一旦大小达到K就停止递归并在那时切换到插入排序。我需要证明这个修正的递归关系的运行时间是theta(NK + Nlog(N / k))?我想知道如何解决这个问题。

1 个答案:

答案 0 :(得分:3)

也许一个好的开始是看看这个问题的递归关系。我想,对于典型的mergesort,它看起来像这样:

T(N) = 2 * T(N / 2) + N

即。您将问题分成两个大小的子问题,然后执行N工作(合并)。我们有一个需要一段时间的基础案例。

将此建模为我们拥有的树:

T(N)   =   N   ->   T(N / 2)   
               ->   T(N / 2)

       =   N   ->   (N / 2)   ->   T(N / 4)
                              ->   T(N / 4)
               ->   (N / 2)   ->   T(N / 4)
                              ->   T(N / 4)

这扩大了

T(N) = N + 2N/2 + 4N/4 + ...
     = N + N + N ...

所以我们真的只需看看它有多深。我们知道i级别在子问题N / 2^i上运行。所以我们的叶子节点(T(1))出现在L所在的N / 2^L = 1级:

N / 2^L = 1
N = 2^L
log N = log(2^L)
log N = L

所以我们的运行时是N log N

现在我们介绍插入排序。我们的树看起来像这样

T(N) = ... -> I(K)
           -> I(K)
             ...x N/K

换句话说,我们会在某个级别L解决大小为N/K的{​​{1}}插入排序问题。插入排序的最坏情况运行时为K。所以在叶子上我们有很多工作总计

K^2

但是我们也有一堆合并要做,如前所述,每个级别的树的成本为(N / K) * I(K) = (N / K) * K * K = N * K 。回到我们之前的方法,让我们找到N(在我们达到大小为L的子问题之前的级别数,从而切换到插入):

K

总的来说我们有

N / 2^L = K
N / K = 2^L
L = log (N/K)

我用算法给你一张校样草图已经太久了,但这会让你的神经元发射。