, t4 D/ p" j" H" F1 g" o4 m: G第一组越界(即end1越界) `/ y, a# }' [1 ]3 w9 A$ a) [
* r# \+ W' O3 w1 k应对方法:这种情况一般介于第一层和最后一层之间,break跳出for循环,不让越界值被访问。2 D9 h/ x7 \8 G0 A6 Q, k
: s0 c7 S' I( w; ]第二组全部越界(即begin2和end2越界)6 H* b5 x! r* B2 k' X6 R9 i
8 x% \0 s5 S$ N5 `9 q8 X5 Y
应对方法:这种情况一般在第一层,break跳出for循环,不让越界值被访问。 ' M# t0 N8 S6 _9 c5 e' g2 G 6 _4 I6 w4 H; H# Q& b第二组部分越界(即end2越界) " c |$ n: Q {7 O' L4 Q( [. A! ]6 x% a% Q8 ]( \
应对方法:实际上这时候就到了最后一层了,把end2修正为sz - 1,不跳出for循环而继续归并。, s6 E9 L' i+ ^. L) b
1 n, Y2 S: I7 f/ J( y/ T, ?4 ~
其实第一种情况和第二种情况可以合并为一种情况,原因:; W( u% p8 T- h6 G. J/ R5 ?
/ b' i3 v. C0 s: t3 M" @/ l: P1 c, Y) H
end1越界时begin2和end2由于比end1大,它们两个肯定也越界了,也就是说发生第一组越界时满足end1、begin2和end2都越界,即包括了第二组越界的条件,这两种情况都满足判断条件begin2 >= sz && end2 >= sz,同时第一和第二种情况的操作都一样——break跳出for循环,所以可以合并为只判断第二组是否全部越界。 j, U& C5 l+ [5 D* y7 Q3 T
3 e1 v$ a8 O7 Y+ N2 R
拿两个数组试一下:6 ^$ V. ]! A" `
0 b( r, d4 }4 Q- G- v6 u: S) I: Y
0 L0 W. b7 @# v1 \/ t/ c- K( s) m. O
p' Z$ u* ?( [0 x8 ?2 I6 e! C' U, }8 [
7 ]* J. p. J* v6 G" f: j1 I
代码实现 4 n, H* N1 ]7 M/ l o $ K) ~* L9 f+ E4 V' f$ Ivoid MergeSortNonR(int* arr, int sz) 8 H- b0 P* U ~. w{ / K2 k0 v# u- k. ?3 S assert(arr);# B4 U1 E7 k" Z. n. Y
' ~+ q J7 w# P& M! e int* tmp = (int*)malloc(sz * sizeof(int));# v1 r6 N5 u+ |9 S. P" ?
if (tmp == NULL)$ x. h6 D T# }9 g
{ 6 o% k" \3 k4 [8 J/ G perror("malloc fail");% y. l! w0 w5 r7 r% l
return;; s q5 ~" ^2 R5 ^/ ^' z
} " e; N( ^! t1 h/ i9 Z$ Y# _* V4 M3 T1 b, Y
int gap = 1;3 g/ [9 k% [8 @
while (gap < sz) 3 j, H' L% j' L2 } { 8 }9 z( ~' S; c" t& G for (int i = 0; i < sz; i += 2 * gap) 4 a8 p2 l" \9 P# h% y) I. H) w) p { 6 n6 j4 s0 \8 e' i$ j# O6 ~ int begin1 = i, end1 = begin1 + gap - 1; # C# t4 n- b2 @, D, U3 s3 h: o int begin2 = end1 + 1, end2 = begin2 + gap - 1;9 X# f y" r2 F: ?* N! n- f. A
int j = begin1; $ G# n F& l, I% Z: M* G; q2 x7 P //越界检测 " F. e7 Y2 C& }7 P/ ~$ G) Z" I if (begin2 >= sz && end2 >= sz)3 A: ]1 \: k- ]2 S0 C" Z2 c+ k
break; 3 X& \4 l5 F" s, B* R if (end2 >= sz)8 f4 i4 w9 P% |9 ^( d$ f J& V" I
end2 = sz - 1;& Z- h* O& S8 H5 W% O
//归并 : C8 M# q$ z! c( ^2 } while (begin1 <= end1 && begin2 <= end2) ' Z$ |* j4 m$ |( e! L# P+ q% d a2 q {. u) [2 b/ W+ K$ U# g' v
if (arr[begin1] < arr[begin2])1 }. o9 A; t) t/ f5 s
tmp[j++] = arr[begin1++];# a( `/ @0 t" c1 k
else ) v7 |& b7 W w5 [! j$ ~ tmp[j++] = arr[begin2++]; 8 K2 k6 X% v G- s% n } ( m; |4 Q& D0 |* F( @5 ?2 `0 \; F $ L; _: R' h/ x9 O& Q; p0 W4 d while (begin1 <= end1) % o# W* o( b! u, D" t tmp[j++] = arr[begin1++]; ! i/ H% Q; V6 g% c+ Y2 W f. P while (begin2 <= end2) ! N" b0 x* a0 Q y" C. c tmp[j++] = arr[begin2++];6 u( M# o2 t, K3 y: X, [& m
6 v) E) V! |+ R$ a Y# _0 [* d
//拷贝回原数组——归并哪部分就拷贝哪部分回去* D7 y6 {$ m7 |/ O& _6 U
memcpy(arr + i, tmp + i, sizeof(int) * (end2 - i + 1));$ ?9 Q% D( J' C, L# w
} # {4 O1 M& y' i, \9 R2 B& Z gap *= 2; % n& G6 e! n2 }' e1 Z } 3 G7 e& G. |3 |; i8 v & c: v. `9 Z9 m1 M- R& z' e}# c' ?5 X. u; p6 |. u
$ `5 f: C" e. a4 o5 \' g
1 8 _ Q+ K: ?9 S1 R: z: N2 9 B5 g, j7 T: F$ Q R- p3 / u) x3 f# m6 d43 H8 X" N+ ~/ q' o. D# I9 D' V$ P
55 I5 a& G9 q# {
6 $ T) b2 d& M: k4 B2 T6 Q7 5 L% X/ s) j# }1 K3 R4 F; T4 [83 c7 x* r& E9 a$ l9 q( r" B
9& I# p+ U# e; o* t
10$ B+ y1 G# \5 Q# O* R
11* w) x2 N3 i3 M! n6 ?; J9 i
122 E2 h- q6 Y" V# ^/ I7 o
13 6 k0 H/ k# g1 n5 g+ V2 s, X+ M3 ^14) M& _' p' q8 b$ Q- B5 R; |% `
15 + c0 S7 E! v% B2 k t16' i2 d6 o( G; ]$ P0 |
178 R! I# R* e X( S7 H( U
18 . K0 S7 \/ Z7 e7 _$ _6 T7 Z19 ) i0 j/ L+ J' h20 : d; E! ]+ K j/ l: y. T7 n) N21: U! a/ r* E+ v$ {
227 [: G1 y8 m7 j9 Y: ]9 O0 ^7 D
232 b/ k! h4 `7 X0 |6 X
24, g% f5 r# [8 Y* {
25 + C# g3 X, @( p26 8 R. {* g Y- p( }27& z/ `' x& j I2 P4 t/ x
287 m2 r) m* y* R$ ^3 g4 | Y
29 $ m8 X1 I( E n30 4 V! A3 p# O8 |- n) M5 s: ]# G* a31 , Q) ~) s# m- ^: ?& ?; S: h9 E: Q32$ u4 R+ A& D! E6 S/ I% ~% T
33/ k; V8 J# L: d- e$ T0 ?+ S
34 ) L% b/ y$ _0 ?; n6 ?2 l5 y, g: R35 ' z# p' g1 P A( c5 e36 ! Q$ G- q9 k/ X$ ]# r; n37 0 D) e3 V: d2 P' a. j) |5 T38 " |8 w1 e' u8 ?2 Q6 _" R% S39* F2 F' [! I( v, k" c3 v" O
40 & Y7 w& |" D% [- W( \2 m" A41 : o9 E2 y1 Y) q9 F. u6 j42 $ m2 `: j2 l \+ G1 y L3 D% H; `43# F9 Q1 L% q4 \9 V
44* @% P% P# h. d* ^ m
45 1 V! ]% E; l; X1 G归并排序的特性总结:5 o; R8 C6 i5 ^% \3 I
1 _) f0 j8 K, I归并的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题。 ( ]! r. y1 k7 L7 o8 L时间复杂度:O(N*logN) 0 t. P5 Z7 P# d# ~空间复杂度:O(N)$ ?0 L5 I. P3 d, \
稳定性:稳定, B- L. S, k/ O) B