我对合并排序中合并函数的运行时分析有些困惑。
Merg(A,p,q,r)
1 n1=q-p+1
2 n2=r-q
3 let L[1..n1+1] and R[1..n2+1] be new arrays
4 for i=1 to n1
5 L[i] = A[p+i-1]
6 for j =1 to n2
7 R[j] = A[q+j]
8 L[n1+1] = infinity
9 R[n2+1] = infinity
10 i =0
11 j=0
12 for k=p to r
13 if L[i]<=R[j]
14 A[k]=L[i]
15 i=i+1
16 else A[k] = R[j]
17 j=j+1
在我的书中它说明如下:要看到合并程序在O(n)时间运行,其中n = r-p + 1,观察第1-3和8-11行中的每一行占用恒定时间,第4-7行的for循环取O(n1 + n2)= O(n)时间,并且有12行第17行的迭代,每次都需要恒定的时间
我的问题是为什么第12-17行每次迭代需要不变的时间而不影响运行时间 第4-7行不需要花费恒定的时间。对我来说,似乎两个循环都在做同样的事情。有人可以帮我澄清这个吗?谢谢!
答案 0 :(得分:1)
第1行到第9行只是将输入(A
)分成两部分(L
和R
)。第10行和第11行正在进行一些初始化以准备合并。合并本身来自第12-17行。
IOW,第12行之前的所有内容(或可以说 10,而不是真正重要)与分析 merge 无关,因为它们都不是合并的一部分一点都不。
编辑:但是,最终,从1到27的单次迭代是线性的:在第4-7行中,您只需在输入数组中走一次,将每个输入恰好分配给L或R.在第12-27行中然后,您将浏览这两个部分,并将它们复制回原始输入。忽略其他一些小细节,例如初始化i
和j
,操作总数正好是2N。对于big-O表示法,常数因子被忽略,因此它是O(N)。
答案 1 :(得分:1)
这是令人困惑的写作。两个循环(4-7和12-17)具有相同的长度(n),并且两个循环的内部是恒定时间(没有嵌套循环)。所以他们每个都是O(n),总共O(n)为整个例程。
关于杰瑞的答案,第4-7行很重要因为它们仍然是O(n)。如果你能够神奇地删除第12-17行,你仍然有一个O(n)程序。