, . , (incremental approach): .
, (divide-and-conquer approach), .
(recursive): , . . . ( , ). , .
. . . . , ( 1 ).
. Merge(A,p,q,r). p,q,r, . , p≤q<r A[p..q] A[q+1..r] , (merges) A[p..r].
(. 1.3-2), , merge (n), n (n=r-p+1). . ( ), . ? ( ) . , . , , Θ(n).
2 5 | 4 6 | 1 3 | 2 6 | |||||||||||
2 4 5 6 | 1 2 3 6 | |||||||||||||
1 2 2 3 4 5 6 6 |
. 2. = (5,2,4,6,1, 3,2,6).
|
|
Merge-Sort(A, p, r), [..r] , . ≥ r , . q, A[..q] ( [n/2 ˥ ) A[q+1..r] ( [/2˩ ). [˥ ( , ), [ ˩ , .
void Merge_Sort(Vector A, int p, int r)
{ int q;
if (p<r) {
q=(p+r)/2;
Merge_Sort(A,p,q);
Merge_Sort(A,q+1,r);
Merge(A,p,q,r); //
} // A[p..q] A[q+1,r]
}
Merge-Sort(A,1, length[A]). =length[A] , 2, 4 ( /2). . 2.
:
const int maxn=100001;
typedef int Vector[maxn];
Vector A, b;
int Merge(Vector A, int p, int q, int r)
{ int i1, i2, i;
i1=p; i2=q+1; i=p;
while (i1<=q && i2<=r) {
if (A[i1]<=A[i2]) b[i++]=A[i1++];
else b[i++]=A[i2++];
}
while (i1<=q) b[i++]=A[i1++];
while (i2<=r) b[i++]=A[i2++];
for (i=p;i<=r;i++) A[i]=b[i];
return 0;
}
? , , (recurrence equation). , .
. , n a , b . , D(n), C(n). T(n) n ( ): T(n)=aT(n/b)+D(n)+C(n). n, . , , - . n , .
, . . ( ) 0(1), 0(n).
O(1), n=1,
T(n)=
2T(n/2)+O(n), n>1.
, (n) = O(nlog n), log ( , , , ). n , 0(n2).
T(n)=2T(n/2)+n. , T(n)= O(nlog n), .., T(n)≤cnlogn >0. . [/2˩, .. T ([/2˩)≤ c [/2˩ log ([/2˩). ,
|
|
T(n)≤2(c [/2˩ log ([/2 ˩))+n≤cnlog(n/2)+n=cnlog(n)-cnlog(2)+n=cnlog(n)-cn+n≤cnlog(n).
c≥1.
, .. n. [/2˩≥ 2 n>3, c , T(n)≤cnlog(n) n=2 n=3.
clock() c #include <time.h>:
clock_t t0,tk;
t0=clock();
Merge_Sort(A,1,n);
t1=clock();
cout<<t=<<(t1-t0)/CLOCKS_PER_SEC<<endl;