# @5 z( U4 }* Y% V' h- c$ t* M2 \! i0 b. E0 C
#include "stdio.h" ! T2 q: Y& g( P, y0 y7 ]5 p, q4 u. ~8 H9 {
typedef int ElemType; / {, ~+ f6 i/ n- @* I2 T0 b+ I/ G+ h
void InsertSort(ElemType a[],int n){ - G; y0 p% G, y; V, O/ a int i,j; 6 ]; Q3 [6 ?+ b! M/ X9 F for (i = 2; i <=n; i++) {6 c3 \" [% x2 G0 d- b8 P5 Z( m& Y
if (a<a[i-1]){- q4 C+ N$ {) V3 b' e" b7 Y; D
a[0]=a;, z9 E/ K( t/ {2 `8 u" k' V
for (j = i-1; a[0]<a[j]; --j)) e! ?1 b8 N h" s9 X
a[j+1]=a[j]; 1 e# H/ r; U# a j a[j+1]=a[0];' }5 V% b5 O0 S5 @3 s
} 3 _% h+ R S+ q* M8 n } ( @- d* p, y4 z" e% B6 C# J1 t} ' E9 k5 b$ C4 X9 A0 n' Rint main(){& q e, B" S. q) v3 E( P
int n; ' B. A8 ~ R1 x! j9 e% z ElemType a[n];5 ?+ }# S8 W3 u) P; C g, x! K
printf("一共有多少个数需要排序:");- O4 X3 |& r( l
scanf("%d",&n);6 u% Q" x1 c$ b/ u( a- V
printf("请输入%d个数:",n);" a% {7 ] S7 e& `1 u6 z
for (int i = 1; i <= n; ++i) {' f) ]: Z4 I8 j) j6 O2 g) H1 a
scanf("%d",&a); 0 L, T1 P- F- y# @, `- \% @% a V } . o8 L8 R2 |8 z: [ InsertSort(a,n);- {+ w: C! S0 G3 g. U
printf("排序后为:"); N( v) v. i1 z+ w9 q, K! @
for (int i = 1; i <= n; ++i) {% G( A; j8 B3 X( o. Y. A0 N
printf("%d\t",a); {; U) r! Q) Q) ^
} 4 w) |) w- s. k6 T} 6 J c9 S8 s2 |0 T" r" ^, G6 ]+ c. _ 0 B9 R! U4 a1 ?8 W1 ]( ]7 R1 . ?: R( j0 j8 x2 R6 b" E20 o8 U6 K) f- }* J7 {5 J5 n
3+ k3 a5 Z( z- i. [
4 * N$ P5 t' T" B5 5 \, [$ I( }" O" R/ J2 O6 6 V; [7 i4 `. v, |7( z( B3 C; O# J8 ?1 y+ z8 I/ Z
8" T2 r; C G G6 Z* q: H5 l
9 + @. G# p9 h& w10 - w' g! t7 p5 l* j110 g& V1 J5 M# K8 {. o
12* F/ Q( I# l9 S
13+ w2 B. r8 b/ G6 _: t; Z8 h
14 6 @; u& V: u M15 7 C/ Q6 L( @! ^( P2 A2 I3 k165 _, D f$ N9 q! v6 Y
17! Y- z( s" F" ]$ S, y/ z8 ~
18 : c' `3 Q* O5 _5 D. Z* l. h19' O9 ]6 `* }( E' N P: l2 r( u
20 $ {+ r, D! M9 x: T' w21 / }1 Q" T7 d: Y5 x! h/ O22$ |& C p. p/ N6 m) t- N
239 F8 [! v& S3 A1 n' E
24; G6 K* i) t1 x/ ?' n$ @' I
25 9 d U4 D# H# ]+ _. ^9 _' A' n: {3 A26 1 v; ]2 c; n& m: B/ _' f27* J! n* d1 n4 s G9 P. B
28 ! Y G8 p, m" C" v# s; s# c: Z* {2 t29 / Z2 u ~, m/ X! I. Q' p9 L302 \8 P# i1 h- ~0 b1 g% p
算法性能 z" q; X' ]: ?( h* ^3 q$ A' y; D
空间效率: 仅使用了常数个辅助单元,复杂度为:O ( 1 ) O(1)O(1) ! G6 t1 V# y- s5 t3 Q' d 5 W! ` x6 M$ g0 D% A# Q! w时间效率: 平均时间复杂度:O ( n 2 ) O(n^2)O(n ! X% m, d6 z. S1 i, E7 p4 U
2 $ M9 ?' y; w* Q' Z ) 7 t/ C& a- F' H+ w8 g6 M 2 C8 R) e; R" s* h5 j( J6 l 6 Z; g2 `1 w' V5 O+ ~3 v& R1 I稳定性: 由于每次插入元素时总是从后向前先比较在移动,所以不会出现相同元素相对位置发生变化的情况,即直接插入排序是一个稳定的排序方法。 # ~) ^- i3 G9 Z. F9 F! Q9 d8 t7 F$ U# P! x
适用性: 适用于顺序存储和链式存储的线性表。为链式存储时,可以从前往后查找指定元素的位置。, u6 b3 _$ R$ n" D6 Q
+ p8 c2 |; y5 g8 P/ o- d; z5 Z
1.2 折半插入排序 7 W$ k6 `8 ~- [# {2 `) B( _图解 " A% E% E* a7 d% f, o# `5 e$ H* _6 J第一趟:8 B, Z. i1 @$ _! ?* _2 z
8 \2 q. E# N, m# v+ y, Z第二趟: ' `% T$ L' Q4 q# v- ^8 t ( {5 K k% U: z 8 [" F/ E) j/ d. H/ {第三趟: ) P8 |, V5 f" m: _6 [" O7 X+ C. i8 @8 ^2 o! P& a
第四趟:略 3 P4 U* {# S+ K第五趟:略8 m; `+ {' L6 d/ D
; [, d. z3 y2 s# p. ?. v基本思想 6 b' ^# l1 J- P2 Z $ Y+ @4 C; Q6 b与直接插入排序相比较,折半插入排序引入了mid,low,high,减少比较次数。 $ ?' ]0 V. [& m% O$ U取将有序子表中间值,若a[mid]>a[0] (待排序元素),low=mid+1,反则,high=mid-1;* P+ J& w* O6 S) u
找到比a[0]大的元素,均向后移一位,将a[0]元素插入待排序子表,形成新的子表。/ D( g. M- I# l8 _6 p. R
代码 ; ]! c/ Y, w5 D. U# x' n 7 s6 _% M* k5 o0 `#include "stdio.h" 8 Z( V& @! L8 `) b 4 p/ J8 w, x% L p Y3 a6 wtypedef int ElemType; ( l+ K L: S# ] 5 h* i. F0 `6 z) }void InsertSort(ElemType a[],int n){ . {6 [8 O- h# x1 P: j8 W int low,hight,mid; 7 {+ `9 y4 z% b7 g7 J+ I) M for (int i = 2; i <= n; ++i) { 5 E$ i9 _- Q- r a[0]=a;, W3 t3 X& c) ], ^- j3 n9 z' Z# p
low=1;hight=i-1;) w7 [* \- D5 N2 \, ?
while (low<=hight){ 5 a$ x; V5 n- V2 e- X% s6 Q, i mid=(low+hight)/2;' R! l k9 S. i6 C b
if (a[mid]>a[0])hight=mid-1;- Y! o ~- {0 B' l) P$ I) h
else low=mid+1; # f& Y* k; k( B$ b( t& D; u0 O }: f k! k+ x- l4 e @
for (int j = i-1; j >= hight+1 ; --j) 1 m4 U$ z( P9 Q' f6 t a[j+1]=a[j];9 | j* C$ g2 L/ _/ E
a[hight+1]=a[0];* c s J! r V! Z+ p
}2 z) I7 f( Z) {1 O+ _, |7 ^( c, W
}: G+ u8 S8 z O9 S T
! v- v1 s& s9 |: c4 l% B& s & v, m" N2 q }- _7 ?int main(){ % J3 `, Z! O# U8 ? int n;) B; H- x: w) [
ElemType a[n];( A4 m/ g% m' L' P; V1 M$ W
printf("一共有多少个数需要排序:");: g1 V- h7 v! L9 s X
scanf("%d",&n); % F9 L. n9 ?0 N8 B/ ? B7 u printf("请输入%d个数:",n); & {& C* u9 a3 {$ z- b# V) `9 A% q for (int i = 1; i <= n; ++i) { 1 d$ n# i# y; N% ^8 G% t0 J scanf("%d",&a);& t' I/ H( f5 ]
} $ M2 N; ~% ]: o; ^ printf("排序后为:"); ) W( v8 H# w/ @& N. i" G5 g( ` InsertSort(a,n); : e2 Z4 V0 u; _% j9 `$ R6 m1 P# e* y/ N# o5 l" r# ?2 M& m" r
for (int i = 1; i <= n; ++i) {( _2 a, l$ b, ]% y* }
printf("%d\t",a);! k& y: J6 ^2 d2 R
}/ z6 w4 h. s8 a( y G& `
}; j. g' K9 i7 A' ^6 a/ [) E
4 g% [& V$ m2 [7 y% k( E; j- q
1% Y' c: |( J8 K) x
21 [, N/ p) c& y' L& Q8 P
3 9 Z/ e8 G3 E& w( C4 1 \" {7 t/ Z# I9 p1 L5, [# V/ y# ]# M
6. w, Y+ ]2 z4 k
78 F; D( I9 ]+ l0 T6 D
8( ?6 u n; G4 U; [9 Z# V0 a }
9 / Q/ M3 j8 }, i( Y6 S+ o107 I9 a6 K, ]' F' [" \
11& h; W- N4 Q9 |9 r1 R" G# n
12 & m8 r G7 P2 I13 2 @1 M3 F* Z* X0 I, I! T% ]1 N! w+ Z5 S14 + N. P/ b2 l$ ]/ \151 k0 M! W1 k. {. a; m! u6 I
162 u" V$ R+ i7 u" J( J6 @) R
17 % p5 P' L5 z: M( `6 {18/ u6 Q3 S- K, d) z
19 6 ?1 P# o: l& R+ ? J0 u1 s20 2 [, Y0 x. @9 c% `. ?8 R9 ]21 4 W% x+ E. Q# Q1 n' o' q6 }0 c22 9 S1 ]+ C+ y. N+ X# R23: l& h9 {; T0 o8 g
241 J& ^. b2 x: ^
25 6 z1 B& G; K7 O; m+ j26 3 {% ~. y C* r27 x0 b5 e6 U6 H8 |! A3 A28/ ?" g' \ O3 R8 y6 K
29 " g" X0 q' [% ^, D30 1 D" x) z2 S1 j8 t31 1 z. |: p: R( N. o; F325 Z$ r4 g! q" Q
335 _/ D2 J! j( y6 f
34$ }3 O1 ?) x1 ]6 G8 a* I* w' w" Q# ~
35 " C# i' m. y8 o6 h36 P) l" ^* N/ q( \- }. m37 " X7 o$ w7 r3 Y) `8 U2 h" K性能. m2 B( y( e! b1 A* p4 X, C7 I
* ~9 b0 \% P- s W% G A2 r
空间复杂度:O ( 1 ) O(1)O(1) " o' k' D$ _9 A* N5 Y' \$ ]9 M时间复杂度:O ( n 2 ) O(n^2)O(n & s) c) r9 g) F0 E E$ n( P
2 5 H' Q% L I' r) T0 q* f( t8 ` ) 5 L. D- b5 l$ X% U稳定性:稳定 # r3 c8 M6 E* t% H! Q$ r适用性:仅适用于顺序表 3 \- i- ?. c/ z4 b) N, f- x2 p% y# {; n5 \! ?0 N
1.3 希尔排序1 \/ }$ m0 U" i; p; q4 r4 ]
图解(动图) 5 ?9 a5 `/ G z( d 9 q3 u. ?" d+ @8 M, z' i 3 E- o3 _, S- Q: o8 C基本思想- c4 X( s5 e# H! G1 E9 _
; e- t: w" \0 z* ^7 y. x3 [先将待排序表分割成若千形如L[i,i+d,i+2d,...,i+kd] 的“特殊”子表,即把相隔某个“增量”的记录组成一个子表,对各个子表分别进行直接插入排序,当整个表中的元素已呈“基本有序”时,再对全体记录进行一次直接插入排序。1 k% D. E) ?$ r+ L3 S8 x- N. @5 w
! V- a, { }; z0 |) k代码) h6 ~2 p' W& ^; L0 O$ m) T4 d
1 z; s/ M, Q% w: O
#include "stdio.h"# t! H. r- ?( B* ~
4 |" p' i2 _. ]0 ttypedef int ElemType; 0 c* t4 I H/ c# z. Y& i2 h3 }; H 2 K" U" v0 |* p& Y3 o4 Kvoid ShellSort(ElemType a[],int n){: w6 `& Y2 G5 M
int j;. L( \* d2 b, ]/ a: {8 A( q
for (int dk = n/2; dk >= 1; dk=dk/2) { //判断每次分成几个序列,只要>=1就排序 8 M8 \9 D0 @ r( X z1 u for (int i = dk+1; i <= n; ++i) { //dk+1:取到小分队的第二个元素(从第一个元素开始)进行直接插入排序! Z, [! h, x5 U" e
if (a<a[i-dk]){ % c8 K. R4 L( v( f( i; F/ j5 {2 m a[0]=a;/ d0 ~! O. ^, n% @0 Q: O
for (j = i-dk; j > 0&&a[0]<a[j]; j-=dk) ; ~5 U- L6 e" g5 n! }9 R5 l5 o( N a[j+dk]=a[j]; 2 Y5 H8 H4 S8 @' v9 { a[j+dk]=a[0];8 ]. d" Z) |, j: C$ B' N- R
}* w1 q% Q. l$ @5 D! s& ]
} 4 ^( S, l! |6 r } & N8 S: b0 x/ R2 @+ m: B} / V- b+ o2 y4 D3 e% y2 W- Y/ O% ]# l% B3 e c* Y" A
int main(){ # E' I% t- g) R int n; 0 {& B8 T+ q/ N: L9 _. d3 n9 O4 @ ElemType a[n]; 8 R+ @0 c+ H( J5 d printf("一共有多少个数需要排序:"); $ @1 M* `3 C5 v" `+ a! B scanf("%d",&n);( K0 C" b* H+ k
printf("请输入%d个数:",n);& i7 a& h8 A9 S% O
for (int i = 1; i <= n; ++i) {9 p$ V2 R2 d) m2 \3 V! U. x
scanf("%d",&a);3 I9 s2 {' }: L8 |) }5 W0 z
} 4 m6 P) W% A2 n+ u5 X) |) f printf("排序后为:");- ^6 f! X& a! H6 o: J: ~% z
ShellSort(a,n); 9 L8 ?/ H) h7 h) L! P [9 Z U/ L) c7 @" h. h% D% ?- @% z
for (int i = 1; i <= n; ++i) {! c' y, N6 d$ E& W( J0 x5 x5 C' P; |
printf("%d\t",a);" ?* U# c) Y6 L- n. b
}( {' s# G; p! Z9 ]& g
} % T4 R: g; G8 z: B 2 j' V7 X5 ?: K# E, ]2 N1 3 x$ N* o% l& M7 v2 ' P3 W B* k# G" A3) m" `3 ]1 `7 d3 M) L9 l
4 2 @% t; P- W. u5) V$ K1 z& i5 M' p9 M4 P7 f0 J5 f: [
6 1 y# z. r6 j: [5 }7& M) g; d. J3 \5 @
8/ B' U$ l% s2 [ r' Q5 g) [: ^
9$ H$ I# T2 K! _/ k/ ~) Y
10 & E0 R; G, E8 }$ |11. k2 S5 Z7 |' r2 Z
12 # o! S8 r9 o6 M( ]% D& N+ d7 X& w: t13 " g/ l* p! d* O# a" `14 ' J$ l5 e% ?0 e) ?7 Y, ^; u+ @& j15, y2 X1 b! v" F/ F
16$ B* v/ L% c8 I5 a0 U( r
177 z9 ~2 N1 h+ `6 k( G0 y
18; r5 p6 z' X# }/ y: D: U
19 2 W' T1 F5 U* t+ v. r4 C20 $ T. Y5 O3 H/ _) k, @# l213 [- T+ ` ]& l& p
22 # p+ j, _- c; D& V239 j5 j' C, A7 }$ ?4 K- x- ~
24 5 g/ q; V& }4 y1 L( R25. p7 Z' t9 H# b( l9 W1 A
26 & a# ~! J, w/ d7 C! M27: i7 r6 i, c$ ?0 t9 j3 _! d
28 m. C4 z+ V$ Z/ X t& a- n2 D1 Q
29! x4 P- [" c0 q0 \" ]& E
30 2 m3 r* e: g9 f# i: n31 # Q( o0 S9 _" s32 b' r9 Q3 k2 z( U
33: t/ \& E/ `$ z7 G% [
34 2 |0 \" q# c- b1 n性能- u: K; @/ C1 m; r! D$ M' l' L
$ O' x2 ^ v; e* U* V, N" m" ?( u
空间效率: 仅使用了常数辅助单位,因而空间复杂度为O ( 1 ) O(1)O(1) 9 V; A) A s, X" J: x. y. u6 x2 U" ~0 O( a
时间效率: 由于希尔排序的时间复杂度依赖于增量序列的函数,这涉及数学上尚未解决的难题,所以其时间复杂度分析比较困难。当n在某个特定范围时,希尔排序的时间复杂度约为O ( n 1.3 ) O(n^{1.3})O(n + N6 m8 r& s$ ]" [1.35 R i3 {, P& k3 Q3 U6 O5 `$ q
),在最环情况下希尔排序的时间复杂度为O ( n 2 ) O(n^2)O(n * z# |/ g4 S n0 e8 X# p, \( G- q7 B2 $ _) {% H3 s. o2 k7 `* K. u )' [" [' p, @! E7 o/ s& ~+ J; D