文章目录 8 N% W- ?% v& G2 A7 X4 l) f) l1.数据结构的定义 4 ~) w% R3 F3 G# |) q: v. M2 线性表 ) }& F& q) J) V2 y! a/ B6 w2 O" W2 s X3 顺序表& l9 r% y! `! V/ O+ t4 b3 x
3.1 概念及结构5 M- j$ J5 m" e; l( _
3.2 接口实现8 U8 a% _6 l {% v+ Y) Z
3.3 顺序表的问题及思考4 O7 O( R( J7 w6 }! d$ z
4 链表 3 ?) K; O' ?) q1 [5 L4.1 链表的概念及结构: S) P7 b! }+ r4 d& i9 ]- ^
4.2 链表的分类; C' V$ ~/ z; f9 z6 ]' w& l7 p
4.3 单向无头链表的实现 & w2 A D3 Y6 Z, \8 h# U4.4 顺序表和链表的区别 2 n3 R. X, D- U& j7 N8 P6 G( N; J5 栈" i9 y X }9 ~7 Y& [2 s [, p
5.1 栈的概念及结构 ( d3 v" c3 U0 {+ z! a$ q- P5.2 栈的实现/ J+ [8 _$ g6 q4 z
6 队列) z& R5 Z9 C3 S; G9 B' j
6.1 队列的概念及结构2 S% [( V* N5 s
6.2 队列的实现 ) M2 o8 z$ n c4 @! I4 {6 A/ O7 k7 树 2 x0 y0 h. |; a: F$ r4 X7.1 树的概念 % p8 {1 k; j) o: v0 Q7 M. R7.2 树的相关概念& p" [8 f$ |1 h/ v7 ]9 o
7.3 树的表示& T* g4 o; ~0 c* U6 E0 r2 P
7.4 树在实际中的运用(表示文件系统的目录树结构) ( t$ m1 J- e& u0 Q8 二叉树 9 q) T6 Z! Y7 F; C" x8.1 二叉树概念5 O; [2 ^4 o& j- A( e' v
8.2 特殊的二叉树 - S) ]; f( a0 t" X7 f8.3 二叉树的存储结构) l8 k1 I. @" Y, N. _
8.4 二叉树的顺序结构 1 L u7 j2 Y- p8.5 二叉树的链式结构 " d( g$ I4 u4 M9 O8.5.1 二叉树的遍历 # h1 W7 ?1 k% X" ?7 C7 h8.5.1.1 前序、中序以及后序遍历5 P' D; z7 ~* @4 p" k& _; x
8.5.1.2 层序遍历5 P# b5 A9 A- \. V8 g% D+ W5 g0 B
9 堆) C8 o- H- {0 T1 c, u
9.1 堆的概念及结构" w2 t; |+ ~% a9 Y5 s0 e1 O3 S) f
9.2 堆的实现+ r6 z3 w O: P* k# g, o
9.2.1 堆向下调整算法 4 y8 g0 h. v. O/ v. U% Q& l; {+ ^, I" l9.2.2 堆的构建/ E) A. J; \; l v# E
9.2.3 堆的代码实现 / j- Z1 E3 M. M9.3 堆的应用 3 v! ~4 }, R6 g9.3.1 堆排序 & ~4 n3 s$ ~% U: f7 P7 r9 n/ n) S9.3.2 TOP-K问题 & s" Z* o/ z7 M+ i' }3 m1.数据结构的定义+ r" t" P9 b0 r8 I R
数据结构是一种具有一定逻辑关系,在计算机中应用某种存储结构,并且封装了相应操作的数据元素的集合。 8 O2 q9 U& I6 B$ S: L8 p$ l6 d - V6 }4 d& l: J" G+ e% O7 V' Q, n4 k数据结构和数据库的区别? 6 g$ ?9 b, b" h8 W J* G9 a2 n' [数据结构是在内存中操作数据,数据库是在外存中操作数据。 % p0 s) ?" }1 m+ L6 K9 w! Z1 t' Z$ L7 @& H; P. s
2 线性表$ v% B- b% P6 j- I, c P
线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串… 9 R* @- P1 b* T% P% j2 o线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储: Q# i1 T' ]% M" M2 u# L/ f/ x
3 顺序表 . R: Q6 l0 r; i3 u% y5 b t2 t3 d6 W3.1 概念及结构 ( h1 T3 B" L) P6 ]7 |" t顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。 ! b4 q% k; D0 O% q5 G0 p. U' _! T
顺序表可以分为:8 ]+ ?) _; A! b1 e7 z% o- I8 P# }% _/ N
8 r8 T3 V! u" O/ W! t f& g
静态顺序表:使用定长数组存储元素。# ^1 B4 J5 n& U: n. f5 X
动态顺序表:使用动态开辟的数组存储。3 C, |4 B7 E& B) A
4 b5 v0 v$ O% z' Y* ^3.2 接口实现 ; D: v# h! i4 L$ M2 w; j静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。 % W( |# K; W, Y7 `( U' o7 K) } 9 V1 ^( w+ v3 B; R" P$ C$ p+ H! qtypedef int SLDataType;0 i2 J6 s' v3 \- u: s! ^( N
// 顺序表的动态存储 ; u4 l' L0 _5 q; Y8 [typedef struct SeqList 0 {) k+ p# I' Y$ j! Y/ J4 Q1 z{ 8 o m7 h" W c7 x8 O# a SLDataType* array; // 指向动态开辟的数组 ' O8 U' q' C' N% i3 y size_t size ; // 有效数据个数" R& J9 D7 ]) C% a! E( F2 h, ~
size_t capicity ; // 容量空间的大小 5 i- s' b/ C$ C$ B) Y}SeqList;) A$ h. N9 o; M! ~* L6 S. n2 Z6 x
// 基本增删查改接口+ e B7 j8 F" x Q4 J) f
// 顺序表初始化3 A$ P+ s. \' q m
void SeqListInit(SeqList* psl); 0 |( g: M2 c: v3 f9 r! b+ g// 检查空间,如果满了,进行增容7 h, b5 V& T. m. H! }3 d
void CheckCapacity(SeqList* psl);1 P5 ]2 g& B) |" x3 M
// 顺序表尾插0 z; P2 g/ W8 q; i
void SeqListPushBack(SeqList* psl, SLDataType x);7 R! e& A+ ]8 U( \- y
// 顺序表尾删4 |, x. k; {1 w* C. v6 n6 G
void SeqListPopBack(SeqList* psl); & ?5 ]6 a1 }$ C% m. I2 S// 顺序表头插 ; @& G% F/ ?" W) S6 {, cvoid SeqListPushFront(SeqList* psl, SLDataType x);: i% J" q9 {9 v6 a
// 顺序表头删 * ^5 A1 q: S9 T" d/ avoid SeqListPopFront(SeqList* psl);, H* }: H; \- C) e5 e
// 顺序表查找 + N$ x. Q) ~ w G: A. wint SeqListFind(SeqList* psl, SLDataType x);# V: `" j( {0 @# U
// 顺序表在pos位置插入x0 m+ x/ A* n" a. Z( A1 `
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);! f9 l7 ~3 a& I/ b
// 顺序表删除pos位置的值( S6 r7 u+ h1 F# [
void SeqListErase(SeqList* psl, size_t pos); ( W; o# h; c1 j+ w, Q- i( B// 顺序表销毁6 M9 e! e" `" J) Y. l
void SeqListDestory(SeqList* psl);; g6 B: o$ ]! d$ b( ?' `
// 顺序表打印 7 g. V* f( }0 ~1 I; Avoid SeqListPrint(SeqList* psl);7 B- W9 U1 `* C% h8 H; y- v' ]
5 j0 a0 ~+ ~$ G/ M9 e
15 c4 \; X3 d, G, X3 G; {3 D" X8 d9 N
2 9 y9 ^7 }0 V9 t! V8 {3 ) G- v4 } N% o4 G4 d6 }, R4 ( Q6 R# }0 D% D) P8 D58 ]: O3 K7 d& F3 R! _4 T
6 . V3 ~% b: J& z, F# [' |7% r9 n# O% X @# L' W
8. l8 ~6 e! r. Y8 D
9 % I, `1 u/ K9 J! y10 ( Q% H5 K) l6 g* R' W9 y( w11 & I" i9 i2 ^4 j7 ]12 7 ~, W e( G# v. V; G13 6 |$ C8 j, g' v14 % n- U# N9 e" ^$ }. F' q15: ]1 N* n+ D' ?% h, f
16" M* s/ _ Y9 V, \5 t
17; v! ?0 t( r- |: U: W. V. X" B( _
180 V& P5 d: c: S* t' Q( a0 `+ y
19 & o3 V) R) i; H7 i( X20 2 Z8 N: A( S( K x0 n1 A; R. e" e21# u; O# _1 w% {8 T+ q
22 " w% u, Q" _# _6 A, W23 ' o1 n0 e+ X) C5 h N24 9 w/ @( g _3 B25! I8 D3 r4 T5 Z7 h+ W. z
267 e; f! a* G2 x6 Y0 _2 q' A. H0 m6 e; ?
27 : y1 J; W! m; }: i9 g28 8 r; P) h4 E5 ]" R( J29 $ |+ |( r0 |6 a% b303 Z3 ~- C( s ?& a4 @( @$ U
317 F: u: B) {4 L9 P% u' l3 j6 c
void SeqListInit(SeqList* ps)/ q ^! \3 p9 w% X8 I1 P, K
{ & u- V7 Z5 N. G- o assert(ps); : q6 ~) F: }2 S9 c( o- X" a# O6 q! \5 ` f# F
ps->a = NULL;* {, ?1 _+ w3 X
ps->size = 0;$ l* Y( Q" ~8 i. P3 ^$ E
ps->capacity = 0;; A5 q- D) H2 n4 o
}5 W3 w/ V) l" U8 G6 G+ Y8 {: V
; C0 j8 ~. p0 ivoid SeqListDestroy(SeqList* ps)- e5 D) p3 v* D3 S
{ 6 `" O# p: Y4 P# P M7 P) H assert(ps);. L h! J- M; d7 Y9 I, @ r/ y+ p9 ^
free(ps->a);: I; a+ u, v; n/ M5 `
ps->a = NULL;/ j- e |0 ~& Y7 f4 U+ P" W( t
ps->size = ps->capacity = 0;0 }2 r+ G7 B) p0 R$ b3 G* Z
}! j" y4 t- E6 ~* ?8 b
0 T' A; h3 F) m
void SeqListPrint(SeqList* ps)& b' C4 K: A, E( q2 f7 s
{8 e8 w8 o( X6 ^* N, w
assert(ps);' }# A/ N' B, f: ?) [7 I
4 i. x3 J; ^/ l* Y, r B for (size_t i = 0; i < ps->size; ++i)3 _* B: c) D/ X& q1 M4 ], _- I
{ 0 a. F) Q1 T7 I( w7 q; g printf("%d ", ps->a[i]); / Z7 m" i% p+ U }) G8 }$ O( C$ ]8 a8 L
5 R+ Q! V# S" [9 U4 B- _
printf("%\n");( z+ @' [3 r5 r" G2 ]) {
} 2 m8 O& K& B3 H4 l) v5 `$ R& y3 S( T2 G
void CheckCacpity(SeqList* ps)+ P5 k5 k6 q) E8 B, Q. Y
{ $ d( |$ @4 g) k0 `) g if (ps->size == ps->capacity) - b: q! `5 v A( h {5 m! ]: S) N& { p% C% a
size_t newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;4 V& w6 {9 m; ?% x9 w/ d( m
ps->a = (SLDateType*)realloc(ps->a, newcapacity*sizeof(SLDateType)); ) K$ a( R4 R) [% {. l ps->capacity = newcapacity;) Q: J X N8 m% a
} + l, t+ O) A+ B0 y$ M% y" L} * @$ O; q5 q _) s2 H) ?+ T6 K/ H6 [% I6 N5 U+ W$ C1 h
// 以下几个接口先讲不复用Insert和Erase的实现,最后再讲复用实现2 G& F7 j; r/ S5 O
void SeqListPushBack(SeqList* ps, SLDateType x) # l1 ~0 p: d2 H2 v ?* [{ 2 U1 {( x5 j1 S: D //assert(ps); # I; Z( c! \, a& l( r* Q2 c7 Z //CheckCacpity(ps); 2 \. h% i; b2 G7 \) y* Q, a7 S; N$ G! ?7 A4 v) f. h: x0 G
//ps->a[ps->size] = x; ; j/ D4 }7 F" M- D& W //ps->size++; + E4 v" j4 I# W8 f: I: B. j$ Q5 V" t4 H+ c* W) j6 K d$ i
SeqListInsert(ps, ps->size, x);7 N$ @( W! Z- [2 b! z, B1 X4 K
}+ E9 Z4 [4 D e) `* b3 M
" j" K, Z% o% n. D# o" }void SeqListPushFront(SeqList* ps, SLDateType x) 6 e0 T X* Q! }6 h0 n% M5 I{ / B3 E# a$ R% j: w* T assert(ps);+ r2 i6 b1 ^: {) c, }# A
) H' H6 {8 ~+ T; R0 a& v. a9 f
/*CheckCacpity(ps);$ q" U+ E$ x" ~; ?
) |2 A% Z9 U/ {
size_t end = ps->size;% s1 y6 ?3 ?5 ~
while (end > 0)4 Y Y( ~$ h) \' x5 w7 |7 U( O
{ 2 l. P6 F. Y. @$ [ ps->a[end] = ps->a[end - 1];( b% c6 B* ]. u! R) L
--end;+ |9 C; ?$ E5 h3 o9 K
} ) q# R, H8 C+ F' V2 J8 I' D. X 9 l' K' f5 S# r- h, b1 W! V# C' H- h& r ps->a[0] = x;4 C8 I5 y" c0 x, N+ q8 b5 N
++ps->size;*/ 1 K: E4 z) k# I6 [) D" r+ q5 S/ B! O , z1 g7 Z& G' S1 {& F SeqListInsert(ps, 0, x);( r2 j$ [- A2 M- t7 V
} 2 P( P& U7 }* R' B# m% x7 C9 J( ]
void SeqListPopFront(SeqList* ps)- P0 V! F; K/ ?; ^9 U V/ y: H
{ : N w: v5 T- G4 B' y& H0 L assert(ps); : |, Q3 Z0 X8 s9 u / P! m7 Z8 Q2 h" P1 K( @1 @3 | //size_t start = 0; 7 L+ }4 Z+ L2 M5 i1 q6 w8 n$ b8 h //while (start < ps->size-1) * h) ^' P1 [6 @8 X3 U5 z //{, ?% W$ ^! m9 @" Y) |. v
// ps->a[start] = ps->a[start + 1]; . d# `6 u' ] @ // ++start; 4 R. y$ e K# t& T8 W //}( a! t; D% B. ?3 f( u
//size_t start = 1;, t5 C0 J# \8 t% S" G% K1 B2 S
//while (start < ps->size) 0 Z6 ]! V/ x# D: C8 q4 m //{5 [+ x0 s- K) m4 U8 N0 c. B! e3 @
// ps->a[start-1] = ps->a[start];9 a/ R( e- J2 @
// ++start; j- P. e. O. \3 s( d" p7 b, _ //}( j' |# V4 o) ]
- B- }/ U9 g2 Q5 ~. Z$ W% S# F3 p
//--ps->size;7 t4 n4 u/ s5 B' _
SeqListErase(ps, 0);* ]5 K- |5 O; M1 y* y& N
}2 d5 P! ~( M6 h% l5 | h
% M: D5 R( _* h4 I0 H+ B7 C8 _
void SeqListPopBack(SeqList* ps), r, l S: H& _8 f5 I
{ 3 I% A) Q. {& j1 |2 B3 D assert(ps); . g! n, L: M" k1 {2 k. \ 0 j8 n7 Z5 p! E4 C$ O: u& t" A" M( H! U //ps->a[ps->size - 1] = 0;9 n8 _ V# P0 b @2 o, q4 m
//ps->size--; e; X- y5 B. B8 x SeqListErase(ps, ps->size-1); 8 m0 V6 j8 n, w, q! L% K} / K$ k2 L4 B5 u r* _( K" @' Q 4 w- L A( F) |+ k! t8 Jint SeqListFind(SeqList* ps, SLDateType x)" p# y% | Q: G( A7 d% W
{ " F* q; z6 u) q9 d6 y for (size_t i = 0; i < ps->size; ++i) 2 @5 H7 w( u3 K { - z! d- d' _2 N6 V if (ps->a[i] == x)' k4 O: m# p# t$ S, [" o
{4 i" T! G1 W g4 |' T9 d' I
return i;9 K" A$ P2 C* Y4 K
}: O- Z0 X S4 r) W0 B- w
}7 F5 b) f0 |9 q: @; a
6 }1 Q( k* |2 e. [4 Y4 Q$ C return -1; % f) l- L" h2 i, I5 X; Q}0 X; h- L- L# x
! B3 l& o; U* L5 D5 o( c
// 顺序表在pos位置插入x) F4 T" e1 N! i
void SeqListInsert(SeqList* ps, size_t pos, SLDateType x) 8 ?! T' I7 i" H3 P" D{+ d4 H1 i& [" l3 o% D l! W+ K0 J7 }
assert(ps); 4 i- M9 B- z8 C: B" k+ U assert(pos <= ps->size);. v) p$ Q! R8 ~" G
" Y6 p& q5 C+ u# \ CheckCacpity(ps); : }2 i. o3 i6 S7 D* ?5 D' U! D. Q* F) R4 g( Z
//int end = ps->size - 1;* c4 b/ E* D8 E8 ?/ |6 I8 U- ~
//while (end >= (int)pos) H0 ~; |1 @3 K% ^
//{ / V0 ]" F+ g( g- m+ E // ps->a[end + 1] = ps->a[end];- t; Q, z( ^1 u" g7 T
// --end;/ @ W- }# ]. B# s q& t5 p# Q
//}3 \2 j3 ~8 [) E0 A
: e& J( Q6 k4 Y# M8 {! L size_t end = ps->size ;0 [) f" I6 J( d8 a! f+ w
while (end > pos)! W1 m6 K, T- A+ o
{ ; X) l/ G: z: H# h. d6 f7 X* I ps->a[end] = ps->a[end - 1]; ) I. ^" n0 c* d# Q; W1 m% R3 Q --end;0 l! y; K# K) ]" X
} . y, t( N% H: S2 F. [; `* a 8 ?5 Q1 k0 q- M! i2 q+ v2 E0 | & D* C. u# \* @- `$ U8 R# P ps->a[pos] = x; ; N; f1 l0 y! ] ps->size++; 5 }5 L* f9 \8 i* O" W4 d} * a6 n. G# U" \5 ]9 e " \; {3 W9 m/ E, j4 o// 顺序表删除pos位置的值 ! o9 r* j! L2 i- T! p5 N* N" lvoid SeqListErase(SeqList* ps, size_t pos)! W4 E0 w5 W" c, J: m' m$ O, _ L
{ $ [+ m* u7 Y) A) u assert(ps && pos < ps->size);: H; k3 ?1 v+ s7 E X: g6 [( I
9 l" B2 {5 g) ~& H' S. T
//size_t start = pos;0 B& \1 U* W7 ~7 ~; G" |6 ?
//while (start < ps->size-1)) K) D6 h& x' J7 K) i1 {1 }
//{ . \1 v& k- D+ y8 G( |+ R // ps->a[start] = ps->a[start + 1]; : z/ r2 Y( z' n$ ` // ++start;7 x$ G; G" s) w
//}6 @1 d9 v1 F5 D
4 P. N" Y4 B3 Y/ j* U" x
size_t start = pos+1;# t" g, _' D3 |' D7 Y7 w: ]" e. J/ c
while (start < ps->size) ) I6 H9 T! O- e1 u, {1 S {2 J! f; A: R7 w, ^, p: T
ps->a[start-1] = ps->a[start]; ! e5 T7 y( v- ~/ P ++start;" u7 x! n6 @8 c/ J m; B+ D/ d
}8 Q' p% V# h" R* Q$ v
1 l9 t- G8 X' a% T& o, \4 i/ M4 u' T
ps->size--;7 S. k5 `; _$ t6 L
}5 o* [, J4 {: Q; G
% ~0 D9 ?9 b- Z1 / n8 r! a8 W( H, P0 U! h. F! A/ h2- g7 u! b0 K7 U8 ~2 d F, n- v* u
3 1 f$ s; _$ W6 f+ U& E4 ' H( s7 Y1 H6 |) _) }" V7 x1 B5 ! P3 X# L7 U# T" b; a3 v& B63 L8 T" G7 d/ D: a# b
7" B$ m2 h3 n- v _
8 0 J5 _1 b; K' h' n6 f! k& e9 0 K8 u5 k9 g7 j" R t105 |6 r2 a6 k3 M# ~ x* f3 `
11 ' \% M$ f' t$ Y7 M; L2 n0 l12 & ]1 D8 m6 P2 I' ?# M139 m- q, ^! R7 Y: n
14 3 Q) j( G+ I' w% Z15 6 F: S; y' ^. G' }/ F16 9 _$ r. J; z2 m17+ W! _! N/ m5 e ~; F6 J" F2 f
18# G4 _ y; o: w9 `, M+ N
19# M f Z2 z. L5 K% C* g% t
20" n+ a5 H2 A* H S2 \6 k0 g
21 2 f, @" R2 f- }+ h b% O22 ( o/ H; Q; G7 W; l23; B7 }/ T# C- p6 X+ b4 z' f2 L
240 D3 {7 a3 D7 b+ u
25 $ _) x- S% x4 c5 S8 \8 I6 ^, n2 r* s26 9 p9 c( C) q0 E2 @4 Q5 S27% S& u$ `# p4 B6 o
28, h6 s( x& v8 J! a2 L
292 J7 ?7 F( A' B/ ^2 g' h+ B+ u0 N
30) F* `: C* r: E8 r1 [
31& d `4 u! p" R3 |, A
32% T0 O0 J9 F- @) l
33- V. ]- Z1 ]6 n" y+ F. J5 X
34) |. N c1 L3 \; r* a( r, F h
35+ L4 g1 `# l, D1 K' F; N5 S" M
36 : ?' F3 {* B- f: b$ c37$ ?: u8 O4 y i9 W9 v
382 u$ q- J4 r/ _+ ?2 u% }' ]
392 w* L& D7 U5 l; n
405 ]3 z+ s7 _- d4 T8 G' m, {
41 + A0 r' J" X$ {2 }6 Q, Z42% { F1 V* C5 t. {7 ?* j
43 . _9 u9 P$ u" q44 % }* m( E% X% D2 Q455 b' ^) p& b! r7 p+ B+ y
46 5 d8 l5 O6 E0 i/ |47 0 b }8 X" R8 L' D0 c: N48( [" n) Z3 k) M; t2 o
49 ) M7 h4 Z! E' j( B/ Y50 6 v5 G5 u5 I1 f9 h m0 F51& ~" `) x5 Z/ s: A% ^- M, |: h
52 ( `. Z3 Y2 i3 h53 v: o \# M r9 | T540 v4 a8 y' R4 @0 h" r8 @
55 " ~# |4 u! Y3 @56 i+ d- e" n2 X$ ]& E( M
57 8 \: A5 q z3 Z+ L- U588 x' a: f$ w6 H$ q7 q' L @$ [
59' J. [9 W/ K1 a5 Y3 r7 Y4 n
600 `% J# l% p, b4 i( ^
61) R1 z( M; Q! h, V; T/ Y- O
624 n/ h2 K$ N* {0 c
63 ; m9 @5 X- I) v64 " z/ K" |, Y, S2 P' U9 \" u$ _659 k9 B" p' F6 J# D
66( X( u$ U) T# G+ i0 }. e+ c3 ~
67 * n8 w' O [% ^- Q+ j) y: M3 b68+ A5 n% H- ]0 q' n! _# N
69 % \* f: _* d! u5 i$ h70! i- P2 _- V. m) c: s
71 . _' ?, r) H- k72 & b# \% N/ Y8 b5 n73 * m9 C5 g) U6 _& @74 + T9 M6 R: L" R3 g75 5 T# ~% T+ V! J% d2 F: @76 {+ \+ q( u. i+ \) F77 M( d* \% H/ Y* d9 r8 E! A6 h
78 & e* n0 F! x3 C79 ( A& S: K; p5 M; C: \% D, s- H80 ' U ]$ R4 D7 s9 V# @! k; ?81 ; k/ b. M& @; ^; F* C82 $ A# t9 M j M) Z; c' h( e4 q83 $ k( L$ I$ ^3 ]% f84 # Q" s8 h3 j7 R3 J85 3 A) T* M0 g& S86 " t) Z, A4 b& X$ ~" o% v87, |, z4 O4 A( O/ E! V% V, `
88 0 }! I T! n# @- [892 ]2 k' ?) a D; ]: g+ C4 [
908 d+ X7 M3 g7 I5 U
91 + q5 V- j4 U. G7 }+ g+ E* v92; P- q: j! z2 q2 w# a: H
93 " x' r) z/ D) J" j1 g4 N4 [94 : g' ^1 h/ ~, K% f0 I: B954 ^ O8 q6 A" y. U* O9 R
961 g8 A, N0 X& K- n/ Q- ?8 m
972 k7 b* p3 a- M
989 u5 @+ e, s8 E1 y6 [* @
99 * D! D* E" C" x' t* i# ?+ B" t1002 T+ |# M N: c8 U8 z
101 9 i; ^% c0 u1 m2 Z9 m5 U102 - @' q+ v( T" R0 p1034 }4 G6 w% h/ I& E- D( k/ j6 P! q0 A
104 3 r3 L% X. u8 k/ c& j105 2 h2 ]: x a T106 ; w X; G/ z. r& M% I+ m107) c/ C; [: R5 U& K' ~
108" l( W1 h7 ~4 \0 m$ c
1095 W* U: J R6 }" D: c4 P. t
1107 ^3 h5 ?5 m. C; b' Z& q: @' U
111 ) c1 }, G6 }* ?+ G0 S$ s112; E7 E7 @/ a; ]9 I5 ^$ u
113; M3 d c: I2 r. k, \% h
114 1 S2 \+ H9 E! G1 H U: ]1 o115 3 @. Z7 b& T2 t+ |) `. d' C! f116 : f7 y( f$ Z; C+ H2 k7 r2 q117 # C; ~4 L- @8 {' Z118 7 m( D% K0 l, U' A! F0 [119, L: n K. h& h# |9 a
120! z8 c% U( R6 `2 k: |! @( e
1214 z1 b5 }5 w, [' y) \
122 . l7 Y3 ?) p- C0 Q w# }# X z4 I123* I/ R9 J$ y0 ] Y# Q3 P
124. _9 a( }$ y" z0 H3 U4 \! _% V
125 1 H9 W& z% h+ d8 \/ J126 / L* `% R3 l6 M127 : l: W, }% v% Y3 `1288 k3 w1 W& ]0 V, W7 k
129- g$ z8 T# V( l" S/ D
130$ [/ w# S/ c. U# }: f
131 " ~8 g0 a# @) H2 N132 5 H( {! W! D5 Z- \+ s133' L5 D. [( ?1 D* m" X
134 / w( T) o" ~. W0 N/ R135 @# n! y% q! v# q5 D, n1367 R' H2 ^5 G+ y, A* q7 `/ Y8 c& {
137 6 k8 |0 V, V" B" n& G- p1 O138, ?+ Y6 J, J* e5 }# i& C# i
1398 v \& G% a4 r4 `, e8 u
140 ' e4 X1 k4 O6 v* d0 k141 . O& T0 B' y- J5 ?142/ x. n G& T5 x, u% V& [1 t3 V
143 8 W4 t: u( t' D1 r144 Z) Y$ l7 s/ A" D) y145# p1 j1 Q$ D, |
146 v4 H5 B+ w+ _0 k' v" p
1472 V9 I& q2 ]# m* R
148 6 \- ?# B& T; Q7 {3 h3 O149 9 O1 B( A, H* @* N' v2 [ O1500 w/ q3 o" r( ^# }6 J8 V: l4 @8 ?& n
151+ b3 \7 `/ [4 I) f( l
152 : s- M: n$ x6 ^3 w; [153, s2 X/ r' P) x( n5 r
154& u4 J+ {5 W2 G4 V9 ?7 n1 N
155 7 e- }) i. {2 O* i6 [156 + s P4 U. R! p' D5 _157 ! N9 G0 E- r, X. U3 `1 B158; T- `; \; i( w+ T4 I1 ?' U3 S! L* M
159 4 G; Z. ^/ S1 s7 R$ J160 * L* I& B4 \3 s) j, Z/ g& [. H161: d9 S# s% v9 J5 }0 u
3.3 顺序表的问题及思考 n) ?! C. |6 w; ]& r; }8 y
问题: & c) P4 |0 L2 `9 |5 Z5 Y+ I* u( s' j. Q
中间/头部的插入删除,时间复杂度为O(N)/ |& H- z6 {' Y/ r( N$ Y' n
增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。 ( @2 {- x. q: z! K3 Z增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。8 z8 T4 O+ s0 i; O% p5 v
思考:如何解决以上问题呢?下面给出了链表的结构来看看。 8 X! I% G" r9 M- R; j3 {, [- a5 p 7 _6 E2 D9 {4 W* D. j4 链表 ! J' b7 o" J1 a Y6 x5 j- P4.1 链表的概念及结构 3 b) k3 m! W8 T1 V( F7 \% ^概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。 n. Q- R: `7 I; Z. @* T' c
4 H: P: x5 v# I n4.2 链表的分类# X0 D. e" O" z' e A6 h5 g
实际中链表的结构非常多样,以下情况组合起来就有8种链表结构: % [# N1 b' d( d. N" x ' b) n& V8 z# x+ ?单向或者双向 5 r8 G% p+ ?& G" v 9 S s5 g9 ]) M2 d) x" o带头或者不带头 / l! u4 S) ^! u, a6 } " m3 H, W6 I, C7 V循环或者非循环' e% a, I, G# t3 y
2 u8 }9 Z1 G' A. b
虽然有这么多的链表的结构,但是我们实际中最常用还是两种结构:4 [9 {7 O4 I B3 P$ }, C; Q6 ^