数学建模社区-数学中国

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

作者: 杨利霞    时间: 2020-5-10 16:11
标题: 线性表顺序表示、链式表示实现方法及其异同点

5 |, O# Z9 M# {% [+ i线性表顺序表示、链式表示实现方法及其异同点! g4 x& e' ]) u! b. F; h
线性表是最常用且最简单的一种数据结构,按存储单元排列可分为顺序表示和链式表示两种方式。
# ~& I0 j. O9 X7 Z2 `* u+ E" S: i$ d  m* b6 |" g
本文采用C++实现两种表示方法。; O: |+ R1 k  ~& j# n* J' \

  S+ O+ `: w2 ?. c( U目录
, H( o3 E+ v& n# v) M0 X( x
) v6 _8 X$ K. o, v8 r( _+ P3 u顺序表示和链式表示的区别:9 [: ~. D* c  {% E" P+ C1 t
& j3 L3 x. f" y7 Y' d0 `6 u0 L( ]4 n6 t
创建方式:: P4 u. ?9 F2 G, [2 |/ b: E7 B
+ z. i, {% z" o7 y$ I2 N' e
时间复杂度:2 Z, z; Q* {9 w, F- X
$ K$ O7 j) o" l
顺序表示和链式表示的相同点:" [. [" d& R+ K' H5 Q7 U% T" ^) |! v
! D9 R! [$ T# W) C' _% f7 D$ c
删除内存空间:
) n$ ~. |! k! \% u4 p$ [+ a
$ G% A; c% W9 T0 F: M5 @代码实现:  S  S6 U* h$ [9 t# @! m

- H8 S; h+ l. R! B9 O, {) N6 a顺序表示方法:  |9 }' e! H' V
- x0 A" D5 X" X- V/ P# S5 f
结构体定义0 q6 |! d: Z- [# k

! [* z! I- f6 X+ J初始化. v8 n8 X4 }% S5 ~$ k; U

# [2 c, m% O6 ]1 r增加元素
2 G5 i" t0 H" Y
, O$ d; K+ T' J% R7 x删除元素! ]! |; U9 c- e% I& x# B  I

' y# r" b  \+ T/ ], `) ?& k销毁列表- O, v8 C5 {4 m" P

0 X  o" }2 K0 k链式表示方法$ s" j. U  x& ~: x/ t; v8 S8 J( v

) v) M  w' Q" a0 S结构体定义/ ?8 D) x& e5 r7 R6 ?7 m, [

! F1 I8 x; y6 }) u初始化
0 R# h: p2 B  {! W6 o, u6 s' T, g5 M
增加节点
& r* A# n: z3 C; l/ L' u( Z8 [
+ U3 x3 ]1 {" M% {& y删除节点
1 G+ g% O: O5 H
. C2 k4 ?2 y+ z' M% U% G6 \3 X& ~2 Q) p显示链表# `2 y, S8 Z2 ]& Y
% j, P* P% z( Y3 o+ J
销毁链表  O6 Y1 L8 J4 Z% X8 [8 X
9 F' Q8 e& b# K0 H$ R9 B# X$ ~" }0 S8 z
顺序表示和链式表示的区别:
+ u% ?4 ^$ z4 Y7 b* u/ y5 g/ g7 C' @- c- X  u$ U% [
创建方式:" p; ]6 n9 M( F
3 `  b7 E2 B6 a9 |1 K
顺序表示方法单次创建多个存储单元,相邻的元素存放在连续的存储空间之中。: _4 h8 X2 o  R0 }( S4 I- |

( x. P& M8 z' c' r6 O(PS:内存空间申请请参考https://blog.csdn.net/Baimax1/article/details/105954552)8 e1 S# ~& ]- Q

/ @2 d* z/ h2 o% w5 h0 l+ A链式表示方法单次创建单个存储单元,存储单元之间地址不一定连续。存储单元包括数据部分和地址部分,数据部分存放需要保存的数据,地址部分保存下一个存储单元的地址(单链表,双向链表的地址部分同时也存放上一个存储单元的地址)。
6 r" h1 {! Z/ G% ^* a& n+ C6 a% X+ t7 ~' K
时间复杂度:
5 t. x( J+ ^$ A- Z& h
  G7 S/ s; R, P" R1 X& z增加 / 删除元素操作:顺序表示方法 O(n);链式表示方法O(1);(PS:在未知位置的元素前 / 后操作)& c! E+ E) r, D# e2 V% X& \

3 [( B8 ^9 b- n$ n& k' ~/ d增加 / 删除元素操作:顺序表示方法 O(n);链式表示方法O(n);(PS:在已知位置的元素前 / 后操作)6 ]( r/ Q5 X. O' M4 B1 G

  Q5 O6 k# n) J  n! Q& w: XPS:顺序表示需要将元素一一后移,链式存储结构需要查找该元素的位置。8 m6 h0 k" Z7 a5 a- |
! X! M2 S# M+ v
修改 元素操作:顺序表示方法 O(1);链式表示方法O(n);# P' ]! r7 J) `4 `0 T9 v0 w* S9 {

0 n( E5 e2 s9 T, M2 J5 P, m, n% w) J查询 元素操作:顺序表示方法 O(n);链式表示方法O(n);* _+ e$ c6 P( f3 i: ?# Y* s

5 A0 f/ O; b5 S3 r顺序表示和链式表示的相同点:& J8 S6 X* j* {2 R% ^

, f& v) c, b) N7 @5 m! m/ l删除内存空间:
2 N9 L+ j& p" S# h5 d. L7 v/ t) ^  f" R- T3 i
内存空间的删除都需要对每一个存储单元单独释放空间。4 y5 z  n' p* o' J9 ^$ e
7 g# h1 U2 n2 b- Q+ g7 A3 s1 [! d
代码实现:1 U/ P; @# c/ F9 S) ^' G/ I
$ W- ~$ x2 t, S6 z" ?1 i$ n( m
顺序表示方法:
, o+ j" @' B( i9 K& I
3 {- e% L2 Y. z1 o结构体定义
  L. ~+ b" w# I( n/ S2 t$ M7 T* l5 e
typedef struct {
. j( j1 s. Q/ y. Z/ c    ElemType * elem;% ~3 S0 K: J  D, \+ K
    int     length;        // 线性表的现有长度 & f4 Z6 D, c( V) l- X* U
    int        listSize;    // 线性表的最大长度/ N' N) F! m6 J+ X' C+ Q- A4 D7 ]
}SqList;0 t2 r2 j; R+ d

$ ]5 y8 D2 g6 b初始化& o. t) ]/ b" C" N& r. |6 `
1 V( A" s; q) z, u: M6 J! v
void InitList(SqList *L){4 Z4 g- O9 c3 A, j. c
    L->elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType)) ;
" l! N$ a" I2 y$ e    if(!L->elem) {2 e3 ~; u2 `2 }  l- S0 ?7 F
        cout<<"申请空间失败!\n";% S' m1 L# T. a  ?
        DestoryList(L);3 V4 u! x* f4 g' F! h' n7 F1 b
    }5 A4 Z2 r* i( g
    L->length = 0;9 \0 A' C) v1 _; Q2 t
    L->listSize = LIST_INIT_SIZE;
7 s" [5 n, k, Q: o    cout<<"线性表初始化完成!\n";
; k5 h) y+ @9 l& M) l8 V$ o6 j}/ Y; {( |* m0 ^' P

% o5 }! Z' C7 Q; p1 I: c增加元素( _9 E* ~& Q1 P

1 ~6 ]! }4 _1 k" L7 Ovoid ListAdd(SqList *L, ElemType e){  //在末尾直接增加元素
7 |/ \, l8 V- Y! j1 g! d    if(L->length>=L->listSize){( i5 z8 s1 I+ l$ d* f3 E/ S7 C
        L->elem = (ElemType *)realloc(L->elem,(L->listSize+LISTINCREMENT)*sizeof(ElemType));/ {7 p' g* J# e- g8 x" ^, o
        if(!L->elem){
) N4 H" D9 M) c: I' s            cout<<"增加空间失败!"<<endl;8 e% B% G* D" p
            DestoryList(L);, v2 [! E$ f( s. m. N
        }
8 G* g: [6 p1 X) J; e! g    }5 q" P4 J4 f% w8 s6 D
    * (L->elem+L->length) = e;4 t4 n* s9 k: C1 N& C5 B
    L->length ++;    % t3 ~; ]" L) v3 U
}/ O8 N6 w$ W' n9 J% n$ {8 J& D4 H
+ [( w4 X/ ~, G& W- q, Y" S4 ^
void ListAddBefor(SqList *L, ElemType e,int e_where){     //在某位置前增加元素( c! i' b8 k! b; a) k
    int i;% v* F! \1 G. [0 [3 g$ a
    L->length++;
" w* G$ _' u' m+ s$ [    for(i=L->length;i>=e_where;i--){
: c' s. v* e  |3 J( v+ z/ Y- V" p        if(L->length>L->listSize){$ }+ j* p& V+ |8 S. [1 c
            L->elem = (ElemType *)realloc(L->elem,(L->listSize+LISTINCREMENT)*sizeof(ElemType));( @4 P) T( j) P, Y$ B& B& E
            if(!L->elem){
& }1 F0 _' J- K6 T                cout<<"增加空间失败!"<<endl;
7 g8 ^3 ?( P1 P" B: C1 r                DestoryList(L); ; @! ]. X0 g1 i2 @, j
            }
1 O) P" ^; v" E) V" p/ T7 w0 B) S        }
2 v9 L; ~5 L  Z8 U4 K3 [        *(L->elem+i+1) = *(L->elem+i);          c4 d' G! F! h5 W" l& r: e
    }
) ]: t) ^/ w+ R3 w+ \4 c6 f$ U) \    *(L->elem+e_where)=e;' V) ]: K7 K+ Z2 J3 I+ L& Z
    cout<<"增加后的线性表如下:"<<endl; ! g( O. h' C! r* T) C; Q
    ListShow(L);
$ D& l2 A2 k9 K7 u; g9 o}
! _" G1 |, V: P; e# \6 I+ c6 v
+ Q! [% O# F- s5 L& i6 U  C+ Hvoid ListAddAfter(SqList *L, ElemType e,int e_where){     //在某位置后增加元素! n# Q/ ]$ a- q2 G8 A
    int i;
+ [! I# f7 A. A- V+ C' [/ }: I; A    L->length++;
3 m- f# f2 P+ h/ C2 s* ^    for(i=L->length;i>e_where;i--){* N+ l' r) D* j
        if(L->length>L->listSize){: a' r! q0 [: b, k* h
            L->elem = (ElemType *)realloc(L->elem,(L->listSize+LISTINCREMENT)*sizeof(ElemType));
* v0 m0 |& n$ y% N3 a            if(!L->elem){
8 {" C) p# o# K! Y" r                cout<<"增加空间失败!"<<endl;
8 I* D9 E1 A; X# H2 j6 t4 q  f                DestoryList(L);
% N% ^2 B4 W+ r; l" i6 r            }/ J5 O/ C; _+ F0 b& R
        }
7 L' L, r& U' B' `+ w  q        *(L->elem+i+1) = *(L->elem+i);        
* C- K& [& j* Q$ _) T/ B+ A0 t7 |' F    }
2 d1 z! H# u) i4 h    *(L->elem+e_where+1)=e;
' X4 |' A8 n! V    cout<<"增加后的线性表如下:"<<endl; ( x  ?9 F2 V6 n/ _: q
    ListShow(L);
4 y8 a4 q8 S+ u6 h/ e. w}
/ _) _3 P. D' q. l! _
6 h8 J0 K8 l' c" y删除元素
0 p1 K0 e1 M/ D4 x5 \+ |! G: ]% H1 }# R; }: H
void ListDelete(SqList *L, int e_where){    //删除某位置元素
& e( q0 f3 q# t/ D1 ?    L->length--;- O6 X+ a9 {1 D$ R7 y
    for(int i=e_where;i<=L->length;i++){
. g1 V$ t, Z+ M8 O9 q) o' C8 Y        *(L->elem+i-1)=*(L->elem+i);
; Q: S7 W2 f5 Z$ b# c5 }1 x    }
+ {8 [% K; h7 I- v5 T- e' r    cout<<"删除后的线性表如下:"<<endl; / @" o) s, v% G" N7 S. Y4 g
    ListShow(L);
% Z6 f3 g$ S( r# }7 c# Q, K( D. r}, ~7 y$ m. s5 `0 G9 `5 A+ D- \
6 t9 g. V! P8 ?( K7 s& `8 F* I
销毁列表
! p. _+ a$ B+ s
9 T7 p; O# k# M+ B# `void DestoryList(SqList *L){
9 ]1 `6 l' n( E; W    int i=0;7 i  z- e2 m* Y  ^
    for(i=0;i<L->listSize;i++){" h( O) @9 X; f0 s/ C' A
        free(L->elem);
3 }; T, D' M  C+ ~        L->elem++;
) ~% r/ h, d& d& K% C& S    }, D: `1 o9 X  v
    exit(0);        : T% ?% e* V' x9 v! j; a7 U0 B$ u
}
6 N6 {$ \0 J* D8 s. m8 d+ L% b. A% l  ~3 S$ d% U  `. R+ ]! k" r/ T4 Z
链式表示方法
& P" R1 O0 d1 z6 S. V# C) I
5 Z+ }$ T% M9 l$ ^0 g( I: G# \结构体定义4 v: k) M4 }8 z- D9 [8 m& y9 x
9 u& c6 m2 L  h- f
typedef struct L_Node{
9 g, s; Q4 f5 m: E1 _( v    ElemType data;- h7 S" \7 |* t' E2 C# W3 z
    struct L_Node *next;
  u4 d. w% r  G/ T    //struct L_Node *last;    //增加可变成双向节点 % B' R  U' a$ X
}LNode;
, B0 r- k6 f7 ?; B, Y
! Y5 D" T' h4 O初始化
& f! j& A0 ]. C0 T& ^! ?& o+ m
5 e. e+ @2 |* ?, z3 i& U' @$ |void LinearNode::InitLNode(){$ E9 w  e5 F6 M) M- O. M
    HeadList = (LNode *)malloc(sizeof(LNode));
; k2 n% }1 O2 }6 @- i" P* |2 f    if(!HeadList){
. [  Q; F% F1 R' d1 c        cout << "初始化链表失败!" << endl; $ c* j" A! y4 x3 @
        exit(0);
7 r3 }1 f, i: M9 @    } ' X$ o' Y6 J4 L( [2 u
    EndList=HeadList;
8 ?( p8 v8 T6 s! \5 Z    HeadList->next = NULL;
# ?* M. J3 S8 r' `3 [4 ~. Z' E    cout<< "初始化链表成功! 初始地址为:" << HeadList << endl;! N4 _, f5 v( K  ~: y  ^
    Length = 0;
! g9 @- U% r3 o) a$ [$ }9 x    e_where= 0;2 ~9 t9 v! q8 `2 i
}
+ x- @, O7 c$ ?' H1 A
/ p5 l( y* `+ T4 z7 \+ i增加节点& v. f# |2 |+ Y' b- A

0 c% l# q" a- i) B1 H) _void LinearNode::AddNodeHead(ElemType num){    //头插法
# S! F! X, o' h    node = (LNode *)malloc(sizeof(LNode));; o7 d3 [8 v9 T
    if(!node){' e( p5 d7 F/ a) f; |2 g, `7 C
        cout << "新建节点失败!" << endl;
) T% ^( O- e+ A' K2 R8 t3 |( S        return; 2 P8 w( ]1 ]5 j2 j2 V
    } 0 ^% L: b% G; }, s) Y( J6 f9 q
    node->data = num;
; w. R0 Z1 U2 V( T    cout << node->data <<"   ";+ q' v9 L7 S: F+ g% f* v
    if(NULL==HeadList->next){
: A! A, _% q! y0 u. {        node->next = NULL;
" y2 w. o/ c5 ]3 Q        HeadList->next = node;. E2 z0 f- R' D# ]
        EndList=node;
- |+ q6 Q% l2 \, I    }9 N2 ~/ R, b2 V
    else{6 q% x3 s2 a2 I" k& j) n
        node->next = HeadList->next;
" F2 Q& }% A, ]4 Z( h/ X) x7 o& @        HeadList->next=node;6 q" }) Z. C! p& _+ t0 c; j6 j# H
    }* Y' Y$ s# h# F/ O9 _! L
    Length++;
9 K4 e0 K0 p  _$ Y& ~/ m; s  A}
% [0 [$ J7 e/ {6 l" K& V
6 ?. ?# {$ Z4 g. |9 G& j5 ]% Fvoid LinearNode::AddNodeEnd(ElemType num){    //尾插法 , B* G8 \/ S) p& R& A" f$ I# }
    node = (LNode *)malloc(sizeof(LNode));
; H3 Q3 [1 Q7 S% k0 I$ O    if(!node){
8 w/ Z, a- @. t        cout << "新建节点失败!" << endl; - M& U3 b9 P7 l+ K# k, K# H
        return; ' G5 f+ s" R* O
    }
) B: h; \2 s6 T. p: S7 M    node->data = num;( G/ C! k* b  W% x
    cout << node->data <<"   ";
: M1 L! B3 {& [4 P( Z" e& P    node->next = NULL;+ D" G+ ^6 Z+ L! c( b
    EndList->next = node;
' t. O- F! G1 L. f1 L+ @    EndList = node;
9 X9 N) c( T( I, l    Length++;
# e! E$ c' r+ L5 L8 m' _1 W0 m}
& k' C' e# N# V: h" W$ e
6 H- d0 n, r9 g  ~5 }删除节点
; M% q' F/ j1 z7 O4 Z& ^* a
& ^3 d/ l! d" E5 svoid LinearNode:eleteNode(ElemType elem){
- ^6 Q8 U! ^8 |( t5 `. h    if(NULL==(HeadList->next)){
) v9 g( m& Z% x, n( Z  R3 Q" R        cout<< "无节点"<<endl;; f, [0 _- h. W( |% j5 U
        return; 4 d/ V/ @4 y3 d; c
    }
9 f) c$ k0 c6 J9 @- O    Node_cur = HeadList;
- n. l9 c- d$ P, g! H! N0 }    while(NULL!=Node_cur->next){1 d- B* l; L1 t9 `4 x9 t* r
        Node_temp = Node_cur->next; 6 b0 D1 L1 M& ~- |1 C. T
        if(elem == Node_temp->data){0 _. I9 F! W) H
            Node_cur->next=Node_temp->next;7 j4 f. k0 u8 f9 k) f7 T  k
            free(Node_temp);
% m) Q: {. b1 F) p  r1 C1 k" m; E        }
; j' f! g- F( T) L# S. t        if(NULL!=Node_cur->next)( E& W* |$ I+ O3 H* o
        Node_cur=Node_cur->next;- p; z& D, M  s8 J# ~
    }' _9 r1 ^- E+ F& W( n
    cout<< elem <<" 元素已删除!"<<endl;
) Z. Z( i# V- b5 }6 _% R5 [, i} , U0 Z# q6 k# h* c; B

- B/ e: w# K" r. E$ `/ x显示链表
9 e. Z% z2 K6 T3 E
% J4 D5 x1 s  Y3 z+ Y% J" `3 }# Jvoid LinearNode::ShowLNode(){
4 f5 Y  H) V* d6 U+ g0 Z    if(NULL==(HeadList->next)){3 z* W. m+ _9 O, X* ~
        cout<< "无节点"<<endl;
( c7 |, w: |. I" `* c- d        return;
; Y% D% J' n( T+ G9 R; Y$ R% f0 j    }
: ~5 n4 t: R4 q& z# T0 h    Node_cur = HeadList->next;
. W+ Q" D7 ^. d* x# N& q    while(NULL!=(Node_cur->next)){* M7 t3 O* {7 V! N+ A  X4 t- m5 Q8 J
        cout<< Node_cur->data << "   ";
0 ], u9 E) }$ k% `0 X1 K        Node_cur = Node_cur->next;0 J4 F2 _( a# o( G
    }6 c3 Q. O5 u2 H
    cout<< Node_cur->data << "   ";% L2 w0 ?- t) ^2 f- J! S. t
    cout<<"链表中的数据已显示!!"<<endl;
+ h' ^' o9 }+ C. ?( \}
. y8 U+ h0 |, S$ p/ |5 V2 C* w
6 }0 H% ]3 C5 G2 b; F% a$ F销毁链表
. H" _. x8 d* X7 ]4 U- o, f' Q
- U0 l. N' l# A9 O9 B' \; Z- ~void LinearNode:estoryLNode(){$ @$ c: N' t6 b6 U8 |+ u
    Node_cur = HeadList->next;
* N% e$ b$ R* {7 F/ I$ T7 I    while(NULL!=(Node_cur->next)){
/ h6 J: D9 o% \& `/ N        Node_temp = Node_cur->next;, K, K+ U1 \" k
        free(Node_cur);
: ]( j& o6 w  [" [- Q7 q+ b        Node_cur = Node_temp;. s, {2 e/ o' [$ ]0 ?9 I  |
    }% D2 q: N2 h  K, b1 v5 W
    free(Node_temp);+ {0 a5 L2 D9 t( v# ?) t
    cout << "数据节点已完全释放!"<<endl; 8 }- X3 b; U" Z( Z# {$ U2 u: m
    free(HeadList);    // 释放头节点 9 _8 [' e, F; }
    cout << "头节点已释放!"<<endl; ! D  R7 H; I8 q& Z6 ]
————————————————# y; B8 X! T( b1 A) }/ h
版权声明:本文为CSDN博主「星河有鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
* G+ k5 z  M% ?# p原文链接:https://blog.csdn.net/Baimax1/article/details/106036286% J9 ]; A/ L3 j4 H* Q% u
1 U3 }7 p8 m3 f3 K

# R& `% g" S8 d5 S" x/ h  u




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