数学建模社区-数学中国

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

作者: 杨利霞    时间: 2020-5-10 16:11
标题: 线性表顺序表示、链式表示实现方法及其异同点
6 H2 w. D' }! |5 {' a
线性表顺序表示、链式表示实现方法及其异同点+ A$ ?5 W, r* T. A/ p" Q3 t7 w
线性表是最常用且最简单的一种数据结构,按存储单元排列可分为顺序表示和链式表示两种方式。
* y" x( x; f3 e3 v2 @  f$ Z3 Y
& J5 R& @$ E; d9 a! F本文采用C++实现两种表示方法。1 d% Z& x5 o. ~3 z7 S
+ V9 Z1 D+ t* D0 q* I. O# i& q
目录% X8 w0 {8 }/ A8 W% B
! `3 G- ~$ a1 U& _9 M
顺序表示和链式表示的区别:
# W$ W5 P6 V2 e6 f. n( G1 B' s
  e: e* ^' [0 }创建方式:
! @& A) E; T; x0 ~8 u
1 h& H: g% t/ I5 A& w5 M) n' D时间复杂度:
. K  J: }9 B5 g7 G3 U  l2 G" H& }& N" O$ x* n# K
顺序表示和链式表示的相同点:# c1 E8 C$ B0 M% l3 g! B  s

4 e$ n2 ^* T4 A3 n8 J# e删除内存空间:
3 P& D9 ^- J: \% F) E, u2 C4 k* o+ |+ }( U8 a3 J# S
代码实现:4 o/ r9 G- L3 S
! \5 |2 S5 M3 o+ U# C7 o7 k/ W
顺序表示方法:
- D; J) K+ j& a$ L% K% {
5 R. ^! g7 T" [. E' C1 Y结构体定义
5 P4 C. j" Z) z4 B6 `
3 Z$ \- |) m! _& T/ F, U7 i" j初始化
' u# M0 ^+ }% ~# Y: D  h/ l; v1 T. _& b' P; I( j
增加元素! u' v5 g3 j& I( D6 j% g

2 u. G4 |4 {5 o( _* A3 ~0 c9 m删除元素
5 q$ ^5 G2 N3 B1 v9 W. n3 k) u4 V- g4 i; v3 n/ z, e; Q( c
销毁列表
! l* |( a; W7 D6 G! t% n. [, _- e& O) O
链式表示方法
, X9 J0 b5 X5 x  }% K4 H* z0 D* v. H9 A& q- \: P- ]
结构体定义$ v; u$ h3 z; L
: p+ x0 u$ b0 }) k4 R: r
初始化
( L/ P" [5 [! T( D, F6 L: u6 _8 N; I) \5 a
增加节点
9 c3 e5 q& M0 d) N+ L6 `" [- R
1 M: l. [9 f: R# s删除节点  W6 X$ ~7 f' m0 g

+ M# x- j7 v# v0 ]5 g显示链表
* Y/ z* K5 _3 I7 h* y8 W
$ ?$ k5 g, @* S3 F* J. u7 |& D  L销毁链表' t* b9 H: k2 V3 f7 x+ s
- B/ i. ^& a$ ?* U2 Z9 d# s8 n
顺序表示和链式表示的区别:
- T- v6 g) `0 K( b; a7 X& O7 c2 J- o2 @2 Y. i
创建方式:
- j, V% K3 ^. B* ]0 |
$ O8 q  f1 y' v; K8 K8 a2 X. I顺序表示方法单次创建多个存储单元,相邻的元素存放在连续的存储空间之中。
: P& f# ~0 H+ R4 F+ w1 _, R2 j% H) F& c5 b
(PS:内存空间申请请参考https://blog.csdn.net/Baimax1/article/details/105954552)2 k' y  ^) ~* s8 }- g

/ M* E  P: B* T: ~" n- F* `* W( H链式表示方法单次创建单个存储单元,存储单元之间地址不一定连续。存储单元包括数据部分和地址部分,数据部分存放需要保存的数据,地址部分保存下一个存储单元的地址(单链表,双向链表的地址部分同时也存放上一个存储单元的地址)。; P  g4 m  V) [# B* i4 H

3 l' Z* V# Y+ T" i' F* e时间复杂度:) v! m5 h& s: d$ b. x! ~! {
$ y* t$ q$ F8 e( E! T* `7 F! {2 O' j
增加 / 删除元素操作:顺序表示方法 O(n);链式表示方法O(1);(PS:在未知位置的元素前 / 后操作)
3 v# p- @  O1 e0 q8 G( @' t' o! G! g1 b$ F2 ?4 w. f
增加 / 删除元素操作:顺序表示方法 O(n);链式表示方法O(n);(PS:在已知位置的元素前 / 后操作)( n5 g7 p, |$ C% P
/ C7 l+ l  l' `9 f# W
PS:顺序表示需要将元素一一后移,链式存储结构需要查找该元素的位置。
0 P) _1 Y5 ]/ `9 i
& ]; S# Z/ T5 f0 P修改 元素操作:顺序表示方法 O(1);链式表示方法O(n);" ?$ v& o" I5 T- p
  O3 @3 H' ]$ f
查询 元素操作:顺序表示方法 O(n);链式表示方法O(n);5 ?7 P& U) v% i& o

3 h9 g( Z8 j- i1 s! t+ g顺序表示和链式表示的相同点:: W1 l) ^, B" \  Y! v

9 A1 a( e" Q# T$ x2 d) K4 G& b删除内存空间:
( R# K4 m1 a1 z/ L  Q
  \* ]: d' G5 ?内存空间的删除都需要对每一个存储单元单独释放空间。5 X- ~3 ~/ Z) ?. u1 K# B, A8 u
: o5 R( x& ], ?3 Q. G( s9 u
代码实现:
9 A+ X; t! s( m. g5 z. p& e* p) k
4 Z* y. j3 S% p顺序表示方法:
0 g% q, T% E9 S, d/ n5 |2 ]( A1 t$ j# q4 p
结构体定义
/ i( T% Q4 x" x2 W
' L0 h* C$ C( R5 }0 X3 @4 r2 w" Mtypedef struct {' T  X2 i* g5 ~
    ElemType * elem;; |$ M' b$ i2 E2 E+ Z) E1 l. Z
    int     length;        // 线性表的现有长度
! @% z! _/ L: W. m    int        listSize;    // 线性表的最大长度; `& U2 J: @8 ?5 l( k
}SqList;% e3 E& m5 C. i! S7 B0 I; _/ w  e

