数学建模社区-数学中国
标题:
线性表顺序表示、链式表示实现方法及其异同点
[打印本页]
作者:
杨利霞
时间:
2020-5-10 16:11
标题:
线性表顺序表示、链式表示实现方法及其异同点
6 p: N" j8 n$ H
线性表顺序表示、链式表示实现方法及其异同点
# ]% a" {+ c6 W8 s
线性表是最常用且最简单的一种数据结构,按存储单元排列可分为顺序表示和链式表示两种方式。
4 R8 g& C+ D+ j/ R
. D. e, ~' s3 X! W: V
本文采用C++实现两种表示方法。
1 O4 I6 ]# H- k, V8 W
e! R/ C5 ~* L: A8 r
目录
7 x D: h, W! j1 A% |
- J- m7 X0 b7 }) e" X. B7 M
顺序表示和链式表示的区别:
1 b; U3 P L) g& @+ k- B
U5 L) S. t B7 z; O4 L
创建方式:
8 u5 U$ e6 U T, e
/ S \$ m V* A
时间复杂度:
7 s# \) F: { @! Z; L, E2 j
! O0 L. \ y5 n, P
顺序表示和链式表示的相同点:
7 y0 \8 G9 Y) _/ \& ]+ U) i4 a& I
6 {+ q. { |; R8 v. ]3 s/ k- }
删除内存空间:
1 G7 D" a& N9 o# V' H" s) I
8 K, o- W+ G4 _6 \/ Z5 ]* A
代码实现:
- ~! U `/ D& _( s6 X- ~$ z
/ {* m t" a& J' z" Y- E
顺序表示方法:
$ Z* G k& z5 B! P1 s" K2 |6 C2 L* f
0 C- C# L* A' ?
结构体定义
1 D) h& W4 j2 n/ V3 S
* n% v2 n {2 @1 Y9 L
初始化
0 Y. s+ {" E8 E+ E8 o; o, K
# m5 k- j: y* w
增加元素
# m/ d, S; I1 h# R; l. `$ D( d
}* ~$ K$ \( F* U1 Q! M# A
删除元素
; H' n8 _( }6 r0 y
6 ~. h* z* _3 ^' s: C
销毁列表
# k6 ]5 x, t* c
& H6 f/ q H7 n& V1 Q; T4 x6 c
链式表示方法
+ W& V! V3 J/ M5 @+ E+ T
* P( J! `& J: X+ I1 K1 x: @
结构体定义
1 h- O: U0 t4 u& `5 t9 W
7 L* U4 V6 `: @
初始化
1 B6 e+ `( R0 c7 q' {- R( e
6 r4 b6 ~# y7 E! q5 _
增加节点
9 N: ^$ B/ f3 z M
/ i9 Z) m$ {, C4 d/ c
删除节点
4 F9 p/ g* l* g# }0 m
M5 `$ J3 H' Z* ]! k+ G( f
显示链表
3 O) {2 U+ b5 w, s# v. y) |
- R3 _8 X: s" [4 p4 c, l( f# q' B
销毁链表
8 w2 Z% w4 I* M5 W0 J; L3 r3 ]$ q( @
" t# Y5 L; W5 Y0 f7 c$ y/ ?
顺序表示和链式表示的区别:
4 ?+ v, k% |1 k, u1 O9 Z7 Y1 c
2 n+ I& e& e6 J$ C+ C" y
创建方式:
9 `8 T* ?* Z" Y6 A/ o2 O: _
( G+ D- |1 c, }; e
顺序表示方法单次创建多个存储单元,相邻的元素存放在连续的存储空间之中。
# [8 h: O; {5 P \7 G [; Y9 S n9 ]
, u( O6 [& y2 I0 u T% T: y: g
(PS:内存空间申请请参考https://blog.csdn.net/Baimax1/article/details/105954552)
# C2 p4 P- W! {$ o
; t! N% ]0 r) ?: w+ Z, @
链式表示方法单次创建单个存储单元,存储单元之间地址不一定连续。存储单元包括数据部分和地址部分,数据部分存放需要保存的数据,地址部分保存下一个存储单元的地址(单链表,双向链表的地址部分同时也存放上一个存储单元的地址)。
6 l* H6 ?) [' A6 X
( l( L% T: \* ?" o2 ^& E5 U
时间复杂度:
8 G, v# t7 G6 v* `/ V
7 v0 Z5 J8 _( }( l
增加 / 删除元素操作:顺序表示方法 O(n);链式表示方法O(1);(PS:在未知位置的元素前 / 后操作)
$ ?) t( |# ~2 p0 K, u$ Q3 Q
6 ~2 j1 d L. f
增加 / 删除元素操作:顺序表示方法 O(n);链式表示方法O(n);(PS:在已知位置的元素前 / 后操作)
: A- g3 l- p- U
. W `/ L4 ]9 ^6 c8 T, X$ Z9 C
PS:顺序表示需要将元素一一后移,链式存储结构需要查找该元素的位置。
7 S8 v' ~. w, ]9 z
" c8 F; l* j& t
修改 元素操作:顺序表示方法 O(1);链式表示方法O(n);
9 [, d5 O* [' a/ e" ?
) \1 y8 |% l5 V+ w4 ^2 d& h
查询 元素操作:顺序表示方法 O(n);链式表示方法O(n);
' S: k( N8 T& N/ D/ e" O* |
& _1 ^4 j% Q* e& A
顺序表示和链式表示的相同点:
; x* i% m' @% S$ ]' w6 J7 S
# G8 ?: W$ e: k0 r
删除内存空间:
# f, {& K E. a' }# V3 H
' H& l0 l* Q" m0 g5 S; [ F/ o% e
内存空间的删除都需要对每一个存储单元单独释放空间。
+ S( q9 Y. T7 S3 v9 |
% t/ P1 f3 V ?% ?4 V
代码实现:
# F/ t* v* t+ o, M: R( o
! x: v1 E# E/ ~ f' B R
顺序表示方法:
" `8 X' e& { |: F9 Q* v! p
; {8 w* Q) W' v0 [: A/ s) h) V
结构体定义
0 l1 O1 C/ _1 q0 c3 f) v. ~
4 H x( `. E" \4 |
typedef struct {
( u8 s' {5 s2 ` O4 |$ c* j
ElemType * elem;
( g# a: ^/ R8 Y) s' V
int length; // 线性表的现有长度
+ f" n. ]+ T5 X# a/ C$ C0 u* h
int listSize; // 线性表的最大长度
2 D2 z+ r6 M7 l9 i1 M% J7 Z# P
}SqList;
9 d( z) s8 t8 o8 w! N! f# a
; i1 g2 I3 h4 i
初始化
! ^* k: M2 S- m* a% P' i" h: m9 Q0 X
8 z x# e4 P& e( C$ N1 p
void InitList(SqList *L){
3 R8 e- p2 P9 ~/ U, B2 z3 v
L->elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType)) ;
, }6 i# O% M3 j5 R/ O4 x- h2 v g2 q
if(!L->elem) {
; F- ^* w' W8 s3 e
cout<<"申请空间失败!\n";
* m3 k5 ~6 F( \
DestoryList(L);
0 C/ J r$ Z* k) [, v) G
}
. U4 l7 G8 t! h2 d5 l
L->length = 0;
+ I; i2 D" I! [& I( M5 s
L->listSize = LIST_INIT_SIZE;
& Y, l* q5 S/ G8 j
cout<<"线性表初始化完成!\n";
7 a" k' e) m' J1 B) O4 i, O
}
1 K, G* A9 E8 c! R- J4 J! m$ O2 I
5 [; q* e3 f7 X. H
增加元素
( c( N" ^: v3 @1 R% g! x* F0 X
4 E7 K6 c. {( m8 z$ W
void ListAdd(SqList *L, ElemType e){ //在末尾直接增加元素
- f* _6 ~1 [6 Z5 K1 f% c) W) e" u
if(L->length>=L->listSize){
+ i! t5 Y) T1 {+ z! \. A3 D5 k
L->elem = (ElemType *)realloc(L->elem,(L->listSize+LISTINCREMENT)*sizeof(ElemType));
; ]( G) z8 N7 P8 C$ Q
if(!L->elem){
: r: P) n$ }( O
cout<<"增加空间失败!"<<endl;
7 Z- U% }' o4 `* Q% h: ]- r5 p
DestoryList(L);
5 P- D0 m* u# `6 d% F4 ^
}
4 a5 W1 v( _: P4 a2 j8 [7 q ]+ E6 U
}
: f% V# P5 M0 v
* (L->elem+L->length) = e;
6 {3 u' N" S8 q2 x
L->length ++;
% K( E7 `9 L' ?2 |9 ?8 @" P
}
' m J8 p0 i! X0 h
+ M& K# i# U6 u/ Q6 I& O; {5 ^
void ListAddBefor(SqList *L, ElemType e,int e_where){ //在某位置前增加元素
# @9 R- ] d* K$ A1 \: v6 B
int i;
3 c) I# z1 s* r9 E0 k, R- X4 l% i9 Z
L->length++;
" @# s9 @9 h/ \, K/ e% _4 }# _
for(i=L->length;i>=e_where;i--){
! C' J+ Y: Z4 ?6 }' c; |+ U
if(L->length>L->listSize){
" U' c+ g4 r, O1 E y
L->elem = (ElemType *)realloc(L->elem,(L->listSize+LISTINCREMENT)*sizeof(ElemType));
$ |& g. j5 e" d% h" i" {3 r
if(!L->elem){
: Q$ x, n, _" `
cout<<"增加空间失败!"<<endl;
9 i/ M$ @7 H& N# s
DestoryList(L);
/ A. |: A( S2 r; C3 ~
}
0 I6 {9 G, Y* b A, [
}
- U) V5 @6 _4 j! M T* z3 j
*(L->elem+i+1) = *(L->elem+i);
( z& ^7 R5 W. }: d
}
, @5 k/ u5 D9 b$ F
*(L->elem+e_where)=e;
5 [2 s5 @! |7 t9 }8 {( _, k- U
cout<<"增加后的线性表如下:"<<endl;
3 |7 N4 @1 l& W) S4 u: p$ v) J% v
ListShow(L);
# |4 q3 P2 m" q4 A- [
}
1 J G4 {3 R% D/ G
# z. l( |1 w" N @6 v1 m2 W2 P+ q0 Z) e
void ListAddAfter(SqList *L, ElemType e,int e_where){ //在某位置后增加元素
6 m3 ?5 q3 _1 l9 p Y `
int i;
1 R) V- K5 c3 l C2 \
L->length++;
0 c% D; H+ M1 @2 D4 t! V
for(i=L->length;i>e_where;i--){
0 x# u! U2 B7 |5 y( I) ?- _
if(L->length>L->listSize){
( x: ]3 J& F: w! u4 p
L->elem = (ElemType *)realloc(L->elem,(L->listSize+LISTINCREMENT)*sizeof(ElemType));
$ I. i# k! y, E9 h) X
if(!L->elem){
7 y4 e. L; Z6 r1 i9 q9 j
cout<<"增加空间失败!"<<endl;
$ o0 O1 o- u: Z/ c
DestoryList(L);
5 o+ ]7 m1 G2 g
}
! d0 H( [# Z7 E7 Y1 G3 j( t
}
; g1 e5 h2 n6 b$ | V: B
*(L->elem+i+1) = *(L->elem+i);
% B% Y: G& @+ k' ]! U G
}
; R. o' m) P: g$ y' C; |" A( G! d
*(L->elem+e_where+1)=e;
9 v5 m1 |" l3 z" b- e8 h' q h
cout<<"增加后的线性表如下:"<<endl;
% P$ i- ^5 O1 f) N! K
ListShow(L);
; H: T7 N, Y" \& E% [
}
; |- C3 t+ j7 ]* R" H+ h' x
/ q+ }( i) l" J R$ a
删除元素
4 }3 e$ u0 d" Z9 ?+ d
2 f3 n% o4 D2 n$ R2 t# ?2 w/ o
void ListDelete(SqList *L, int e_where){ //删除某位置元素
! G( D9 w" N6 A) U( I
L->length--;
( W) M4 e& |4 s; C" q2 B
for(int i=e_where;i<=L->length;i++){
" r: Z8 ^' U4 R
*(L->elem+i-1)=*(L->elem+i);
0 y" v* h3 @, T _0 F! S6 T" v
}
* A! C1 z) i" ?1 e" \) f$ W& h
cout<<"删除后的线性表如下:"<<endl;
" t' [$ s! T1 f F6 X; g& M
ListShow(L);
4 m9 A i* M5 V) ?6 s$ T( S& E4 W
}
2 r) s2 Z: B: J! m, B
$ e) R9 L3 F# @7 i: F" y
销毁列表
8 {( i# b. p" q Q, v
! d8 p; X3 r8 {
void DestoryList(SqList *L){
7 k' l5 @; p# F. K# p% m
int i=0;
( o0 l6 Z% x& }/ |+ G
for(i=0;i<L->listSize;i++){
5 m2 b! p- T6 r/ N( G) B- O( j
free(L->elem);
; y* I0 s5 o# k6 n1 U
L->elem++;
2 G- _& g+ H/ U3 \, x b& b) B
}
% U; J( J8 T- m- S' a
exit(0);
0 P& L0 e& d6 X% |1 r: b
}
4 f& q7 X$ D4 r
# s. Q' {' G* [* F `+ I. t0 t
链式表示方法
3 w7 D5 y* v1 E$ x6 D
# H7 I$ U1 @$ B+ n3 f2 u. E
结构体定义
% H8 V* {( }- ^; v4 M* n
1 J/ g' D; x2 j: ]/ r( a: E$ B
typedef struct L_Node{
( A ?& x: I3 k& x/ F# x
ElemType data;
1 Y: C$ x4 G# {, M
struct L_Node *next;
d( }, ?7 `1 n" Z- `$ t" b. u
//struct L_Node *last; //增加可变成双向节点
. w$ [9 g/ J- F1 O1 x
}LNode;
7 V( U/ T' m# x1 Y1 g
5 w" G/ P6 A( |0 z7 E
初始化
' d3 N* P" Z6 x/ d
/ W! s# H6 [) Q9 H: {' Z
void LinearNode::InitLNode(){
1 P- W6 u2 {; l
HeadList = (LNode *)malloc(sizeof(LNode));
! l) _! X9 i7 Q6 Z% Z: F* \% J
if(!HeadList){
7 v: q; H% P8 k X3 w
cout << "初始化链表失败!" << endl;
6 ]7 ^" V7 [! w/ ] w
exit(0);
5 I: z$ ?+ ~! C$ Y- f
}
( l# \. ~6 E4 c4 ]. G' Y X. y
EndList=HeadList;
2 |) N4 Q- ]6 C8 Q, w& E! O
HeadList->next = NULL;
; i' B, S8 ?$ v) `
cout<< "初始化链表成功! 初始地址为:" << HeadList << endl;
3 w( C% S q& @* Q
Length = 0;
, c4 {# e: M: x7 y
e_where= 0;
- I. R: g( X4 r$ x
}
& m$ K; N/ h# W% |0 _2 x
. x5 l- [: _9 S" _' o
增加节点
6 k6 ^8 W/ U) ~: W! n1 a
9 G9 X6 y" B* V, t) R! A
void LinearNode::AddNodeHead(ElemType num){ //头插法
3 [. p6 u+ @, F8 [9 ]
node = (LNode *)malloc(sizeof(LNode));
. L: `) l4 B9 v% y+ O$ [0 Z B9 R6 {2 v
if(!node){
a# d5 m& u" K4 }* I
cout << "新建节点失败!" << endl;
$ f1 K/ i% U$ H6 S
return;
! |' {7 e8 p* W8 X
}
& t) G" l7 Q$ g% b
node->data = num;
3 d5 G* M1 q) l! N3 W
cout << node->data <<" ";
, Y! A6 a* x) {( G& M
if(NULL==HeadList->next){
! J5 S5 w! P& @1 l
node->next = NULL;
: ~: J/ z9 w' S. l6 X) ?, G
HeadList->next = node;
: n9 n0 W8 W- z
EndList=node;
( B2 T+ T+ E7 M+ Y& M# ?9 O
}
0 b- Z" U+ d4 @ B% g) a8 O
else{
4 ?. [7 k& c, W4 B* C9 c
node->next = HeadList->next;
; @' L/ A2 m4 W- |
HeadList->next=node;
# V# j8 u2 \0 ?+ I: J9 i
}
5 c6 W) i6 O ]- g+ |4 d
Length++;
" }3 b, K: ~2 U/ W6 {
}
: S2 S& {" i3 K6 T, x3 B! a0 R% }1 x
+ r2 ^. _) n/ a
void LinearNode::AddNodeEnd(ElemType num){ //尾插法
" D+ H1 n4 Z. D/ m+ U
node = (LNode *)malloc(sizeof(LNode));
7 b* p! T+ L6 u; ~7 [5 \& g
if(!node){
/ h, x" \* a4 g/ D6 f
cout << "新建节点失败!" << endl;
" o4 f0 N3 c7 c ~4 D% z2 }
return;
: w6 x5 l0 q4 V# E
}
, E5 \9 U5 i, H# j: u* G: B
node->data = num;
: c z* |1 @. b! X
cout << node->data <<" ";
3 W0 ?5 V6 d" x# K( V }2 n T
node->next = NULL;
3 ^6 g* s# c" F
EndList->next = node;
% c8 f, `/ O, O, G R5 o: Z
EndList = node;
6 v* {& T6 Z- @! e
Length++;
* d! Z" K. c1 X- d! ]
}
1 V$ o% S+ U4 {# |" u
s* i+ v3 E p/ L1 B
删除节点
5 n) a( X+ m% D
N5 t6 ^- @( a- F. P, ]; W
void LinearNode:
eleteNode(ElemType elem){
8 v y7 W8 B' \& b6 f
if(NULL==(HeadList->next)){
2 p$ x! a1 H/ {3 Y9 s0 D6 ?
cout<< "无节点"<<endl;
. Q( ^4 @4 H0 o# n, ? @
return;
+ N. t. x2 G$ T7 I2 C/ }5 o1 _/ w, I
}
9 @; p! B; E+ M
Node_cur = HeadList;
% ]$ t! K0 d" B, E7 k
while(NULL!=Node_cur->next){
% M3 c! L' m }
Node_temp = Node_cur->next;
& g( Z0 u* N% H4 u
if(elem == Node_temp->data){
2 c7 q4 ^# [! E6 z8 r# ]
Node_cur->next=Node_temp->next;
# O$ J' C9 j6 |# K M# d ^0 G
free(Node_temp);
% y Q5 d# a) z7 ^' x( q
}
& `6 a* H5 `2 R8 Y$ l
if(NULL!=Node_cur->next)
/ u8 @& ~7 S; F ^$ L/ @( x9 U2 _
Node_cur=Node_cur->next;
7 C' @3 [7 s% B/ N/ s0 n
}
! m% o# H6 \- {- J- }
cout<< elem <<" 元素已删除!"<<endl;
2 l& G6 R# T& x9 A
}
! e6 `0 P L. ~/ p1 F
1 D* o0 C4 @7 A
显示链表
# K; ]1 @4 B8 P% V5 a$ n3 w' X% h
; `6 {* e: o, e
void LinearNode::ShowLNode(){
4 N+ `; r- A1 c% C! d
if(NULL==(HeadList->next)){
" r0 `' d" n1 Z3 j7 }
cout<< "无节点"<<endl;
1 d9 a2 U- s$ @8 B3 f4 d
return;
9 q) Z0 N' Q' i
}
8 o3 B% o' K$ y5 u& `) E3 g1 F- V
Node_cur = HeadList->next;
& Q- ^/ p/ X2 R
while(NULL!=(Node_cur->next)){
V" T+ Q& a6 R3 G6 C
cout<< Node_cur->data << " ";
5 ^8 G% t8 j! P; }
Node_cur = Node_cur->next;
2 y) w q( q' Z, e5 B9 T K3 q
}
* m" A# W4 X+ `4 b5 H4 X
cout<< Node_cur->data << " ";
4 M0 n& H$ G$ Z' j! u9 |
cout<<"链表中的数据已显示!!"<<endl;
" T6 z& x- ^7 m" u% P% m% m
}
" n6 G5 I. j& {3 M
# q2 v+ ?3 _1 p
销毁链表
5 B3 E/ T4 @! t% b( g& J6 M) G* d; j8 e
1 H' @* R. _/ x5 U1 E5 W
void LinearNode:
estoryLNode(){
: p6 {% f) `6 C3 m
Node_cur = HeadList->next;
# P$ d* j7 E1 ?/ B/ w0 x
while(NULL!=(Node_cur->next)){
& ~+ Y1 ]" B! @" k
Node_temp = Node_cur->next;
$ K0 W w. n$ n8 h# k5 k
free(Node_cur);
: N. \8 n4 X* k- w9 H; \! d8 ~+ Y
Node_cur = Node_temp;
6 `/ l* u& V- G9 o5 n
}
6 Q7 A+ j0 d+ }! z5 M
free(Node_temp);
* j8 h( g6 B, ^
cout << "数据节点已完全释放!"<<endl;
' {* w$ q }: n# k
free(HeadList); // 释放头节点
o5 C% t- I* @5 L- k
cout << "头节点已释放!"<<endl;
+ n' J) U" ~% _3 A9 I0 ` s0 O
————————————————
; j4 l3 D$ w: Q) [
版权声明:本文为CSDN博主「星河有鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
) [! M+ T9 Q0 N1 d' j& y
原文链接:https://blog.csdn.net/Baimax1/article/details/106036286
8 j0 L$ [8 j% M1 w2 R. c( M
+ E6 C/ P; d( F5 W, \9 v( p
/ U2 _ z C% \6 m- C _
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5