我有一个关于合并排序的大喔的演讲,我很困惑。
显示的是:
0合并[< ----- n -------->] = n
1合并[< - n / 2 - ] [ - n / 2 --->] =(n / 2 + n / 2)= n
2合并[n / 4] [n / 4] [n / 4] [n / 4] = 2(n / 4 + n / 4)= n
....
log(n) merges = n
总=(n + n + n + ... + n)= lg n = O(n log n)
我不明白为什么(n + n + ... + n)也可以表示为n的对数基数2以及它们如何得到2次合并= 2(n / 4 + n / 4)
答案 0 :(得分:2)
在1合并的情况下,您需要对两个子数组进行排序,其中每个子数组将花费与 n / 2 成比例的时间进行排序。从这个意义上讲,要对这两个子阵列进行排序,您需要一个与 n 成比例的时间。
类似地,当您进行2次合并时,有4个子阵列要进行排序,其中每个子阵列的时间与 n / 4 成正比,这将再次总结为 n < /强>
同样,如果您有 n 合并,则需要与 n 成比例的时间来对所有子数组进行排序。从这个意义上说,我们可以将合并排序所花费的时间写成如下。
T(n)= 2 * T(n / 2)+ n
你会理解这个递归调用可以深入(比如 h 的高度)直到n/(2^h) = 1
。通过在此处记录,我们得到 h = log(n)。这就是log(n)来到场景的方式。此处日志取自基地2。
由于您有 log(n)步骤,其中每个步骤的时间与 n 成比例,因此总时间可以表示为,
n * log(n)
在大O符号中,我们将其作为上限O(nlog(n))
。希望你明白了。
答案 1 :(得分:1)
在您的问题中写下以下部分的最后一行,
0合并[&lt; ----- n --------&gt;] = n
1合并[&lt; - n / 2 - ] [ - n / 2 ---&gt;] =(n / 2 + n / 2)= n
2合并[n / 4] [n / 4] [n / 4] [n / 4] = 2(n / 4 + n / 4)= n
...
n merges = n - 这行不正确!
错了。您将不会有n个大小为n的合并,但Log n合并大小为n。
在每个级别,您将问题大小划分为两个大小一半的问题。当你继续潜水时,你可以做的总分是Log n。 (怎么样?假设可能的总分为x。那么n = 2 x 或x = Log 2 n。)
因为在每个级别你都做了O(n)的总工作,所以对于Log n级别,所有完成的工作的总和将是O(n Log n)。
答案 2 :(得分:0)
你的树有一个深度的log(n)和n的宽度。 :)
答案 3 :(得分:0)
日志部分的结果是“在我只剩下一个元素之前,我可以将数据分成两部分?”这是递归树的深度。 n的倍数来自这样一个事实:对于树中的每个级别,您将在该级别的所有合并步骤之后查看数据集中的每个元素。
recurse downwards:
n unsorted elements
[n/2][n/2] split until singletons...
...
merge n elements at each step when recursing back up
[][][]...[][][]
[ ] ... [ ]
...
[n/2][n/2]
n sorted elements
答案 4 :(得分:0)
这非常简单。如您所示,每次合并都需要O(n)。您需要执行的合并数是log n(基数2),因为每个合并都会使排序部分的大小加倍。