我遇到了这段代码,在链接列表上执行合并排序。 作者声称它及时运行O(nlog n).. 这是它的链接...... http://www.geeksforgeeks.org/merge-sort-for-linked-list/ 我的主张是它需要至少O(n ^ 2)时间...这是我的论点...... 看,你划分列表(是数组或链表),记录n次(参考递归树),在每个分区期间,给定一个大小列表i = n,n / 2,...,n / 2 ^ k,我们将花费O(i)时间对原始/已经分割的列表进行分区。因为sigma O(i)= O(n),我们可以说,我们需要花费O(n)时间对任何给定的调用进行分区分区(sloppily),所以考虑到执行单个分区所花费的时间,现在出现的问题是总共会发生多少个分区,我们观察到每个级别i的分区数等于2 ^ i ,所以求和2 ^ 0 + 2 ^ 1 + .... + 2 ^(lg n)给出[2(lg n)-1]作为总和,它只是(n-1)简化,暗示我们称分区为n-1,(让它近似为n),时间如此,复杂性至少是n ^ 2的大欧米茄。 如果我错了,请让我知道...谢谢:)。
然后在一些回顾之后,我将主方法应用于递归关系,其中我替换了1的theta,对于这种类型的合并排序,对于具有theta为n的数组的传统合并排序(因为除法和组合操作取每个n次的θ,运行时间结果为(n lg n)... 我也注意到每个级别的成本是n(因为2次幂i *(n /(2pow i)))...是每个级别所需的时间...所以它在每个级别的n的θ为* lg n知道它的theta of(n lg n).....我只是解决了我自己的问题吗?请帮助我有点困惑自己..
答案 0 :(得分:4)
大小为n的输入列表的递归复杂性定义是
T(n) = O(n) + 2 * T(n / 2)
扩展这个我们得到:
T(n) = O(n) + 2 * (O(n / 2) + 2 * T(n / 4))
= O(n) + O(n) + 4 * T(n / 4)
我们再次扩展:
T(n) = O(n) + O(n) + O(n) + 8 * T(n / 8)
显然这里有一种模式。由于我们可以完全重复这个扩展O(log n)次,我们有
T(n) = O(n) + O(n) + ... + O(n) (O(log n) terms)
= O(n log n)
答案 1 :(得分:0)
出于某些奇怪的原因,你正在两次执行任务。
要拆分和合并大小为n的链表,需要O(n)时间。递归的深度是O(log n)
您的论点是分裂步骤需要O(i)时间,分割步数之和变为O(n)然后您将其称为仅执行一次分割所花费的时间。
相反,让我们考虑一下,大小为n的问题形成两个n / 2问题,四个n / 4问题八个n / 8等等,直到形成2 ^ log n n / 2 ^ logn子问题。总结这些你得到O(nlogn)来执行拆分。 另一个O(nlogn)结合子问题。