0 M7 }$ o* |3 M0 vs o r t ( A , i ) ;0 U V6 [' y V) B% n
# x( C: ]: i O& }: ? G
s o r t ( B , j ) ; ' j, P4 X, @( e4 S; U2 d$ Q5 e$ H- a. d5 [- H
m e rge(A,B,E,i,j,); //把A 和B 合并到E3 s+ }9 U0 X) O. m% M# a: U4 l& e
$ C$ [6 M7 ?6 f5 w+ \
} 3 g, F1 I2 U& T* i! e# r 8 w/ _& Y0 w7 N: @5 Zelse 使用插入排序算法对E 进行排序8 F3 {+ p! P" G# l1 k6 r" P. A
2 c8 h i2 t5 V+ ~ x, T. Q* |0 Q1 n! R; J/ l6 ^- H
另一种二路归并排序算法是这样的:首先将每两个相邻的大小为1的子序列归并,然后对上一次归并所得到的大小为2的子序列进行相邻归并,如此反复,直至最后归并到一个序列,归并过程完成。通过轮流地将元素从a 归并到b 并从b 归并到a,可以虚拟地消除复制过程。二路归并排序算法见程序1 4 - 3。 ! x7 B( m6 y" O% c& d/ P2 Y ' Z3 m" f8 s/ S1 |$ j. r+ j程序14-3 二路归并排序 8 M9 ~* F2 k1 G2 k+ |* h% F V" g4 V7 z/ X. O+ p
template<CLASS T> 9 _) H! E- V, J2 Y/ v- }' ~ N4 {; c 3 E. O- ^: C. Lvoid MergeSort(T a[], int n) 3 o7 O! H/ G7 u0 F a; } . [4 n9 t% r- \% ]. ~{// 使用归并排序算法对a[0:n-1] 进行排序 0 b @; Z; _' g8 Q4 `- X& ?& ~. F' o3 N2 v" k
T *b = new T [n];9 S: M' e2 r. m! n k" z! f8 Q
6 G- C5 @/ t( L' S" X; r
int s = 1; // 段的大小 ' i* q9 r9 E- d, s7 p 3 T) g- Y+ J3 ewhile (s < n) {: @4 ^9 q* Z2 Z) x8 c% i& h/ i Y
0 q3 h- `* }6 g* L. P1 hMergePass(a, b, s, n); // 从a归并到b5 u6 I7 X% v; O, T% @
. M3 N$ P1 J/ N8 {; c8 o: C
s += s; / k( |! I5 Y* N7 `1 \# b1 `6 H X' [1 v
MergePass(b, a, s, n); // 从b 归并到a) ~( c3 \7 N) K& S
# h6 a1 d, H. ~4 }+ c3 b% Z: w
s += s; / z+ t4 [; d0 L, ~- \/ T& ~! H' U, n# n$ o3 o4 V
} , f2 Y' g; t8 W% K' a9 H4 U% V" r; _# Q: i& k3 m; \
} - d0 `, Z9 h( _. E5 w& j$ I 3 ^: S, H# B5 e$ |9 k% o% i为了完成排序代码,首先需要完成函数M e rg e P a s s。函数M e rg e P a s s(见程序1 4 - 4)仅用来确定欲归并子序列的左端和右端,实际的归并工作由函数M e rg e (见程序1 4 - 5 )来完成。函数M e rg e要求针对类型T定义一个操作符< =。如果需要排序的数据类型是用户自定义类型,则必须重载操作符< =。这种设计方法允许我们按元素的任一个域进行排序。重载操作符< =的目的是用来比较需要排序的域。 8 r' Q8 m# y6 v* @" i5 P( | / U3 Z! t* k( O3 Y% w" x5 B5 I7 A程序14-4 MergePass函数# B W8 S, _5 T) ?
, N/ h* f5 X2 D S! q: O. ^
template<CLASS T> U! p, d# ^; O4 m5 P1 B" d4 |1 Y/ D9 M1 Y3 v* G
void MergePass(T x[], T y[], int s, int n) * e4 X8 j# S/ p6 ] & c4 }2 I* n) i0 ~3 Y{// 归并大小为s的相邻段 |: a- s( z/ ]5 e v/ q- h$ q. p
3 p" r; {, v' }8 S' S' ^0 X ?int i = 0; ( ]9 _4 _' E, n- I% @, y0 }* H0 h& c) S. n/ }0 F8 y
while (i <= n - 2 * s) { ' J: j* f$ B; v; \8 N5 U& O 6 @$ _6 E5 f s- O( t# Y/ b// 归并两个大小为s的相邻段. |6 M: f/ I0 k
. i/ D( ^2 c) A) B3 S* KMerge(x, y, i, i+s-1, i+2*s-1); 6 O5 y3 V) O* j& Z5 E: Z6 u" M/ w 7 S) g( R! J& }i = i + 2 * s;: I3 A; {2 Q/ D! `; l' f% q
9 x0 T8 w- d, c0 {" q+ {) h
}0 K3 h T4 c8 V& R2 K% Q3 k+ U/ m# W% j ^. |
% g8 q' z/ v1 ?/ e& Q$ b$ e5 K
// 剩下不足2个元素5 A4 ?- I* s4 _5 \3 v3 z1 b
" L$ S6 p3 Z) Wif (i + s < n) Merge(x, y, i, i+s-1, n-1); - _4 H/ B) L- F7 T0 q & c% W4 {& F @else for (int j = i; j <= n-1; j++)5 T J! v8 L. e& l- |
3 T/ a; @9 K x, X+ B, _8 ]
// 把最后一段复制到y5 h$ L2 b/ m. Y) @5 u