数学建模社区-数学中国

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

作者: 杨利霞    时间: 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 W7 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 X8 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) evoid 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/ ovoid 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$ Btypedef 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! Avoid 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, ]; Wvoid 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 e1 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