" A3 C( L {$ c o" v7 i先将待排序表分割成若千形如L[i,i+d,i+2d,...,i+kd] 的“特殊”子表,即把相隔某个“增量”的记录组成一个子表,对各个子表分别进行直接插入排序,当整个表中的元素已呈“基本有序”时,再对全体记录进行一次直接插入排序。8 }0 y' e! t E* q# e
0 {3 u. c0 H4 ^# H; r' M' P/ G: L代码 / ?9 T: D p3 K& o+ A' j R8 j2 Z9 N2 c
#include "stdio.h"( z1 A3 @2 ^1 Z6 n3 O$ M
( z+ h# l7 U# _% a. @0 F Y8 z# Z8 @typedef int ElemType; 9 q9 n6 d- ~" o1 M& w6 P {; P& h* U$ x( Q5 ~
void ShellSort(ElemType a[],int n){ 2 t1 d) |3 x! p* [1 Y" K int j; ! W% @# x( h- M8 K: v: m% K5 t for (int dk = n/2; dk >= 1; dk=dk/2) { //判断每次分成几个序列,只要>=1就排序0 z) `1 \# ]$ ^3 j- ] H9 ?" c
for (int i = dk+1; i <= n; ++i) { //dk+1:取到小分队的第二个元素(从第一个元素开始)进行直接插入排序! R% W" J4 i: p% h' v- f2 u
if (a<a[i-dk]){1 s! H' ~. l/ P" Y4 M
a[0]=a;$ D: y: D" a9 i4 {' D
for (j = i-dk; j > 0&&a[0]<a[j]; j-=dk) 7 L: M; ?# g5 ` a[j+dk]=a[j]; 3 H0 A6 U$ k& L' j3 d, g E a[j+dk]=a[0]; & e" F. z- H! h# e2 f% V6 [ }' B( c2 c( P3 C4 |/ x, O
}, `! U3 H e' T- b8 y1 W. p) G- D
} ! q, Z, Q5 e/ L8 t& M} 2 N, n2 L t1 n! m3 C2 a 1 x- G, m) b% @5 f; l. B7 a; Y/ xint main(){ * L$ T# R8 k6 u* t) ~ int n;4 B5 K* q4 Q" g7 J! N( o
ElemType a[n]; " R7 A" `- i+ Y9 @, s. f/ ?; n' V: I printf("一共有多少个数需要排序:");1 a+ k0 |: V$ A& k" R/ n8 B7 g3 T: l
scanf("%d",&n); " P( n2 T" E" r6 S9 C printf("请输入%d个数:",n); 9 y8 w; ~/ z% \+ X& o for (int i = 1; i <= n; ++i) {# f. }7 p7 z7 ^0 ]8 F, @
scanf("%d",&a); ' `0 A- M. G( D9 \& ` } $ a( {, u( D j printf("排序后为:"); 1 h4 O( I# j. u. K ShellSort(a,n);# P$ e# m- Y3 {9 M0 u# i
; d1 D9 \8 n+ K6 Y
for (int i = 1; i <= n; ++i) { % J2 a) g7 q4 u" ` printf("%d\t",a); 8 ?) W( S, g" Q } 0 y& X' s+ ?- e. k) {6 |( @}* R d5 i' B1 Y6 O
# g3 L/ ]& u: _4 N/ u19 d. A9 } E" i8 U7 Q' U$ w4 J
2 * `7 r9 c4 p4 |/ R6 }3 5 h O4 v7 q0 \# z& J% c) ?/ E4& O0 F* \" P1 V3 l: w7 u! Y2 q' w
57 r$ X, }- x9 n
6 + l. g9 {0 H/ d- \8 X5 I7 ' J/ V, R$ M" R& e# M3 k0 K n( z8 8 M1 a: l, m$ K/ ?/ X8 v9. P" c" L7 `) ]
10( W. l c S9 [2 M- C
11 : j' H- P3 N7 F6 a* _' S12$ M( b$ m3 d# V+ \; e8 c
13 9 T- s) O- X9 u* f5 s# ^7 H. C: }147 F8 ~9 ~: l0 y7 |& B
156 w" B5 e9 h2 F' @. s' M0 V9 o, h
16 6 C ]$ u$ c5 s3 j/ b S9 R F! g! k17 4 a: G( z5 h s4 z0 T9 A181 I% ~3 `/ ]/ Q4 n7 |" j2 k0 X- \
19; C A' F( \' W% F& J( G4 N) D
209 w. O8 l; R U' C6 `1 M
21 2 @5 u% G2 X) i" X220 S I( \4 \" I& ?3 P
23% }; |7 m1 S( v( p
243 }& T7 `* s* }; \! \) i ~5 S
25 ! T7 w% W1 m3 P L) W6 n3 i26 . |6 K4 F3 s. N+ f9 I- C) I27 |8 P- I/ r9 n- Z28* z1 j5 N: s* ?" [
29$ {" k6 `0 M- s
30' r) Y* `, I# H/ r% U
31# }4 l0 |4 x; A: \' N
32. R7 h3 y- D. w) e( M
33 + c: e# U: s0 v; s% ~. k& n/ ^349 f1 v. j* K4 j/ t- u$ C$ D: r) L' W
性能 8 {: Q1 v( t4 s( K) X0 U , T# y; R2 r8 C0 Z7 o& |空间效率: 仅使用了常数辅助单位,因而空间复杂度为O ( 1 ) O(1)O(1)6 c4 N4 S& H2 G7 L
+ T$ D% w( R# W5 b时间效率: 由于希尔排序的时间复杂度依赖于增量序列的函数,这涉及数学上尚未解决的难题,所以其时间复杂度分析比较困难。当n在某个特定范围时,希尔排序的时间复杂度约为O ( n 1.3 ) O(n^{1.3})O(n 6 j0 R5 M! c8 C' y1 n: g4 O
1.3* O! E: } T1 M* B5 o
),在最环情况下希尔排序的时间复杂度为O ( n 2 ) O(n^2)O(n 5 \# }# @) |- |% E% ~
2 ' G$ e9 V! }. v5 q% P' v; H ) " }4 B0 n8 K% [$ D( O6 Z + K! ] _$ B/ l0 {8 g& u% B稳定性: 当相同关键字的记录被划分到不同的子表时文可能会改变它们之间的相对次序,因此希尔排序是一种不稳定的排序方法。' Y: [* w! N; m, ^
- B- _* D/ d# e b i# r0 ?" K$ Q& T2 T* \' {% s# G
适用性: 希尔排序算法仅适用于线性表为顺序存储的情况。 b7 B1 H, R9 `+ }) `
+ S3 J' p0 o: Q7 ~8 I. W+ I
2. 交换排序 # I5 Y, Q! e6 K0 W2.1 冒泡排序 # K4 K1 h2 y: q5 o$ j! O图解* z5 b x) G% u) \! h7 }$ v4 p& O