数学建模社区-数学中国

标题: 线性表顺序表示、链式表示实现方法及其异同点 [打印本页]

作者: 杨利霞    时间: 2020-5-10 16:11
标题: 线性表顺序表示、链式表示实现方法及其异同点
% ^3 s7 ?4 w0 s9 l% Y5 w0 l. m8 Q
线性表顺序表示、链式表示实现方法及其异同点. o% w' q' I" X! j. N/ t: w
线性表是最常用且最简单的一种数据结构,按存储单元排列可分为顺序表示和链式表示两种方式。
) S! k' b3 C! j9 V3 m+ X0 _/ k* m4 r5 H$ D. b) ]# K
本文采用C++实现两种表示方法。
) h2 Y5 V9 |* |5 m" @" H4 Y8 w/ G4 i/ z" w2 b
目录( W. g4 S( V3 l4 u
' [0 _* c" ?+ n# A6 r! y0 J
顺序表示和链式表示的区别:8 ?) g! W$ K6 w8 Z$ O

4 Y3 A, v# d! \2 _8 V创建方式:1 w6 D" G( m9 [) W. P
* l/ g/ V" f" k$ p+ H
时间复杂度:0 ^+ j6 }5 }& F6 A0 R' s

+ K) E3 h- a4 F: E( U0 S顺序表示和链式表示的相同点:" `3 h2 w/ P+ w. E. }

% t% X- B0 [% F3 e删除内存空间:
: Q- e% F  N: Z* {
8 o, Z! W) O+ V" c% o代码实现:
8 L' L/ v& X/ D# _2 K
9 u( Q: O; e7 C3 S' }顺序表示方法:
4 D5 r7 [/ A1 M* [
' G9 q2 r, k" e, ~1 b/ Z结构体定义& @2 \6 T. k( A$ W9 e. B% d$ y
- `) }) S$ a) c& K
初始化
6 C$ L8 {' C6 ?
$ ~$ w5 M6 Z( z7 H$ b+ R7 d& o增加元素( `5 f- F6 R7 b" p7 n$ h
# W8 C8 ?( P/ ?9 g2 J
删除元素
4 v8 H$ l) U; Z8 q$ A) p4 {7 @8 h4 T' H2 x7 E, n
销毁列表
' W$ |! |( L9 V. J/ g1 Z& S
" M& r" q* n; [% t3 e9 o7 z, O链式表示方法' t# D- @$ O% W8 n
! I; e6 B% w6 i1 J
结构体定义
& \1 G$ x5 R" Z( {! I' f5 S' }& M  R2 i8 a8 c9 D6 U
初始化/ g; C/ R9 z' c; X7 {: L9 c
7 N0 ]% w- P( S( L  }  L
增加节点
% u6 S" g+ Z0 e( @. u
: b& |* q4 }. f  |: F- E删除节点6 I5 K/ F& V/ D; J1 ?

) Z# r! \3 A% a1 X, E/ e$ N; r显示链表" g" [6 O6 S2 z! T1 C( D' _

1 {4 ?; l/ ]1 }2 I3 }0 n7 L8 H销毁链表
. I4 @3 {8 N$ Z9 o5 M; a& @$ _/ F9 I6 ~2 d5 B/ r
顺序表示和链式表示的区别:( y2 e  ?: }$ x) ]