9 P3 t- ]& G; N6 V8 ]9 {  \; V( }初始化
+ i* c" f) s1 b7 C
- {5 u6 b. C/ C* P  `! o/ g2 nvoid InitList(SqList *L){% _8 M9 \+ W( k, z
    L->elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType)) ;( M% _6 a' {( O
    if(!L->elem) {
2 M7 u! \6 _+ d3 q        cout<<"申请空间失败!\n";
2 V5 t( j2 }) A+ u( H        DestoryList(L);; o% M$ b8 `0 V
    }# p, p; A4 d" s/ @; Y; k- r8 I5 C5 G
    L->length = 0;- {2 F4 B) }" O( `
    L->listSize = LIST_INIT_SIZE;
8 K" ?# W; L2 q5 ^& b/ W3 Q7 {    cout<<"线性表初始化完成!\n";2 R) u# O& J6 u1 ~
}
6 f1 g7 j$ i+ y7 E% O: c, Q/ H% {# {8 Z
增加元素
/ ?  z+ C! f* `5 U/ E& m: W0 s6 R& Z
: ^. l; r8 g2 p9 vvoid ListAdd(SqList *L, ElemType e){  //在末尾直接增加元素
, w& o. s7 m7 N! L5 Y- t    if(L->length>=L->listSize){
, W4 G6 X0 l5 p& I: j! C0 J( q; B        L->elem = (ElemType *)realloc(L->elem,(L->listSize+LISTINCREMENT)*sizeof(ElemType));
4 S. {( Q: ]+ o/ L, ^        if(!L->elem){
$ ~3 }' w8 |+ w0 \            cout<<"增加空间失败!"<<endl;/ V3 T+ [0 O8 O8 b) y
            DestoryList(L);  K; E: H, b8 H7 Y, d/ o& j2 O
        }# b9 Z* X* O9 Q/ f: e3 a2 O! a0 {
    }; H4 H6 u- x& Y4 Q, F6 v
    * (L->elem+L->length) = e;* N; s8 @8 w& K9 b( u# B3 b
    L->length ++;    + m6 _: p$ B8 I" f& H1 ~  w
}
( W3 \, f+ t6 A* u9 s- i( I& {+ s' z* u2 o( P, z  ?! l& f! }
void ListAddBefor(SqList *L, ElemType e,int e_where){     //在某位置前增加元素
( e& l+ P" V0 X$ Y7 Z/ c    int i;
: z' h. ~( }$ R: f    L->length++;
% R; @' V9 z: B8 S    for(i=L->length;i>=e_where;i--){+ b# b  {! v' M; k  H' j
        if(L->length>L->listSize){" P" _7 ~: m& n  B
            L->elem = (ElemType *)realloc(L->elem,(L->listSize+LISTINCREMENT)*sizeof(ElemType));
! k5 K$ Q4 }3 D: x            if(!L->elem){2 V% _' |) e& o$ m9 o$ F
                cout<<"增加空间失败!"<<endl;' s2 j! p' J% l3 }
                DestoryList(L); ( a& }8 G; a( L! F+ k1 }* [
            }
# [% @1 z6 O$ D+ q& z: v; c        }9 b% Z3 [4 ?( w" v" Z
        *(L->elem+i+1) = *(L->elem+i);        
' ?* r# S# \- k    }' J! d8 p7 z5 j. T5 J) h- l
    *(L->elem+e_where)=e;+ `0 P/ @# k- ^( w0 u! C: ^
    cout<<"增加后的线性表如下:"<<endl; ; s, C! Z1 G' Z
    ListShow(L);
: ?" }" N. ?2 ]% V+ d0 `, h. ^+ ^}
% v, J+ z/ }  P9 ~
+ _; s& |( l! V0 J6 G7 q& J4 ~void ListAddAfter(SqList *L, ElemType e,int e_where){     //在某位置后增加元素
2 |% w) i$ Q8 v8 H    int i;! z1 G) y2 V: [+ Y5 k/ X
    L->length++;0 h/ `8 x: q" A! E* h+ V
    for(i=L->length;i>e_where;i--){
# `$ K3 R8 T; l        if(L->length>L->listSize){
# x8 z" p: O9 o* o+ |0 @) M            L->elem = (ElemType *)realloc(L->elem,(L->listSize+LISTINCREMENT)*sizeof(ElemType));# x# [3 n; m! {9 v
            if(!L->elem){" n+ g0 n0 ]- t  z+ x  v! F
                cout<<"增加空间失败!"<<endl;
: F9 @4 Z3 ?- R4 a                DestoryList(L); . k* v* R( I: v7 ^+ J* ]
            }5 i! y: ~: @: W8 g
        }
