QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1464|回复: 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
    + }+ v; y) g  b# L/ |; S4 X
    图的存储结构——邻接多重表(多重邻接表)的实现
    ) }# @% a- m( I' h0 S3 Z7.2 图的存储结构
    ; \: X9 K" j( F0 T
    9 H/ t& x& J' d, [" Y7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    # \! h, ^, s2 [; _) L& |) L1 s9 a邻接多重表的类定义
    * n$ D' }+ i+ U8 _邻接多重表的顶点结点类模板
    * V: I' K! @, f9 H4 m) V  R* l+ t邻接多重表的边结点类模板/ g* d9 B+ C: E+ i/ X- j) z
    邻接多重表的类模板. u% K7 z( G6 I- Y% N/ }
    邻接多重表与邻接表的对比
    ! y& C. E/ C* G' V& r; }7.2.3 邻接多重表(多重邻接表)Adjacency Multilist; L) k6 L1 y6 O$ S
    2 S/ Y9 v1 H; ~' j
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    " ~% Z8 ~% a: n/ S( _! |在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    : Z- g3 W( q! p! T% ~) Q) _" J+ z6 ?& N# n
    邻接多重表的类定义* Y% u1 z/ A8 L# T3 H7 _
    1.png . m# e0 s3 K" s& q* r
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:+ r+ E6 A. ]5 M/ j
    data域存储有关顶点的信息;
      b" J' _% H, A" s8 xfirstarc域是链接指针,指向第一条依附于该顶点的边。: {% [/ j8 N7 u
    所有的顶点结点组成一个顺序表。

    3 W$ D5 V, R7 ]/ a
    6 R& g& K6 e$ I9 e( C+ r* G7 R, e
    template <class ElemType ,class WeightType>8 |) G  e' K* A9 G' X
    class MultiAdjListNetworkVex
    2 t  k9 T" f9 ~7 ]* R/ r{
    - A4 Z8 y% |% r  ~' |7 s6 Gpublic:/ o3 E( K' [/ @; F8 l* s
            ElemType data;/ k4 y( Z4 A9 j' j* b
            MultiAdjListNetworkArc<WeightType> *firstarc;
    # M  t! E2 K7 W6 v3 e6 M+ p( `5 z% k/ y. k9 c/ f9 L- o
            MultiAdjListNetworkVex()
    * s% W0 i6 u% v1 {4 w) o4 }5 _# m7 h        {- m+ ?( @8 I9 F6 t7 w: q+ t
                    firstarc = NULL;
    1 N7 B) ~' \2 ]3 f4 E        }
    + o2 @$ G5 R1 |$ N% `        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    # Z  @# `8 D3 M# R2 F: ~4 ]. @        {. {% H% {5 O/ e" u+ P1 ?
                    data = val;
    . J8 F9 V- {* _% g8 {. T                firstarc = adj;+ o% ~( w; u. o8 t
            }' x, G1 t, |9 k1 M) h1 [$ O: e
    };
    ; x8 e+ [, k& q* o
    ) [0 t; D* b$ z" n& l邻接多重表的边结点类模板
    0 H) U! S/ t6 u; d
    & A6 M# _$ a5 z$ C8 a9 F7 q! g- j在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    ' v$ K/ k( f( V, K: U8 Ntag是标记域,标记该边是否被处理或被搜索过;/ g/ {* a3 G' k3 M4 W: u4 C/ ]; \
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;! y3 {, [' S8 H7 S
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;1 D' @: t) N9 w
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    - c# T- {5 ^: K2 U# C* r  G) g! a3 \. e# _: @; c& i
    2.png
    4 H# p0 U. d( M+ y/ |7 n& R  ttemplate <class WeightType>
    , z" H$ M4 E0 M8 l) F5 qclass MultiAdjListNetworkArc5 F" ^1 ?& w! |* ~1 c- W
    {# z0 E( G! I) p' O5 e0 l
    public:
    7 }8 B( a) d9 C/ a' V* o    int mark;                                       //标记该边是否被搜索或处理过; |/ J) k0 c$ d* L5 c, V; m
            WeightType weight;                              //边的权重& e2 z9 s% v! w2 M- |
            int adjVex1;                                    //边的一个顶点
    ' F- w+ Z2 x' a        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1* m$ A6 M3 @5 D3 Y
            int adjVex2;
    7 G+ [& ?1 `1 A5 X1 q5 h) ]: T        MultiAdjListNetworkArc<WeightType>* nextarc2;
    3 C) C$ l5 @$ Z2 X: m+ N2 S  ~+ I+ |6 l6 o8 U0 H9 M/ u9 |, P
            MultiAdjListNetworkArc()
    & w. {) g% r" W* y" ~1 u7 h1 j1 m) j1 @6 l        {
    / Q9 ~0 S. d3 T$ D' x9 n6 ?$ x: k                adjVex1= -1;
    4 [! L& y7 m; \0 @) G( }                adjVex2= -1;
    0 Q6 b& |% R/ L0 P        }
    " A- q. l& D$ L  L, E& H        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    + _. n- n" J' ^8 D1 {        {
    ; J: P/ a8 h. m! F                adjVex1 = v1;       adjVex2 = v2;
    5 F& L: h- X  ?% J' n                weight = w;
    1 k6 H- {( k4 b# h& C5 U; i( U4 Q                nextarc1 = next1;   nextarc2=next2;' j9 ~" ^, u: @9 z' ?
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    ' J5 ?2 G. p' ^; o/ Q6 B        }$ X/ o3 K1 T: Y
    8 T% n, a7 `' x! {
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    . y7 K5 r+ R; g3 gclass MultiAdjListNetwork
    6 U3 j. A8 `+ {4 }# o% g5 Q! P* t5 R{* b& h( X3 s: J# f" f
    protected:
    + J) ~* X: ^3 B8 J: G4 z% O    int vexNum, vexMaxNum, arcNum;$ z$ t5 S( q7 y# S2 G) E( `2 e. e6 }
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    8 T- K0 L) V7 G. I8 b    int* tag;
    ' _) c, N3 u/ f1 n$ {- b    WeightType infinity;- {' e' k; a; g/ K5 ]( H! o

    4 |" E1 X) U- g& a( Mpublic:9 }3 K8 s  g; H5 W
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);" e$ R! \( y9 q1 k2 s% H' N" i9 V& P

    : W0 \4 t  }- t6 Y- b' T) _. B    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);) s/ c2 O: m5 e* |6 Z8 P9 D# T

    # R5 Q" F7 h3 W- _    void Clear();7 y. K( x& T7 ~; g+ R" P+ d* R5 s
        bool IsEmpty()1 }& |; Z) h4 V# J  N1 B
        {. @# \7 r7 b7 I6 h9 _* T
            return vexNum == 0;
    / L8 s2 O7 T/ _4 g& f' P    }
    ( z0 P. D& ^9 M7 t    int GetArcNum()const  Q1 t: C7 D4 l  d/ b. |" ]
        {
    3 z  E$ U3 t7 X% J! D        return arcNum;
    2 p6 e$ L0 C) M7 a: M    }
    2 @0 \9 _. t, P! L    int GetvexNum()const& P$ Q5 X% K: D# j: k: X
        {" K8 n7 u0 i: |9 I+ W' h' D5 K: H$ {
            return vexNum;
    ( _! v; T7 Q9 s' K: d- _5 Z    }2 r, I; t, R' `7 K! u$ g
    ( j! [5 s* P" \$ {, n' K( h
    : ~' R) m5 o9 S/ z5 M5 _( a
        int FirstAdjVex(int v)const;
    $ z$ n- N4 y: G! r    int NextAdjVex(int v1, int v2)const;
    7 M  l5 {* ]# s0 T& _- _3 e1 ^, g    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    5 ^. i" i8 A! _8 ?% i4 g    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    / S; e, H9 `2 B; [% T9 Y$ @# Z2 G* X) B% m& V2 @# j
        void InsertVex(const ElemType& d);5 ]# l% L% i. R) d0 G5 G: \) f
        void InsertArc(int v1, int v2, WeightType w);
    ' d1 s: o5 K+ o/ E* ~1 v* ]+ R* s
        void DeleteVex(const ElemType& d);# G8 D" o. V5 v
        void DeleteArc(int v1, int v2);2 [/ f1 W2 f* W9 }) T0 w* j

    / g% n8 n! k; {    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    4 I5 p5 L: y/ n: y& E    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);# K$ _4 o( x, m9 E( m+ H# G. ?+ W
    ( f" s( u! w& l9 l( |% @3 V
        ///深度优先遍历2 N. J, r( A0 Q2 q
        void DFS1(const int v);
    ( q' B5 x9 X9 y    void DFS1Traverse();) h2 V  b- A1 P; B
        void DFS2();, r5 W$ y- k5 [- F1 d5 C" c1 Q2 p
    ; @5 K# C% |( y* ?
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    7 p0 y) k" {, Z0 n& I3 S    void DFS3();
    1 l# g# ~6 a! ?- |. D% C' L% z: E" F: j" Q' D1 U
        void BFS();6 G9 q0 h) _/ ~. }1 @
        void Show();& v9 Y! f/ Q5 ]: q
    };
    7 m: r, [" f' `6 o5 Q7 ~* I$ e! e! H1 o+ Z
    2.函数的实现% s- m8 N! l: W* }
    研讨题,能够运行,但是代码不一定是最优的。
    $ a! g; }( z, }3 s8 y' m" t+ S# R
    #include <stack>8 M( v* o4 g2 v, N& J, X1 Q1 q9 J
    #include <queue>3 x% H9 Z8 R# I# R- N

    . |' o/ }, Q7 f6 r# j! x2 qtemplate <class ElemType,class WeightType>* ~7 W* ], r. J
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    6 v' p, p5 F4 @* i) _{1 }9 r( R5 H: P% N2 |
        if(vertexMaxNum < 0)) i2 f0 I" e, \; O# W
            throw Error("允许的顶点最大数目不能为负!");
    & h, d+ X3 R0 q    if (vertexMaxNum < vertexNum)& `2 u% ~: H# [' W
            throw Error("顶点数目不能大于允许的顶点最大数目!");7 U+ \/ @' b: p* T: \
        vexNum = vertexNum;
    7 E+ A0 \/ w3 X8 L( k. }$ t! m    vexMaxNum = vertexMaxNum;
    / V3 T) u$ x( R& D# A0 w5 K! I+ I7 E    arcNum = 0;
    - t2 O8 n* [* n# a' h    infinity = infinit;0 B. z- v) ~4 |/ s
        tag = new int[vexMaxNum];- _  O% q& p* ^4 E8 ]6 o: K
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];7 u* I8 U& D. g( b3 r
        for (int v = 0; v < vexNum; v++)( E/ t) J1 J% K0 Y4 S
        {& D7 I8 e& z) j9 V: \' ?
            tag[v] = 0;3 x; u7 D& L  [6 `8 X& u
            vexTable[v].data = es[v];
    ( r) c; s$ T" {5 f! H( W2 A        vexTable[v].firstarc = NULL;
    & O7 {' m2 `( Z" ~& m    }) L( s4 _) k" f# Z7 @2 H2 i
    }
    ) g- Y) a# \; z$ ]: @/ `; ?template <class ElemType,class WeightType>8 n1 Q5 B# c* b0 n: u' Y
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    - T+ x6 j. T4 ?9 A, _/ a& c& ]{
    ' B7 F9 |2 B0 z$ d! D7 g0 T, x    if (vertexMaxNum < 0)
    & c! `6 \0 W6 m  n' k- s9 i+ u        throw Error("允许的顶点最大数目不能为负!");
    7 g, r$ Y0 Z$ Y0 O    vexNum = 0;
    7 N/ ]! ?) o7 r7 u3 C# j: _    vexMaxNum = vertexMaxNum;) X2 }: b2 z1 p) U% q) o( V/ S
        arcNum = 0;
    6 U3 U! N" M, h    infinity = infinit;
    0 e+ Q. N& Q1 o/ U6 }5 c' C$ ^    tag = new int[vexMaxNum];( ]; y7 M  H1 z& I: M9 Y
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    + N; U+ Z) n$ d+ s; t}
    6 X  Q% f- }8 t3 k: ?template<class ElemType, class WeightType>
    2 K9 h3 ~# x2 f/ r, pint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const2 y- Y7 [! U7 ^4 m" K5 \
    {/ Q, F" M9 \. d7 l  D" E
        if (v < 0 || v >= vexNum)7 h! F. T" e2 X
            throw Error("v不合法!");
    / v# m* Z2 D2 |, E    if (vexTable[v].firstarc == NULL)
    % o* L- X/ ^) b0 @5 z0 |        return -1;2 D! }9 K  H# R, k  l: `6 F$ |' L
        else
    ' @/ j5 j5 {+ f# P# G  V        return vexTable[v].firstarc->adjVex1;
      ?  a& s, U- k  z* u}* Y. a' X# Z5 ~! n9 y
    6 y: P: C' v1 {: G
    template<class ElemType, class WeightType>
    / y, @' H$ m8 n1 t1 p, w2 vint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    # q8 C7 x5 g0 P5 k* q# E* i{% ]/ J* i+ S9 A0 Z. j
        MultiAdjListNetworkArc<WeightType>* p;
    1 @) |7 Y% }  {$ W3 A) B    if (v1 < 0 || v1 >= vexNum)' A4 @; D# @$ X) L8 O' F, Q
            throw Error("v1不合法!");1 \6 P# Z2 P- G5 |$ Q1 l
        if (v2 < 0 || v2 >= vexNum)
    $ _0 c) I6 P8 F! b" a8 t* j8 A8 n1 G        throw Error("v2不合法!");2 {/ o3 f- j3 }, w* t! a
        if (v1 == v2)
    ' A, H9 S& d8 v6 O+ C2 [$ Z3 W5 V        throw Error("v1不能等于v2!");( S6 _$ i0 V7 j: ?9 s- x3 ~! B
        p = vexTable[v1].firstarc;
    1 N* @# R* m) Z$ W    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)& `7 |% g( n1 A, O/ c& q
            p = p->nextarc;
    . U9 B6 R$ q+ H5 `' S    if (p == NULL || p->nextarc == NULL); r3 o3 s1 s; ~" G' q
            return -1;  //不存在下一个邻接点( Z# ?% G% J# F4 S; T
        else if(p->adjVex1==v2)$ Y; j5 K# X- d4 g9 e
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    $ A" a* @3 Z2 W" @. q' o0 l    else6 ^! V, V0 ?- B: ^
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);: L8 s; J& z0 j" L
    }
    + r! F* i' _6 Ftemplate<class ElemType, class WeightType>
    ' K: {7 w' m+ d5 L, I4 W. q5 V+ Dvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()* J% y4 A. x; l9 h( r
    {) B( O9 o7 d3 h5 M
        if (IsEmpty()) return;& u  c/ ^( n/ w
        int n = vexNum;
    9 Q% l, N/ {8 m) }    for (int u = 0; u < n ; u++)
    " T6 v& i7 _' {# J& ~& S2 f' N        DeleteVex(vexTable[0].data);5 A  G4 G; a6 @5 O, k, M
        return;
    / t/ }5 {" l* b  |: c1 |2 J}! U9 J( e1 F, [0 C. D
    template<class ElemType, class WeightType>
    1 q& ]# b& r2 Z8 w3 ]* r" ?" H2 RMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    . A# _# j$ W' i. n# G7 \8 K{6 N( M+ n1 i6 L: I
        Clear();
    7 u$ L/ j8 Y2 w& N2 Y# n}- d  x& ~: N  c' U. F8 P
    template<class ElemType, class WeightType>/ k: {  J2 I  j; u
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)" \% n% A, ~. Y2 E$ ]8 K
    {* ~; T7 U9 f8 w- v, F
        vexMaxNum = copy.vexMaxNum;' P: p& y5 c- `- S1 l$ Z5 s
        vexNum = copy.vexNum;7 t( B% P( _3 i) x( d5 k9 ~+ r2 P2 Q+ U
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];0 Z1 A5 {! M: R4 m0 B- M
        arcNum = 0;7 L0 W, A3 E8 x+ `2 N/ R0 P
        infinity = copy.infinity;, X  f. U  N& |( y- }7 r
        tag = new int[vexMaxNum];
    ( |# I' Q( \+ t1 W* b2 g# ?4 ?% _0 s/ W; T; n5 {$ o7 S
        for (int v = 0; v < vexNum; v++)
    9 y/ s/ s0 c1 D    {
    0 K' U0 T: O7 ^8 Z        tag[v] = 0;
    8 n1 V- ~$ N  v$ w- ?3 H/ ?: d6 e9 r        vexTable[v].data = copy.vexTable[v].data;
    * |1 x" M* i+ n$ q        vexTable[v].firstarc = NULL;2 y( f/ X: c7 T7 E* B
        }
    4 L) ^- P8 D+ D    MultiAdjListNetworkArc<WeightType>* p;
    & y6 F. v" M' Z) [! o$ `* _
    + U+ j1 T" o: H- p) I    for (int u = 0; u < vexNum; u++)
    5 {& M; U9 g* J. J3 @* w    {
    8 [2 V" c( q- i: D5 t/ X* [        p = copy.vexTable.firstarc;
    ! D3 I: h# N9 V6 U        while (p != NULL)! S, l, k7 G# Q5 A  F& z6 t
            {' y* @4 h2 i  ]- s& V
                InsertArc(p->adjVex1, p->adjVex2, p->weight);7 k2 W# A8 c: N: X% b! y6 X2 Q
                p=NextArc(u,p);: V5 a5 A; S1 I; M$ n/ Y* t
            }/ a0 L& S& g3 N) U* t5 Q
        }4 g  t. A% c+ T  f" G5 _2 J% c5 h
    }; K6 a5 ^) P, _1 B* ~6 f
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    % }% W/ E$ ?, Q9 V1 f4 TMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    5 |( h- k1 z! c- d3 |% }{
    + D0 O2 F4 S4 k6 W3 g& }    if (this == &copy) return *this;5 d2 K( {( R- w' S* ~1 W
        Clear();  d+ J0 K" \3 ~% ?! m0 s2 ]
        vexMaxNum = copy.vexMaxNum;
    ) H% c& t2 ~; y( ^    vexNum = copy.vexNum;
    , W# P& o" N) T& b. P    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    - {, X$ a& X+ @% ]& E    arcNum = 0;
    ; S) H: G7 R+ ]) y; P6 C9 j    infinity = copy.infinity;
    # }! e. ?* A1 E) f    tag = new int[vexMaxNum];2 T+ ^4 s6 Z1 ~

    6 T: z+ |2 [" O" o2 x    for (int v = 0; v < vexNum; v++)
    ; D) F! g2 j7 f. X2 c    {# w" q, E$ I. {0 S& m
            tag[v] = 0;
    , D) A3 `( g. O: S' H5 L1 Q& q        vexTable[v].data = copy.vexTable[v].data;* r: O& @# Z$ M3 i9 C
            vexTable[v].firstarc = NULL;. e: P* e% R8 e2 \; A  L, h. q
        }1 q! d: E) F! m8 x/ ]! K4 }4 C# {
        MultiAdjListNetworkArc<WeightType>* p;
    2 w/ V2 b0 q) z. X$ K
    # D9 O8 G) k3 S( l    for (int u = 0; u < vexNum; u++)& O! O4 v' {% J% ?0 [; H. B4 v
        {7 F4 ?. i) C- ^% B# L) P. y6 ]
            p = copy.vexTable.firstarc;
    + q% t6 \% H9 g6 p        while (p != NULL)" L" y* z$ O9 ]+ _
            {0 B$ k! [0 K& D& x# m  K$ e
                InsertArc(p->adjVex1, p->adjVex2, p->weight);# s  T% W: r) B
                p=NextArc(u,p);
    3 }) x+ x0 m2 v: Z        }
    / j* ?& J* x3 A  z* n, I( C' m    }
    & L  Z) m  i0 s    return *this;
    4 u  W2 J* \2 E4 m) P; e' v, F1 n}
    # c/ y! |% G3 x/ [template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    2 j7 U9 q6 J: S$ gMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    . Q8 B- I, L6 t& @{2 ?% _% o% B) s; g! C+ O( S
        if(p==NULL) return NULL;# Q  e6 H) a' w
        if(p->adjVex1==v1)
    + j8 e. L3 Y- [, O        return p->nextarc1;' |$ }0 r. k! S1 d! r6 [& ~
        else9 r: e9 B; E: }9 }- W7 g: I$ r& F, q
            return p->nextarc2;- F2 D+ k* V! A6 y/ q2 T9 Q  q: ~
    }
    ' p$ {& e) \3 b* d+ htemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    : l& v+ E8 \8 G9 @5 M- t) fMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    9 }( n6 c3 y0 A- M: O{( A: W$ k2 p7 ]! S
        if(p==NULL)return NULL;
    ' @4 O( Y' ^( n6 C    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    + _6 D/ \- k7 }1 t: J; h0 A    if(q==p)4 f: K' m+ }/ r3 o. F# k: X
            return NULL;! D* J8 n/ D. j6 c# {7 M# W: f8 B% K
        while(q)
    & n) h/ C: Q. t- j  P. Q( |    {4 `+ T( P: x$ @$ d; k6 c
            if(q->nextarc1==p ||q->nextarc2==p)
    . ~2 _' |+ `$ G5 m" D            break;3 q, n! Z+ K1 n  x" |+ f
            q=NextArc(v1,q);+ ^1 g& j; a8 `0 m; \
        }4 w5 k" d  b' q$ x
        return q;8 J6 Z! r# r# }6 i
    }+ Y) X4 g5 C7 ?1 D
    template<class ElemType, class WeightType>" |/ M; j3 I  O2 f) l( E0 L
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)" X5 M2 {: }; W
    {
    " A3 U" I& O8 f, z, S+ k* g* b$ x    if (vexNum == vexMaxNum)4 q; e( |" Q' s) j% w  P% A# \. |! c
            throw Error("图的顶点数不能超过允许的最大数!");
    % W% x" W: H& \/ }9 o; H    vexTable[vexNum].data = d;( m# F7 P7 H6 _9 @* _8 M/ w
        vexTable[vexNum].firstarc = NULL;: K' G1 D) W6 ^3 q
        tag[vexNum] = 0;- V7 f/ D, a: Y7 {! N& o1 b
        vexNum++;- r6 \: ]2 ]2 |3 K: Y7 I1 {
    }5 v! l5 K2 e6 J, E% y! |9 f1 o3 N, A
    template<class ElemType, class WeightType>
    . G9 Y9 U% i8 N: w) y/ vvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    ' E" ~2 T0 p0 U" b) @1 ], T{
    * H, }4 B! b, Y7 U    MultiAdjListNetworkArc<WeightType>* p,*q;
    4 M* S4 P# q  v5 Y8 _( k    if (v1 < 0 || v1 >= vexNum)
    4 T7 c7 P- z/ g. H$ `1 D* P" p/ N        throw Error("v1不合法!");
    0 n  F, R! {. q& ?# a    if (v2 < 0 || v2 >= vexNum)
    ; ]  j, d+ i6 ^; \9 U8 L        throw Error("v2不合法!");
    0 y/ J# Q0 C  p& Q: K8 `: t    if (v1 == v2)8 c+ L# b6 e) N, }; E8 H
            throw Error("v1不能等于v2!");# a+ E1 Q0 O# P2 f( {  {% t* O
        if (w == infinity)
    3 w7 k% A: R! `3 |        throw Error("w不能为无穷大!");+ e7 T7 L& c, T
    " S* \, A. _- `% \  R; o  i" o' q0 D
    . z' e/ O' y8 |& A! t% Y) ^
        p = vexTable[v1].firstarc;9 H5 z9 `/ A9 Z3 r/ ^
        while(p)
    . t) T9 |' C7 E0 H2 f8 Z    {
    6 _) q; h" ^# Q! S        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中' V4 m% K+ h* u1 Q* e4 L
            {3 Q1 F& v; @' a
                if(p->weight!=w)# s- y9 |8 c/ A# f( X( [* W
                    p->weight=w;* d4 |7 [/ |. m
                return;$ G0 E3 k+ q8 u/ @/ A
            }0 j/ ~. V  e5 v( V7 j' L$ u

      v0 v0 X9 [' x/ U        p=NextArc(v1,p);
    ) P: _* e' M6 R( Y    }! ^. B1 f2 N5 ~( o* a5 t/ v
        p = vexTable[v1].firstarc;" W7 D/ t5 j$ [! w* A8 x) j1 K, S
        q = vexTable[v2].firstarc;- z1 a- l( a; _8 j! Z8 Y3 L
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法9 P: s* ?- k- W' S
        vexTable[v2].firstarc =vexTable[v1].firstarc;0 Z: |6 g8 M( G7 e/ y7 a6 S; {
        arcNum++;$ n& z2 a4 V* z0 d2 ]
    }
    . W1 b/ d; _8 s; Z
    " X3 Y& F9 j4 ~9 M7 v5 T- Ytemplate<class ElemType, class WeightType>: z) Q! K- Y& v3 N7 S
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)& D3 C. C& {- w8 i
    {
    ) z& s" c, _& E# r5 V5 \# C1 I" l) H8 O
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    6 J8 c/ x' [$ [; n# [4 y9 X/ D    if (v1 < 0 || v1 >= vexNum)+ |+ h% M; |* i* L9 w4 Z6 j. \+ S% V
            throw Error("v1不合法!");5 d' R1 [$ K$ b. ~% r) L
        if (v2 < 0 || v2 >= vexNum)6 u5 Z2 t8 d8 e" O/ s
            throw Error("v2不合法!");5 }3 L& {( g& Y* ]5 ~: d
        if (v1 == v2)+ U# ]6 V" |% b% i4 ?. w5 `' [
            throw Error("v1不能等于v2!");' v7 N5 H6 X, x0 z4 `; Y  d

    1 G5 g3 h0 g; W: j# G. A    p = vexTable[v1].firstarc;4 |, n& g  Z) [! C2 P. v; t
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)& [/ A( ]; X* |. c$ G2 w( Q9 @
        {; n; {& p( p$ b
            q = p;$ B3 x) ]& V' t4 X8 @9 x8 _$ ?
            p = NextArc(v1,p);: o  {6 Q% f* U( l$ v! R3 W
        }//找到要删除的边结点p及其前一结点q9 y9 ^7 T3 m& r/ g: S5 M

    + D$ u. t& b/ O9 ?    if (p != NULL)//找到v1-v2的边- Z' |9 {+ P5 b& d8 P
        {- r, W* T+ i1 M3 g+ D/ @$ B1 `
            r=LastArc(v2,p);6 a* h0 ~( ?* S% w
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    $ G  m0 O# B. f; P            if(p->adjVex2==v2)6 j- [. R: x6 V3 n+ E% p
                    vexTable[v1].firstarc = p->nextarc1;
      C9 ^! b: p/ Q& e( B3 D; @3 p            else vexTable[v1].firstarc=p->nextarc2;
    8 b: O; c9 u* K" h! O        else//不是第一条边
    7 M6 w; f# i. E8 t; U5 u+ {( V  q        {
    4 r$ D1 f# K7 ^/ A6 K$ a1 `            if(q->adjVex1==v1)' f; y  X, f. ~# s* ~: S# Y
                    q->nextarc1 = NextArc(v1,p);
    % y3 V5 \* k* Z2 W3 r            else1 @1 Y, Q( L. p$ ]- d; Q- ^
                    q->nextarc2=NextArc(v1,p);: W; @. Q; |$ v, G
    - w6 @1 t) I9 u* W0 w
            }. y* o! W9 e5 g+ Z: g
            if(r==NULL)3 x6 i; w$ I7 P/ ^0 P& K/ ^
                if(p->adjVex2==v2)
    7 V9 o/ f9 u/ P) f% _                vexTable[v2].firstarc = p->nextarc2;
    + f6 \( y. ]: u" L  S) Y            else vexTable[v2].firstarc=p->nextarc1;
    8 M5 t+ l- k* a# ~$ C        else# j/ v+ o- c) s7 X" b
            {6 z- L! ~$ }/ C% {# M$ T
                if(r->adjVex2==v2)9 h* t) h# N0 J, ]* ]  M
                    r->nextarc2 = NextArc(v2,p);
    " p* l9 q7 ?2 N, f% \            else
    % S4 X! d5 p% E3 t  R" g) j                r->nextarc1=NextArc(v2,p);' `* `9 U' a% z' i! ?  x  y; }. C# _  c
            }9 ]' H" q9 h& F2 V* S& @3 M
            delete p;
    & I! M! Z/ t& I0 W$ @+ @2 C        arcNum--;
    / T% N; d5 `" B4 j# q4 }! ?4 f    }
    ! o  M' u5 d7 V7 H& a; ?- c6 w/ @: g& i) _( B. G5 i
    }8 u6 f7 F4 C5 J/ f) ], O! X  s
    template<class ElemType, class WeightType> void7 M# `2 b7 m  {# l& @0 E+ e
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    . @! N9 O$ g0 ~  G/ {{
    5 i2 Z& o, G1 @. v- Z# ?5 r    int v;) k  K) o3 H* K8 g. I, |6 r
        MultiAdjListNetworkArc<WeightType>* p;6 W& R2 T% v- ]5 L
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    3 _+ ]1 s# `" y% D        if (vexTable[v].data == d)
    4 X0 F0 \2 O6 `  B& i% S; N            break;; ]4 C! k0 }; k- q! p( h# ~: C
        if(v==vexNum)
    . t8 \2 j/ p! \8 o6 G, T2 Y2 L        throw Error("图中不存在要删除的顶点!");
      H' I& e; G/ x
    $ p! W: i; U$ j( f. o2 a    for (int u = 0; u < vexNum; u++)//删除与d相连的边1 c! z. n8 D) _3 V/ U
            if (u != v)4 y2 C2 ^+ N3 t) s
            {
    , }# ~& y# v8 V" J, V+ N            DeleteArc(u, v);* R6 o2 W, _! W7 p5 y2 u
            }
    8 u3 `& t% R" q" v) |5 W( C. |    vexTable[v].firstarc=NULL;0 A" e+ A& @# A1 }
    * x. ~: ^. M' N8 D
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    + M  v$ ?* z. J2 ~3 @9 c    vexTable[v].data = vexTable[vexNum].data;5 x1 J. P+ g7 K: Y" o+ Y
        vexTable[v].firstarc = vexTable[vexNum].firstarc;/ }! C' b6 c. p' M7 M6 }, v5 k
        vexTable[vexNum].firstarc = NULL;
    1 L1 _1 }! j9 u% \6 J, ^& @    tag[v] = tag[vexNum];
      F( ]3 w: D/ ~) F9 R    //原来与最后一个顶点相连的边改为与v相连) ~: E- S  e, M7 I0 V9 c1 i
        for (int u = 0; u < vexNum; u++), \/ b; u# W/ y6 o- _
        {
    8 _! N2 T6 v+ q        if (u != v), [" b% g+ C6 ^0 a8 `. O9 f  L
            {. Q2 i+ _6 ?4 Z" U
                p = vexTable.firstarc;4 ~5 P% n. W* ^) R8 z' ?
                while (p)
    6 I& c4 O0 P% c( f) y$ \( T8 s/ c            {1 G5 m3 N; Q2 B$ w& N1 k( o" f
                    if (p->adjVex1==vexNum)
    / Q& t3 `1 _% b7 h# _/ F/ {' V$ n" {: `                    p->adjVex1= v;
    ! o  f; i( V3 d: i& P* q1 y                else if(p->adjVex2==vexNum)2 C- E  J6 z3 z5 M7 X, t, j, w
                        p->adjVex2=v;$ P7 S( d% b  s3 H
                    p = NextArc(u,p);
    1 O0 }7 K( o: h5 q7 m. k. j            }
    ; T8 w! k' U* p" O4 \4 C: T6 L        }& G8 N9 s/ z4 J  }! X3 T# t1 e
        }
    : W- A% `6 R4 \- @- E, }}
      `1 M' s) e# g* _/ G! o///深度优先遍历
    9 e4 P+ [5 M' Z1 ?- otemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v): _6 Z7 ~# G& }! [: z: p. D
    {
    ( ^% g8 o4 j: [/ j9 [    tag[v]=1;
    7 {8 f7 I  V& ]8 b! J6 _1 m. r    cout<<setw(3)<<vexTable[v].data;1 I  B' `2 Y/ v, c4 M# u
        MultiAdjListNetworkArc<WeightType> *p;/ K! X5 Y0 t5 R! J
        p=vexTable[v].firstarc;' G( `2 \( f* d5 A+ c& e* K
        while(p)8 N$ ^2 U; C3 j# G4 c
        {, G, c& m8 a3 G7 h
            if(tag[p->adjVex1]==0)
    , R3 Y* k2 {+ ]9 m& t            DFS1(p->adjVex1);
      ?) {8 y. F' a' i        else if(tag[p->adjVex2]==0)  K+ F) A, F6 L: ?8 g- l# P$ Z
                DFS1(p->adjVex2);
    . Q2 H1 L* Y" |% b& r' z        p=NextArc(v,p);( I* K& `! v6 C& c, \  z
        }( q, H3 I1 n. V( T
    }
    - l; D% a9 s7 [2 p: b: @) d% W# |template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()7 t- C4 v% c% S# l9 v: A! q( K' g: D
    {/ v" @% r: K4 M5 b
        for(int i=0; i<vexNum; i++)8 e" d2 L. Y, {
            tag=0;
    4 R* M$ A+ N* L$ U+ A" `6 z4 B    for(int v=0; v<vexNum; v++)
    2 o7 Z) o! n+ }9 P- v2 l0 o7 B    {
    # X3 p0 H2 `  H$ R        if(tag[v]==0)1 ]2 M1 }! l! |0 [
                DFS1(v);9 }) z  n0 }* x& Q; H4 k$ v
        }
    0 s3 F* k/ z8 I$ ?% M  M, K}
    4 S3 _: ?8 o7 o1 K8 p9 Ztemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2(), m) a- g( @0 e3 ]! b) g
    {* w& h! Z9 j+ i, A3 v: `
        stack<int> s;, [% y( j; r* U5 [: F. z& ]
        int tmp;
    # _0 h- {. p- f3 A    MultiAdjListNetworkArc<WeightType> *p,*q;
    1 p3 B; u6 U% D& M0 B/ X( J! q- `8 {    for(int i=0; i<vexNum; i++)
    ; x  m5 s% _8 Q& h3 v% I* ^5 k        tag=0;
    2 R7 i" A8 C# E: H    for(int i=0; i<vexNum; i++)
      R! m6 b' C' t$ Y; x    {" l. z# V, ~$ T. ^' F8 g: Q7 _0 t
            tmp=i;
    9 z; H0 \( L+ ?/ `( ~        while(tag[tmp]==0||!s.empty())# x: F3 N- e2 b! Q/ t2 d
            {
    ' Q# M3 h5 X7 [' `0 b2 x; \) s            p=vexTable[tmp].firstarc;
    1 }9 o$ v0 \! |/ O            while(tag[tmp]==0)
    / n- Y7 J7 s; }4 I8 s- i3 u            {6 P4 e/ C: M$ [$ z) Z* K
                    s.push(tmp);: i5 |" ~# G; p- T
                    cout<<setw(3)<<vexTable[tmp].data;8 F* c# i0 a- T6 Y9 M2 e1 O
                    tag[tmp]=1;& g2 V( t" R' h1 m3 d, _$ \
                    p=vexTable[tmp].firstarc;
    . W2 i: A: _, W2 ]# A) J# K                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for( v$ p: z4 i2 G# i$ C' N+ b4 L
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);1 ?6 h+ P& z( k5 s
                    //cout<<" 1st     tmp="<<tmp<<endl;7 o4 J1 K# n/ J8 E5 u) y
                }
    , A% L3 E# q8 F            if(!s.empty())7 |2 o; A$ H: o5 {$ h
                {
    ; r# h. p$ W0 W- ^5 c: E9 q( C                tmp=s.top();/ z3 |0 h0 E0 J; s# \
                    s.pop();( o3 H0 U  \) h  c
                    q=vexTable[tmp].firstarc;" B' J9 ]8 L- m: n4 O$ f$ J
                    int t=tmp;; v( i) k! s; [( c0 z8 ^
                    while(q&&tag[tmp]!=0)! t0 r8 b/ A* Q; N4 ^8 z) S, e
                    {
    4 Y) b- U' m0 }. V9 Z                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
      p1 t2 u/ R6 U" Z3 n* m8 q% F                    //cout<<" 2nd     tmp="<<tmp<<endl;
    ; Y# v3 ~& u4 f                    q=NextArc(t,q);; t2 P% h4 G) e  z1 G. d! ~( Z
                    }1 F' \' e8 M. k
                    if(tag[tmp]==0)% @/ ?. E. k; q. P
                        s.push(t);3 v$ n% S1 E/ m4 f3 R
                    ///1、对应上面连通分支只有1个点的情况
    ! C* {; j# x5 T+ o5 C  e                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    % v6 m* Z1 \6 z& @; m  n                ///tmp要么等于找到的第一个未访问节点,- H* F  T# }- D) c8 V
                    ///要么等于与t相连最后一个点(已被访问过)
    , E' `. l5 Y$ T) M  ?& v: g: o! C                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    $ B2 }& H' V/ P8 k0 X* F            }5 u, K2 {  O: K; W( J3 f1 N5 P
            }
    / l: e2 ^; t' \: q    }" o' H4 E& q% C5 z0 j( B) S
    }
      y7 v$ P- L. T6 }  M$ ?" p//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-13 M9 g) ~0 m: G2 s2 |
    template<class ElemType, class WeightType> int1 O4 q; b3 |- Y* V
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    + ^( G/ J+ }: ?$ D( {{
    + U, u- V  @9 @' B    if(head==pre)8 n$ G7 [8 o3 E) r9 y
            return -1;
    % V+ n, _7 D1 {4 E9 O& D4 _; a7 U
    / O5 t0 g2 ]$ B8 r5 U: |# J    MultiAdjListNetworkArc<WeightType> *p;
    $ E1 c  Y! ?. G) X9 y  K    p=vexTable[head].firstarc;
    8 I* A% h2 N5 M- V8 p6 |+ @    if(pre==-1&&p!=NULL)
    - U/ e* B! ?& O        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    5 ~4 Q: D; ^( y4 {% B    //pre!=-1&&p!=NULL
    : ~8 q) N6 g8 h6 h/ E' z0 B    while(p!=NULL)
    0 m' X. Y+ {" ~" w" Q, Q) P    {/ i  g/ O- e/ ]' {9 H
            if(p->adjVex1==head && p->adjVex2!=pre)/ R4 Y5 }1 C. ~; n4 j
                p=p->nextarc1;
    3 [6 e9 a" r  m        else if(p->adjVex2==head && p->adjVex1!=pre)
    0 s% [# V9 V- F, k            p=p->nextarc2;
    1 k8 ?. Q7 d' v4 d$ z" i        else if(p->adjVex1==head && p->adjVex2==pre)
    % w. g! Q1 ]+ c* @9 G1 b        {
    4 Y8 Z, J8 n% a: }0 `! {( A  O            p=p->nextarc1;9 V* r  J) a* ~
                break;
    + h/ P5 \1 U  t, R6 O& D- y        }
    $ A4 Q* v5 @3 B% H# m        else if(p->adjVex2==head && p->adjVex1==pre)
    % ]" R3 X5 y7 b* g        {* N) M$ ^" n+ e5 r% _$ K; d
                p=p->nextarc2;
    % _; i. p- t% |' F            break;
    9 u# K& y# r4 ]. Z& H& F$ g0 Y        }5 c9 ?) S! h* J0 Y
        }; p/ S+ m) p4 q. P' @; `" W
        if(p!=NULL), @" u- N+ m( a. U( d
        {2 C, t4 F2 F  U. A
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    ! n. v8 y5 \5 C" ]5 Q3 O* R    }$ |" Q! e$ r. ^0 b; i- }9 {) J
        else
    2 |) i8 v, d, p' \; e1 [% i        return -1;& W3 w8 ^2 R0 F/ ^- N, X5 l
    }$ i7 A9 g& |9 O" O
    ' c) D& t) g1 o% V
    2 h0 W# L# ~- {1 A, h# _
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    ' w- D' E! a# w! S( Y{5 R' X8 L! B3 r* l* x5 X2 @4 g; k: O/ j
        stack<int> s;. p+ p1 h' R  ~1 ~! T
        int p,cur,pre;
    1 h$ t' b& _4 s# h    //MultiAdjListNetworkArc<WeightType> *p,*q;
    & ]" `$ V) R7 z% a) [' `0 X    for(int i=0; i<vexNum; i++) tag=0;//初始化! J. E: l+ z. G
    ! d3 n5 L0 r; @- i
        for(int i=0; i<vexNum; i++)8 Y) G& t% u; q. ^' R+ q: H
        {
    ( r' W1 r. {3 Z6 k. I8 d        cur=i;pre=-1;" G5 f: Q! @+ x. O! G
            while(tag[cur]==0||!s.empty())
    2 Y3 E/ P: b% k* y+ ]        {3 G3 P8 h0 `2 O
                while(tag[cur]==0)
    4 W# J- H; c- I            {
    6 W# y8 g) j. M1 D, h( c9 J8 [                cout<<vexTable[cur].data<<"  ";! H% y* x$ e, k  j/ H- Q- o0 V; u
                    s.push(cur);
    , d1 ~/ N) a+ _                tag[cur]=1;
    5 s7 }7 }4 {* U; P) O               //初次访问,标记入栈
    ) {% Y+ F, P8 A- I$ T# |# \  M
    0 U8 @) r6 N# F+ s! w               p=GetAdjVex(cur,pre);//p是cur的连通顶点- o% f, d, J# R# h" c% Z
                   if(p==-1)
    , E  Y3 b# ?' I' ^$ A8 y               {
    % E2 w& v: L$ m2 ~, M" z6 T                   pre=cur;s.pop();
    / q$ v/ v' Z# z% T2 S: V8 ]                   break;, M( N, K0 ~* |- ^1 o4 `! J
                   }( B* w0 p7 w& S1 X! |3 N6 |
                   else/ C7 }- ]8 b0 K+ F
                   {/ p3 i& c; a8 T  j
                       pre=cur;
    0 H7 C3 k$ _1 h2 Y; _9 Q5 x# L. k                   cur=p;+ f4 Q' b5 F: Z
                   }
    7 o1 a$ C. K3 y, n" A! P
    + T2 ~  D% j  j% A7 L  x$ J- D            }+ Z4 n* |$ w" M* W
                while(!s.empty())* A1 o3 j6 o. B/ H) Z$ u# g
                {! N2 U& c  C5 b- A# V+ m
                    cur=s.top();1 z' |% D  b3 }* M, M7 M0 z
                    p=GetAdjVex(cur,pre);
    " L" n& r2 C9 V: P                if(tag[p]==0)
    # J. ?$ j, @0 {$ J; }0 w& k                {
    7 v4 @3 L0 M5 e. W8 q2 x+ j0 t: r                    pre=cur;* [- T' I$ p' x# u# I& s
                        cur=p;
    + m& d8 s: m7 X                    break;
    $ _4 G0 t0 h# M# N* W                }
    1 k7 c# E3 Y- T+ p- F. b' r                else+ M; v" R' `2 L# j3 D
                    {+ k0 y9 v. A% X1 Z1 V; A: Y9 Z
                        pre=s.top();$ N4 v) j1 n: E( d8 D: c$ ?
                        s.pop();
    & O4 ~8 h' K) }4 V* g                }
      Y, A5 k* O' h, O3 z1 ?4 S( E) M$ Q& W& N7 j
                }
    ' q1 H  \/ A3 t, p
    % L) Y' X% B) g- I# U) j( a        }) x* K5 u- l) V- z0 C3 u8 Q
        }
    . G' ~0 l) L& p% ~$ }}8 A6 O: v* y* Y: y' S& i
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()1 a* ^# ]) s. ^4 i& L
    {
    & F" j2 b; N% Y; D7 B3 c    for(int i=0; i<vexNum; i++)! d# V6 `: I; ~0 i6 u8 c/ h
            tag=0;: t* D# R2 }% U' n0 M' c* }- s: y
        queue<int> q;
    1 V9 k' v/ v8 m! p    int tmp,t;
    9 F: A5 u0 c( s, L6 a    MultiAdjListNetworkArc<WeightType> *p;0 N- G# }$ X  z4 e- g2 R
        for(int i=0; i<vexNum; i++)* I2 T8 l3 l7 C5 k8 ?
        {
    7 N1 r7 q' f2 J" r' Q' _+ r! }        if(tag==0): X- g" g1 ?5 G- E7 A8 _
            {/ q; X( T( g) [6 ^+ E1 T- c) }
                tag=1;
    / Z! V# @. C' v" ]; [# g" e7 G) X0 V            q.push(i);' X: V) [/ A$ y. K
                cout<<setw(3)<<vexTable.data;# h2 \" l- V) s
            }
    5 v" c: ~1 ?( L+ F* b        while(!q.empty())
    7 Q" r2 w; Z% P! l" w/ M; W        {
    0 W0 Y) d; J3 R            tmp=q.front();0 g9 N2 T7 b3 w
                q.pop();
    . V! d+ |- A- K( i& u            p=vexTable[tmp].firstarc;
    3 A) s! W; t1 U! }- D            while(p!=NULL)
    ! e, m; X; r  y* D            {" W( s: j( _! y  r! M
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    . s5 n- v) x0 X8 P7 [) u                if(tag[t]==0)
    ! P. h. b! t, p3 K3 l' P- W3 u                {
    ! X1 {! Q7 S! K" `& f  T                    cout<<setw(3)<<vexTable[t].data;% q9 j  Q- g5 p# C- k8 s. \5 {+ v
                        tag[t]=1;
    1 l) i7 R/ z  [. \! |  S' L                    q.push(t);
    2 P! w0 n' q; b                }3 H" c/ {7 I- N8 V$ @4 ?
                    p=NextArc(tmp,p);
    ) |1 J5 a9 `& t' K, r% a( \            }
    8 t# U9 s5 s% D$ T  n$ ~        }$ i, F* H7 p7 ^9 G' [: n
        }( U: x7 W+ I! I0 b# J" t5 c
    }, Q& ]2 [3 j% R
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()+ {. m" f, ?0 C- I2 p* t% x" i
    {3 x/ @9 ?% v+ p7 e
        MultiAdjListNetworkArc<WeightType> *p;
    7 l4 E  X; p( @& o    cout << "无向图有" << vexNum << "个点,分别为:";; B3 ?6 v* C9 v5 `3 R! G
        for (int i = 0; i < vexNum; i++)4 P5 v0 _% B" R
            cout << vexTable.data << " ";
    7 g9 _4 o& u' U    cout << endl;- T1 U* _& Z' Q- T/ i6 o
        cout << "无向图有" << arcNum << "条边"<<endl;
    % |2 `# l( p! |: F    for (int i = 0; i < vexNum; i++)
    % {* y& \7 h  ^& ?# x    {
    ) f, B0 [! ?, _7 \. @        cout<<"和" << vexTable.data << "有关的边:";0 i8 s9 r3 ~' B, g" D
            p = vexTable.firstarc;
    ! j& P+ n& u2 L' |: H$ ^# X4 |) I6 ~        while (p != NULL)' q* a+ w0 s0 A  V% U
            {+ H5 I3 I. S0 _: i$ N& t8 s( x
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    & C1 V3 Q. Z7 N: s: ]5 p            p=NextArc(i,p);' d; X! f* L# M1 ^4 @5 K
            }$ q3 r2 }( k1 ?1 s0 [* k1 |. \
            cout << endl;
    6 ?- ]9 [; |% z; i    }
    4 N. l( C- D: v1 W}+ `; j8 b: ~9 h) t
      j$ E  ^+ {5 {

    9 Z/ e+ O! O6 h* }9 y+ x邻接多重表与邻接表的对比+ w: b4 a4 e$ k: X8 }

    ( [1 S1 `: E: k9 b) b2 S- J邻接表链接- ]  {0 @, Z% n4 N) q
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
      {3 Q: p; u8 o4 @- L, P在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。8 }9 {+ x/ ?7 f* T4 P. O
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。/ n: |0 }/ l3 g8 p
    ————————————————
    1 K+ K& U: z0 c4 B版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。3 m9 ?+ C: y5 L+ k) s6 T/ n
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    ( e/ y0 d! o; f1 P9 n: t! E5 R
    2 l, r. g4 t$ W0 c! q4 x, a/ X% y) q; V1 w% ^
    9 j7 n8 a, p8 B2 p0 x2 p: e

    * Y# N2 I, Z7 V4 t————————————————
    . U% z% J* c" m' i) ~  @版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ! w3 G0 ]$ d( j: Y. I' p( ?原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958, G. R( p" y& p; m' K

    - s+ w! O9 v$ X; ]& c. A: c& l7 h+ ], `* I) I
    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-10-22 05:03 , Processed in 2.753275 second(s), 53 queries .

    回顶部