QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1534|回复: 0
打印 上一主题 下一主题

图的存储结构——邻接多重表(多重邻接表)的实现

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2020-4-26 15:26 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta

    0 H. v3 i' a# y6 k5 i" C6 P图的存储结构——邻接多重表(多重邻接表)的实现
    # h) |8 w$ Z, \' W0 C7.2 图的存储结构# I# b4 j( {" ^' H. }

    - {+ ]* ^" G# c3 l* w7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    ; J/ {0 J. F/ i7 x/ g5 M) b邻接多重表的类定义( L# f. T+ K  Q3 \# T
    邻接多重表的顶点结点类模板
    1 k$ Z6 e" G/ O% o+ N  W邻接多重表的边结点类模板
    8 m- N, I$ N/ `* N' l; ~. v邻接多重表的类模板
    2 e$ p3 q, Z% Z; e3 `4 T+ `8 O邻接多重表与邻接表的对比+ g0 {/ c/ b3 |. l$ ^% D) Q
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    0 s! }- e# b" b4 N$ K+ X% F# @
    ( G! [% [/ z' ?& b: ?$ q在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。0 j* h4 s3 h) V7 m
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。% e5 s& q# N' N3 B8 @5 G
    9 s+ ?! K, D1 ^- V; [! t+ A, x# g
    邻接多重表的类定义
    9 ~5 x9 T, ^# ]8 _1 ^, Y) s5 @  j) U 1.png
    : N. S$ [( G# ~" P5 A. p邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    - c8 T0 u" Y4 j6 S/ M  j! H) V: {data域存储有关顶点的信息;
    ; O7 b# i5 H& y! t5 Rfirstarc域是链接指针,指向第一条依附于该顶点的边。! N9 R; [* _3 j/ A. B& f9 M
    所有的顶点结点组成一个顺序表。

    - M9 v+ n' S. I

    ' d. z- x# U9 c8 e0 C* F( A% otemplate <class ElemType ,class WeightType>3 Z8 J1 O- c9 J. g  _3 i+ D% X
    class MultiAdjListNetworkVex) i) T8 g/ N0 ]' v
    {- M% Y0 x6 s% I1 ^
    public:
    2 f' w6 r7 n. |% A# e3 a% C        ElemType data;" @* h6 M: W! F  E
            MultiAdjListNetworkArc<WeightType> *firstarc;
    " r! a" A/ P4 e+ D
    9 R- R& x, f- [% p" Q( _        MultiAdjListNetworkVex()
    6 U# k* C+ `( U% v  t" G        {$ U+ n) ~+ I# D+ q2 z1 c; L  C
                    firstarc = NULL;
    2 h; S! Q1 Y3 t        }$ D% d. W7 S6 }7 R5 e
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)2 ]- n7 ?8 I5 Q2 `
            {
    $ y2 K& t. N2 S+ h9 v7 M                data = val;1 ^, u0 [8 @* f6 J. P* B
                    firstarc = adj;
    ) b& g! A8 V/ z: f        }' d) ]. l& g# ~. A
    };
    ) C& ?' L5 U, e# n
    % c' @- @5 S# n+ W- j% [邻接多重表的边结点类模板2 `# [2 b& ^: S( G% I
    - ]* F4 N. F( f! `
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    ( C1 v7 C* G3 g' `$ H* ~tag是标记域,标记该边是否被处理或被搜索过;9 F+ N) Z5 `1 S5 g6 ]/ t3 v3 N" b
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    2 l) t8 s0 m" z( p1 v! [nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    $ H, q) [1 W: |' ]nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。& {2 {# j% d  ~0 r  o& o
    , |; I4 X# X& _
    2.png . G; {8 G0 G7 p6 l& L, k- ~
    template <class WeightType>& s! @8 L) N& a! ^# X
    class MultiAdjListNetworkArc
      P  }. `( T7 x6 S{
    : S$ U3 ]: U; d: P& p( B/ R$ jpublic:
    9 o0 A7 s4 U7 v$ A7 i    int mark;                                       //标记该边是否被搜索或处理过7 z. ^9 W& W; \+ N: y% }
            WeightType weight;                              //边的权重
    6 e4 F- k0 [' ^        int adjVex1;                                    //边的一个顶点( W4 W6 p$ Z0 f7 v& S
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    ' g! a0 {3 ]* n1 l2 r( H7 i* F# H        int adjVex2;
      G# \7 {9 [9 R6 i) M% N; m" q5 J        MultiAdjListNetworkArc<WeightType>* nextarc2;) N7 ?4 g* A* ^% d
    . x( @9 k6 f* x" {# t5 d
            MultiAdjListNetworkArc()
    ; o% G1 N$ t) A9 c" y& Q" ?        {4 o3 v- F  r9 Z4 a$ x
                    adjVex1= -1;
    ) g. h2 G, [' e& a                adjVex2= -1;
    # G6 x) k  f$ ?6 q* b0 P        }9 |2 e5 v; n, m4 F% A/ r
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)& Q- W9 I: X: E2 T. w, o; m
            {* r( A# C6 c! A! U) _' S: _
                    adjVex1 = v1;       adjVex2 = v2;% J  Q; B- {. M5 ]6 ~! V
                    weight = w;
    ; h1 X9 }4 U2 j$ m( A; c% r$ n                nextarc1 = next1;   nextarc2=next2;% o, D3 ^, K4 \2 Y( D% k: i' ~
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    ' i  W& B1 A" Z2 I& |0 W        }- D+ S, g4 z& h6 `- k4 E

    , K7 s: W4 t3 a7 X邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>( U; {- W! J+ T- j" @2 C" C
    class MultiAdjListNetwork
    - U& s$ |5 o: Z+ a0 P' ~) c& i{
    0 L% p/ V$ H# ^4 a" C  P6 v0 u7 Eprotected:" B: u* K' P2 p, G& L, J0 P- k
        int vexNum, vexMaxNum, arcNum;1 z# x& ~; v0 s: z$ @+ W: e
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    . D+ o) k' b8 @2 P    int* tag;- J5 L- X+ Z4 _" p4 S0 x, Z
        WeightType infinity;/ L5 [* i+ h8 d  v5 g( |: U/ Y

    & y; d1 c% Z2 _/ l- J' P5 qpublic:
    $ L: p0 c) U8 i* F    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);) X9 ]" `5 R+ L: j$ ]
    0 Z) J' B" G3 b' ^: ]5 }# g
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    ' ^1 ]: o+ ]( q2 A- [6 ~. K& E1 d& U) [! `6 v0 L
        void Clear();% q. l, e* P, Q% c
        bool IsEmpty(); \) O+ G$ E* P2 o* P: m
        {
    " p6 {/ y5 I, r5 o% k        return vexNum == 0;
    9 O  P' X8 l5 L( @    }# Y; n1 Q4 V1 g# {0 S" u
        int GetArcNum()const
    # l0 F0 h' b% \! T" c8 Q    {4 Z6 U9 U' f2 R, ^- E0 f( v5 ]$ O
            return arcNum;
    8 r8 ?  A2 B% T8 n/ D    }5 n8 n% [% N- S( B9 i9 W; h' a
        int GetvexNum()const8 {+ a/ f/ H! n; K0 R
        {' g( T3 D% F: ?
            return vexNum;
    - w$ v7 N* Y3 ]9 W: A; x+ g    }
    & V0 W8 N( n! |: J- b) r1 v1 l/ n5 a) z

    ; G6 ?7 o: N$ p2 w+ u    int FirstAdjVex(int v)const;& ]* O3 t, B9 c  x! a
        int NextAdjVex(int v1, int v2)const;3 _) Z4 f( e0 c2 R
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;5 t& i' P7 W# H: j  J2 z! |7 o
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
      l' _0 w/ x( ^% g  {' j, u. V* a5 H; h+ N% [5 z0 u
        void InsertVex(const ElemType& d);2 C5 Q& R/ J7 M5 {2 v" ?* _' Q
        void InsertArc(int v1, int v2, WeightType w);
    3 q# A% @1 e0 d
    0 a: q  l6 s+ e: F/ s$ \- u& f    void DeleteVex(const ElemType& d);/ u3 {- R# T5 D
        void DeleteArc(int v1, int v2);: E( w9 L. _2 H. s" W
    + @& H0 W5 e, C4 x. j/ ]; c
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    ; K5 t- n; k, Y$ h% J4 J    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    " s, o! s, k( b1 _8 J+ ~6 U! U
    . x9 `  Z; v3 `5 u) W5 ^9 J    ///深度优先遍历, M/ D( ~) G1 i& N  @1 s2 h, O
        void DFS1(const int v);7 S5 d" R8 l# D& Z% J. Y
        void DFS1Traverse();$ N! m  ~; d7 [9 P* i5 z
        void DFS2();+ Y) v3 j/ J. d( r9 O% `. D0 A
    ' l* {" K  T: G$ t! m$ P9 t, I% z
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1- R! y& o$ U; U5 i
        void DFS3();+ V: |3 J; t' U; h2 C
    & H3 {; M. t8 D. X3 n  B
        void BFS();6 A% s3 M0 O8 t1 V3 O% Y" s
        void Show();
    0 Y3 j9 R$ N4 T& Q5 L$ n- g( z+ V5 K};
    6 H; `- c% I( e0 \3 N. X( w
    ( Y1 \% b5 Z, A4 G1 a6 W6 [2.函数的实现
    2 I- T3 W  y' Z) f* I3 C6 T研讨题,能够运行,但是代码不一定是最优的。
    , J7 B. {/ J- c7 w  Q' x# _3 `9 W' h4 s  b& W5 m. C  o; ^1 z
    #include <stack>
    + Q, I/ y' p3 ]2 u" h( q1 `) x( ~#include <queue>
    , M, s$ R+ w8 j( H/ O
    0 a- q. u3 H' u- @/ G3 @9 Vtemplate <class ElemType,class WeightType>
    ) K4 U5 Z+ C) \9 R( wMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)6 j. `6 S5 H, T2 N* h
    {
    9 u. r5 Q7 H% h2 U% p  T    if(vertexMaxNum < 0)- f) C7 j1 ]9 ~0 e; u, l
            throw Error("允许的顶点最大数目不能为负!");
    ) r3 E  {% Y" p# R$ r    if (vertexMaxNum < vertexNum)
    1 {% c) P: R+ i4 F+ J* w* [        throw Error("顶点数目不能大于允许的顶点最大数目!");; }" N6 ]! z1 Q1 @3 K
        vexNum = vertexNum;' ]5 y8 w' y0 v2 E4 r  x9 W1 s
        vexMaxNum = vertexMaxNum;
    ) |, D/ u1 j7 L- ^- H    arcNum = 0;
    , h& t) Z" l# W& ]# }    infinity = infinit;
    4 m% U8 R; s: y4 q2 i    tag = new int[vexMaxNum];
    1 z( ~$ \' w5 l* b$ l; D    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];  T9 q# Z8 b5 ~7 [, o5 O
        for (int v = 0; v < vexNum; v++)
    . o) G1 S1 o, Y" |; ^    {# ]9 A3 }( |2 s! M8 [
            tag[v] = 0;
    % Z/ s, s* N# C  P0 j+ K5 j        vexTable[v].data = es[v];; Z7 {' H! w; s# s' K
            vexTable[v].firstarc = NULL;5 G' Y$ q) n/ _. I3 s6 G5 {. V
        }
    6 b+ F- `. p: U2 I* N}  f& }! M2 ~9 k
    template <class ElemType,class WeightType>
    ; K. G$ q" _( VMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    / b- @3 G. L. b8 C/ Z{+ Q9 m" q6 \1 F! A
        if (vertexMaxNum < 0)
    " i) z+ ]$ L3 M        throw Error("允许的顶点最大数目不能为负!");
    6 q6 T- G$ Q6 p, ^$ d7 N    vexNum = 0;
    % i( V% h1 t# Z7 c: A, z. l8 C    vexMaxNum = vertexMaxNum;
    1 m* E" Z/ c/ S) b% y% c/ a- D3 U    arcNum = 0;, l( [% F0 {' _( \. j; t! r8 [
        infinity = infinit;- T& d! o0 m; v% h) }+ f2 O& a
        tag = new int[vexMaxNum];
    ! i9 j: g* r8 f! k1 P. u    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];3 C4 L% y% n9 @0 k+ A  E  L
    }) [) k2 N* A" ~9 D+ d
    template<class ElemType, class WeightType>3 O2 X5 B+ [+ S) I; d) a% V
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const$ d  R& S' f  \$ P1 m( N5 m8 `$ W$ j
    {9 O3 V$ D# S' n" x9 z
        if (v < 0 || v >= vexNum)
    2 K! e0 C# @! n- {2 [        throw Error("v不合法!");
      u# ^# k/ L. v' F    if (vexTable[v].firstarc == NULL)/ t% a2 F) \# b) K
            return -1;
    8 O" C8 j% {2 ~    else9 N1 c& O( g, I# e
            return vexTable[v].firstarc->adjVex1;4 A, w: s( S. x5 F: e
    }' e7 g+ [/ H& `- G# _" }
    2 ]3 \( `" g5 r0 i. J* U2 d
    template<class ElemType, class WeightType>
    7 x7 i2 q& l5 t$ m& W/ m/ fint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    5 v; J2 Z, {+ N; ~& U{& @% D' Y3 `: R7 Q# H% \
        MultiAdjListNetworkArc<WeightType>* p;1 K, d' y1 s9 r' Z3 K
        if (v1 < 0 || v1 >= vexNum)' M4 A: Y7 U/ Z3 v! o5 t+ `
            throw Error("v1不合法!");2 C& e* Q$ j' v$ ^! A+ a) ]& S
        if (v2 < 0 || v2 >= vexNum)
    . l) j! \/ L; W: g. T; J  [! O        throw Error("v2不合法!");
    3 w2 [: D# y& R, R7 ~' T/ q! ]    if (v1 == v2)
    5 g4 J# _4 b- D2 b  I        throw Error("v1不能等于v2!");6 J3 ?; y5 K+ D9 [" l
        p = vexTable[v1].firstarc;4 Z1 d8 J+ C  J! U6 y" Z2 Y- b
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    9 p. H0 C( X  ]* v9 s. z- H5 w        p = p->nextarc;- _- O! w6 Y$ u
        if (p == NULL || p->nextarc == NULL)
    # p1 _# N0 R% o: I% F& \6 e        return -1;  //不存在下一个邻接点
    1 ~3 V# N( _2 [    else if(p->adjVex1==v2), F3 f! [8 L* Q# e( T* y/ ?9 Z
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    ) W  Y- X9 S/ _+ f8 y# Q    else
    5 \0 @& {/ G# [' M; I3 d        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);/ g4 d/ k0 w6 o' p/ ~2 V1 ?: [- G3 J/ ?
    }
    ; o1 |) @( S) }  Wtemplate<class ElemType, class WeightType>0 I0 z0 K. S- z4 a9 ]3 J
    void MultiAdjListNetwork<ElemType, WeightType>::Clear(): Z) N$ p3 l7 k. [4 _- N+ B
    {: E/ F2 b+ [4 H
        if (IsEmpty()) return;, z+ r* S# j4 l9 m
        int n = vexNum;
    + U; }% A5 [. C0 I5 O4 ]4 V0 g    for (int u = 0; u < n ; u++)' p' u: G/ y" u5 M
            DeleteVex(vexTable[0].data);' _" D; H% [& k8 v% w3 ~8 _
        return;
    7 r; O) S. a2 U+ u}
    0 y; R5 F0 T! Q( _template<class ElemType, class WeightType>
    1 j; e" g3 V  {7 X" PMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()+ U1 u2 C0 J0 V; X: X
    {3 r* w- z1 Q) Q$ ]
        Clear();8 u  h6 ~! w# M4 E% M9 s9 V9 t
    }) v7 h/ g" z, s% I6 e1 \0 Z  x2 q
    template<class ElemType, class WeightType>' ]9 X7 r0 ^( m* a& ~/ {% c* W
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)# T0 i; n& s6 ^$ i" z
    {: E3 w: t/ V" V9 c% Z( u6 @0 Z
        vexMaxNum = copy.vexMaxNum;0 S# P, ]2 K; x+ J* J2 R, }1 C; N7 y2 |7 Y
        vexNum = copy.vexNum;
    5 i; s2 j$ _# |0 f* J    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
      c# g2 ]" ^& n7 N5 e! q4 ^+ H    arcNum = 0;
    6 \/ P, S0 @. c4 U    infinity = copy.infinity;: J* O& ?0 p" _% W0 U3 }: l3 d
        tag = new int[vexMaxNum];
    ' S+ m, V9 [& h/ {
    ( U: C) K+ @, l" A% F7 M( ~    for (int v = 0; v < vexNum; v++)
    0 ?# r) ^2 V/ |" `- T4 B" U    {) ^7 y' h+ r' Q! i9 ?- C- H& R
            tag[v] = 0;
    & u$ {  ]" n7 m  Q& E6 o        vexTable[v].data = copy.vexTable[v].data;
    1 u* [, c1 K2 f; L) P8 s! }        vexTable[v].firstarc = NULL;
    ' Y. J6 ^/ B. w    }% A4 ]% a" n# k$ M: @
        MultiAdjListNetworkArc<WeightType>* p;* a, C1 k) u- j( v3 p+ b
    . _+ n9 t2 ?  Z2 Q) ]
        for (int u = 0; u < vexNum; u++)1 ]  m+ O, A3 Z" h6 d( N) O
        {7 f2 c$ v1 {! Q9 X$ x0 F/ c
            p = copy.vexTable.firstarc;
    - z- v, A/ ^6 X5 U+ B( t        while (p != NULL)+ u# P* S* E7 r  I
            {% b( S+ q  B( M$ X8 ^' |
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    ( R5 V2 [1 w- s: I9 I            p=NextArc(u,p);' m- X$ u3 ]9 F" g9 i7 E
            }
    ; {& h  b- ?4 ^3 e    }8 r3 {; S8 j/ U2 I' N2 C
    }/ Y$ F: J' p  j* W
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    # u* ?* p) s& FMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    - I; N6 R+ @% M! H; r{: Z$ w/ n  R8 x' _  z3 i/ D
        if (this == &copy) return *this;1 j7 ^7 C  z  P
        Clear();9 |/ o  S4 K) L" x/ h" F, K* ]
        vexMaxNum = copy.vexMaxNum;. n/ [* Q/ e5 t: `! e0 S
        vexNum = copy.vexNum;$ [' j' }$ x$ g1 q
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    ! U' \! Q9 {) }& m# c    arcNum = 0;
    + X& ~2 ?: q/ Q, E    infinity = copy.infinity;# u" ^$ M6 T* t6 E) L/ ^: f
        tag = new int[vexMaxNum];! i" V* D3 Z# b, j

    ( b" E. O4 x7 ]; N6 }1 C6 i    for (int v = 0; v < vexNum; v++)
    9 a9 |" Z! n) F4 [" m/ s    {& s+ m. `- @- n! _4 ]) T
            tag[v] = 0;
    * z6 p* o+ f# K- r" s8 v8 g        vexTable[v].data = copy.vexTable[v].data;
    2 A% m2 s8 N: q' q' ]6 g6 J        vexTable[v].firstarc = NULL;8 Z; D( y4 ~* J; l
        }
    3 F3 I& {% s" e: _) P    MultiAdjListNetworkArc<WeightType>* p;
    . h. Y% f: \2 K4 K) \0 w9 J. x7 m7 j( x
        for (int u = 0; u < vexNum; u++)
    . ^& K% o& H1 a; @9 P% P- p6 U0 O$ W    {
    # n  k# ?8 S* Q. \- Q. v1 f        p = copy.vexTable.firstarc;5 ?6 A) r' P* ~/ y+ E3 h/ Z
            while (p != NULL)
    ) \1 ~, x4 Y+ E' ^+ x: U0 Q: W2 i        {
    5 a3 o3 e* l( l% e9 m            InsertArc(p->adjVex1, p->adjVex2, p->weight);9 E% W" j2 ^2 F+ F8 [0 F
                p=NextArc(u,p);
    " Z. ]! a" S. s7 s& U0 W: r        }
    0 V( X7 L  V% [3 M0 T/ B, O    }) e1 h% Y! s- z6 ]1 T% m
        return *this;0 {- v( @. G1 I7 k. k( H$ \
    }% n" V; Z. Y8 B2 s( P) v: J
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*2 z0 U0 `1 ^7 H5 N# J+ g- Z
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const" K* x- }6 N0 g$ n5 N6 `
    {$ w+ Y8 T# r$ J  g' {8 C. w
        if(p==NULL) return NULL;
    " n* p$ }: p0 S    if(p->adjVex1==v1)2 I5 E) T, e3 m8 {( g+ d: ~- G$ b
            return p->nextarc1;
    0 }) _5 ^3 k! A, {0 |' K8 O    else3 a/ s+ }8 k# V% Q  q3 L3 M
            return p->nextarc2;
    # m" R0 }$ I& h* ~) V7 D5 u5 C}
    ( |# ]+ R. x/ Q' [2 ttemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    2 ^; v% u  K' u% q' B, \. eMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    : T* G# x0 ^3 m8 i( k& l6 X5 G6 \6 a{
    4 @/ Y! Y& l. ]6 S    if(p==NULL)return NULL;6 J. z7 u2 [, v. B4 x+ [1 H: ]. }
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
      w$ s7 v) j" N    if(q==p)6 _! Q! |7 t8 S- m6 Q5 B# K; O
            return NULL;0 N, b3 f/ h% U8 S7 T
        while(q)8 y0 w: P& i2 h5 f! O, r
        {9 p9 _3 E) r, O* [( `( L
            if(q->nextarc1==p ||q->nextarc2==p)
      f8 {9 i, d5 p) H% i1 z( f7 M" b            break;! M& ]% n% Y8 q# y1 F, P
            q=NextArc(v1,q);0 W# p- ~  M, I# U$ w
        }+ w9 u8 c$ [' J* I
        return q;
    . R3 I9 _5 [: G0 l}
    4 V  t# L) m& U& |template<class ElemType, class WeightType>
      Q( j2 w8 e% Ivoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    / O  L5 u! R# D8 Y, i{
    9 u! f# Y0 X: W: a2 G  N    if (vexNum == vexMaxNum)
      \! j) {' p9 a" L6 J7 F        throw Error("图的顶点数不能超过允许的最大数!");
    4 E0 M* N- Q( I+ A) A5 O    vexTable[vexNum].data = d;
    2 ^/ q9 Q9 ?4 M    vexTable[vexNum].firstarc = NULL;# D+ u' ?% d$ D  i+ k! i+ M/ H
        tag[vexNum] = 0;
    , H5 f7 B& q9 Q" w0 ~. ?& t    vexNum++;
    * k4 R6 W% r! }9 ^2 _0 f9 x' v}1 R. P* t" d. p6 P
    template<class ElemType, class WeightType>
    6 a9 V# B# B- B  w$ `void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    / S, ^! K( L0 p. Q: Z{( X7 p4 s2 D6 }, ?
        MultiAdjListNetworkArc<WeightType>* p,*q;0 T: T" R: k+ q" D$ z5 e
        if (v1 < 0 || v1 >= vexNum)
    0 o6 P& ^$ Z# a; _4 E: P# ^        throw Error("v1不合法!");8 [' S+ S, R" X( g( H
        if (v2 < 0 || v2 >= vexNum)% M+ |* t: |. d/ }
            throw Error("v2不合法!");
    ( |8 S3 g1 u" G) l7 k% i+ S    if (v1 == v2)
    ! S( ~6 l- R; X& s1 k. F8 o" E        throw Error("v1不能等于v2!");5 m6 J' O) d* i1 j% E
        if (w == infinity)+ S& D, x$ {- m3 m2 ^( j
            throw Error("w不能为无穷大!");3 X$ O. L' y) j4 p

    4 f+ c: @0 P4 p. T7 s- q
    6 `* C6 ]3 z; E' l% p    p = vexTable[v1].firstarc;
    : j# ]5 ~# c3 D    while(p)
    ( I2 J! u0 E) A    {
    ) o" }" M% ~0 A# W- w/ a5 r        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    0 v5 N( G; s6 H) o9 @0 f        {; E, a9 w4 g" l# E' O. j' T: M
                if(p->weight!=w)+ w: h( i6 |/ e' [+ G6 ?: M: E
                    p->weight=w;
    : U8 E2 Y  o4 i6 `            return;
    ) n! n$ E" @- q! k2 S7 Z        }
    " N- N" f; c# a  ^0 n+ B# N2 D
    % {' t/ i$ w: o5 a# C, Y        p=NextArc(v1,p);- h3 }& m  b5 @8 w. b
        }! W" y1 ^3 R1 x8 I8 }9 a; q
        p = vexTable[v1].firstarc;
    " C* v; I2 @# T; k! G+ O9 X    q = vexTable[v2].firstarc;
    " q. p" H7 W* }% [    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法0 M+ H- K$ g  Z2 e* X" X. l
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    7 J- z! h/ V" K$ @7 _0 r8 m# z    arcNum++;
    6 Q; a9 A* G3 F}
      C% c& {0 o1 h2 u0 C! i7 b, t% d. [$ J" a0 F; ~( n! i
    template<class ElemType, class WeightType>- _  h& r2 _/ l3 j5 d. g
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    8 K3 s! b" A+ n3 p{6 C, }' G5 B0 `

    5 ?/ h+ j" R5 a5 k9 F    MultiAdjListNetworkArc<WeightType>* p, * q,*r;# }: s* d" x! a/ i% t& A9 S% q
        if (v1 < 0 || v1 >= vexNum)
    & Y, k- _3 p( Y# x  B8 y        throw Error("v1不合法!");
    7 o  }8 X7 p/ H/ L4 t! e    if (v2 < 0 || v2 >= vexNum)  Z9 `' J) \) B* I; U& |) z" Y% }  c
            throw Error("v2不合法!");
    . w0 m, d# G) S" ^    if (v1 == v2)
    0 d  d, p; f9 c; U0 w0 b        throw Error("v1不能等于v2!");2 p; Z  V: ]3 k* x7 K, R
    & u/ X8 P5 D7 _. u+ c0 A( H8 {7 T0 c
        p = vexTable[v1].firstarc;; J/ c5 t" U( f7 r' y( y
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    # A4 n$ `0 j! e3 S" P" e3 B; \    {
    & W8 t* j9 m+ q: P; K# H2 d5 a2 n        q = p;% ^3 d$ X9 i/ w
            p = NextArc(v1,p);+ Y* n) w; O3 C3 d" |
        }//找到要删除的边结点p及其前一结点q8 ~) t8 x8 x# I5 u5 p1 X
    9 V8 q0 l/ g7 M* m, S
        if (p != NULL)//找到v1-v2的边
    ; Z+ l# }$ p$ I+ ^; o    {/ _9 o8 z  l# t6 I: f6 O; l2 p
            r=LastArc(v2,p);0 h, J- G; p: Q% W/ H6 o, b& I
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    & s. }% ~8 X  y) K            if(p->adjVex2==v2)
    % r  Q' j: Q$ b; `& C                vexTable[v1].firstarc = p->nextarc1;
    ) z' j: r* S) w* [            else vexTable[v1].firstarc=p->nextarc2;
    & I1 T. l& e7 M        else//不是第一条边: B, O  |1 D8 P, k# p, i7 F$ p
            {
    5 u, A1 f2 a( ], p* I8 n3 M( ^            if(q->adjVex1==v1)
    ! Z8 P8 J  _6 }                q->nextarc1 = NextArc(v1,p);. U$ O1 s8 z  c9 f% t+ X
                else
    - ^: o# P1 L$ g, ^                q->nextarc2=NextArc(v1,p);
    . c3 F, C+ m6 |4 Q0 L+ [
    * X" I7 i- F7 R+ y, u( e8 O        }
    6 e  J/ a) d; \+ b; V$ m; L        if(r==NULL)
    3 ~4 b# M' u3 g$ c- g            if(p->adjVex2==v2)
    4 K  U: _2 Q% v+ G                vexTable[v2].firstarc = p->nextarc2;
    + a5 N* C& h% I0 R" ?            else vexTable[v2].firstarc=p->nextarc1;
    + ]( Q# E, D# ~& m4 M1 G        else
    ) t! F; a, ~* g' [( k& n        {
    5 O; e1 }9 l2 d! |0 X  u6 Y            if(r->adjVex2==v2)( g' B' K$ Z1 y5 [% {
                    r->nextarc2 = NextArc(v2,p);
    : Z, O9 G7 J$ g2 S/ F( s& {            else! W9 O5 c& u3 o- A- L9 T+ S" q& V" \
                    r->nextarc1=NextArc(v2,p);, D) u' y( w8 J1 M: ~
            }8 d$ |8 k$ J3 l/ O( M0 |: o! S* t# i
            delete p;# e3 I7 @1 J% [( w1 t1 k
            arcNum--;
    1 U# h  b( x1 t  C6 g4 J9 R    }0 \. x4 ?. ~" ~

    ( S, ]6 E) k- f. i- y# b# W4 J}! ~2 A; d/ k) }% C
    template<class ElemType, class WeightType> void1 K' J: G; w+ p$ c9 Y: ?) d, f2 b
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)2 h7 c) h+ Y, a# ?: _3 l
    {9 n( ^. G: d- r$ A7 w
        int v;
    4 V- y% X3 Z  \    MultiAdjListNetworkArc<WeightType>* p;2 }; @; N5 l# r" a% O
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    2 W: W1 i4 f; R! j) E) W        if (vexTable[v].data == d). P: N! C- u! R8 U
                break;( H6 z1 V5 `6 k; u6 w' K; ^
        if(v==vexNum)
    : G4 L4 _$ u" L1 k! J) _3 n- l        throw Error("图中不存在要删除的顶点!");
    4 |+ e7 ^1 S$ r/ j- h: b# z  r0 V0 R4 i. a+ e7 S3 h
        for (int u = 0; u < vexNum; u++)//删除与d相连的边& `! @5 p; c7 K
            if (u != v)" ]+ Q% n9 Y: }
            {
    9 ?; J* _1 Z0 L; X5 f3 _9 }            DeleteArc(u, v);+ z$ c% R# i3 l7 a
            }4 m8 N8 h, p+ \
        vexTable[v].firstarc=NULL;. M7 j9 ~$ L  S' A! O

    0 G6 K3 t- c( e" B5 K: D  J    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    % Q$ a' n2 K9 H# I  x' u  @2 E$ b    vexTable[v].data = vexTable[vexNum].data;  n# I5 c: U: H1 q1 ^) x! J/ C
        vexTable[v].firstarc = vexTable[vexNum].firstarc;
    ) m6 b2 A2 V. `2 s' g9 @' l- S    vexTable[vexNum].firstarc = NULL;
    + n& [1 ~' w8 J3 k- F+ E$ \    tag[v] = tag[vexNum];3 z) P5 v5 G  U2 H9 t9 n
        //原来与最后一个顶点相连的边改为与v相连4 P* |8 d" f6 L$ R" u0 P) E
        for (int u = 0; u < vexNum; u++)
    " x# ~6 J' S; [1 Y1 r    {
    : O0 n3 p9 ^0 `1 Z        if (u != v)
    " l7 \2 {6 e6 ?& ?# K& [        {/ O2 ?' G  [6 G; k: m* z9 n
                p = vexTable.firstarc;3 }+ f, l% b( M
                while (p)& l6 D! m5 _1 ]0 k
                {
    $ i4 j  b# p; a5 s                if (p->adjVex1==vexNum)/ x) V) o# a* G
                        p->adjVex1= v;
    6 [8 T9 b* K+ g* U6 K$ _: }                else if(p->adjVex2==vexNum)% d, p! W9 t( [+ C; k
                        p->adjVex2=v;) Y( m) e7 ~* X
                    p = NextArc(u,p);* R  ~; P0 u9 x* a( E
                }" \6 s- u% T, {- H5 E
            }; f$ K; K* f6 ]- f2 @
        }" B) ^" E- K! |4 `
    }& T! f' P4 G4 C4 d/ Y
    ///深度优先遍历5 B4 D4 r3 |( k1 R6 R2 w4 f9 N% D
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)7 y3 {& F) @: S, ?6 [) o% ~
    {
    / M8 k# U" I5 |1 B. \    tag[v]=1;; Y* O  B" T# }7 Y3 W, I
        cout<<setw(3)<<vexTable[v].data;; y4 d: m8 B+ u: C
        MultiAdjListNetworkArc<WeightType> *p;2 [; S/ t* l2 x7 y7 k8 m" q9 v
        p=vexTable[v].firstarc;8 K4 j6 `; j  \' w  G8 I
        while(p)0 N+ ^. ~! i% ~; `+ x
        {
    1 y- g% v! z; `+ y        if(tag[p->adjVex1]==0)- @8 r/ B; D. r" ]
                DFS1(p->adjVex1);+ K. e+ ~; m" n4 }
            else if(tag[p->adjVex2]==0)# E3 A# p9 `7 ^
                DFS1(p->adjVex2);
    5 S8 M9 b3 R7 ?+ B% A        p=NextArc(v,p);
    9 N; S4 F. y# V/ `    }
    0 K2 m! @8 C; r% b- w}; a* e8 Q, N3 n* q. C
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    " I1 I/ _, t, X{
    : r; X- R2 g/ B- r3 V+ ?    for(int i=0; i<vexNum; i++)% N9 d. c2 [9 Y( U3 K, S' b6 U/ k
            tag=0;$ B4 P! f1 x8 R' J
        for(int v=0; v<vexNum; v++)
    $ @& t0 ?. f) o* I; I    {: ?. c6 I, S9 @$ {# R
            if(tag[v]==0)
    $ k3 @1 _. R4 U            DFS1(v);
    : h# A6 y, q* |1 i    }
    , m* ^, i% @# n+ C  o" _* D}
    + a# N" Z+ J) @template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    4 R' X  X  R$ b1 y{1 c7 K9 k3 [% T! j; H  k# \* R
        stack<int> s;( V" t7 [0 K$ U1 D
        int tmp;# w5 s% D: m9 _% O
        MultiAdjListNetworkArc<WeightType> *p,*q;
    4 A, U6 ]9 i; l9 H    for(int i=0; i<vexNum; i++)
    0 r  M5 B6 K+ o1 U$ ]        tag=0;% Z' O2 t! W. V3 u
        for(int i=0; i<vexNum; i++)" M6 k: I4 C8 }' A% j
        {/ q1 o5 Z/ m; G- i& I5 G/ g
            tmp=i;
    # i- o! @/ I$ [- y5 r# i( v        while(tag[tmp]==0||!s.empty())
    , p1 ^5 ]1 c" r/ [8 v6 {/ V/ V        {
    . ]  Y/ r: s& L9 z# [            p=vexTable[tmp].firstarc;5 k) ?+ N# u$ P' m% k, i4 N
                while(tag[tmp]==0)
    % N) l7 ~3 ]! @" C/ z  E+ i: n            {9 g3 d- ^; D# T1 [* d
                    s.push(tmp);! q3 _( e+ L2 x$ ~
                    cout<<setw(3)<<vexTable[tmp].data;2 E3 Q! k8 y$ `
                    tag[tmp]=1;8 n) d1 C  U& Z
                    p=vexTable[tmp].firstarc;+ j+ O! U5 L. y  s2 ]! ?& k
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    ( S3 r) G( I' a$ t" T# X                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    : X$ M* J) ?& E3 k$ D' U                //cout<<" 1st     tmp="<<tmp<<endl;) v0 H7 A5 q3 c3 w) [, V: b5 [
                }* j) x: ~6 C0 ^3 L# D1 a$ @
                if(!s.empty())
    9 W$ f& D, ]  H4 B6 P1 x            {; h# @9 H- B* {
                    tmp=s.top();0 z& e. L, [, e& z7 m
                    s.pop();
    7 ]* u- `! W& |# ?1 ]                q=vexTable[tmp].firstarc;
    ( s+ N+ h: B" D7 J8 x) R5 i                int t=tmp;
    % {- @* w' S3 K+ G0 K  h                while(q&&tag[tmp]!=0)
    2 R8 R  M6 g% D) Z                {, z/ D7 D8 M/ X" Y
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);. D4 E6 E1 f. |  W: q
                        //cout<<" 2nd     tmp="<<tmp<<endl;6 `, C! o' J9 [- x& v5 G. ^* h
                        q=NextArc(t,q);* S+ p$ Q. X* B: n3 W- D3 m
                    }7 D( U  @8 F" I7 Z
                    if(tag[tmp]==0)6 q! ]$ f: v* F% D, ?: O/ Y
                        s.push(t);
    9 t) G2 R: ~$ J$ C/ D6 @                ///1、对应上面连通分支只有1个点的情况
    5 X6 X% \% f+ L8 @1 B                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈5 ?) Z5 Z, {, t6 q2 _  z. q9 b
                    ///tmp要么等于找到的第一个未访问节点,
    1 Y% U' t+ j; T% v/ F                ///要么等于与t相连最后一个点(已被访问过)* ]; B2 |  Z( c' ~# c! E: T
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    # _( \/ ?- r8 Z3 T  C            }( }* l$ X# u  x: u7 k! d0 R
            }
    $ Z* P8 ^6 J2 t    }
    ; z8 P( x8 b6 ~}2 T7 b3 ?0 [) C3 V6 e' f% [3 L
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1. H& H, @. S# U. C1 w$ G% [( \
    template<class ElemType, class WeightType> int
    9 t) O" k9 g: X! P6 NMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)7 o# b, A! K& S. n! T3 c
    {. d+ g" L/ }6 x) ~$ R& c; L, {
        if(head==pre)4 Q: u6 B1 G$ B: w! W, }
            return -1;
    : H% o/ {$ O2 Y. X0 k% w- t+ y) |3 l; ]& m" L  W! X6 q; v
        MultiAdjListNetworkArc<WeightType> *p;/ H) J8 b1 |+ Z1 y2 L. ^
        p=vexTable[head].firstarc;
    & D( N5 v* E9 u8 n    if(pre==-1&&p!=NULL)2 _# E2 ^! N, a% I3 S+ I4 A% n$ i7 q( H) c
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    4 O" z, m3 s: n; p) M; \0 j8 G% S    //pre!=-1&&p!=NULL" E; _5 i7 b# l$ h' L8 H
        while(p!=NULL)! S* y- I5 u+ N8 E  |9 O) ^# k' Y" l' M
        {) j6 ]6 [- O- s1 m
            if(p->adjVex1==head && p->adjVex2!=pre)' ~4 e. W* ~$ b: e0 ~+ c% z5 W
                p=p->nextarc1;5 ]  T! W) p( o" @4 v
            else if(p->adjVex2==head && p->adjVex1!=pre)- ]* l6 X9 y8 s; U+ y: q7 f
                p=p->nextarc2;
    ) r% y0 c0 C" ]3 o- l$ F: X  m        else if(p->adjVex1==head && p->adjVex2==pre)
    , _; g( S0 t7 G* D        {
    9 \% a# ]  G6 {$ |' m, g! ?            p=p->nextarc1;& X( M" @1 n: O
                break;: Y4 f+ H2 g2 f1 |" }4 j! ]/ E* E
            }
    ' n0 o5 W  R. ?7 M- a- x# k+ G        else if(p->adjVex2==head && p->adjVex1==pre)* E+ b2 d1 Q: ~3 q
            {
    9 z1 L( M# c- s% L            p=p->nextarc2;! A  m; r% [& f3 j7 Q/ r
                break;
    + e, w/ H: z9 R5 @9 f4 t+ _4 j        }! n* v3 n4 _8 E2 L
        }% ?, Q& n0 `- V
        if(p!=NULL)+ b% @" T7 F( l) U+ g
        {: p$ F  |5 v$ P* ~8 F+ C9 u- O
            return p->adjVex1==head?p->adjVex2:p->adjVex1;* y3 d. j5 A/ ^3 r. J
        }+ n" F- B# D2 U% D2 s5 W
        else" A) z. R& k/ J! |: K+ c
            return -1;
    - ]  I! e) |! e4 }2 b}
    + ~* d9 b9 v$ P$ x! a% ^' n0 L7 h. x* M; j) s

    3 k9 K* M. u6 t, S' otemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    ! t4 d+ Z! k: p7 _{
    & E5 d, `# g0 B/ f    stack<int> s;9 ~1 \4 j4 B, a8 Q8 {5 b
        int p,cur,pre;
    ; ~* ^: \! a% {1 R' S1 E    //MultiAdjListNetworkArc<WeightType> *p,*q;
    $ w+ K- K! R5 @6 l) N    for(int i=0; i<vexNum; i++) tag=0;//初始化# u$ A6 D" L9 X+ L! a0 Q
    $ u; h% \8 [) F+ H
        for(int i=0; i<vexNum; i++)) x9 U9 B. `% _, u
        {
    6 w' }! k% S: O  r3 {  A        cur=i;pre=-1;
    9 N) Z0 \$ q! b        while(tag[cur]==0||!s.empty())
    + G7 b6 b: j+ A: A/ K% N( z        {1 U+ V. }, A9 a2 ]1 t
                while(tag[cur]==0)
    & a* E- j0 `! d- u% I" B* s            {- T% p( }# V' a6 x2 Y' f  v
                    cout<<vexTable[cur].data<<"  ";
    9 I) R5 Z7 W, F9 @5 t2 N( L0 w                s.push(cur);
    2 O3 r7 Z: h6 R! a% j5 \7 g8 S, V7 D                tag[cur]=1;
    ; _  a+ C( t- d8 U               //初次访问,标记入栈
    " D! q9 a& s& _0 X8 X& K  U2 g4 H1 I8 r
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点0 P; n+ |% ]! k3 o
                   if(p==-1)+ Z6 j& Z/ R8 \# m0 t" _( {: L
                   {
    / X) n" b, n  x% S& Z+ Q                   pre=cur;s.pop();
    2 `, s7 C5 P' y- W                   break;! e' A5 n: |/ Y* k/ Z: O
                   }0 ^0 G0 J9 ^9 r% `0 [+ V  |
                   else
    # r6 G, r( e5 k+ i               {$ m* R8 _* w; H7 U: Z/ _7 v: ]7 Y
                       pre=cur;  i1 D) W) B/ a, h
                       cur=p;
    0 S/ H" F  s9 n7 J9 j; j               }5 S$ _. E* G* V7 d8 P- o1 e' P+ d

    7 E/ T. V6 }& {6 x. X            }
      i( C# o( `$ r. I1 i            while(!s.empty())& \6 x7 @! ~5 T* R. A+ @
                {
    - |% ~/ I! n; o                cur=s.top();  Q3 ^2 S& d$ a0 P+ m, D8 S
                    p=GetAdjVex(cur,pre);( ?2 l. m/ H) n9 e6 c6 D7 R
                    if(tag[p]==0)
    & w3 D+ M. p8 u$ L2 Y  t9 u: B7 q                {% b6 O  P% x8 O, i. I3 _, @! G+ w
                        pre=cur;
    5 {0 ?4 M- T% X5 @) Q6 A+ l; p                    cur=p;
    / o+ g( q* c! F% U. _                    break;  o" E9 i' M8 B2 m1 C" q$ n# O
                    }
    % G2 g- K; ^! E1 W6 G, p                else
    0 V0 ~' N$ @1 n$ m9 [, V7 A8 p                {
    % g5 J, F* [7 |/ E% h9 w$ s                    pre=s.top();1 X, Q& X8 B/ Z6 W$ X
                        s.pop();1 U. C3 J9 f, W! ?
                    }, x) H0 Q0 v% ]0 v
    # E$ c$ Q6 l: C1 Y; Q# m2 g
                }3 A4 N! z4 H1 A; |. I

    # S8 E0 ^9 x4 a) D& m) _- ]  |        }8 O8 z; W/ ]) w( K2 ]3 I
        }
    6 \7 U2 e& t8 B/ V/ N* o# J}
    3 E) e  o5 ~0 D+ K, a  U) Ytemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    6 L. p! R* v% d{. U% W+ [' o$ @# C- ^
        for(int i=0; i<vexNum; i++)1 r4 |. X/ i$ v
            tag=0;; G; {) S: X; R* B8 Z, O, p& j1 ]0 |
        queue<int> q;% o  O, g/ G1 R3 \
        int tmp,t;" k; X& U% r% ]& T7 p3 Q* Y
        MultiAdjListNetworkArc<WeightType> *p;1 `! ^! |: f$ e
        for(int i=0; i<vexNum; i++)
    6 L3 S- {* _$ Q7 ~& i+ L, Y    {% B6 d8 V. m' c& Y' a% Y
            if(tag==0)
    , B8 p& l0 B$ _6 `7 g$ K        {  z. K8 |, D; Y# D6 K9 _$ |- [
                tag=1;6 ~! ~# F. h0 D. M/ \. @! J
                q.push(i);0 m0 y" u9 d; C! H# t) @) X, K4 W
                cout<<setw(3)<<vexTable.data;7 {/ `6 V6 U1 V& n! `$ {9 {
            }) \  N3 M0 Z" q4 l( Q: L( O! m
            while(!q.empty())" I$ i7 A; F% {. O) W  W9 n, n, i
            {
    # H/ B( S$ S1 C, m+ N0 J            tmp=q.front();, Q* n! x) |' v3 C/ u
                q.pop();5 c' s6 ?  M  N5 r- U' E' k
                p=vexTable[tmp].firstarc;2 q4 u) E9 G# [6 {7 o
                while(p!=NULL)* K8 l4 C3 i8 k- W& [. J1 N3 }8 [) n
                {
    ! w6 S7 R. }. o4 J. A                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    $ i* l* E8 F) W& y% s                if(tag[t]==0)
    ' T& Z' s2 n. [% K4 s* C                {' Y7 w5 f# ^1 @2 F( k5 V
                        cout<<setw(3)<<vexTable[t].data;  m: Y0 a# o1 t% m& V
                        tag[t]=1;
    / t, a0 T- ]1 {3 T" @                    q.push(t);1 K$ p! V+ ?- n( `4 f2 v
                    }
    + m9 v; m: J: l" q+ V                p=NextArc(tmp,p);' E2 z* t0 q6 W4 C4 D5 |+ W6 a; |
                }
    , A1 f! l5 V3 M; K        }, @2 X1 I* |9 l/ e- O" f/ P% e
        }
    # c5 Z+ r" N# j0 E. a* @}# |* K8 y- z4 {4 P- |  Z8 n
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()$ x! ^# c9 s" S; o1 m" W- ~  K
    {
    8 H/ h! }! d7 n9 z* U- Q2 R    MultiAdjListNetworkArc<WeightType> *p;
    ! {' b5 D& z# D) `3 A    cout << "无向图有" << vexNum << "个点,分别为:";
    9 K6 A3 O, M) d4 N( m" w' r    for (int i = 0; i < vexNum; i++)  E; C1 U3 P; u5 c1 C
            cout << vexTable.data << " ";
    2 _2 b& v) ]+ d" k" V" e  ]    cout << endl;" w' B6 `: J; Q) D+ b/ G
        cout << "无向图有" << arcNum << "条边"<<endl;
    . [9 |: E3 F& |2 e# e    for (int i = 0; i < vexNum; i++)
    8 v1 z9 H( Z/ ?6 Z4 j$ |    {
    % }- |. N: s2 f; g        cout<<"和" << vexTable.data << "有关的边:";
    2 ^% @" J; S! i        p = vexTable.firstarc;% A6 v- Z) x: g6 D. t; u
            while (p != NULL)
    $ Q$ A3 R% ~- C) v* Z        {
      k# ^( Z% @! ^            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
      E4 F0 C' O7 I, ]3 I; ]1 e            p=NextArc(i,p);
    7 b! z# X2 q3 u  B" N        }- p  d# D  W$ g8 t" W6 p; N
            cout << endl;
    , m" T, ?' }. m3 w4 {6 {) t! O( r) a# R    }( r2 m1 [$ R" ^& m$ n8 j
    }
    $ z9 H, O! q4 F- f0 U
    7 I2 L7 R/ ?: g9 Z" j: p& t" O
    ; f9 v# m8 l2 T( N# I0 ?邻接多重表与邻接表的对比6 U0 h6 I  v1 x/ V2 q5 n

    ( i9 q  q7 b* X9 V$ G( Q- F0 _# x邻接表链接
    4 b; L& O* C* k% N4 b在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    3 ]* m. Z* ~0 A5 ?在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。+ q3 }/ O1 R1 R5 n! B
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
      i% q$ R! \8 c, w6 A4 o3 f————————————————; r7 R: `: F' K4 ^1 v3 _
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。8 m1 A( X+ W, W
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958* V7 }3 E: W& i6 G  N) [$ l

    # U" M9 V: w: p0 I: y# ?* l3 k  K

    9 O! m: u7 ?, g& c
    ; {6 P7 l" ?. ~5 l! ]9 N1 W2 V————————————————, N$ \+ K* V, u1 I
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    & O4 k% X0 y  @- t原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    9 U% Q2 O" A$ _: K  I
    * N0 F+ l3 D! ?  t% Q
    ) V" M2 c% u: E* [8 ?! P# M8 l) g
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2025-12-13 02:17 , Processed in 2.496927 second(s), 53 queries .

    回顶部