1 Q! \! U. u& o+ G: j4 q( o, v, r        *(L->elem+i+1) = *(L->elem+i);        & n/ @. N7 U9 w' R6 R( X; C$ Z
    }- o  Z; E8 Q, N! u. y4 R
    *(L->elem+e_where+1)=e;
1 t7 U$ h8 ~* d, U% I    cout<<"增加后的线性表如下:"<<endl; 4 S5 m8 ~* O: f' Q, C% d0 E2 D
    ListShow(L);
, E9 }. ?9 g; u9 b}
8 Y/ k8 M8 k8 c& ~% {4 W
' o6 n* I0 S4 T$ s删除元素
! p/ J' A9 x8 M; X% ^& W$ h& D4 d) u0 x  [3 Q, T
void ListDelete(SqList *L, int e_where){    //删除某位置元素
: O5 E7 d) ^% {+ T, C: @    L->length--;# E8 s8 W& p: q+ N0 g  I
    for(int i=e_where;i<=L->length;i++){8 b3 @0 K# s/ a
        *(L->elem+i-1)=*(L->elem+i);2 m. ^, _# W" l
    }2 K( J$ q; a8 C4 H$ q+ s' Q! n
    cout<<"删除后的线性表如下:"<<endl;
- v& R* \% I" S# i" q( L$ X    ListShow(L);
& X+ x8 S! @; \5 e}
6 q/ |! R- |- ]& e5 Z: t4 w$ n1 K) z* B9 o! u8 `( b; M: U
销毁列表
: s$ {# ]! m0 E$ I6 H; ~- C* D2 Y! g2 _( A) G8 j( ^
void DestoryList(SqList *L){
$ g3 a# H' m1 b6 S7 {4 _    int i=0;* C# Y& D" }$ g4 t8 [# a8 u
    for(i=0;i<L->listSize;i++){
$ S' q/ k: ]8 N! d& Y& |4 H        free(L->elem);4 ~+ u3 C+ U: o  u4 p! Z
        L->elem++;
) s8 g( A7 V' a! l8 C    }, {& M! n2 x! M2 F5 t
    exit(0);        - e/ k6 u! a. D4 v& {$ ~7 X
}+ r7 ?: y) B  c( A. s6 J% C

' |  ?# b/ F5 X% _链式表示方法$ f7 p8 H7 E( @, I9 c* k/ P
) x  d# `- ~- H; {0 H- f; ]8 A6 Y
结构体定义
6 i% s  [' v* N0 v' U: d; r" h. a; {
typedef struct L_Node{
) C. g8 C: b1 P- N. V' W5 y, G# u    ElemType data;
( Z* C% C" G2 D3 \1 X9 v    struct L_Node *next;9 R- C/ W7 H1 O+ V3 ^
    //struct L_Node *last;    //增加可变成双向节点 3 F: F# d1 `% N) J: _3 V# @: ]
}LNode;( E* h, b: h# @: }. J3 b

+ u1 l; I# v" X初始化8 }/ `0 C7 a9 v# M, D
1 |8 E9 m- ?2 @/ r: V
void LinearNode::InitLNode(){
4 D7 [, L2 W+ h% _) |/ ]    HeadList = (LNode *)malloc(sizeof(LNode));$ F/ s2 j  Z# D# ?* ^4 c- G2 p
    if(!HeadList){
  ^' q7 q1 s+ z" O5 p        cout << "初始化链表失败!" << endl;
5 k0 c6 d: @, s; A% [: g5 M        exit(0);
8 w) d( P0 E( F$ K* `; v    } 9 b( f2 j! u, J1 ~- Z
    EndList=HeadList;. U$ z$ \+ u% `
    HeadList->next = NULL;2 Z" y, D" N/ m. T& p7 e
    cout<< "初始化链表成功! 初始地址为:" << HeadList << endl;
# a9 H2 I! _+ `" ~: T! A- h* ?    Length = 0;
! z  H" @& K/ a    e_where= 0;
5 ]/ ]+ M. F2 d  {- Q4 F}
8 o* `' F5 x' j" x; V/ `
8 r1 q5 W7 [% _6 m增加节点
1 k: G( P  I( M
& a8 o# v- F; x" e8 p* Fvoid LinearNode::AddNodeHead(ElemType num){    //头插法
7 D3 H7 m' t" T$ P2 D    node = (LNode *)malloc(sizeof(LNode));
+ m; \: U% ]! z9 D    if(!node){
0 |& Z  F+ s; }0 P: Z  }        cout << "新建节点失败!" << endl;
- z9 e& A4 A) A2 J! |: V) T        return;
' ^( i) K  X% X. e    } 8 ?- p1 o4 t. k: W8 D9 H
    node->data = num;
' U* H3 r! t. t# Y1 Z9 L    cout << node->data <<"   ";: N' J' Q# `# v+ G7 F( M
    if(NULL==HeadList->next){
; ?9 p, Q  C$ r& G        node->next = NULL;+ [4 S" S8 _5 {6 k) t7 K( r
        HeadList->next = node;
( k$ q6 q; L9 Z. U; |# v- B  p        EndList=node;
! A0 _. c* e8 V7 r# ^; [    }8 z* w) ~0 V/ m0 |
    else{
$ F5 x# y  d- j; F        node->next = HeadList->next;
. e& B. H8 ]3 f" }( S        HeadList->next=node;
2 P/ f( T3 t3 |) D" x2 \; w    }* ?7 J2 X. b* e
    Length++; ! A3 J5 P5 j  @$ u4 P& R
}# {$ f$ s9 w1 W& A$ [

% Y; c! Y. l6 p& h1 I9 R( s: ivoid LinearNode::AddNodeEnd(ElemType num){    //尾插法
: H) u0 k% Q7 t# O( o, ^3 [    node = (LNode *)malloc(sizeof(LNode));) M- h4 }) O$ J% d0 l6 Z9 @
    if(!node){/ ^) z/ ]- Y/ i, u; i& d0 u9 v8 |
        cout << "新建节点失败!" << endl;
3 k) ^" `- w* h# ^  t6 m' ^3 r( U        return;
$ }0 T! X5 S4 K; ^) c    } ' d# W4 S% J- S: Y3 o/ y
    node->data = num;0 B2 e' G6 P. y3 t! b; T' n
    cout << node->data <<"   ";
5 n3 c5 E8 F2 [% f  A& w* W    node->next = NULL;
6 Y% x: a9 s0 m9 I  p& \    EndList->next = node;
1 H' n8 E% k, D5 z0 H    EndList = node;
' o2 C' k4 U& Y2 p: q$ k3 c    Length++; $ a& o# c) s* U. L* j
}, U: F/ C% o1 |
" c' k0 D- z7 g- U0 K+ z
删除节点! }& Y8 `; J% O: @, r$ [! `
  Q& X7 C2 n& |! o
