我在斯坦福大学的一张幻灯片中遇到了这个问题,如果我们将数组拆分为4或8而不是2,那么对合并代码的复杂性会产生什么影响。
答案 0 :(得分:2)
它将是相同的:O(n log n)
。你将有一个较短的树,对数的基数会改变,但这对于大哦无关紧要,因为基数a
中的对数与基数b
中的对数不同常数:
log_a(x) = log_b(x) / log_b(a)
1 / log_b(a) = constant
大哦忽略常数。
为了合并O(n)
或4
或许多部分,您仍然必须在每个树级别进行8
工作,这些部分与更多递归调用相结合,可能只会整个事情在实践中甚至更慢。
答案 1 :(得分:0)
通常,您可以将数组拆分为任意大小的相等大小的子数组,然后递归地对子数组进行排序,然后使用最小堆继续从排序的子数组的集合中提取下一个最小的元素。如果您分解的子数组的数量是常量,那么每个操作的每个最小堆的执行时间是不变的,因此您到达相同的O(n log n)时间。
答案 2 :(得分:0)
直观地说,将数组拆分成两部分,然后重新进行或从头开始将其拆分为4部分之间没有太大区别。
基于this的归纳的更正式证明(我假设数组被分成k):
Definitions:
Let T(N) - number of array stores to mergesort of input of size N
Then mergesort recurrence T(N) = k*T(N/k) + N (for N > 1, T(1) = 0)
Claim:
If T(N) satisfies the recurrence above then T(N) = Nlg(N)
Note - all the logarithms below are on base k
Proof:
Base case: N=1
Inductive hypothesis: T(N) = NlgN
Goal: show that T(kN) = kN(lg(kN))
T(kN) = kT(N) + kN [mergesort recurrence]
= kNlgN + kN [inductive hypothesis]
= kN(lg[(kN/k)] [algebra]
= kN(lg(kN) - lgk) [algebra]
= kN(lg(kN) - 1) + kN [algebra - for base k, lg(k )= 1]
= kNlg(kN) [QED]