合并排序随机拆分

时间:2015-02-11 18:30:36

标签: algorithm sorting data-structures time-complexity

在Mergesort算法中,不是将数组拆分成相等的一半,而是尝试在每次调用中从随机点拆分数组,我想计算这个算法的平均时间?

我们的笔记将其计算为正常的合并排序。任何正式的想法?

2 个答案:

答案 0 :(得分:2)

以下是时间复杂度为O(n log n)的证明(它不是很正式)。

  1. 如果最大部分的大小最多为初始子阵列的3/4,那么让我们调用分裂“好”(它看起来是这样的:bad bad good good good good bad bad表示具有8个元素的数组)。分裂为好的概率是1/2。这意味着在两个分裂中我们期望一个两个“好”。

  2. 让我们绘制一个递归合并排序调用树:

        [a_1, a_2, a_3, ..., a_n]    --- level 1
             /             \
    [a_1, ..., a_k]   [a_k + 1, a_n] --- level 2
        /    \            /  \
    ...                              --- level 3
    
                                     ...
    
                                     --- level m   
    

    很明显,每个级别最多有n个元素,因此时间复杂度为O(n * m)

  3. 但是1)。表示级别数为2 * log(n, 4 / 3),其中log(a, b)a基数b的对数,即O(log n)

  4. 因此,时间复杂度为O(n * log n)

答案 1 :(得分:0)

我假设您正在谈论递归合并排序。

在标准合并排序中,您将阵列分割在中点,因此您最终会在每个级别(大多数)使用相同大小的子阵列。但是如果你在其他地方分裂,那么除了在病态情况下,你仍然会得到几乎相同数量的子阵列。

以这种方式看待:标准合并排序的分而治之的方法导致log n"等级"排序,每个级别包含所有n个项目。您可以在每个级别进行n次比较以对子阵列进行排序。那是n log n来自的地方。

如果您随机拆分阵列,那么您必须拥有更多级别,但并非所有级别都处于所有级别。也就是说,较小的子阵列在较长的子阵列之前产生单项阵列。因此,并非所有项目都在算法的所有级别进行比较。这意味着某些项目的比较频率高于其他项目,但平均,每个项目的比较时间为log n次。

所以你真正要问的是,给定N个分成k个排序数组的项目总数,如果每个k个数组的长度相同,而不是k个数组是不同的长度。

答案是否定的。无论单个数组的长度如何,合并k个排序数组中的N个项都需要相同的时间。有关示例,请参阅How to sort K sorted arrays, with MERGE SORT

所以问题的答案是,使用随机拆分进行递归合并排序的平均情况(以及最好的情况)将是O(n log n),堆栈空间使用情况O(log n)。最坏的情况,只有当你的随机拆分总是将数组拆分成一个包含单个项的子数组,而另一个包含剩余部分时,才需要O(n)堆栈空间,但仍然只有O(n log n)时间。

请注意,如果使用迭代合并排序,则时间和空间使用不会有渐近的差异。