void LinearNode:eleteNode(ElemType elem){
' G* d/ n, ^8 \4 {) @, c& H+ `    if(NULL==(HeadList->next)){1 b$ g$ O/ e# x$ D8 _/ Q( z
        cout<< "无节点"<<endl;7 P" J+ u; G# |; n5 M( x7 q
        return;
" w; V1 y5 W0 N7 s& k3 M1 _$ V    }1 N8 X; `5 w" {6 y' D
    Node_cur = HeadList;
+ S7 \7 R( v# O& o/ x    while(NULL!=Node_cur->next){
: t6 V( G5 J% Q/ B8 B$ Y        Node_temp = Node_cur->next;
$ n$ G; Y+ p: C3 V        if(elem == Node_temp->data){2 [4 c- u3 R$ _; u9 j
            Node_cur->next=Node_temp->next;
  F" S9 e. U% x- b4 J4 o  \            free(Node_temp);
3 F0 e( ]5 h, F7 }0 F( X        }
% J7 @% k' p6 g! t% R2 [& T# ~' Z        if(NULL!=Node_cur->next)' ^3 L% }# Y  e1 Q  Q
        Node_cur=Node_cur->next;/ S' W  k3 r3 C; P
    }+ n6 j) ^' G# ]' K/ a$ i
    cout<< elem <<" 元素已删除!"<<endl; % z# n3 E: E0 C8 |
} - r! u0 g/ p4 ^. _1 a6 X! O! {4 m$ L- m
+ |7 l" e9 t! \3 \5 m
显示链表  x/ \  C% ]5 @/ m) V/ z

  ~' b1 L2 i2 f" K) c: Nvoid LinearNode::ShowLNode(){
  B% w0 z( \- T$ V    if(NULL==(HeadList->next)){5 Z) J; k5 k2 A  o8 h* z5 u
        cout<< "无节点"<<endl;! Z0 n; w2 k1 `6 R1 o
        return; 2 P* ^$ `; t4 I# K/ D$ K
    }8 a* i: U# }6 y% [* E6 @$ m/ n$ c% v
    Node_cur = HeadList->next; ! G" K; x- @2 B( G! u- t
    while(NULL!=(Node_cur->next)){( y+ J$ M7 Y8 I
        cout<< Node_cur->data << "   ";& l4 Y1 R" y' F: v5 H3 r& H! M
        Node_cur = Node_cur->next;
, d% r$ z0 _0 l! O    }& ]& _4 f% T% g/ j, m, Y
    cout<< Node_cur->data << "   ";2 K3 M+ I; s8 D( A; ]
    cout<<"链表中的数据已显示!!"<<endl;
5 M8 |2 R- v- q, v" K8 I5 v}5 B$ H0 G  S- T
2 h7 H4 O' o, |( v- t* w
销毁链表; m5 O- Q! X% v* e

2 e$ {2 n) J- k$ j" c% Nvoid LinearNode:estoryLNode(){" i6 Q5 \! X6 ^( V: P
    Node_cur = HeadList->next;
; y9 l7 V9 v+ k7 d    while(NULL!=(Node_cur->next)){
6 M8 w4 ~6 s; B        Node_temp = Node_cur->next;- ?3 Z+ ?$ W( k* e2 o, l6 ]7 ]
        free(Node_cur);
, i5 E5 c. X+ J  w; L! R        Node_cur = Node_temp;
2 N# m. D, J, i    }
! |  [1 L) H5 F0 \, s! X1 H    free(Node_temp);
) x8 @, D% \' ^. {8 z& s5 [6 s    cout << "数据节点已完全释放!"<<endl; 9 q3 q7 S" q4 P1 m& p
    free(HeadList);    // 释放头节点 / U9 Q. g: Q% O! J
    cout << "头节点已释放!"<<endl;
0 \8 R, f0 L  l4 r' V' d+ [" N8 c————————————————. X, W# D8 J% ]3 ~! s3 r- x
版权声明:本文为CSDN博主「星河有鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
( G: _" {. X- J0 ?) `, `& g原文链接:https://blog.csdn.net/Baimax1/article/details/106036286
: ^& h0 d3 L2 n' H! Y  i& w0 a) H4 I. X* i$ J& V6 \# }
1 X( a! X0 n! [





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