QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1452|回复: 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
    & B; @  Q' t0 i
    图的存储结构——邻接多重表(多重邻接表)的实现
    7 k5 L$ E- m$ c, a7.2 图的存储结构, \2 r$ E9 t  }! C2 o$ n' @0 Z: o

    - v% j1 P# Y  z2 ^. W) B7.2.3 邻接多重表(多重邻接表)Adjacency Multilist+ ^; N! W8 E/ [& O! G. x# m: R
    邻接多重表的类定义. u. F0 ^5 v& P# D0 p; w
    邻接多重表的顶点结点类模板
    / g" J3 j+ g7 n- E0 u2 V& V% Q邻接多重表的边结点类模板
    5 S/ `! o$ D4 z; O$ n0 _6 z$ D邻接多重表的类模板
    $ I9 @- Z" O/ C! W/ J  S& D1 z9 z邻接多重表与邻接表的对比: z7 {* t' Z3 B5 E9 v- y# [5 l
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist, S1 l; |- ]  e! `

    / N5 i6 U3 y  L: r在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    . v: |& R' L9 }' Q, m. S在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    4 H5 D! d6 Z" y/ H1 C& N# K
    , v# S9 Y9 d6 H5 _3 `' G0 _& B邻接多重表的类定义  c7 e) i8 @5 k# d
    1.png
    ) u0 c1 b- b, e& r4 r4 W邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    ; S- ?9 W: o1 c  p5 e2 L% v  Sdata域存储有关顶点的信息;
    1 v3 P6 G1 O& [# H5 o- \firstarc域是链接指针,指向第一条依附于该顶点的边。
    , W8 W$ m( B/ s7 \) W' A所有的顶点结点组成一个顺序表。


    9 c6 p1 f/ E7 P
    & M, ~3 g  h9 q' q1 xtemplate <class ElemType ,class WeightType>
    4 L$ @% l8 g# n! @class MultiAdjListNetworkVex' c% L+ A% p6 `* Q# Y; \; T
    {
    1 D/ E; w3 |- U5 ]" c. j# u5 ipublic:
    , b  u* X' N% S! [9 i5 `        ElemType data;
    1 }: S& a3 p& C6 y! ^- P        MultiAdjListNetworkArc<WeightType> *firstarc;3 K  W- i  L2 k6 H( F; l6 a* f
    3 t0 t& _4 ?, m% i) `# c) ^9 s
            MultiAdjListNetworkVex()
    ) z, i) W/ W# {& h7 Q/ W: O/ |        {" Z  S: ]* y+ [7 ?! y
                    firstarc = NULL;
    ' u+ J  U2 B' J8 ^        }
    . `$ `, g; V: X3 G1 t- L. f        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)0 y& S3 G: T9 u1 I
            {
    8 d3 t3 J' p/ C/ v: U: h% n                data = val;7 T9 H) P  k# i
                    firstarc = adj;
      ^) k. Z! k5 {8 I# ]/ x/ n! e        }4 U7 A5 }7 @% S/ ^
    };& P: c% H/ U) n* S0 E/ y" Y. H
    6 T& u. A  Y$ F4 [8 V) i9 ?
    邻接多重表的边结点类模板
    4 z! A' Q$ B( t5 S, t: q7 p
    6 w' l4 V& h; E4 @8 s# O在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:2 B2 i4 M( V2 e, x3 y2 i
    tag是标记域,标记该边是否被处理或被搜索过;
    / P5 q+ M1 o+ U  m2 {+ uweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;7 U; s/ j; t  }% W
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;( Z+ ?' q& @3 O* v9 e# E0 p, ]
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    * K) R. T3 K" e' }% [% Q: G( V2 r
    ( X! _* f# v1 o* c% A* J( W! F 2.png 4 p4 @- x5 N( L" c+ O+ p0 `1 B6 Y# v5 |
    template <class WeightType>
      B7 {1 a; a, q5 Wclass MultiAdjListNetworkArc
    ; ~7 r( H: [* S$ w{# c" a$ g9 L8 y. R/ c
    public:: N- O" V4 u2 p. F" T' Q
        int mark;                                       //标记该边是否被搜索或处理过2 T. E, L; n5 a0 d! x0 @8 K3 G
            WeightType weight;                              //边的权重
    & i" Q. ?- t0 |$ ^& ?3 ]        int adjVex1;                                    //边的一个顶点. `+ f* s5 A; Y, _$ z, W7 r2 ]1 M
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1  B+ M& S* V2 ]5 y/ b
            int adjVex2;" |0 {" P4 {7 i. o
            MultiAdjListNetworkArc<WeightType>* nextarc2;
    : Q4 E, }7 l5 ?; N- t& y8 g
    2 _9 @3 j1 B& J/ A' b0 y        MultiAdjListNetworkArc()
    + U2 W) ?1 P, ~        {
    3 f% W& N/ A% g. |# H) Y( ^                adjVex1= -1;# v. o; b% X9 S( Y; Y3 l9 P" _% b
                    adjVex2= -1;# y+ i  V6 \& s! e* F" U7 m
            }
    ! k9 E: M% G* d0 R" R+ z6 `        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)( @+ _8 }" p2 e6 y: ]( K
            {
    0 V( r3 b8 K7 t3 k                adjVex1 = v1;       adjVex2 = v2;
    " U! A7 f2 E6 v5 [. E% i- @                weight = w;
    / U/ W5 F* Z4 q; {* P                nextarc1 = next1;   nextarc2=next2;9 X# r: Q; K4 h! v( @6 K; t
                    mark = 0;           //0表示未被搜索,1表示被搜索过0 r' w: Y! n( q
            }
    ( t/ G. g( e0 f+ r. X( Y' ^, U2 i% E2 L6 |/ V* R& m) C3 X
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>4 x( m+ p* e0 u
    class MultiAdjListNetwork
    2 l' V3 w! z& c1 Q4 i( C8 i{
    $ D9 J( Q3 h$ w8 Qprotected:
    * ]- H9 j1 T& O  r* ?4 z    int vexNum, vexMaxNum, arcNum;$ E6 _8 k. _* j- Y- D' l( C! H
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;7 H+ D( p7 F5 V) e8 z
        int* tag;8 O# _. Q9 N* q. n3 j
        WeightType infinity;
    " _) l6 E' L4 ^0 i! R& r+ X. m* R' ]; L: Q7 [  S+ Z8 h
    public:
    + k. B0 o) {3 J$ \    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    , l; r: j* w7 j& v2 z- k/ U
    : U( e7 l) F" P4 V% P    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    + p; j+ z/ E3 x5 P
    8 G% N' H( t5 M$ ~    void Clear();! w: n7 K% U2 Q- x3 j+ W' c
        bool IsEmpty()
    # Y6 [4 |) j$ @& }" d4 m+ }    {
    / C1 ?5 H* M. Y% J3 b        return vexNum == 0;
    8 F# g5 u$ R& j/ C8 D8 X9 ]    }
    - l- @4 z0 K1 q# X8 n    int GetArcNum()const9 _/ E" D+ t) F3 y( J# y, t
        {
    ! n, x+ m* Q- Y$ ?+ x        return arcNum;, b& h( L' ^1 H. _0 E" d! e
        }
    & h1 I" l) D/ Y, Q: {6 a' a    int GetvexNum()const* d6 w6 X! v+ M8 T% B" i
        {5 a5 |) X7 m* y# B, b
            return vexNum;
    8 M5 i9 F5 D4 c, ~( q' {; U/ o2 b    }+ P1 ^5 O6 O+ X, w
    9 U) _5 t3 ~/ o4 v; e, v% r. D, @
    , L0 |( T: s# y$ |- q6 q- k# A5 q
        int FirstAdjVex(int v)const;
    * X, ]" F% J& V/ u) I, `    int NextAdjVex(int v1, int v2)const;  C9 `. F8 d+ M; k8 M) p: I
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;6 D) D( e/ r1 o2 F9 I; A
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;( Q3 F% y2 }1 T$ w7 L

    , Y% Q* J9 Q/ I9 M, e    void InsertVex(const ElemType& d);
    7 q' R6 J6 \* h' w6 L5 P3 |7 I    void InsertArc(int v1, int v2, WeightType w);' |- s1 M' F. i8 ?( M. B

    ! Z! ?7 [6 a, }    void DeleteVex(const ElemType& d);
    6 `0 Z- N* X# I    void DeleteArc(int v1, int v2);& Y  a, x/ ^0 X; W( m
    4 i' R  r% M6 {& `
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);: H5 U) ?4 d, |7 [
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);1 ?1 j3 J. i( R5 B, K

    2 U! a! \9 t2 d$ t    ///深度优先遍历
    . B2 {& V9 Y+ e" R9 l) T' s    void DFS1(const int v);
      v% ~3 w' y: \4 M, \  q* p    void DFS1Traverse();
    & ]7 O/ Q$ w+ @7 A    void DFS2();* E5 X& x5 ~' n/ M% M5 h

    , A* ~  d5 R+ L& |7 L% }    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-14 ]% ^" W. k4 Z! G- |3 h
        void DFS3();
    : B4 R8 L1 d8 Y! `. L) y$ i3 H/ A, r) C
        void BFS();0 M! j7 r3 Z$ h1 u
        void Show();! ^% O) q( x9 P5 z4 l7 v
    };
    ' g" t; G+ C$ d9 d
    2 L! z" R+ B$ }) J2.函数的实现
    & ?; [6 z7 J  u8 m研讨题,能够运行,但是代码不一定是最优的。6 k8 P6 J2 O+ n  P6 x

      X' p9 R- p! F/ Q. a' J- U3 ?#include <stack>
    $ ?+ D7 K- `2 \9 ?8 M) J#include <queue>+ w( @& z# g5 K) d( P. O
    ( w5 E$ W$ `% a
    template <class ElemType,class WeightType>( q8 e6 m$ B2 \3 F6 |
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    4 {/ m, Q4 Y+ ~4 c0 A! S" c" {{% d( h5 v* W# l. z0 D& k' \" ]
        if(vertexMaxNum < 0)  K" ]+ j8 S- a" L# X. b) F+ Z
            throw Error("允许的顶点最大数目不能为负!");
    3 h5 O% t5 H! O6 @    if (vertexMaxNum < vertexNum)! ^# l/ N% o) |* d* c4 l, T
            throw Error("顶点数目不能大于允许的顶点最大数目!");
    / B& ]/ }' b+ _    vexNum = vertexNum;2 C) o  X- n; {. }% I, Q
        vexMaxNum = vertexMaxNum;
    3 v5 ^% d; \2 W4 T& V$ ~    arcNum = 0;
      b8 C7 q* ^: ?& C2 D; ~- I" i    infinity = infinit;1 H9 I3 ^# A8 f7 W) j" Q. g
        tag = new int[vexMaxNum];
    + V1 K" D, |4 A0 ~9 e0 X7 |    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];, B" [' _/ V% Q
        for (int v = 0; v < vexNum; v++)
    5 A. r  c5 o4 c4 x    {
    : c" d/ ~' s1 _- q/ s4 U        tag[v] = 0;2 b/ t) n( U- x6 ?, P
            vexTable[v].data = es[v];
    2 D! j4 l) o6 u' Z# Y5 H        vexTable[v].firstarc = NULL;( t/ J$ C" f- e
        }& h4 G+ E: y! ]. q8 u
    }
    " q, ^% v& U; Mtemplate <class ElemType,class WeightType>
      p! v7 ~" H! a! QMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    $ A0 a4 y0 W8 ]) L# j% Y{% M9 [( V9 c, [& ]0 _" g/ H7 n
        if (vertexMaxNum < 0)
    # {0 l  I+ w/ g. F" S& W0 [3 ~        throw Error("允许的顶点最大数目不能为负!");2 X8 N5 R) F. m: l% Z
        vexNum = 0;1 u3 p$ U, c, `* Z4 N3 z- T
        vexMaxNum = vertexMaxNum;
    9 f! \5 L3 _+ M    arcNum = 0;! Y$ c8 a) |4 o/ A
        infinity = infinit;: n6 z" t$ F$ p7 h+ A; C# \! K$ `
        tag = new int[vexMaxNum];
    ! `% {  ?9 i. v9 r& h    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];2 @1 s6 E% ~  o# U; y
    }
    , x9 b1 R: U+ h" Q$ w' l9 C/ ]template<class ElemType, class WeightType>
    4 h8 v+ a- U8 {7 x% r! b- k& oint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    # I) l" _' O) Z2 ]. ~{
    $ r# D, t( Q9 W  j/ X( X- @    if (v < 0 || v >= vexNum)7 d5 u5 @0 x/ }' K: D: r
            throw Error("v不合法!");3 ~- a# J" `0 I7 P7 V
        if (vexTable[v].firstarc == NULL)
    0 D4 s# o0 u7 v' k8 N/ d, F        return -1;
    + J: J" R: }. c! F# M- J1 \' t6 o    else
    ) I( k9 Q2 P- f) |        return vexTable[v].firstarc->adjVex1;
    - \7 o& _8 w5 z( D}
    * }" ^2 K9 ]0 i+ L. R1 M2 d; Z$ I4 d) k2 E
    template<class ElemType, class WeightType>
    , E3 _4 U* y9 |* ]+ |int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const$ r8 r$ j7 A3 Q3 e9 }! a
    {
    0 W0 u& z, `  T, K    MultiAdjListNetworkArc<WeightType>* p;
    ; j( e( t: q) \; n- Z% O$ K    if (v1 < 0 || v1 >= vexNum)
    5 ^0 l/ A1 ?  z$ i& r2 u        throw Error("v1不合法!");
    / x+ H( _+ L. Y, B3 g    if (v2 < 0 || v2 >= vexNum)3 B, ~6 q7 u2 c) O* C2 a  A/ X7 d
            throw Error("v2不合法!");
    : D, F, u3 C4 Z: g" O    if (v1 == v2)% W; Q1 Q/ R$ M- S  p/ H# o
            throw Error("v1不能等于v2!");
    ( f; l2 ?; s: h. ?3 B    p = vexTable[v1].firstarc;
    ' i* K* J+ l; r5 A# e    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    1 K# {1 j$ @$ }+ N  r        p = p->nextarc;
    - h& r! F0 j% S# K* _- d% W    if (p == NULL || p->nextarc == NULL); M1 s  r! M( g/ t6 u5 }
            return -1;  //不存在下一个邻接点2 J& \; l5 ?6 u4 F8 N3 f
        else if(p->adjVex1==v2)4 u# u5 V; q8 T! L/ r
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    9 ?& p. f: P7 U( [+ i    else
    ( H' Y/ y" ~3 Q# Y, T        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);! f8 O0 ]% p; M7 l7 n) W% i
    }
    : V: U4 [. i1 H+ v* @3 w" Ytemplate<class ElemType, class WeightType>
    # \& ~% V; s7 mvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()( ?2 j0 V1 S" v: j$ m0 w
    {
    - K; K1 \4 g! Z' ?1 Z  w8 g+ P$ u    if (IsEmpty()) return;
    4 g  S' C7 p, d    int n = vexNum;- S+ v/ B5 I: O
        for (int u = 0; u < n ; u++)
    ( m" k6 N" \, ^8 x1 a        DeleteVex(vexTable[0].data);7 R% [, L5 |2 T" O7 ?4 [3 m
        return;
    : p0 ]3 a0 E. q& i+ w}  C! [" u# t' ^, I+ m3 M
    template<class ElemType, class WeightType>/ ]; l' i5 ]5 h
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()( q; ]& S4 r% f8 x8 m1 R' w
    {
      W6 j- |) X6 K, r, }) w  O) F    Clear();" b1 L4 Q1 }2 d! F
    }
    * ~( M8 q/ F4 t( Xtemplate<class ElemType, class WeightType>
    " S- d) ?8 ]* G' y' H' GMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    8 s9 ~6 B; E8 e4 g) W6 s& l2 l{
    # J! d$ D/ a. u% J% L    vexMaxNum = copy.vexMaxNum;4 u" v+ d$ f- Y+ p( f+ Y
        vexNum = copy.vexNum;5 k! f8 f  j6 f/ V9 K6 {' r' E/ C
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    " q' R, }/ o# M; L; W    arcNum = 0;2 w  v* ~- N4 G
        infinity = copy.infinity;
      d/ h1 `! i& G* ?    tag = new int[vexMaxNum];4 ]$ t! \" P' f( l5 m+ c& |

    ( i* E8 R. l+ Y# B    for (int v = 0; v < vexNum; v++)
    7 ], Z; z" V$ ?    {! Y/ d( \% t2 O. x) T8 W
            tag[v] = 0;
    ( A6 A% k4 e! L9 o        vexTable[v].data = copy.vexTable[v].data;# `; ~2 _" J" O9 C5 {, a
            vexTable[v].firstarc = NULL;5 R1 _- i8 U* K9 d+ u2 g; G$ f0 p  {
        }
    ! L$ A- A5 E& l2 d5 r# E    MultiAdjListNetworkArc<WeightType>* p;
    & T% c5 f3 [& c) k
    0 i: H& D6 Y  w; x3 m" D    for (int u = 0; u < vexNum; u++)
    " W8 A! |+ Y8 d  P& U0 }' M' h    {, X; p, s& V/ ?
            p = copy.vexTable.firstarc;" ~/ \8 G/ t* m$ |
            while (p != NULL), U0 J- T2 e! ]5 S9 r7 X
            {* t2 J* S! K  V: R, l5 c8 d
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    ) M- o5 N* |" C* O+ T' [            p=NextArc(u,p);! j$ K) X& G1 d& P
            }
    " l9 I' x3 T& T    }
    - e1 g) l' q: v8 u$ s}
    * n  G* E) A; d0 a; T( Utemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&5 d  D' b9 D* R# n& M/ ~* U
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    9 D8 Z1 X/ l6 B2 Y{0 {! Q8 Z1 W8 h0 V: ?
        if (this == &copy) return *this;' y$ Q4 F% r/ I
        Clear();0 D' E: b( M* Q$ U' B6 f' B( D
        vexMaxNum = copy.vexMaxNum;1 z) [3 p  |$ X* `& Y
        vexNum = copy.vexNum;6 D( C8 T# B- l' _3 O, W1 m0 Y0 b
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    9 R; t0 W: B- m    arcNum = 0;
    : |% w7 k4 t& Z. e* C, A    infinity = copy.infinity;' x: o8 [) F6 U% y$ @2 M2 _" ]$ r
        tag = new int[vexMaxNum];
    + x; S! A3 u" Y- p3 C7 h+ D9 X- q$ p  {
        for (int v = 0; v < vexNum; v++)/ J/ ^/ x+ {  ~3 D
        {. Z" a( S! I; {' Q5 G/ ?( V
            tag[v] = 0;
    " x8 K; f& D  X; |( y        vexTable[v].data = copy.vexTable[v].data;0 q* _1 z0 m* p0 G
            vexTable[v].firstarc = NULL;$ U( p) K9 K: ?6 D3 f' i
        }- r% @& ]& o/ z2 o6 y
        MultiAdjListNetworkArc<WeightType>* p;
    ! ]( O- R% a6 p( h+ M1 p( {/ u7 |* b% n) b
        for (int u = 0; u < vexNum; u++)- G" z5 N9 i7 E0 _1 Z  q" |
        {
    $ K2 u' G4 t5 H4 }0 E        p = copy.vexTable.firstarc;
    0 z% ]* l. b! |& {% n8 b$ c8 N. r7 L        while (p != NULL)
    ) H1 {) D, H, J5 y        {
      |$ c+ |6 {# p8 g            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    8 l+ X3 x% N7 J" G            p=NextArc(u,p);9 j& D8 Y1 b# @# B& f. M
            }/ v# J3 S9 G: ~5 G  s
        }! \! o& j/ t& E7 V) Z! T
        return *this;
    7 ?- S% m/ x) {8 j! u' c" n0 O}
    0 c+ c) E1 T- I& [$ a4 _$ l! Ktemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*+ Q, C5 H* B) ]8 q3 ?1 `* A1 {
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    3 [, e4 O$ A3 S9 v$ ?! |& A{: Z! b$ |2 z6 n$ u# [) n7 a& M# k+ z: Z
        if(p==NULL) return NULL;
    ; ]1 G( [% m$ ^; l3 G    if(p->adjVex1==v1)
    1 D8 g- O& O) k' K) \( I- p' ]2 K        return p->nextarc1;
    & p; J# m* z# x1 y# f    else1 D- t; `2 S( `( h5 d) V5 L
            return p->nextarc2;* c4 ]4 ]0 h: W7 L& N7 B7 R9 ^
    }
    " K3 r- L! ?: u* Q, H9 ptemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    $ l  S- m& A7 t2 p% s0 C, qMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const1 j: _, a! B9 b, h$ w4 ]
    {
    6 s. ~* C6 |' Y8 E, X& N2 k4 T* L: V    if(p==NULL)return NULL;5 s8 `3 U. v8 @. ?& R0 Q
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;* r( h# r" z2 F& b0 M9 |+ C9 ], M
        if(q==p)
    6 ^! Y" Y0 }) A3 Z        return NULL;: ?! \% a0 n; i9 M9 P. j) @
        while(q)& w% m' i4 S; g. A" b1 V
        {( ], K1 u. F- y  v' W  Z
            if(q->nextarc1==p ||q->nextarc2==p)( t* {. I/ u5 q) X/ d/ j# q
                break;
    % P# O1 O$ x6 B; o1 O; D        q=NextArc(v1,q);
    ( O; h6 c: @7 I5 `) z  ^8 i% D    }) m, Z+ V' X; d. S' c& n7 ]
        return q;
    6 p. |1 I, f0 h+ {7 r}
    % T& F8 z3 V0 x0 J  a! btemplate<class ElemType, class WeightType>" a: t6 J; @. `+ Q" ^2 V! C
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)6 g0 [0 f1 B4 o7 \' E! f) G
    {: {( h  q' C4 X$ ^
        if (vexNum == vexMaxNum)
    0 Y- ~) c9 M% {5 x        throw Error("图的顶点数不能超过允许的最大数!");% h/ p8 R/ t$ X/ C* H4 q$ R: T
        vexTable[vexNum].data = d;
    $ w0 ?2 y1 E4 x/ X8 j    vexTable[vexNum].firstarc = NULL;1 Y4 t1 p& x, t4 Z9 Q, u  {1 n; F4 k
        tag[vexNum] = 0;
    2 J5 T3 v  j+ R. O    vexNum++;
    + t* I  F9 ?8 p4 V- c! _: d5 H}
      A- N  ^8 t4 a2 T1 N1 Itemplate<class ElemType, class WeightType>
    . G3 `$ t9 Q! k5 p% G4 H$ Zvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
      V/ K' X0 H/ ^- v$ k% o{* G" I. q) @* [
        MultiAdjListNetworkArc<WeightType>* p,*q;
    & t# t- ^) X: ?( X+ F& t8 c1 p7 S    if (v1 < 0 || v1 >= vexNum)1 P6 B6 z) N3 ~3 f9 f
            throw Error("v1不合法!");4 J2 K1 X6 S$ S; U) W
        if (v2 < 0 || v2 >= vexNum)$ f1 T, ^6 `) B/ V
            throw Error("v2不合法!");: W  I+ X( a6 C! D1 B
        if (v1 == v2)
    & _, I5 \) y4 S- x; L- C        throw Error("v1不能等于v2!");% s6 C5 f$ H3 U" a
        if (w == infinity)
    + j% b6 G! x$ A5 n        throw Error("w不能为无穷大!");- t  u2 K( `) i: X* G) K% s

    & C. s$ H) l& e3 [- ]+ Y4 t5 k6 G5 Y) T8 R; s7 Z! E' f
        p = vexTable[v1].firstarc;( K- v" O9 S# V" J4 C( M. X
        while(p)
    0 c( m: ]5 A1 W# p7 L    {0 ~1 W7 [2 ]: t+ L4 U
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    4 y/ r+ }% l; w$ t, G        {
    & {# Q  I8 H$ B- S            if(p->weight!=w)4 Y7 x0 d# o  e2 @5 L, M
                    p->weight=w;. G7 Y' t% {5 X  v
                return;) ^: r6 C1 T# q' Q& }. m
            }! U. X  {: o+ }

    * @+ k9 e( K! ]: O* {        p=NextArc(v1,p);
    4 j% R0 i/ h/ `! s$ j. A& p$ W( }5 V" Q7 t    }
    ( I( P# h  v# q    p = vexTable[v1].firstarc;( T3 v) Q# @2 t# H2 F6 f" `
        q = vexTable[v2].firstarc;
    % G+ U( V5 e& v$ E    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    + v; d& ]  Q7 u    vexTable[v2].firstarc =vexTable[v1].firstarc;
    2 S( o1 N7 @8 p2 s' l    arcNum++;
    & [! J( }2 E# @8 r& ^}. O8 @/ a7 J7 T0 X9 y6 U! f' `0 a

    - E7 p8 h& K4 q* ?+ x5 L, W; }# Stemplate<class ElemType, class WeightType>5 G& A! {- G8 k6 x! `; r9 s
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    5 e4 w% `: ^/ D/ q+ ?9 m5 ^{
    1 }* v4 Q; D8 o1 l0 s' M9 l& B7 [& K7 r3 I  q, |% h
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;7 g% Y+ I  G5 I
        if (v1 < 0 || v1 >= vexNum)
    " |/ o! q2 `" y3 J. F        throw Error("v1不合法!");, N9 B+ S6 k; Y/ T& ?- \
        if (v2 < 0 || v2 >= vexNum)
    , y+ P' s* [0 O  O: g        throw Error("v2不合法!");
    + C$ P8 }, ~  O9 D    if (v1 == v2)' D7 u& i: S1 X8 k; P* Y$ L0 `1 \
            throw Error("v1不能等于v2!");
    ; F0 a! D) a' Z% G, Q
      w1 {) R% M" w; ]0 ~& ^" Q    p = vexTable[v1].firstarc;
    : ?9 M( T1 o. e, W1 S# N$ v    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)8 V6 k- O0 ^' |7 z* B7 x( {
        {
    # n0 p3 ^6 M/ D: J. O4 b        q = p;) C  K; x1 e# b  C5 r: Y
            p = NextArc(v1,p);2 q1 \, x6 p7 H" M! \6 y
        }//找到要删除的边结点p及其前一结点q" F3 v0 a7 D4 d- s" d$ T

    " o' [% Y2 |0 `4 U7 Z- L$ |; H    if (p != NULL)//找到v1-v2的边
    1 ^5 v% K% \4 E" l    {
    ( U1 N4 d1 q6 C* v        r=LastArc(v2,p);, P4 w  q0 c# w7 K6 _% y% r
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL" n) ?/ z/ m  |" ~3 R, w
                if(p->adjVex2==v2); Q) _( E& d8 j' [6 \! b* r$ ^0 i
                    vexTable[v1].firstarc = p->nextarc1;
    3 |  H8 `& n6 T  A' l; d5 i            else vexTable[v1].firstarc=p->nextarc2;
    ) F$ \( T& i* |' l( l        else//不是第一条边
    + c/ W8 O5 @: J! {9 C        {+ Q2 M6 z$ d4 d7 w- y& l8 e( D& m2 n
                if(q->adjVex1==v1)
    : S2 E& g. j! l1 {1 ~                q->nextarc1 = NextArc(v1,p);
    % n- p& w& p( J" W; |1 e, y7 a            else
    / W9 l; R  g1 C+ e0 ^( c  y9 W                q->nextarc2=NextArc(v1,p);
    ; W. \) M6 {) C+ ]$ g' L
    ( U' E) w5 [, ?, D  r        }
    " X6 b+ s, h8 U5 Z: s8 e7 q        if(r==NULL)5 j* F; }3 N) k1 T. j. O0 Z. ]
                if(p->adjVex2==v2)9 `( S( F$ m( r1 Q( p
                    vexTable[v2].firstarc = p->nextarc2;0 x4 u. p3 o/ g6 Q! m! I$ [" c5 B5 V
                else vexTable[v2].firstarc=p->nextarc1;: ], F) v6 U  G* [9 M* |
            else/ }- m5 r! t5 w# L( U: j  q% s
            {- n: h. d& G1 ^6 G
                if(r->adjVex2==v2)/ d- R8 |7 Z! N4 c) c3 r; G  V
                    r->nextarc2 = NextArc(v2,p);
    8 U+ X7 E( `& H            else/ q1 ~4 O! y/ d- P; y1 N& k
                    r->nextarc1=NextArc(v2,p);2 ~) I6 O$ B- E" Y, q
            }
    # L1 w& J) [/ v        delete p;! h) h9 t, |$ y3 j
            arcNum--;: P& M: ^* y& m, x* L  I2 i
        }
    7 {' t. @% \' Y% ^; n  f, L; A6 w! u0 w) P" Q
    }0 @1 i; t* l+ @9 O* \
    template<class ElemType, class WeightType> void
    + D. k4 }' {! B- T; o1 r% FMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)  _" p- t8 A6 e! c4 X( l4 d
    {3 }: L' y: V( l8 u5 L# x
        int v;
    6 b! ~* u* @. e) }& E) p  `% Q    MultiAdjListNetworkArc<WeightType>* p;
    ' }& W& f: l. I7 a7 B    for (v = 0; v < vexNum; v++)//找到d对应顶点2 G2 D7 Z8 R: _5 Z" p# @' c
            if (vexTable[v].data == d)
    8 r% v+ ]- _; |& M. e9 `) n            break;( u* e  N' Z  }$ Y7 X
        if(v==vexNum)
    : W$ d7 A8 T4 S        throw Error("图中不存在要删除的顶点!");
      _' H; T6 r, s; J/ p: A* F
    1 N1 j0 \' |. c; N0 {3 f    for (int u = 0; u < vexNum; u++)//删除与d相连的边
      ^- O. K2 X; m9 ^) w( M9 d1 Z" ?0 U        if (u != v)
    6 p* s2 H2 {+ g# E) @+ ]2 P        {
    + b+ Y1 ]% R$ M& Z( Q$ F; P& h            DeleteArc(u, v);7 U) ?0 j/ Y* j1 _0 J) W0 z7 q) C
            }9 G) X  M2 x# @6 a, v
        vexTable[v].firstarc=NULL;. f- h0 N( `- ]8 w7 y% I1 K5 A

    5 Y7 C( ]( |$ e* J( \5 D, g$ s    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置, l  n$ X5 d1 i1 R- s& @3 M
        vexTable[v].data = vexTable[vexNum].data;
    % o$ {1 j  A& ~7 \    vexTable[v].firstarc = vexTable[vexNum].firstarc;
    2 [  h/ }/ N  s8 z    vexTable[vexNum].firstarc = NULL;
    4 E+ e* A3 g' _& ~$ t    tag[v] = tag[vexNum];
    ; c2 o6 L  g! j0 k    //原来与最后一个顶点相连的边改为与v相连
    ( ]) C1 t3 z( S2 T    for (int u = 0; u < vexNum; u++)
      v' S) _4 ?- k$ I0 j& J' D" S    {
    + _) f3 |, c. \2 i/ m# C; n        if (u != v)
    + |, v; a% G+ c        {3 b6 c7 x$ y. u( ], R- K
                p = vexTable.firstarc;* V' z' }; m7 X, l* [6 l1 W* X
                while (p)
    , |" d5 @, w4 B* j" n$ W9 f) i# G            {' W; g' j3 K3 C. R, G# p$ v+ f
                    if (p->adjVex1==vexNum), Q2 @! j3 A" E, c+ T
                        p->adjVex1= v;
    8 y4 R8 C& i* G( B* ~" D% ?% c) U                else if(p->adjVex2==vexNum)0 x+ S; j/ K* r' w
                        p->adjVex2=v;
    8 S9 A8 y  O/ n+ S1 ]) g. e% f' n                p = NextArc(u,p);+ w0 y- b4 \( _# Q' h6 q1 z
                }, C0 f3 ?1 v5 u5 c9 K# j! e
            }
    ; e7 H) t$ }4 j: N, {1 n    }
    ' }# K2 E! y2 m+ f- A, e}- N" I, K9 T  ]. e' _( V
    ///深度优先遍历
    + l2 @: O8 B+ w% u: Qtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    4 Q! _! U  n/ ~{# ?9 ~8 l5 P+ |$ `: g
        tag[v]=1;. `0 j( ]/ o% K; {
        cout<<setw(3)<<vexTable[v].data;
    5 G/ Z0 y/ N4 `5 c* v    MultiAdjListNetworkArc<WeightType> *p;
    9 W3 W# W: {; K" F% t, m0 V    p=vexTable[v].firstarc;9 h! p  `/ O. ]) f. T2 w
        while(p); @2 S; \, U* p# z9 M" c' j
        {3 T4 j- m" ~$ J* j! ?0 L
            if(tag[p->adjVex1]==0)
      }  u; U; c$ s' \7 j" H4 G6 q9 V            DFS1(p->adjVex1);% R5 R$ O* J% h
            else if(tag[p->adjVex2]==0)
    / B# ~- p7 I6 [            DFS1(p->adjVex2);+ M7 _, w1 ^) @
            p=NextArc(v,p);7 G- W  l/ t2 H4 K$ h: R( j5 ]
        }
    " E5 }" }  v2 C8 u/ @5 G. x. f}5 w7 ^" R9 [; V  P( l4 N
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()" n" A( F9 H' |. A6 ~
    {
    3 I& Z7 s) R' n; g- s    for(int i=0; i<vexNum; i++)
    % A2 M$ _! C5 i( j2 v7 ?        tag=0;
    0 G+ b* t/ R  Y( A" }& B2 K    for(int v=0; v<vexNum; v++)8 M7 m/ K5 t' N$ m
        {! G$ F( V) r9 n8 y
            if(tag[v]==0): z- H' ~; Z9 g: e. L6 M
                DFS1(v);
    / e3 a+ N' d; ^6 `6 j4 N    }
    8 x7 q; y8 e3 ^& C  O5 V9 ?}
    7 i" S# t* S) c% Y8 }! Btemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    ; W9 V# Q1 h; _{3 H" x3 P' D' Y; i5 m2 g: w
        stack<int> s;
    . {/ W8 m: x/ I    int tmp;
    , x% E8 G* S, u9 x2 x    MultiAdjListNetworkArc<WeightType> *p,*q;& X- n/ J+ D4 H; g2 i8 Q- g. C" h9 ?4 G
        for(int i=0; i<vexNum; i++)
    5 \0 y6 m! S4 C        tag=0;5 _# L2 `( J, }3 `9 f& w" g
        for(int i=0; i<vexNum; i++)
    ) I: x% h" U5 q% q0 X" N2 ]# j    {' A# Y/ k% K/ v
            tmp=i;
    5 d6 k" A9 {& E0 n& _4 ~5 }        while(tag[tmp]==0||!s.empty())
    6 g% _; h7 g9 |( N: [& m- d        {
    * G* d8 M8 T7 m            p=vexTable[tmp].firstarc;; a) T9 Q0 b8 }( U9 o
                while(tag[tmp]==0)
    - ?& |1 m  m8 `+ z8 S( d5 d5 y            {5 t% G* d, ]9 K0 g
                    s.push(tmp);$ w, h& s) q1 ^9 O3 a
                    cout<<setw(3)<<vexTable[tmp].data;
    : ?; q% U3 C1 z+ `                tag[tmp]=1;& {+ C! k/ _% C, {5 L
                    p=vexTable[tmp].firstarc;
    ) n0 w( B& J9 Q  A  R                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for8 L3 ]4 t- g- m- f5 c
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    9 G0 W* b7 V5 V( r# T7 v) v                //cout<<" 1st     tmp="<<tmp<<endl;
    : S8 v' Q1 N5 y. i            }
    ( w  [* d2 {8 A  c            if(!s.empty())
    + T: B2 a/ }* p- o            {
    , M1 A' k4 t/ F3 R! H4 v$ R                tmp=s.top();$ q  X) C4 n7 Q! p# \9 P$ T' n
                    s.pop();' M! G. ]  m$ l+ G
                    q=vexTable[tmp].firstarc;
    , @) C0 C; y- q- R                int t=tmp;
    : s  \* z+ P5 J2 j: q6 D6 `  j                while(q&&tag[tmp]!=0)
    9 [' f2 A" ^9 v% b                {
    3 V. Q4 O7 y: x6 D                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    4 E9 y# O1 ?) M! F. ?                    //cout<<" 2nd     tmp="<<tmp<<endl;
    * `: _2 X- B9 M# i3 [                    q=NextArc(t,q);: [7 F* Q8 I, c) h5 q
                    }
    # q+ g* d/ ~& `# ~( y                if(tag[tmp]==0)
    ; s: d1 }0 L' ^; _; I: f% h  a                    s.push(t);
    : W; u6 H3 i, w                ///1、对应上面连通分支只有1个点的情况
    ; ^5 E* H( x9 d# [& Q5 W# h# ]: j0 ?                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈1 J9 Z* H; W8 ~9 i* n" X- ^& n
                    ///tmp要么等于找到的第一个未访问节点,
    . S  ^( c% f0 e% H                ///要么等于与t相连最后一个点(已被访问过)
    - e- j  S7 B! R, o, f, o                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点1 T$ |) G0 {6 O! k; o# ^( `
                }% {5 L/ T4 @+ R
            }
    - C$ j  i! V3 i$ V, Y* c# T- @    }, K- U/ r: x1 |' Z
    }
    8 o. A% I# C6 {; I* t2 [. v, }, Z//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    + k1 [9 }8 ~) m8 R( Otemplate<class ElemType, class WeightType> int+ o% A' ^" M. f% C3 l8 S
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    / m+ u$ I/ Y- X, }{, o" X. ~* \2 o' X- ]( g5 x
        if(head==pre); J2 r, Z4 l+ \# e* @
            return -1;
    8 c- S5 B' J; b7 m# H9 O7 X  u& m
    " [' X, [4 W7 c2 \# V- u! ?    MultiAdjListNetworkArc<WeightType> *p;
    # e+ N# x" j! ~" r! c$ t    p=vexTable[head].firstarc;
    2 a8 a1 Y4 y4 d9 o& {. L    if(pre==-1&&p!=NULL)
    : m; ^6 \7 _0 I: F1 I) Z        return p->adjVex1==head?p->adjVex2:p->adjVex1;  {; I8 G1 N# M4 L) p; ?1 ^' a
        //pre!=-1&&p!=NULL
    & ]. t) d0 t# d; D) O8 ^7 R) `. n    while(p!=NULL)8 v# r, K4 s- a$ Y% f. ]% F
        {
    " T  ]/ J# e: d        if(p->adjVex1==head && p->adjVex2!=pre)9 i% x) n4 F+ i  x4 A
                p=p->nextarc1;
    9 N  H( N% ?6 S) P. A, J3 y        else if(p->adjVex2==head && p->adjVex1!=pre)7 l8 R9 O6 [. b0 h* ]8 s4 ~. `
                p=p->nextarc2;
    8 P# x8 o8 g; d; t$ \6 R        else if(p->adjVex1==head && p->adjVex2==pre)! Q% O; }3 L0 P4 F
            {
    2 \1 \7 f: [  V4 Z- R            p=p->nextarc1;
    3 P* D! u8 }9 b; `  M& ^            break;9 J+ Y2 B, l# t1 X# Q4 ^# g
            }
    : R4 I9 r9 u! b: l5 I8 }        else if(p->adjVex2==head && p->adjVex1==pre)2 e2 w8 E* d! r6 H+ l
            {+ c# o5 Z. [/ ~
                p=p->nextarc2;4 N% I/ D% E. E' c% G! P
                break;- z6 x9 O3 B. `
            }
    + Y- ?1 k8 N) a- B4 U, _/ ]    }
    ( o1 m. e5 j' z, d& F0 W- A    if(p!=NULL)% e  ]1 [. L; L/ D- b5 l7 k
        {( C+ C. y% X1 S' v7 E
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    2 ]2 _7 H0 U. I# I3 d. T$ C9 V+ ~6 m: @    }
    8 B2 r- @. g7 W    else7 c+ q9 m2 G+ C0 [; z2 O
            return -1;( w/ X1 `  }0 M& b% H
    }6 l. C  A2 S/ I% n0 M/ V
    " G  _" ^9 r( T* b) X9 ^7 B
    9 |' a% H: L7 q5 H, b
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    + q7 M' _  j" o: q{
    ) m3 s* c! ~; P  T, i    stack<int> s;& t5 ?* L' G( a6 s+ b) _( y2 M- C
        int p,cur,pre;
    ' O& e+ E$ ?' ~/ B- {    //MultiAdjListNetworkArc<WeightType> *p,*q;
    7 J1 _# O8 o4 V. M) [3 [8 T    for(int i=0; i<vexNum; i++) tag=0;//初始化7 |' ~9 a$ k1 w0 Y" \2 t" n4 A" ^

    2 ]0 A, ?! h' H" h    for(int i=0; i<vexNum; i++)' B! J6 M2 O% ^# J8 O
        {
    1 h. l. L8 W+ M" R9 z# x: _        cur=i;pre=-1;- |9 b$ }& p0 n# b1 k% r8 c9 \8 L
            while(tag[cur]==0||!s.empty()); s& r/ b0 f, M$ @: P, r9 W- t
            {
    ! N4 Q8 n' g/ J; Z& f# \            while(tag[cur]==0)' ^. M# X* T% A. O
                {
    - x  u. [5 Q+ C' H( I& c! W' b                cout<<vexTable[cur].data<<"  ";' h" r% i9 j/ a7 T+ i& K
                    s.push(cur);
    ; Z' u7 K( M  \* h                tag[cur]=1;+ A" ~! k! y7 X4 c  _
                   //初次访问,标记入栈
    ; F8 _& ^/ C5 A; ]- P8 k: U+ E0 [$ f. b( G' @
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点2 Z8 f! V, j5 {# ^8 d
                   if(p==-1)
    3 t+ d, b3 z8 h+ c0 C+ a/ p               {, g1 v; }" a* i+ ]/ k- d( A0 `0 e
                       pre=cur;s.pop();
    . q3 J; H( t* e1 x                   break;& U% @  U: I0 p
                   }
    5 _4 V/ H/ f9 d7 \               else
    # `& C' K: U! X& O" A* U$ L: \* E3 M               {; g6 h# w& Q3 N* B% x
                       pre=cur;
    5 g. ]; W& r0 c                   cur=p;
    / X' [  Z+ ]$ S4 n. l& h) q3 w               }9 B" d/ u% {' A  Q& [

    4 I1 X# W# x. l9 R9 |8 I            }6 G1 l( V0 T; Y$ }1 A
                while(!s.empty())
    % U7 |( g: N, y( X- ~7 k; v4 B            {
    - r8 K9 G3 K. f# k0 q! @                cur=s.top();: w1 Z6 Y" G' @2 ?
                    p=GetAdjVex(cur,pre);/ E" G$ \3 x+ m- F* y! a
                    if(tag[p]==0)
    ) }; R/ k2 m: {, p5 S# @5 }+ Q                {- O1 H( ~! L% O/ U
                        pre=cur;
    1 A* S. L8 _: e% b1 o! G                    cur=p;
    - a7 z$ Y! M6 j                    break;
    , D( w+ b8 c' [0 P8 i7 l* r                }3 u; @4 v! ]3 a5 E
                    else% [7 P8 `, [7 p
                    {
    ; x2 t) ?! t2 N- G0 \2 a) m. o                    pre=s.top();
    2 J0 D$ f' M7 e$ V                    s.pop();
    : a0 @9 K7 V" j) |1 X, C                }
    3 c# V+ X- y% @* k: f. y' S2 D( u+ H$ E
                }
    7 Q+ v0 F0 E2 h1 m$ U% Q
    * G. b& m/ Z! y5 J- c7 G        }
    " m0 X% s! U7 _/ e7 j; m    }
    2 n3 }5 U2 B, P3 x4 u}; `- q. A! K$ }/ |( S
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    . E; D. H6 h. n# [% [{
    ) j, S- ~4 K' u# b    for(int i=0; i<vexNum; i++)1 V0 i' K: E5 c7 Q
            tag=0;
    1 r3 _. H! n% R    queue<int> q;9 u- O0 N- v/ [; i& p( Z
        int tmp,t;
    - }+ x2 Q2 i$ X# Q, r    MultiAdjListNetworkArc<WeightType> *p;8 V( P- `8 |0 |1 C. ~
        for(int i=0; i<vexNum; i++)0 A! ?, O: M. I
        {
    $ L- O' G) b1 R( l1 Q& @        if(tag==0)3 ]' y/ f- `8 O. G- t
            {
    0 |! R6 a( k  [! q7 @+ `! g, x# O  I7 ~0 c            tag=1;4 F1 d0 U8 U" {" L
                q.push(i);
    3 r& u3 k9 }! \            cout<<setw(3)<<vexTable.data;
    ' s4 \( s5 L" C% C! x" B        }/ x. L. S0 o5 L' s7 G* s0 J
            while(!q.empty())
    ( O$ h! z. `7 _        {
    - @; n% C9 s) W5 ^$ _            tmp=q.front();
    3 k0 e! R7 Z; h: M            q.pop();$ ]5 l2 h, I+ c
                p=vexTable[tmp].firstarc;
    , _! V0 d2 R9 T: T! U            while(p!=NULL)
    % N" o1 n" ~: M8 n$ g            {
    # j7 i) b( b9 v9 f                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    ! e/ N6 q% c/ Y/ F# a                if(tag[t]==0)
    2 [' L0 T$ U; J8 J9 w0 ]                {
    4 @1 l/ }* [$ o% H5 V- h                    cout<<setw(3)<<vexTable[t].data;
    ( ^- M& q  x$ z0 @; C" l$ V' a                    tag[t]=1;
    , X( E" e1 p. g7 w" G" @( h                    q.push(t);1 o; W+ P2 o2 ]2 ?" U
                    }3 J+ B5 n& M+ d3 G9 R6 \: z2 s) Z
                    p=NextArc(tmp,p);
    * l; [$ q3 M& x1 a( C1 S7 B            }% o4 p% |! U; _7 @3 B9 ]
            }6 r; }# i7 j1 c
        }
    5 q8 u+ p" W9 n( C/ {}, Y' Q5 e8 ^; D6 F& m: q/ x
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()0 ?8 G! _$ Q" Y
    {0 \) L" |# O- h6 m- U2 R; N! y! p) ~
        MultiAdjListNetworkArc<WeightType> *p;: ]$ E/ w8 Q! ]6 \
        cout << "无向图有" << vexNum << "个点,分别为:";+ K+ l% C+ Y4 g- T( z  k
        for (int i = 0; i < vexNum; i++)2 W( a9 p7 h; J& S
            cout << vexTable.data << " ";% |" S' q) P+ ~" v  a5 H
        cout << endl;# G, h& s1 T+ y% g
        cout << "无向图有" << arcNum << "条边"<<endl;
    , u% ^- X/ N& ^. k    for (int i = 0; i < vexNum; i++)
    4 @$ {3 N# Q0 x) r5 j    {/ {4 L$ b" ^+ J  p
            cout<<"和" << vexTable.data << "有关的边:";# W' z, v( p& b. f7 Z2 C; C
            p = vexTable.firstarc;
    / }, Y8 t. s9 c" u, \        while (p != NULL)) H& F: b( h; I3 U: h  L% U1 t
            {
    1 _) |* V6 ?2 ^2 Y6 K! _            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    3 B. }1 j. L( ~1 g$ ?            p=NextArc(i,p);
    ; w2 @5 L, c5 ^% T$ S& z+ w        }- s* Z6 u! @6 J1 Z) Z
            cout << endl;0 Q  N" G1 D9 |
        }
    / D3 v9 p4 ]7 K8 G: v}
    : J. p: O/ l5 v7 F8 Q2 F( F
    : w2 g# j7 }% M7 w' O) k( s# A3 ?6 R5 ?! a
    邻接多重表与邻接表的对比5 \& T& f' J' U( P0 G4 m' q
    1 `; r) p  l' @. ]8 U
    邻接表链接
    8 f8 d) {! _$ Z在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。' f9 u& n- `4 j% O) i
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。1 g* c9 b; z' L  A) ?& V
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。( {& w4 u/ F0 {" r
    ————————————————& L; U$ I- m5 @
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。* W) G! m$ c4 U. {
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    * a4 n7 c8 L& Y! B  W" R
    * F  ?8 {( P; W) ~2 i) G! r* @( C, {( |" |( k- d
    5 K& X- R( n4 N% ?5 k) c7 C
    # i! _' C0 X+ L# [3 _; j- o
    ————————————————
      v) ?1 i7 W# n2 ?& a" f版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
      h$ h- U2 ]3 E2 v5 H2 s原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    , y, J; W0 b2 |0 c& x& y+ U# o$ ~
    + H5 V" ]8 X+ p! L2 `4 M# E+ [8 o2 F/ f. Q9 @1 A4 k
    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-9-18 04:05 , Processed in 0.530391 second(s), 53 queries .

    回顶部