数学建模社区-数学中国
标题: 【Java演示】什么是链表?数据结构 [打印本页]
作者: 杨利霞 时间: 2020-5-4 15:55
标题: 【Java演示】什么是链表?数据结构
: i( F$ B2 ~# m; y3 F; D- ]$ U【Java演示】什么是链表?数据结构
3 v$ A+ X: G# S0 x6 V. m& Y一、单向链表- _4 H$ C0 f7 w9 o& w4 ?3 p
( [. a, c$ i, `* l) {
9 s: N+ p K- I) E& z( \
链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。9 |, h$ j! p$ m5 H0 s$ W- b
单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。5 S* c) B% w- [' B6 d) d
链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。+ M' c. N- n4 `7 B: v+ c9 W- m
0 v9 Z: E' ^' n2 {
什么叫随机存储呢?# X1 I/ Q" d! K# M" u3 z) i
* H0 F& J# Z r: Q
如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。
( K l: [( I2 v2 i0 U g上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。+ I' z( T/ [9 i0 H% R
/ O; n" X# e% v- @" S) \: E/ B$ e& {/ ^" ?" M4 s0 ]# D! f, r4 m
图中的箭头代表链表节点的next指针。
链表的基本操作1. 查找节点在查找元素时,链表不像数组那样可以通过下标快速进行定位,只能从头节点开始向后一个一个节点逐一查找。
) `3 U" n- g3 z% p0 V4 }6 e
: X8 {& `# B2 W! G$ I
/**
) w& S C) w0 H6 w, @+ D/ X * 链表查找元素; R( q3 \5 V0 D! o0 |& `
** R( @4 \+ u0 I
* @param index 查找的位置 \' B& D/ ^) ^" J6 k
* @return index位置的Node对象. }' {8 _* b8 m, P: Q& h) H6 q ]
*/' b9 d& m4 \8 ~7 t! |! f
public Node get(int index) {+ h/ n' i5 h$ @4 A6 l" d; M
if (index < 0 || index > size) {8 D2 A3 {( R# A: P, ?+ l @
throw new IndexOutOfBoundsException("超出链表的节点的范围!");
( l2 e; m3 r/ _ }
) `+ a3 n; J: E7 E* g1 D& u" { Node temp = head;! x- k, U% X8 O( M& j8 _* U5 n
for (int i = 0; i < index; i++) {
/ _ t1 U# c. m8 ]7 |% w temp = temp.next;0 {7 V, X" O: g' r: G3 o
}3 W9 u" V @. l* `. g- J5 \# E
return temp;
- ~2 F- W1 y2 t) g5 ~! r7 A }; X4 f: T- ?7 d1 t9 L& M) E- \
! u: ?) D: |# q q; D链表中的数据只能按顺序进行访问,最坏的时间复杂度是O(n)
2. 更新节点
, W: }& c/ L2 a. ?: w- B
( ^" F9 g G! H& B) u7 `如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。+ q* d: Z8 i5 ~, ?% R* _) l
如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)
! ] |: e- N1 N7 k/**
) {4 m' X7 Z) M6 e1 _ * 更新节点 将列表中指定位置的节点的data替换为指定的data。
3 h8 @& H: J* L" t% b$ { *! T- V% x$ j: g. |6 G+ w5 ]' t
* @param index 需要更新的节点的位置9 A2 t' q% L, @2 u' U$ }
* @param data 新data
5 Z0 @$ ^0 y1 w# D8 t$ p * @return 旧data1 @! ]/ _9 a; l u* i* y
*/, U- t/ `/ L! j3 Q- z
public int set(int index, int data) {
- n$ G& ~5 Z5 y. b/ p: @9 o) s Node x = get(index);
3 U3 T. ~& b/ | int oldVal = x.data;7 M% {9 m% {9 t) u0 L9 l
x.data = data;
$ \ Q- R1 v. _. B" r return oldVal;6 j( l$ S7 c4 W( V: ~" W- m4 Q
}
7 B- b# i& c$ E! R. a
4 G' O# B4 R; O$ v* l' ]2 g' b8 k3. 插入节点只要内存空间允许,能够插入链表的元素是无穷无尽的,不需要像数组那样考虑扩容的问题。
与数组类似,链表插入节点时,同样分为3种情况。
- 尾部插入
- 头部插入
- 中间插入
2 Z4 f& f9 ], a. x7 e
3.1. 尾部插入尾部插入,是最简单的情况,把最后一个节点的next指针指向新插入的节点即可。
: y: g/ |! ~: ^4 v
, G1 y4 h* `2 {& G
3.2. 头部插入头部插入,可以分成两个步骤。
- 第1步,把新节点的next指针指向原先的头节点。
- 第2步,把新节点变为链表的头节点。( O2 Z$ L! F+ G7 U1 f; ^( L
+ O/ A6 S( M& b, o3 U
6 ^/ F: k# d4 L* h3.3. 中间插入中间插入,同样分为两个步骤。
- 第1步,新节点的next指针,指向插入位置的节点。
- 第2步,插入位置前置节点的next指针,指向新节点。2 h. ~: w- z4 |5 u
5 d1 ?% }3 _9 T; k. Z" n" _) X; L$ i. b5 L2 ^, C) N+ n
三钟情况的代码合到一起4 Z& D5 Z$ Y4 i; q8 e w, S
7 n6 ~. c+ u% ?. ]/*** b; K4 D7 { a$ p+ G% I
* 链表插入元素+ g) _4 |- Q) n; {
*
- O5 I6 y3 |) l: G * @param index 插入位置
0 S# f3 L k! F1 h0 A * @param data 插入元素 被插入的链表节点的数据
- v# q5 O* `" i/ }8 u */
1 R0 b8 q: Y3 w- g* F& F public void insert(int index, int data) {
: h2 f3 G7 N0 x! y+ F if (index < 0 || index > size) {0 }* |3 p& \ ^# n% l p0 i [; L
throw new IndexOutOfBoundsException("超出链表节点范围!");9 q8 |1 z9 x/ e- U
}
( B0 E0 a- F- U) S Node insertedNode = new Node(data);
" r9 t, w7 ^$ b9 `( F if (size == 0) {. ^3 O, h8 [ J' }$ {
//空链表; V, K5 g3 ^, t4 \& k: r4 k
head = insertedNode;
* s7 {( v0 z( D6 q `! d$ l9 H last = insertedNode;# W$ x8 T5 n3 b5 c7 D) g! X! h
} else if (index == 0) {
1 B& o) G4 D# d2 n# G //插入头部; a+ B i O W, C$ y
insertedNode.next = head;
. C6 e9 j/ l0 K+ W, d head = insertedNode;% `/ T- O: r2 P! r A
} else if (size == index) {2 F0 x2 }1 T2 P$ x
//插入尾部. }7 F+ s! S0 [( m9 \3 O. j
last.next = insertedNode;& F" u& q, j& b
last = insertedNode;
! i9 ~7 }, m% \& q% H2 ] } else {
; a+ x8 S1 y4 N5 Y) H //插入中间
& H# O: O# n: q6 M Node prvNode = get(index - 1);
\1 \2 D) Z5 L) K( Z4 z( y2 e insertedNode.next = prvNode.next;/ y9 U% `2 _' X; e( a9 q
prvNode.next = insertedNode;
3 N: y* J1 ~+ E; j7 B; S3 j! n }
0 f9 F# A' @% |1 v. @7 e+ E6 ` size++;
) U+ C6 u+ K/ ^9 ^: E: u1 } }
( B1 A# ]- {/ ~/ H5 z# u6 h( g) k3 L, U7 B, L4 }& m
/**
|/ K8 T+ h# G5 V/ s * 链表插入元素8 g9 J# ~* {3 W9 t# c7 h
*# c6 H& Y8 A8 U8 w4 H) V& Z
* @param index 插入位置7 V1 Q5 G) t- G0 B \# u* Z
* @param data 插入元素 被插入的链表节点的数据, r7 I6 R! z6 Z W; w% [% \
*/
9 @! B# [! F8 s: c0 ]2 W public void insert(int index, int data) {1 q% b6 Q/ F* i% M6 h$ x6 e9 h4 _4 x
if (index < 0 || index > size) {
7 ~8 W5 S, S/ e) F throw new IndexOutOfBoundsException("超出链表节点范围!");
; ^/ h# b) f3 t2 k }' h' O0 n' |$ W4 v$ ~! A! N% `
Node insertedNode = new Node(data);
* [! w1 i1 m8 c if (size == 0) {0 j% e. I0 [& \& X
//空链表
( i8 i; z0 h8 P- V3 r+ @7 t- s head = insertedNode;
; G& A+ w1 ~2 c( `/ u3 R last = insertedNode;
/ G' ^- ]$ M1 o8 k! M. F, S& z } else if (index == 0) {! j6 S! B2 j% {' U( {) _7 N
//插入头部3 }( `. p- E. j0 }& C* a" K
insertedNode.next = head;
0 ~' l* N' ?) a, T) E head = insertedNode;, d8 |) A" [6 u4 P1 B3 n
} else if (size == index) {" U6 m+ F! t7 N# S% @
//插入尾部
( a7 k( J) t5 a last.next = insertedNode;
4 Z0 G# Y2 Y! ?% M { last = insertedNode;. A3 |; M4 t% w5 r
} else {& x' M5 e& w: g! B7 I" o
//插入中间/ s0 ]0 p) i- Z& f8 d/ `; ]+ P, S; T
Node prvNode = get(index - 1);
$ N7 r4 Z: J2 z+ r. G% I# C insertedNode.next = prvNode.next;
5 h; M' F* ~' A prvNode.next = insertedNode;4 I1 e1 U" a e+ f5 R4 l; n' x, [
}6 j: }" T! o( a0 B q/ @& J+ r
size++;0 v: T# o( A; Q& k
}
' Z1 A2 V* }5 K. y. e! D4. 删除元素链表的删除操作同样分为3种情况。
- 尾部删除
- 头部删除
- 中间删除
3 [2 b" ~ y. R; s
4.1. 尾部删除尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即
0 Y3 o( ~$ I1 b) O5 `& r可。
6 h2 j) ]# }+ R! k [, I; F+ D
3 \0 o7 @5 e( @: z8 B/ R
4.1. 头部删除头部删除,也很简单,把链表的头节点设为原先头节点的next指针即可。
% Z; [6 x+ U& m8 V) W& E; l# g2 Q
: I- Z( Q' A2 Z% K7 ^0 R, F" z
4.1. 中间删除中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要
+ u* s8 o; F/ b, f删除元素的下一个节点即可。
2 w$ ~# n+ B6 P: y9 M
6 ^/ n- _8 A- q+ ]+ G8 ^/ e! J# N
* V! x0 V8 ~) N* t
这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。
" Y O o }% d如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)& x: `- E' {1 l/ Q
/**
$ o3 J" @7 h; a( X/ P' b * 链表删除元素
' E9 f" F! j) o8 q! C' A5 Z/ o *
& n6 A8 a, R, |% Q& Q; K4 W" w * @param index 删除的位置: M1 C& w, [3 j
* @return 被删除的节点1 T9 j. P5 `' a% E1 {, {& S
*/& W8 [& P/ G3 Q H r0 t
public Node remove(int index) {
. |7 Z1 n( A3 ]$ r if (index < 0 || index > size) {1 D0 T3 o8 i6 s @4 B
throw new IndexOutOfBoundsException("超出链表节点范围");. {1 z# N9 _' d! E" {* {5 ^6 F: A
}6 o& [" s d' R& p/ o! V; z0 M6 v0 k
Node removeNode;
4 W) T7 @/ o( L) X% v1 c- Z6 z# _ if (index == 0) {
7 n" A+ l0 j7 a& i% j1 s# q if (size == 0) {
" `5 b% F8 p7 K3 X( N2 c throw new NullPointerException("当前链表为空,不可以进行删除操作");5 P9 _) I' T1 n. M5 A) U& p3 c
}0 R u$ s' m8 ?* t
//删除头节点* J/ U! i) T" D% N
removeNode = head;
. k! A& U6 a8 q! s; R5 O) P; g; g head = head.next;8 {; A/ h6 G' e9 _# v, e1 s
} else if (index == size - 1) {
+ L& r, J* @( ?; y //删除尾节点
5 i# {+ ?' Y# K7 |* |$ H Node preNode = get(index - 1);
6 Z* M8 O2 c$ Y; P+ i6 } removeNode = preNode.next;
9 _& k3 w. o: {! d; {5 w3 \: K preNode.next = null;' B, R& P" }/ d: O: \. ]
last = preNode;
0 C$ S% p( F5 S7 G" \# {1 S. H% y } else {
1 g @3 H% p' | //删除中间节点) K( `8 z( a3 B% s" w8 Z
Node prevNode = get(index - 1);
3 M6 [/ h8 @5 A/ l3 \ removeNode = prevNode.next;
9 k1 V0 ]/ l9 ~0 _ prevNode.next = prevNode.next.next;* O5 b* k5 Y# H0 Y9 j" p0 v
}
" v# z: r5 E1 }4 K1 f size--;
3 w) a2 k5 s7 `& V9 |, O4 A return removeNode;
Z$ ^: s0 M |. h+ J }
5 I$ Y; u/ {$ V9 u; IJava实现链表的完整代码package chapter2.part2;, u! B, w& C/ G& I
0 g% F) ]9 j- Y4 M7 q" E7 P" l% r
/**; U( q4 v* k6 R
* Created by IntelliJ IDEA.5 @- o0 H/ u) K
*) ?* |# t$ z, `7 n+ Q9 @
* @Author: 张志浩 Zhang Zhihao2 ^/ g3 y/ P# o/ E. `* h
* @Email: 3382885270@qq.com
7 W, {3 _) _( t K: n% x* J6 w * @Date: 2020/5/3
8 O, T- D1 F0 z1 Y0 y! y4 w6 J, E * @Time: 13:396 a0 K- w8 V. l) I8 T, m! b
* @Version: 1.0
! o) U' T9 E! p, U6 a% E! K! N9 H */
5 z# X$ v2 a8 G$ l/ t; N3 O' Kpublic class MyLinkedList2 {/ B) u- V. q+ }, a3 E6 ?
private Node head; //头节点* b2 B- [7 z- _
private Node last; //尾节点
/ d/ h9 u2 X, X& z& [ private int size; //链表实际长度
5 {6 p2 R4 h" `# z
# q; O3 ?1 @& m- Y# V5 G- v V public static void main(String[] args) {
- M4 ^- {4 X8 J+ a: k5 V4 S! F$ ` MyLinkedList2 myLinkedList = new MyLinkedList2();* g. e$ G" P6 m( F) ~' ]) a+ e
// myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作
7 [4 A! \: P' a( l// myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围
( h* o/ i& W" F6 d& d8 H& D: o* u myLinkedList.insert(0, 3);
7 l) D( y3 D2 c& O myLinkedList.insert(1, 7);, T% K% X- q( j
myLinkedList.insert(2, 9);
& F5 U( N2 W: ]% P5 B myLinkedList.insert(3, 5);
2 y) l5 [2 f0 }7 T4 g myLinkedList.insert(1, 6);
j P3 @4 t3 H2 E myLinkedList.remove(0);, W& Z8 |3 l2 P% L3 K( n. P9 r
myLinkedList.set(0, 23);
- \. y; m- f: z( O1 G myLinkedList.output();
% `8 D% X# ?8 i. @8 M/ ~ }
7 l5 R. C3 |' u) d( \
5 x6 M. \8 Q- @8 d; u /**3 X$ z5 i" h/ j" S. ?( d* c
* 链表插入元素
x( j+ Q- n3 G2 Y! v *
; K2 m! p/ ]1 o8 Z * @param index 插入位置
$ r$ H. `! f9 }( l8 q * @param data 插入元素 被插入的链表节点的数据
0 q; N' _5 T E5 h% z! p1 K2 I */
* h; _$ Y; Q/ [& B& d# g public void insert(int index, int data) {
* C- a0 [/ y) o+ N. z$ c if (index < 0 || index > size) {
! Z/ D4 u. \$ @( y( }+ f throw new IndexOutOfBoundsException("超出链表节点范围!");1 m4 v% g, }7 H& s+ k1 a5 X
}
9 c# G6 r" W) g M+ W, e Node insertedNode = new Node(data);5 v) q4 d7 K$ ]8 z' S
if (size == 0) {+ ]" e a% D0 }
//空链表# e7 ^: Q- J* P: Y6 u7 C
head = insertedNode;
8 S- i$ `7 ?( s( N1 e last = insertedNode;
3 \: C+ }) b+ ? } else if (index == 0) {) l4 K+ C& o, s+ {2 v- q1 f
//插入头部% ^& q: A$ r9 t* ]7 u
insertedNode.next = head;6 i) I( w3 [4 h$ r3 g
head = insertedNode;& n% H1 l7 I# Z6 O- f4 g" [
} else if (size == index) {2 z7 r z2 O, k1 H8 S& R
//插入尾部
' R) ~2 F; E9 L+ s' v% S! W3 x last.next = insertedNode;- o! U8 k1 G3 j6 n+ o" _# L* X
last = insertedNode;5 ^7 M6 W5 L( h- F( E
} else {! A- l; F8 ]" M
//插入中间
3 b5 W0 E0 T/ o, }+ \! G9 O! k, ? Node prvNode = get(index - 1);' s( e" i0 U% W* w0 z3 |
insertedNode.next = prvNode.next;4 W9 l9 E9 w( k1 p" I/ F
prvNode.next = insertedNode;* i1 N, G* z; A6 H( @; `# {. l
}5 }5 [: Y! e% S/ |* u! \, R' z7 S
size++;; _5 }6 a4 d; t; T$ w
}! g F3 ^) `; y
$ x+ z7 N; ~( R( w$ P /**: Q+ y- j6 E# j3 m. q" |
* 链表删除元素7 A: \% _2 b: A9 A, |" |: A
*
9 C4 S' f" A6 h& W1 j1 ] * @param index 删除的位置3 D; l! y8 ^" x Y
* @return 被删除的节点" ^2 R# l$ |$ T9 N+ q2 r( Q
*/
1 W: L: x# i* c; F public Node remove(int index) {/ r& q' |5 a: p' w5 A! Y% W
if (index < 0 || index > size) {
. Q5 k+ J; f$ p- f. r* Y3 a' l( [ throw new IndexOutOfBoundsException("超出链表节点范围");. R y Z g/ H' u) T$ G
}/ b4 o: K& a/ l* ]! W: W' M+ K
Node removeNode;: j) w6 N0 m! z
if (index == 0) {5 i( ?, P w+ F! }: Q6 M; j4 f, \
if (size == 0) {0 u9 `0 G6 J5 @- Q
throw new NullPointerException("当前链表为空,不可以进行删除操作");1 A% q' X) ]2 w2 \8 S
}! n5 ?9 |- ^2 r) N
//删除头节点$ Y+ }0 ~5 y/ {) S) w9 Z' P
removeNode = head;: ] d4 J4 j8 m: Q2 Y: C
head = head.next;6 u' W1 d6 z& I; E1 C3 K& G
} else if (index == size - 1) {, S% Y( n0 f1 J0 T+ B
//删除尾节点
' N3 k+ F- M0 O1 Q% K+ \/ N& G: ? Node preNode = get(index - 1);# s) D* D1 e' s$ j2 A
removeNode = preNode.next;
' M0 S5 P) {4 t+ ^4 F preNode.next = null;
9 |7 b$ K: k5 `6 H! F last = preNode;( `+ J; C& k( n" h
} else {+ s) a [- f9 A8 w
//删除中间节点
( d% C: y6 A) i: V; b' L Node prevNode = get(index - 1);
+ E, P! Q2 r o2 x removeNode = prevNode.next;
; v4 c2 b" r! K- w) ~6 T$ y' ? prevNode.next = prevNode.next.next;
( W8 [; n& W0 r! @6 a }
: S8 U7 |% ^' a. H! g% Q' m# b size--;$ c" M* G+ d k) i8 j
return removeNode;
( u4 e3 x( E6 ?" U& o }; a- j- w7 p: [0 t/ H- S
8 o' J* [# n% z* e3 V% e4 Y
/** L# U9 Q% j6 l6 L$ O2 f
* 更新节点 将列表中指定位置的节点的data替换为指定的data。
! e0 I( d3 Q+ @7 x: j *
* R5 E, F1 V) h. T * @param index 需要更新的节点的位置& E0 m$ l! `" F9 ^' \# p. o
* @param data 新data0 G8 h3 j- s1 \2 `5 L8 o, p$ {
* @return 旧data
4 c2 W" D5 O4 w1 H$ ^. S# Y */
0 a5 F) P0 U/ b& D) G9 C; h public int set(int index, int data) {9 l a* \( O3 ?0 A+ w6 u& U% }
Node x = get(index);( c/ B0 U4 G& k, b! q. T
int oldVal = x.data;$ J) w" x5 J7 C4 D$ c. [: R
x.data = data;' Z: _) [( p% L, ]8 D
return oldVal;
% ?& i7 |2 q( x, u! r' [% E" h }
. |7 `, @6 O/ P7 o* f! a2 r) w1 @# `; @ `, B \4 `+ @
/**; O- D& l7 P. L: g: [% P
* 链表查找元素
' v1 O% R8 _2 ]! _ *
7 J6 |. X- S1 R5 }$ z4 Y) h7 n * @param index 查找的位置
9 r' Q5 M; o8 E, g7 V2 X' w6 a * @return index位置的Node对象& x# H' x$ S8 T8 x
*// C3 h) o# b5 V
public Node get(int index) {5 a+ g- s/ V; T) a, w& }
if (index < 0 || index > size) {- K7 K: U8 N' T& n) X& d; {/ _
throw new IndexOutOfBoundsException("超出链表的节点的范围!");8 |7 g5 U0 b0 K
}
0 \9 ~( m y8 U Node temp = head;9 D8 e/ H1 j' F# T! J
for (int i = 0; i < index; i++) {8 x0 K( n9 g, [8 P
temp = temp.next;- e/ r" X) N; ^5 C$ O, r. g
}0 C3 F. Z' P- z% l
return temp;
. ~+ {: H2 I& b9 b }
6 r, X0 w5 a# T& i$ E3 C5 V( Q6 H# g F1 ^9 ^. S
/**
: @) {5 i% } J/ H$ E, h% d * 输出链表
m" Z6 i, @- j */
" a9 g& W4 V- J5 _4 m- L1 ^ public void output() {
2 L% i1 D0 G3 L. \ Node temp = head;
3 W4 ]0 f; R! T2 Z9 ^ while (temp != null) {( w7 T5 |8 L* i# U; B1 C( L* P
System.out.print(temp.data + " ");$ R; {% t2 T8 v# L
temp = temp.next;' q W; N- @: h5 n9 `0 g7 I
}! z0 a8 D! M1 m1 b
}8 N1 P/ g7 \- \$ S+ R D
+ }0 c0 P; {9 T. r8 f+ _ /**
8 J& w4 e+ l, |$ \ * 链表节点7 c; x a/ h2 O) a
*/2 N8 F) z8 h% q" T J3 e; l
class Node {
+ p h( m0 Y8 i2 e- j! I2 R int data;- @$ c9 F. G5 F4 @
Node next;
, S& `% ]& E5 ~8 N1 |- o1 Z$ c3 F' Q
Node(int data) {
, L# ~* R' F% r) y- O# @ this.data = data;: h: e3 j U, g3 n( v6 m
}
m8 ?% l n- |' o }
7 k1 ?8 x: K3 J& F1 e}$ B1 }1 ?4 J3 x
9 |; |- t6 q' b0 `
9 r$ u* ]9 [9 E
二、双向链表
" Y ^/ v9 q! z4 \双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。
$ f& g8 A3 Y' u! f0 D& v8 R, u; Z, L. s1 K6 {3 z+ Y. P
% S z: I# w' Z# _$ d8 `! c9 g: @( t4 y, \& v* d- E
% o; ~6 F! C6 n0 g
————————————————
# o" S0 w- v, I; O: m# t版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。. \4 s$ u5 w+ @ G
原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468
% a& d# z* V0 b+ H6 o( U7 Z2 u+ B& ~ b p" c9 A) G( u' a
q! M9 Y. ^! O! N
-
2.png
(256.36 KB, 下载次数: 286)
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) |
Powered by Discuz! X2.5 |