1 [6 l- p$ B1 c5 Z! U  O创建方式:3 |5 j# q4 ~( t

. _( S" i- x5 U4 ~+ t顺序表示方法单次创建多个存储单元,相邻的元素存放在连续的存储空间之中。+ y& B6 }! D3 F8 ?9 O) ]
0 z/ O: ^. w$ d* y7 H. C( X
(PS:内存空间申请请参考https://blog.csdn.net/Baimax1/article/details/105954552)) ]' }  \8 z( Z; S5 O6 E

! C$ |$ C& W/ a' ]链式表示方法单次创建单个存储单元,存储单元之间地址不一定连续。存储单元包括数据部分和地址部分,数据部分存放需要保存的数据,地址部分保存下一个存储单元的地址(单链表,双向链表的地址部分同时也存放上一个存储单元的地址)。
& w8 I. Q" d% Z
; |0 Y! g- x# i# _: h+ q时间复杂度:
2 c! \0 Z, t2 F9 e$ m; D5 _
* }2 P9 l, t, v; c增加 / 删除元素操作:顺序表示方法 O(n);链式表示方法O(1);(PS:在未知位置的元素前 / 后操作)
- S' F( r! i" l  f9 [5 d' o% W7 L" f1 z4 F
增加 / 删除元素操作:顺序表示方法 O(n);链式表示方法O(n);(PS:在已知位置的元素前 / 后操作)8 D  i9 \7 }* n" w
% L: f8 q1 X% E/ g* K' x
PS:顺序表示需要将元素一一后移,链式存储结构需要查找该元素的位置。' X! @2 p- x( H5 l$ f8 X# M$ O+ G
: [; c/ k+ H/ q: N% f
修改 元素操作:顺序表示方法 O(1);链式表示方法O(n);
8 C& Y9 F  U; x7 _
& ~/ t1 c! ?2 P  ~查询 元素操作:顺序表示方法 O(n);链式表示方法O(n);' ?# J% J8 j1 y7 `# V' N$ f( [4 z

9 [1 d5 e8 E$ n+ k顺序表示和链式表示的相同点:, S, Q; M* _6 {* _

! O5 o: w" @6 G- Y; J5 n删除内存空间:1 T  U8 S! j  j  ]/ E8 \# S
; `1 w9 w1 X( o
内存空间的删除都需要对每一个存储单元单独释放空间。
( p& @% O+ |* [9 m6 ^& ?. a& y( ?* i# X8 ]6 g' o; V
代码实现:
# A) A' E" W& t$ U5 B/ {- f( l+ L* f: v3 l% J
顺序表示方法:
' o  F' F! p) b7 x" _! X0 j/ w% v
结构体定义7 Q; I* L# K1 ^( _; |, {& F2 K

! K2 J, @! Z: m& j5 z1 {typedef struct {9 ]5 w2 H3 X2 f5 U
    ElemType * elem;  @% k$ L5 G  N6 y& T1 t( z
    int     length;        // 线性表的现有长度 - \/ v/ g1 f0 V2 I+ J
    int        listSize;    // 线性表的最大长度
  ^- r+ o" V# T}SqList;
. C  G7 E5 V" [! G" D% K1 u3 {  N6 L- S
初始化
1 Q! G' ]+ N: v) f. n+ X- }+ Y! X' t) Z+ N3 t1 ~. i# l4 H! y9 v. H
void InitList(SqList *L){
- u2 T; x; f! X" [* e    L->elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType)) ;- \9 G' o" Q& X
    if(!L->elem) {' c6 H2 V/ I) p: V5 S4 j
        cout<<"申请空间失败!\n";
5 K6 u' p' w5 H$ U        DestoryList(L);# n4 R3 M( W9 v* U& r3 _" y
    }4 x  ?  m& L3 g" F" `0 ]" p
    L->length = 0;
" Z7 f1 S. u1 y2 D( |% d$ P    L->listSize = LIST_INIT_SIZE;
# v( j# I/ f; Q$ B  k# M* G9 v7 J/ i" H. L    cout<<"线性表初始化完成!\n";
9 Q, V# E- x9 F0 a0 B6 t! \! {5 w}
; l% W$ Q2 ~6 M/ F+ Y9 p. f: f; }4 E- }; N2 F
增加元素" i; \4 v8 T7 D# B" @5 N
1 F* U; y* P$ ]0 i+ l  a1 h
void ListAdd(SqList *L, ElemType e){  //在末尾直接增加元素2 T6 c& i: F/ S
    if(L->length>=L->listSize){5 e$ W5 F3 I2 p
        L->elem = (ElemType *)realloc(L->elem,(L->listSize+LISTINCREMENT)*sizeof(ElemType));7 Q. V/ @  U) w' I9 a0 e
        if(!L->elem){
* n( V7 m0 n) J  W3 E            cout<<"增加空间失败!"<<endl;( ]$ @) F1 O, f5 H
            DestoryList(L);* Z& ?: ]  R0 c: U9 W. ?
        }
& G+ z  l4 n, p! o) z' ^    }
2 L' ~# k  u  }; O    * (L->elem+L->length) = e;
  r9 d: P0 x' B- \7 X, n$ c    L->length ++;    # Z" N' T/ p* c  C
}
( P) Q" H0 v7 ^6 _+ I. l" l! [5 ^+ _1 U9 z* l
void ListAddBefor(SqList *L, ElemType e,int e_where){     //在某位置前增加元素  O/ N/ R% _  j: Q0 g0 J
    int i;: {+ f/ D+ D6 F3 Z
    L->length++;
$ E- @( G" {4 V# T7 K    for(i=L->length;i>=e_where;i--){
2 a9 V) w) j1 d) N        if(L->length>L->listSize){
4 \0 G8 t- Z" W7 u6 x; R            L->elem = (ElemType *)realloc(L->elem,(L->listSize+LISTINCREMENT)*sizeof(ElemType));
/ z7 G2 f' F$ P# C1 Z            if(!L->elem){
- h9 @% h# w2 |5 h6 j                cout<<"增加空间失败!"<<endl;' f5 D, B. C' Q0 r5 E! j3 Z2 l
                DestoryList(L);
# ^  ^6 F' s/ o9 A& Z  W+ B            }1 j- u. ?4 g7 C. u' L
        }. F5 q+ I1 p7 f) F/ p
        *(L->elem+i+1) = *(L->elem+i);        
