【发布时间】:2015-05-27 01:14:09
【问题描述】:
我在斯坦福的一张幻灯片中遇到了这个问题,如果我们将数组分成 4 个或 8 个而不是 2 个,对合并排序代码的复杂性会有什么影响。
【问题讨论】:
-
就 big-O 而言,没有什么区别。无论哪种方式,它都是 O(N log N)。对数的底数会从 2 变为 4 或 8,但对数的底数与复杂度无关。
标签: algorithm sorting mergesort
我在斯坦福的一张幻灯片中遇到了这个问题,如果我们将数组分成 4 个或 8 个而不是 2 个,对合并排序代码的复杂性会有什么影响。
【问题讨论】:
标签: algorithm sorting mergesort
应该是一样的:O(n log n)。您将有一个较短的树,并且对数的底会发生变化,但这对于 big-oh 来说并不重要,因为以 a 为底的对数与以 b 为底的对数有一个常数:
log_a(x) = log_b(x) / log_b(a)
1 / log_b(a) = constant
而且 big-oh 会忽略常量。
为了合并4 或8 或许多部分,您仍然需要在每个树级别执行O(n) 工作,这些部分与更多递归调用相结合,可能只会让整个事情变得更慢练习。
【讨论】:
通常,您可以将数组拆分为任意大小的相等大小的子数组,然后对子数组进行递归排序,然后使用最小堆从已排序子数组的集合中不断提取下一个最小元素。如果您分解的子数组的数量是恒定的,那么每个操作的每个最小堆的执行时间是恒定的,因此您到达相同的 O(n log n) 时间。
【讨论】:
直观地说,这与将数组拆分为两部分然后再次执行或从一开始将其拆分为 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]
【讨论】:
T(n)=2*T(n/2)+n 与例如直接T(n)=8*T(n/8)+3*n,肯定会看到这个。第一个似乎是n*logBase(2,n),第二个似乎是3*n*logBase(8,n)(对吗?),所以,是的。