. c- c% O; k" `    }: f, c$ x. l. [. b+ [6 E
    *(L->elem+e_where)=e;
1 C/ q  ^5 c; Q1 ]# |    cout<<"增加后的线性表如下:"<<endl; 6 o) R( ?5 s, S$ a
    ListShow(L);5 ?" ~# t( P) B8 L# k" A
} 4 O. s8 t$ B* U7 t; G6 F+ |

, e. V5 B# A; Z. q" Evoid ListAddAfter(SqList *L, ElemType e,int e_where){     //在某位置后增加元素6 i5 I% {6 w& G: m
    int i;
3 ?1 c, H9 J6 e0 r    L->length++;
' x. O! @% n; |( Z8 r    for(i=L->length;i>e_where;i--){
9 E4 Z; ^) H$ G5 J7 _: |* h3 {% t        if(L->length>L->listSize){; x7 K7 s5 A7 ^3 o
            L->elem = (ElemType *)realloc(L->elem,(L->listSize+LISTINCREMENT)*sizeof(ElemType));! n2 R3 ^( ?" h& w8 r
            if(!L->elem){8 V7 Q- {& R; }, T# \; P( ^' t
                cout<<"增加空间失败!"<<endl;
; `' P+ H8 ?7 e" K                DestoryList(L);
+ b7 w9 ?- Z8 w4 \3 B2 J            }
; n9 s0 k6 D& F        }; a* r2 Y0 W5 y2 n7 c$ M, u
        *(L->elem+i+1) = *(L->elem+i);        
! [1 o. T/ @; r! f2 t    }
$ R" q; s% q' U6 w+ I8 h" y" C    *(L->elem+e_where+1)=e;
3 G2 F: I4 K$ a: p; a( w    cout<<"增加后的线性表如下:"<<endl; 9 y5 a- K% q, [* B1 N" ~; m& Q7 J
    ListShow(L);
' I1 X( _1 |/ K# l" [; z) [, U" z}
) H9 v& }9 G8 W; A% n+ c
/ p& g9 H' w; e( r# ]2 n删除元素
0 F# _/ [: a: c  b) M% Y( D! ~1 `3 o8 X% w& J, W% c6 D
void ListDelete(SqList *L, int e_where){    //删除某位置元素
' M* e4 T- R1 X* k. h" A9 q1 a    L->length--;# G# c! y1 R6 k2 z
    for(int i=e_where;i<=L->length;i++){! [( y# o2 e, D8 H( O6 Z7 R
        *(L->elem+i-1)=*(L->elem+i);2 c8 h4 a7 a' p- z- P/ n2 z
    }
" e1 y9 k6 @! x! C    cout<<"删除后的线性表如下:"<<endl;
$ e+ f$ ]# Z0 s" p    ListShow(L);1 X6 ]2 D: y, _1 u5 ^) p
}' @' L8 s' q+ s5 K! `

6 V/ `2 C' K, n0 b* F8 i; M销毁列表
# }% z! b/ Q5 c% E* W6 n0 w$ d) l* v8 w8 o( t
void DestoryList(SqList *L){
' `( w$ W  K. o2 b8 o1 E    int i=0;1 s/ Z6 j" {1 u% s4 Z  H2 O
    for(i=0;i<L->listSize;i++){
& Y3 t7 O, Q% G" M; @* q9 J        free(L->elem);% I3 x' H' u/ @" b/ {, I
        L->elem++;2 d0 a5 L- p, @* n
    }: K6 s  F0 }! x0 f
    exit(0);          \) w) B/ r7 z9 I& i
}
9 d2 T- g* }$ H+ z; h2 p" R2 X# ^& x5 P
链式表示方法6 P: Q6 e; F% _: H6 ~( o

8 n; A1 ~. L% y结构体定义7 C- F3 k& L  V& ]/ }

5 a, p( p6 g: Rtypedef struct L_Node{( q4 P) \7 v5 Q/ `) R7 k, \
    ElemType data;; r$ c  P1 M$ K8 {$ r/ N
    struct L_Node *next;
' }1 `3 h9 Y" X. S0 d) E    //struct L_Node *last;    //增加可变成双向节点
6 F3 l* ]; t+ Y5 C}LNode;
) ~& i5 Z4 d! q  K0 [8 z6 L
$ Q, r6 n5 w6 C! `  s初始化
9 d. a; `5 O2 m9 H; {3 `+ N
3 q; k" }7 g, Z" S$ jvoid LinearNode::InitLNode(){
9 a( `" c( C2 I    HeadList = (LNode *)malloc(sizeof(LNode));* x5 {) n  A+ F; K- Z6 S
    if(!HeadList){
! B# X/ [) K* z! D/ t        cout << "初始化链表失败!" << endl;
, c& [& d0 S/ Y; _& j) u9 \$ T        exit(0); $ K1 L8 [1 O4 I
    }
" a" j. Z/ r5 n6 x    EndList=HeadList;
/ \) J# T  [0 o; G    HeadList->next = NULL;
( {" w! n2 p0 Z  S    cout<< "初始化链表成功! 初始地址为:" << HeadList << endl;
, x, {' g" ?3 \$ e# M5 R% w9 }    Length = 0;5 |4 [8 p7 |, @: X' |
    e_where= 0;
6 Y( g( L8 m6 n1 |, [- _' U( J}
% u$ |. e$ ]4 w. V5 D% |- C% j, A$ R$ H
增加节点
9 E2 |: K) g  t8 _
' m' ]9 z7 Z+ q' O0 c7 Evoid LinearNode::AddNodeHead(ElemType num){    //头插法 0 B4 K8 y8 C6 x9 T4 _1 z3 v: d- A$ T
    node = (LNode *)malloc(sizeof(LNode));
* O0 @# e+ S5 f2 D    if(!node){
% H  O. G, y  h2 K6 p- ~6 R; i% N3 o        cout << "新建节点失败!" << endl;
) {3 n2 E# m( g, `        return; . j5 R" r* m8 Z) A6 X+ ?
    }
9 F, Y/ c4 o3 m4 C, ]4 [' q    node->data = num;
) M8 v. H, K* V) l8 }( }2 S9 R2 l: X. N    cout << node->data <<"   ";
' b& O1 _1 Y  U7 Z% h8 L    if(NULL==HeadList->next){# R% r' M/ z0 E+ G" S' Z3 {
        node->next = NULL;
2 q. A( I5 Q6 Q. y% y7 {% U        HeadList->next = node;
, B. M* c4 |0 l& ?( k& u, r        EndList=node;
. [1 n9 s$ W0 u$ u    }
2 o: U) N7 _2 ^6 n( w& j8 z    else{
! R9 U6 G% T$ B# g) U& I2 `        node->next = HeadList->next;3 L& w* y7 X' I( c1 i- S
        HeadList->next=node;% ?- ^; W4 E1 f8 ]/ Y4 m" g9 [& U
    }
6 p$ C% I7 v. B9 _    Length++; 7 @$ e- l" p5 C
}; t: U; ^3 Q4 [( j; c0 ~) @# [9 q

3 |( ^' C% E1 g. K. ^1 Svoid LinearNode::AddNodeEnd(ElemType num){    //尾插法
. x, ]+ r5 g* C2 A& B    node = (LNode *)malloc(sizeof(LNode));. I/ T! H  E  L3 k3 w/ t
    if(!node){" X4 s0 Y+ x) E0 r
        cout << "新建节点失败!" << endl; 9 p+ M+ E. n$ r' o8 A
        return; 6 z' n& u: j, S8 L: N& j" n" V- u& z
    } / j0 a) O/ S+ @+ L9 s$ o6 Q# K* \
    node->data = num;
. U8 V3 w  D, w" p    cout << node->data <<"   ";
& I* K- P2 V+ J( m+ U) t    node->next = NULL;
. d' H! _. c( q3 M7 Q  I6 p! {    EndList->next = node;
1 ]* Q- [1 W# }4 U/ C" w- _4 r    EndList = node;
8 f% ~( w3 H! v, I1 u9 u1 p# |    Length++;
, U) i: A$ @9 J$ m( |5 d* L}$ ]9 r2 n, p; v: E+ p( Q

2 l& p4 f5 o% {- `! s- g/ }删除节点
) K* d5 L! U% T$ d0 W& S
, @  A7 c3 n$ c, O6 Y- Fvoid LinearNode:eleteNode(ElemType elem){
+ m5 F5 k% w8 {8 C$ H( ~    if(NULL==(HeadList->next)){
1 y$ q6 k9 G* l0 f4 m5 _        cout<< "无节点"<<endl;, ]- K4 ]/ P1 H- [7 R% u. S
        return;
% e5 E' u8 R2 [9 ?0 w7 p+ S    }$ I3 K2 \1 E* m7 s8 q7 Y
    Node_cur = HeadList;" f# d4 e0 x4 ?: X# B. {
    while(NULL!=Node_cur->next){
( h1 E' o  Y8 f% R  _& U  i9 Y        Node_temp = Node_cur->next; 7 [, q, m6 P( D0 Z$ t0 P
        if(elem == Node_temp->data){- g/ m0 B. r3 |) ~
            Node_cur->next=Node_temp->next;" y, b) v8 Q. S& l
            free(Node_temp);
, ]2 D' d/ B" ~$ k0 z# q        }  {1 T4 d) Z2 f4 H2 b2 L; p
        if(NULL!=Node_cur->next)9 I$ k& \1 a& z
        Node_cur=Node_cur->next;9 {6 G& x6 A/ S' f
    }
% u- a8 ~# |& L( y: Q* \    cout<< elem <<" 元素已删除!"<<endl; 3 p1 d1 _" d& E3 V. c* z! t
} ( }( [9 X' Q6 o% ^$ ^7 v% k
1 h! K* u% F" D6 v: h( ~" x* v
显示链表. O* K, t( `# J1 m; C1 _
$ i9 c) o; u5 P$ A( S% L
void LinearNode::ShowLNode(){
# \8 I/ K1 g/ `# l3 B1 }: T/ b$ S    if(NULL==(HeadList->next)){5 l4 {! R" M4 F# N6 B' M/ |
        cout<< "无节点"<<endl;
+ U2 t1 C7 H. t5 E' p        return; 6 D; B7 _: D' I4 g. X8 L
    }
- M7 U7 @. i$ v( X8 H) }8 ~    Node_cur = HeadList->next;
# l2 p4 N, Y6 ~* W: T% S    while(NULL!=(Node_cur->next)){! k9 P' T8 n# l% x; L4 O
        cout<< Node_cur->data << "   ";
! w3 Q# v' w9 b4 H6 V0 L        Node_cur = Node_cur->next;- k" ?6 M5 J# F  w1 m$ K
    }
- T, g8 o8 _: w5 ^- F9 T8 J    cout<< Node_cur->data << "   ";' j0 D; s3 P% s& ~% j8 b
    cout<<"链表中的数据已显示!!"<<endl;8 u8 ]$ P5 j; j+ L3 H- q
}' ]) X& _6 Q( x5 N# y' S2 m3 a" X
7 ?* D1 S, T  g: w/ T% E+ o' R8 z  K
销毁链表
4 l1 G! V1 \6 U" s
( j, J# K2 B+ nvoid LinearNode:estoryLNode(){
8 k, t& w, `- R/ j8 b    Node_cur = HeadList->next; / i/ ?. T1 c# K/ n5 D+ ^
    while(NULL!=(Node_cur->next)){) |- n+ |7 f* A1 w6 J& F
        Node_temp = Node_cur->next;9 B; v' v: v, r3 X8 d0 \  [
        free(Node_cur);
* H) V' Q  z1 M- ~        Node_cur = Node_temp;2 X; ~  r0 @% N% z  H1 H: T  N- R
    }0 g& K+ k$ x5 S" q
    free(Node_temp);" j  E# P& X# d. t
    cout << "数据节点已完全释放!"<<endl; . e1 ~  i5 \8 O$ k& |8 M
    free(HeadList);    // 释放头节点 / m0 N$ U/ S! P; a
    cout << "头节点已释放!"<<endl;
& [) x4 @5 v8 F————————————————
! y% N( m# M! k6 u3 s. x8 p版权声明:本文为CSDN博主「星河有鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。* k' h$ }3 j2 W) O5 t$ m. l
原文链接:https://blog.csdn.net/Baimax1/article/details/106036286
1 F8 \" f) C( `8 f% \# u8 }8 f
; H$ h. M8 O0 d$ U8 |! a9 ^4 m1 b# a





欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5