QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1618|回复: 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
    * \; k: w; t0 j  B( D
    图的存储结构——邻接多重表(多重邻接表)的实现
    . L: E/ f, b, M8 t5 b5 F7.2 图的存储结构
    ; s4 ]/ T$ C( w$ S1 I: {2 |# r) i- {$ o8 W' x
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    3 w  q. X$ |5 N/ D8 E" o邻接多重表的类定义# G# F( C$ F2 O0 ~7 ^6 E3 [  ?1 r
    邻接多重表的顶点结点类模板2 @2 V) W. g+ [$ ]- @, I( U4 P& E
    邻接多重表的边结点类模板5 ~2 _8 w" U" @
    邻接多重表的类模板
    % T( x# U- r  X* A3 M7 ^8 M+ X7 Z' x邻接多重表与邻接表的对比1 T/ ]6 W5 U! B- E; J2 d2 Y" W2 \
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist8 f0 g# U9 Q4 a& H

    1 `: ~, v) h3 u' c; i在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。  ?5 i! g: S! J! r' L9 g
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。4 n2 B% K4 V' @/ x/ ^. _
      z+ v( y3 H& \# ~
    邻接多重表的类定义- X: o& f+ i4 F9 S! w3 @
    1.png
    ( ~) c3 F3 r& H* S邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:) b* `% q* H& l7 S
    data域存储有关顶点的信息;
    5 e! p* ^: Z. k- Y" y/ ?firstarc域是链接指针,指向第一条依附于该顶点的边。' t4 ]0 r$ z0 y1 {& p) G! Y+ d
    所有的顶点结点组成一个顺序表。

    & ~6 O6 g6 x' K( ?  ]3 I) H
    # [$ w) ]/ P* @$ w9 c, X
    template <class ElemType ,class WeightType>3 t/ \, s' B8 S3 A
    class MultiAdjListNetworkVex9 R$ }" \" c2 T) W1 d! Y8 i8 \# w
    {
    + K1 u) E+ a8 K* v# A1 d' r- |public:
    9 ]. Y4 l7 f; y7 \  ?1 {4 T        ElemType data;
    5 g5 r5 p7 z( d# d  t& p) \2 n* j# U        MultiAdjListNetworkArc<WeightType> *firstarc;
    / m6 R, C5 g7 V" S
    4 o( I5 ]6 ^5 I$ c# R2 _$ K  L: V0 C        MultiAdjListNetworkVex()+ m* J! z' W& U( E9 I& U; P4 d( ?
            {4 C4 y, |& T: [" I$ Z
                    firstarc = NULL;
    : s, Z" q6 R0 ^' B$ Y& U        }7 {5 V4 d' O+ _$ ~
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)9 ^9 e/ o% C. I5 I- @" r
            {
    0 @' v+ V7 B9 f0 W  X5 t" s                data = val;
    # [% ?8 l) c( C                firstarc = adj;( G* c. z! A0 {7 A
            }- X/ p' \4 K( J# E9 t# Y' v  |
    };/ L( \2 _2 k( f# ?! }
    6 [: \6 N- j2 p
    邻接多重表的边结点类模板
    5 y$ \# m% B1 u' ]; B
    0 `1 z) O1 k5 E8 [. N) K; r在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:+ {3 X: [" W) T8 y( K$ C, K3 E
    tag是标记域,标记该边是否被处理或被搜索过;7 n2 j* @$ R* h5 q1 z
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    ! A" j) `" c0 \; }/ _  {! ~$ ~5 _nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    : B, X8 F2 D4 ?1 N6 Nnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    6 g2 a; ?" N8 l# p$ ]" m' }1 F* H0 N. ]. s$ J
    2.png
    / ~) U) T: y# J$ z) u; I" _template <class WeightType>
    2 e# G8 Q3 ]5 ?5 a, c: Oclass MultiAdjListNetworkArc* n5 v! E0 X2 ?9 ]' T" @2 D
    {
    ( R+ O! x. Y1 N5 v- j# s0 M$ a7 [public:, {1 |  M9 T- [/ k( E& _' b3 H' ~
        int mark;                                       //标记该边是否被搜索或处理过6 Q6 l3 G* u: ?" }* ?
            WeightType weight;                              //边的权重
    # ~  b+ d; ?& E' k  W        int adjVex1;                                    //边的一个顶点8 \0 [$ A, t8 l. j0 ?/ ]
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    / C" }; Q% r  P        int adjVex2;/ o5 f7 f) w. e! |$ D6 j$ n1 g8 ~
            MultiAdjListNetworkArc<WeightType>* nextarc2;, Y; ^2 H: y+ e; A! P
    * V4 u" U' i1 j; T
            MultiAdjListNetworkArc()
    : R2 R4 L3 R5 S5 s4 [, A. S- \        {
    " ]  \  q9 Y1 o1 E7 s                adjVex1= -1;
    - J2 j+ L) O4 i: y2 c: x5 \                adjVex2= -1;7 F  h$ n: _8 _/ H/ S  U
            }
    7 J% G( P: _  k+ t4 g        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)( G. n' A1 F% q( O+ e. x: c
            {' W. T& F: m( y1 h
                    adjVex1 = v1;       adjVex2 = v2;
    , t8 V# u3 m/ ?! T: H) {                weight = w;
    ! _( t* ^+ ?, n' F6 b2 L+ l                nextarc1 = next1;   nextarc2=next2;
    9 N8 r% g$ J" A1 H' A9 d                mark = 0;           //0表示未被搜索,1表示被搜索过
    5 p# D7 Y2 m/ @5 m6 q# C! K        }
    $ b9 }: B3 ]! B8 v9 C8 u2 D3 b& A3 ~, \* c  f8 O4 d
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>* y) Y$ g) c4 i4 _' Q$ _' j4 X
    class MultiAdjListNetwork
    7 d% n8 X$ z: c5 `' u{" E1 Z9 E) {- X. u: c+ a
    protected:
    ! H5 s( T$ k7 N3 |; Q    int vexNum, vexMaxNum, arcNum;; u7 H: W. O3 L: U- z
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;  o$ X! k' c. T! e% E- q5 O$ \* p
        int* tag;
    0 I( k2 @4 v9 y  U6 e/ \    WeightType infinity;3 a* f9 y8 w3 X, x8 N
    " W3 l) f0 J- n7 }* Y  x; _7 _
    public:! t6 G1 F$ z# S9 R# u
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);8 G) T, b/ q. A8 b% D$ O

    : I, y! K+ X- L% H& \) m0 h    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);2 r4 @+ T. f2 }" p, b9 v6 n
    . \( ^) ^$ o0 R8 W# T8 k
        void Clear();
    + V  D! S+ i' T    bool IsEmpty()
    % S; w% ?0 I* E, o4 G    {
    ) P  \# u6 q3 A& j5 A* g        return vexNum == 0;
    / t% Z& o+ t" }8 Z1 n+ t    }
    1 w# Z% d9 R; p$ A6 K    int GetArcNum()const7 H8 I' K3 K  Q, g
        {
    / |2 g% z- Y4 `        return arcNum;
      ]6 V' f# X8 q* Y    }$ R# B( e) U0 ]
        int GetvexNum()const
    - s1 ?; b* o  Z9 U- e  t/ S    {
    ' a, J5 j/ y1 B        return vexNum;* n2 u8 l2 a) }; o
        }- T5 q  n/ y8 f! A  W5 g
    # t1 F$ j" v% l" o3 H& p+ r

    3 i/ S! D) c" v" Q$ L    int FirstAdjVex(int v)const;: m% j: z3 U) r5 }. K( `+ q) c6 W
        int NextAdjVex(int v1, int v2)const;
    ! U' m3 |2 }7 o    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    , R8 @, ?- D3 q) k    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    & P% A3 H5 U3 e# a* M
    / W3 o8 o5 U) G1 |7 ^    void InsertVex(const ElemType& d);; H" B8 y; H/ L0 L1 r
        void InsertArc(int v1, int v2, WeightType w);& ~0 [+ q/ |1 A% o
    7 Q% x8 q' ]7 I
        void DeleteVex(const ElemType& d);
    4 f. h: h. a0 n( e    void DeleteArc(int v1, int v2);
    # B2 L) U; D: {4 Y$ G' k
    2 l$ Z% @& D$ I7 s( P9 [7 H    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);; i& b$ R( S4 k$ F/ D8 h$ }
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);: ^+ Q# p, D) `
    * r+ {) l8 e1 c- g
        ///深度优先遍历( h! z7 @4 ~3 b* Q( }: f
        void DFS1(const int v);
    2 |2 `( v2 g. S; _    void DFS1Traverse();
    0 O5 e. m5 q; r* M+ _1 n    void DFS2();
    2 ?' W0 A3 O2 }9 j* I, D7 i5 C* p$ P6 _; l- E# E% l1 a. l
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    , }* p. T0 ^/ y9 ~2 g$ u    void DFS3();0 S8 ^8 f4 z! x5 M1 s" w: q

    , J3 Q: L; F  b% [# R    void BFS();
    ' e) U, f. Q) K# d8 d7 u$ r    void Show();
    ; _0 r1 |/ Q' d/ |: K};) r5 I. }1 e0 n. e2 t2 S
    ( ]" e  E6 r$ @
    2.函数的实现
    2 X( @: w$ P4 @5 t/ D9 m研讨题,能够运行,但是代码不一定是最优的。
    7 @3 |. g  t$ a# h* L" x: J6 [- p$ i4 R& d  o  ]/ b
    #include <stack>
    % a1 c( u1 i9 R/ P# C: p#include <queue>9 L# f4 V, _: Q5 `3 q9 ^" D
      S6 _. w1 L+ _0 y, P; a8 \
    template <class ElemType,class WeightType>
    & P' M0 k0 P+ j/ _' v0 ?MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    7 g1 |" K9 S+ r0 y, y! f{  T. T9 f+ x* m0 A  [; q
        if(vertexMaxNum < 0)
    / \: _& c9 J. z5 s$ j! W        throw Error("允许的顶点最大数目不能为负!");( S- C+ q% b5 W* n' O
        if (vertexMaxNum < vertexNum)2 O% }' G( W& r( q# L  w* y
            throw Error("顶点数目不能大于允许的顶点最大数目!");
    : A3 W8 ~% m/ q& R7 v    vexNum = vertexNum;
    : _8 c' X5 f9 O( W1 Z) W. I7 F    vexMaxNum = vertexMaxNum;
    ( J& ~7 p4 Q+ n  \% I& _$ O    arcNum = 0;
    4 f! {3 A' j, I' _    infinity = infinit;
    ( x1 Q# ]% v% [1 q    tag = new int[vexMaxNum];
    & O- G+ |5 }* Q  R/ H3 M( F' t3 n3 Y. y    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    / ~- h5 [' Y& O* W1 \% Q! g0 @    for (int v = 0; v < vexNum; v++)
    $ o: H) [: m& s# X; O$ e+ ]! C    {
    ( K9 p# o" m3 R$ Q. ^        tag[v] = 0;9 E+ \$ `# v- Z9 v" r3 R$ y1 u
            vexTable[v].data = es[v];# b* e1 j! S/ w) s' F2 X# J+ N; Z/ a# Y
            vexTable[v].firstarc = NULL;& J. N, j( s8 C* Z& P3 t7 i
        }5 s1 q7 d2 I0 k3 V9 V8 d7 @) M
    }  G; c# {" V4 A! n0 h
    template <class ElemType,class WeightType>4 w, k$ y( a3 y$ f0 k" K! F* Q
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)  B; r* x. Y  Q, X& D& C+ F- c" `
    {3 {+ H. p; I! y0 f
        if (vertexMaxNum < 0)6 W; g5 i. c8 C) e2 ?
            throw Error("允许的顶点最大数目不能为负!");- @2 _& G# m  o+ O3 R- h: H
        vexNum = 0;
    ! Y: }, E$ v$ t8 C: M, n" W8 G1 \    vexMaxNum = vertexMaxNum;
    . v6 j$ o7 O& h# o' l0 k$ K0 l    arcNum = 0;  o2 L. f7 x" Q3 r4 }8 M
        infinity = infinit;
    / q1 A3 x4 ~$ B# x! Q    tag = new int[vexMaxNum];9 ^3 ~% ]1 M) e  o" M, p
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    + |, `3 `% ^+ y$ T: f}
    . c4 n2 i# H7 n0 g2 d; o, p1 ftemplate<class ElemType, class WeightType>
    9 h9 ^) @1 j) ]& v& @int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const/ ]0 w" l) b+ g% |
    {
    ( f( Y' b$ Y" ^' s% D    if (v < 0 || v >= vexNum)
    ) Z9 G/ |7 j$ q0 s7 c( M' f  h        throw Error("v不合法!");+ N8 l7 ]* ?2 _9 s
        if (vexTable[v].firstarc == NULL)
    9 I# O5 I/ p& J- T- {        return -1;0 `5 ~, Z- l9 p4 @9 A) g
        else$ _+ S& _# |. v: X" f2 f
            return vexTable[v].firstarc->adjVex1;$ c% i5 N+ v# K3 C
    }  d" N. r0 M9 \  ?/ }- L8 v9 D1 b
      `3 a$ N! ^2 ?" y1 i+ E1 }
    template<class ElemType, class WeightType>1 \+ ?. ?' A5 m1 v6 Y' J0 T
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const8 a" N/ W. S* w$ b3 i7 t
    {
    3 @( d" D) I( Q( e    MultiAdjListNetworkArc<WeightType>* p;* g& p7 j) \0 s2 G: \0 h
        if (v1 < 0 || v1 >= vexNum)
    0 H! y/ d4 e6 E  ?$ I8 W8 B( W  ?        throw Error("v1不合法!");
    $ Q4 r# Y& A( S- ], h6 e    if (v2 < 0 || v2 >= vexNum)9 s1 I7 X: S$ Y8 _* S
            throw Error("v2不合法!");
    ! ^+ B3 q5 x* f: d4 y' K- V0 U    if (v1 == v2)) w! Y2 ]' `7 w( ?0 x5 [" B& Y
            throw Error("v1不能等于v2!");
    8 E" R  D: Q. s  d5 J    p = vexTable[v1].firstarc;4 \* L! I# ]6 |! p
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    ; b7 M5 H6 }2 Q8 s0 i        p = p->nextarc;( j: x  c; d! T! t5 w# M
        if (p == NULL || p->nextarc == NULL)
    , }4 o7 x! }" @        return -1;  //不存在下一个邻接点
    9 _. F1 x: i5 o( o    else if(p->adjVex1==v2)# R) o% M- N4 i0 o7 m6 c, L
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);7 D% @% r. b8 `  f8 B
        else9 g( k1 J  D  v& Z2 `- W8 d
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    + V, Z! d7 h- L/ ?}2 s9 D# Y- {" s" U
    template<class ElemType, class WeightType>/ M1 \% k$ o' e( U( N# T1 [6 G% `4 r
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()1 ~1 K% O7 Q- z! g. c
    {
    9 P. u6 _3 r2 L    if (IsEmpty()) return;* W1 t1 g1 `4 R; f
        int n = vexNum;
    ( p/ l# R, P! ^6 V- e0 q    for (int u = 0; u < n ; u++)& C7 f4 J2 n' w- ]) Q* I% ?9 y
            DeleteVex(vexTable[0].data);
    4 ^, u( Z: E4 i5 \  k    return;
    7 O6 ?7 y- I! j2 V}& l" S+ v) q! a2 h
    template<class ElemType, class WeightType>! F9 `* a, V, n: D0 f, j8 N
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()8 P) b5 s5 ~9 `+ |. L3 C
    {# a3 {5 Z  ]5 @6 y5 T
        Clear();$ ]* c! r3 b* w! c1 Z% e
    }: x7 j0 [. C& D" Z! e7 H
    template<class ElemType, class WeightType>& L7 |: q1 d" i; h: M7 \
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    ' |( D2 b. o8 ?9 q! j4 X3 ?- ^{
    + v: F  z3 [9 N" {7 Z3 X    vexMaxNum = copy.vexMaxNum;
    $ e9 T# a0 P" j, A5 [$ X9 x& q2 l    vexNum = copy.vexNum;$ h+ m# s8 @8 U& y( p
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    ; d- t# _" }4 V6 \, E    arcNum = 0;
    / ~- H( ?+ g. w. `  r    infinity = copy.infinity;0 X, m$ Y% Y% b5 A$ D
        tag = new int[vexMaxNum];( V2 G. z: `* ]: t

    8 q- f$ ]* Z5 O9 Y6 V    for (int v = 0; v < vexNum; v++)
    2 o2 |- x; O1 i: o2 M4 `    {% x) _2 ?* s4 z7 b
            tag[v] = 0;  Y. d: U6 R) |( a* J) S; t. x
            vexTable[v].data = copy.vexTable[v].data;5 O2 n: j( l0 ~7 o. P
            vexTable[v].firstarc = NULL;
    " W! w% j7 M9 H3 J    }
    . k: H/ G! J5 u# X, \    MultiAdjListNetworkArc<WeightType>* p;% K$ o. Y) Q4 W/ b: ?! E! v

    8 p: K7 a' u% f- g7 K( _    for (int u = 0; u < vexNum; u++)0 y" n( b5 ]0 Y& W# o6 _' }2 i+ S. C& |  J
        {
    ! \2 b% N" \( O+ E& u: S1 R" N/ Q        p = copy.vexTable.firstarc;
    ( j# q: R5 G& r0 j) E! f. o        while (p != NULL)( A4 D$ r0 ]' T2 Y# A) A; R: A
            {
    ' r& R& u% E8 [            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    8 R4 O& e( M) E* b            p=NextArc(u,p);5 K4 `3 c1 Q$ W0 _, \
            }
    ' f. H; P1 F" @# k: f    }) e' T) b$ x- \, l
    }2 X; ^& }: d8 A/ s6 k$ {8 H
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    % Z+ V$ c, E9 q7 uMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    . Q* [5 O- p0 K% T' T0 n{
    6 H# U* [% a# N$ j    if (this == &copy) return *this;
    # R# i( h: {, X) u* S( r( m    Clear();
    , W; {' |6 s2 b/ r    vexMaxNum = copy.vexMaxNum;! m7 M  w$ S$ m+ C, Y; G4 C1 }
        vexNum = copy.vexNum;+ B3 f) z. d% V4 d6 c
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];2 {1 V% f. K) q' d+ y
        arcNum = 0;
    & G$ C0 E6 {% z# \! t    infinity = copy.infinity;
    4 `; U) n! O7 P    tag = new int[vexMaxNum];, H0 B( K+ n3 K( t
    8 l; y  Q2 g+ f8 D8 Q4 B
        for (int v = 0; v < vexNum; v++)0 N+ x2 h! a5 l2 S4 \1 I8 Z2 k
        {
    3 d% z* _- O& Q, B5 P7 @        tag[v] = 0;
    5 H, V3 I" i6 {7 C        vexTable[v].data = copy.vexTable[v].data;
    2 [; H) ]3 t" g        vexTable[v].firstarc = NULL;/ T8 n- z( k" q2 j2 r& Y9 e7 O5 `
        }
    : [$ B# v8 R9 r/ k" a    MultiAdjListNetworkArc<WeightType>* p;" B( n' h2 Y' C
    9 s# a4 n0 a$ o1 \4 i/ v  A
        for (int u = 0; u < vexNum; u++)2 k& c: a/ e; h7 I
        {
    6 A8 r( S' }! |0 Z- G        p = copy.vexTable.firstarc;/ {- C" }- I" ?
            while (p != NULL)* C0 A2 f- Y: w" ~
            {, V; L: H. U# [
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    2 ~3 t% S5 E% m            p=NextArc(u,p);
    / a3 ?, p8 p0 P, u        }
    1 d0 ~* B* ?# |, w# T% i/ N    }8 ?3 `/ M, W; Y, S; K4 ^1 C
        return *this;: a- k2 a# M# `
    }! X% F$ U& r3 T8 w; l  `$ I1 F
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*) o7 y0 D5 ]3 U5 A  r. O. |
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const, H' Y7 g, x" w0 x* a
    {
    ! c5 k! l( W# T* I; m) x4 c/ e    if(p==NULL) return NULL;- ?' f7 c- v! {  m' Y2 c
        if(p->adjVex1==v1)
    & W) N; S0 H" h* l7 k- g        return p->nextarc1;
    ! Q* O  F8 c& G+ e* p    else
      b( [% ~& J7 o' H        return p->nextarc2;
    - _. V5 p* g# M5 ~( ]}
    3 J" g8 N- C# q5 R8 vtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    1 J) A! R" U6 @0 E9 U+ XMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    7 d4 ~& _8 M+ E9 n9 s/ O2 E& v& B) N{
    7 ]1 {2 r9 p' d7 G. y1 a$ p4 N  Y    if(p==NULL)return NULL;( o# _( X% L8 l9 ?- c
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;, K1 a# }0 B9 p
        if(q==p)
    1 ^/ A6 v) `" r% w& N0 d. W/ V/ Z7 f        return NULL;" b! |6 I+ V# z' [# e7 m' Z) h1 Y0 [7 J
        while(q)* y- X: |! E; f# Y; u6 `
        {
    % }3 i4 C5 I9 `' V3 J        if(q->nextarc1==p ||q->nextarc2==p)
    , P# H. b) L0 i            break;, O7 N! ?- j- R2 G. [
            q=NextArc(v1,q);7 x! J& I2 l2 U/ e; s
        }
    / U0 K: ]5 x0 A8 K1 x7 k7 X    return q;+ T7 a. F8 Z( x, P7 a. ?  v( v1 W  W
    }
    4 a# V( f" Y2 m3 V  f  etemplate<class ElemType, class WeightType>( Q( G9 K# r+ B1 q4 t* F: L
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    4 R# ?5 E8 |* ?+ y% C{% i# A6 Q( K- I* L
        if (vexNum == vexMaxNum)
    & j+ {& A  B2 O        throw Error("图的顶点数不能超过允许的最大数!");
    $ f8 H9 R( z4 Q6 O, `+ {2 k    vexTable[vexNum].data = d;2 i7 B/ Q; C! S5 P/ Q: p
        vexTable[vexNum].firstarc = NULL;
    : `. W4 ^) o+ r0 A' h6 b( |    tag[vexNum] = 0;# b. j% B; `; i  t5 I
        vexNum++;
    3 t+ A8 s( `* |' G9 d9 c5 k& N}
    % ?0 G% B# c+ \) {1 ^template<class ElemType, class WeightType>7 r" P/ s6 g% c. y$ o: K* v* D
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    3 c6 I' B* u4 K{
    . f4 L: s! o, r0 o7 T" P+ q' n; E    MultiAdjListNetworkArc<WeightType>* p,*q;6 {7 l% L) H- f4 d( U5 q
        if (v1 < 0 || v1 >= vexNum)
    ( \0 T1 C; E# |/ S* t( Y        throw Error("v1不合法!");
    5 o6 t: l: _; V# i2 e  j& y' l    if (v2 < 0 || v2 >= vexNum)
    1 a, i9 L. w; y& l  ^        throw Error("v2不合法!");
    / x! h2 E4 K( d- e    if (v1 == v2)
    ; n0 a$ {$ N; W        throw Error("v1不能等于v2!");. {3 d% ^+ y) J# A" k2 e
        if (w == infinity)2 b7 ?$ F! O+ _8 F
            throw Error("w不能为无穷大!");
    ( e  e4 T' B* W* J& j( @  Q7 y' r7 S# ~$ _6 P3 B9 [

    + h- j+ F# X( d: R7 n1 n' ~* e    p = vexTable[v1].firstarc;7 {/ n( f& n- g7 U
        while(p)" L4 z2 {; t3 X9 w, e
        {
    6 [0 y( M+ D4 \7 `        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中( N! ]% {0 X" p" C( d
            {
      T/ z! P3 j' M+ B2 ?- K) e8 s            if(p->weight!=w)
    / e8 g- y& v  N# |2 C3 @                p->weight=w;4 L. \4 ~5 G. W( Y5 l
                return;$ z3 a5 y' C3 f7 r( `' A6 i0 N7 C. [
            }6 @- I1 R# Z& l; g( t5 K* W, s0 ]

    # X. l% R# ]0 e9 e" ?8 o        p=NextArc(v1,p);: h2 A1 {8 z/ Z/ x2 a. g( p
        }
    * }: @! G. ]# L' e: @; a    p = vexTable[v1].firstarc;1 q9 e3 g5 L# a# u* {
        q = vexTable[v2].firstarc;/ H" W! L2 T( T) M7 O
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法  u, |6 }5 C4 q( ^- v: f7 s
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    ; a0 K3 Y6 }6 y0 K; j$ [4 Q( p5 l    arcNum++;; C' B* i6 o0 q. D1 ?
    }
      }1 _8 i, q% t' ]$ d4 w- S! t; g5 e2 E' j  k6 R4 P9 U
    template<class ElemType, class WeightType>
    0 u1 A3 V9 T( N* B& F. s. evoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    # {1 e) S. _) e) `8 _  ]{4 q0 L6 U4 C8 w# P& L6 B. }& _

    ( \+ p* ]3 g+ k' f. h    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    7 a8 c) U9 V' {    if (v1 < 0 || v1 >= vexNum)
    2 |3 f1 d. T; N' \1 @. w        throw Error("v1不合法!");, q5 E" I% X! N9 T  e. F( K) ~) W' W
        if (v2 < 0 || v2 >= vexNum)) ?" Z% \* ?5 @
            throw Error("v2不合法!");, Z: Y# p% e! |7 G0 {
        if (v1 == v2)5 L8 r8 M1 G6 D0 W
            throw Error("v1不能等于v2!");
    6 g( [  f7 S" ^& M; s+ m" g6 {9 P' y0 t* q5 _4 p4 k
        p = vexTable[v1].firstarc;
    4 K& b+ h! B4 {& {+ M9 y# a    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    & K$ E; A* P* E' ~9 g    {
    & M4 E5 g7 s4 l, k4 b        q = p;
    / o7 {# h) v% j        p = NextArc(v1,p);6 p, O9 C3 |/ {7 H4 p" p
        }//找到要删除的边结点p及其前一结点q
    - o5 b' O. }. W1 ~9 `$ U4 c) f7 z; L7 C- a
        if (p != NULL)//找到v1-v2的边2 D7 U5 l) K$ W' O. C* N
        {( W# |# X  t) z4 |) X
            r=LastArc(v2,p);
    . {2 R% x7 X$ z2 `0 z        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    ; i! z) h+ h+ g" A; M8 \            if(p->adjVex2==v2)
    2 B$ c- |7 u8 O* \) C3 U, k                vexTable[v1].firstarc = p->nextarc1;+ T  ^" {, G( L
                else vexTable[v1].firstarc=p->nextarc2;! C  [& q8 W& D  Y% o7 G9 Z
            else//不是第一条边. v7 B+ T# Z- e2 s
            {
    % o4 Q$ |1 y$ |! n- w4 K* q            if(q->adjVex1==v1)
    7 `7 k+ e) R( @5 n1 g) v                q->nextarc1 = NextArc(v1,p);
    7 f' T! W5 T1 D* ^: T            else) G, e9 T+ F0 `
                    q->nextarc2=NextArc(v1,p);
    , g, B3 G6 n! D( i( k6 D* P/ }, Z) W( i4 f& L4 A" x8 g: p
            }
    7 j& {5 g6 @! r2 K        if(r==NULL)
    3 p6 _7 J3 b1 Z  @8 e/ a            if(p->adjVex2==v2)& `0 h. Y1 c" r
                    vexTable[v2].firstarc = p->nextarc2;
    $ ~  F# q- _+ Z/ e            else vexTable[v2].firstarc=p->nextarc1;2 s4 d* L' X& I' V4 T7 K3 Z
            else
    ( t' j8 O# B7 ^) T9 {# g# z        {) j6 H+ a5 D5 f/ @
                if(r->adjVex2==v2)
    . t9 p: l' }" h! e0 Q' k                r->nextarc2 = NextArc(v2,p);
    1 @; K( p4 ?/ [3 P4 l& i; h, o6 a            else
    $ ~& N! b$ [( G% k4 s$ T                r->nextarc1=NextArc(v2,p);) t; g( A1 U: Q' y6 R' X  L; o" i
            }
    * y" T2 C" T! Z: B1 u+ f' U: S        delete p;4 _' ~& C: |% i  `1 N& B
            arcNum--;
    , E" k- T) \0 I8 e) c+ \    }) K& ]. R" k$ [, o/ c9 X
    4 S6 S: {: C! c" O4 u! M2 W
    }
    * S9 ^% b: Y# f, ^. Ttemplate<class ElemType, class WeightType> void$ W3 q7 }. \  S) i) _
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    * z2 _6 P0 [, g0 _6 U8 @7 C6 H{
    * b$ Q* R5 p0 L/ s    int v;
    & Y, z% N5 C% I2 t' x    MultiAdjListNetworkArc<WeightType>* p;0 R4 i. V- s1 j' J
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    6 I4 B  G- m$ I* ^. r9 ]        if (vexTable[v].data == d)
    2 L5 ?! V+ d* M( ]2 y* H5 H" `            break;
    % _! ?" X+ z3 A: h$ f. f5 S9 f2 X: p9 o    if(v==vexNum)0 n1 r, B4 Y. N" l5 ]
            throw Error("图中不存在要删除的顶点!");
    # e2 D$ O3 t7 L! x& W6 r
    . \: A1 ?) s1 h7 {0 t, w    for (int u = 0; u < vexNum; u++)//删除与d相连的边
    $ z- o- f. v* a' W        if (u != v)
    + k+ F) ^* `, `7 Q3 x        {
    - Q. n6 d. j5 E0 ?- L            DeleteArc(u, v);; k$ s) v) ^! g* R; R/ B0 J0 T
            }
    4 z, y" u1 \+ [$ g) _, v    vexTable[v].firstarc=NULL;
    1 T6 y2 @, S, M8 ?5 X# O& Y" ]" g! [  P& J; [3 B! h% W- E2 J
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
      ~5 a+ q1 j, ]% K    vexTable[v].data = vexTable[vexNum].data;
    8 }4 X0 e- [% p1 J3 E3 r$ J    vexTable[v].firstarc = vexTable[vexNum].firstarc;
    + @* T" ]( D- i6 i4 k) ~* x+ ]    vexTable[vexNum].firstarc = NULL;
    3 y( I- L" ?  `    tag[v] = tag[vexNum];
    6 D& H& E, k3 O4 d    //原来与最后一个顶点相连的边改为与v相连, x1 x5 C: R2 n3 n% Z
        for (int u = 0; u < vexNum; u++)
    , b7 \: {" V8 b$ i& _) R; |    {/ h% W6 E5 v4 |: p- r5 m
            if (u != v)
    # e; Y- {4 a6 W        {- x$ U: ]* E+ l1 X( s
                p = vexTable.firstarc;. i/ R# h* f! a
                while (p)+ K* J% n1 ]$ J& J4 T
                {' Z1 ^5 I2 M3 M5 @; H4 s7 e1 ^
                    if (p->adjVex1==vexNum)
    3 X* [3 d1 Z1 O# Z                    p->adjVex1= v;8 h" D* g% L5 H; M+ i1 j
                    else if(p->adjVex2==vexNum)
    + A7 Q8 z7 v$ k' h% J7 i( }                    p->adjVex2=v;
    3 M1 @9 O: u  K1 `! {9 o; b  h                p = NextArc(u,p);2 z3 h$ f# |3 l8 a. P
                }
    ' ]7 b* S0 e0 o, ~        }- r5 d& S% p8 t  V: t. X+ C
        }
    : V6 c$ J; {" h0 w3 z}
    7 C, p: f3 \. D! n///深度优先遍历
    + l% m7 ^: H; F3 o2 G; X! dtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    ) `) k  ?2 P' r2 c8 ]& H{
    ' z  q; _% j* v% X9 v0 {; }* \    tag[v]=1;
    ; o8 r) o+ @4 K2 a9 l# z9 J; U    cout<<setw(3)<<vexTable[v].data;
    , i1 V* V) X2 r% O    MultiAdjListNetworkArc<WeightType> *p;
    * o" q; Z; P* C$ y" B  o    p=vexTable[v].firstarc;
    5 T$ q! s. h( Y% w: j* _& p& E    while(p)' e6 n- T3 W" U" Q* T/ M
        {
    / I! ?, i6 g3 b1 Y4 J, O        if(tag[p->adjVex1]==0)
    8 ~" B4 N' N$ a, G: c# G            DFS1(p->adjVex1);2 v! ~% r! G/ S  y
            else if(tag[p->adjVex2]==0)6 R& |. d0 ?/ h3 F1 O( m0 x
                DFS1(p->adjVex2);
    5 h+ b8 M% |" E, E0 w. J        p=NextArc(v,p);
    7 R  b! T9 w  d4 q3 @) y* u    }* ?( c+ P2 C  g: c6 j
    }
      G/ o  E) x* l7 {/ r6 m7 Gtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()/ e, u5 y/ o5 i# `( o+ v8 p
    {% A9 _9 V1 v+ |5 a0 ]4 u, E
        for(int i=0; i<vexNum; i++)
    ( F" N, G% y9 k        tag=0;9 n5 o" u* _. p/ H. \/ K
        for(int v=0; v<vexNum; v++)  |4 q$ l( D+ X2 z: K8 l
        {
    6 h9 ^% K6 z5 n. e" G% y        if(tag[v]==0)
    1 A3 o5 d$ ]# L1 R            DFS1(v);7 h  M9 x, M8 i1 O
        }
    * U3 O1 D) a1 x' E  w}
    8 Q+ Z/ o7 {) f  T- itemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()" g7 T6 C* I) I5 {2 D" B
    {
    . V$ R0 t, v' V6 Z( R/ c    stack<int> s;: x; b6 z, o1 Q2 r$ v
        int tmp;4 s0 ?" |7 U* p
        MultiAdjListNetworkArc<WeightType> *p,*q;7 X- Y5 i+ ^0 T; P
        for(int i=0; i<vexNum; i++)
    2 L( k; D, G( u        tag=0;' i2 y+ t* N6 ]* E
        for(int i=0; i<vexNum; i++)
    2 ^6 P4 M1 a- S& |8 n    {
    - s% \9 P' C" y8 P7 G        tmp=i;+ b( O7 d, [1 Q6 O
            while(tag[tmp]==0||!s.empty())
    * t7 G* C9 D  e4 I        {9 z- a! L' b" E: M7 l
                p=vexTable[tmp].firstarc;
    0 R/ j2 _. Z5 S5 S8 ~$ b: d            while(tag[tmp]==0)
    , l# ~) k. G( q1 c            {
    : o9 P7 k$ E) u1 v                s.push(tmp);
    7 l' v' b/ E# s( A) ]                cout<<setw(3)<<vexTable[tmp].data;. v. x! C- t' u( i9 L% P, X& |
                    tag[tmp]=1;. Q8 {1 M7 R) M. h2 |+ f
                    p=vexTable[tmp].firstarc;( b( O8 k: a$ T
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    ; g% Q0 ~2 Y. l, w" [( O6 [                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);# r! |9 Q* ?) b3 j4 U
                    //cout<<" 1st     tmp="<<tmp<<endl;
    / \0 u, V& v# a, U3 T            }
    $ D  E) T# ^) k6 }3 t" W' l            if(!s.empty())
    ; R! {5 ?" W5 p2 y" Y            {/ ?# L6 r2 @) O8 O5 E- K
                    tmp=s.top();
    - \" E2 o5 O: d; h" Y$ \                s.pop();8 p/ ?$ G/ N) z# T0 ^1 V3 `; E# U
                    q=vexTable[tmp].firstarc;
    6 G3 G) w. k' c- r5 u2 H% W                int t=tmp;  N+ J  _# J" k4 W7 x- A
                    while(q&&tag[tmp]!=0)
    7 P* L" R7 F0 m. y. }# g' |                {5 {" A. D, j/ n
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);7 e6 _' `/ \: J* x" R3 k- p7 w
                        //cout<<" 2nd     tmp="<<tmp<<endl;
    ) a- t  S2 h' r                    q=NextArc(t,q);: R: Z6 u- W. D  i" Z: m3 q
                    }
    8 B+ e: x% {3 _                if(tag[tmp]==0)! |+ U% g# y  h$ z* p% _/ p) C
                        s.push(t);
    ( O5 \8 }1 _( T! D                ///1、对应上面连通分支只有1个点的情况- c  h3 H$ K, k
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈% f# [! y; l% N4 x, M& M
                    ///tmp要么等于找到的第一个未访问节点,
    . k; X+ n/ y/ P3 @$ ^) x! U                ///要么等于与t相连最后一个点(已被访问过)
    7 a( ]! s/ a. @0 f9 g' X! M                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点0 D& W% c, J5 }' h+ r/ H6 i8 D
                }" [2 a" `' J! q3 \! q5 ?" |6 {! p5 p
            }
    0 b  r+ w2 `- j4 n6 ~% Z& F    }$ H& K: f2 w$ T2 ?! ~
    }2 v6 a" D! y4 T
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1* D) p) D9 H; m5 C' e& w3 H
    template<class ElemType, class WeightType> int
    ( D$ ^& W' P( D" EMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre): [- a. h5 T4 I% M
    {- ^+ j/ C; U/ ^( p7 G; w' C
        if(head==pre)
    ' Y3 n/ u  ]0 j6 X        return -1;
    ! ^0 q! ]: F' V# l2 O% p5 X) u2 V5 i- m5 V4 b! y* R
        MultiAdjListNetworkArc<WeightType> *p;) `, o# A, G% @* S
        p=vexTable[head].firstarc;& P- B1 X: ^. [: y! \
        if(pre==-1&&p!=NULL)
    , Q" ^1 c( w5 R; Q5 \        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    3 Y$ b% u: g4 P4 e$ f: A    //pre!=-1&&p!=NULL9 e- k* \- e( i2 x2 p7 |" ~4 O
        while(p!=NULL)8 r% r- W; q$ }" @' H
        {
    . }. n7 f: c2 M: \9 f8 Y8 L8 f# E        if(p->adjVex1==head && p->adjVex2!=pre)
    / \* `. n2 @4 c# S: ~, j            p=p->nextarc1;
    4 {6 ?- H8 q+ `: _8 a, |        else if(p->adjVex2==head && p->adjVex1!=pre)
    7 S& J1 V# j: [9 {/ y# ]            p=p->nextarc2;
    8 h" w/ W* \' u" ~. U        else if(p->adjVex1==head && p->adjVex2==pre)
    6 n+ l* {4 }% D. @) ?        {: w( K9 }7 i2 @
                p=p->nextarc1;
    / B4 Q3 p& d" ]- `! r            break;
    3 }6 S4 M% r. a! G, a* ?* P2 v        }
    + v9 ^" o( s  m) G        else if(p->adjVex2==head && p->adjVex1==pre)
    $ k( N& c/ x$ H4 c$ L5 Q* h- ]: p        {- }+ ^1 m! {% Y; K$ A: T
                p=p->nextarc2;+ y1 L' f/ n0 {' E5 I! v
                break;
    8 T% y7 H4 N' ^        }9 G/ f9 b& O; {$ g9 L  L
        }
    - x! j" A. q8 S: b+ }% F    if(p!=NULL). `7 ^  y4 X2 `& R
        {$ x, p' ^% L) {6 \
            return p->adjVex1==head?p->adjVex2:p->adjVex1;9 j& Q9 `- g2 z7 ^: n
        }
    7 a0 k! k5 h, ?$ L% N( Z% B    else
    " k; I  f  K4 e4 }. M& u1 r# G. ^# u        return -1;
    , \* }# l$ Z+ l( R}
    2 O. V5 U3 ^7 ?) c4 h- ~/ r5 \7 ~
    ! ~8 N6 y! l# Z
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()3 W6 k. N. Q: R
    {
    - z& ^5 T6 y7 q) N4 ?5 A    stack<int> s;
    . G5 Y& R' m& |/ P6 s    int p,cur,pre;. e* P$ V- {0 o+ [, W6 ^: x
        //MultiAdjListNetworkArc<WeightType> *p,*q;7 |; s# Z1 N; K- \" X1 ]
        for(int i=0; i<vexNum; i++) tag=0;//初始化# J4 c1 I4 k4 b# j5 ^" _5 C$ m

    % e2 O8 u5 ~3 J. P' ^3 P    for(int i=0; i<vexNum; i++)3 C. D* }6 \7 a% Y$ m0 N
        {0 X; U) \. ?8 q
            cur=i;pre=-1;) C1 \- H, A+ @) p8 w& k- [1 N9 t
            while(tag[cur]==0||!s.empty())
    7 c: c* [! \: d' N        {+ a' i0 ?) W' ^& ^4 m1 L
                while(tag[cur]==0)# ~: l* I2 {1 @5 s1 `
                {
    5 C4 y1 L0 t& d" o                cout<<vexTable[cur].data<<"  ";' g0 j+ s) w" z& r$ U' S1 d
                    s.push(cur);; m2 k# L. l2 Z/ N
                    tag[cur]=1;) a! _+ h: I. W% G
                   //初次访问,标记入栈
    : ?  A* Y! T4 J/ M; O
      @4 K, O( g# }3 ^8 _               p=GetAdjVex(cur,pre);//p是cur的连通顶点
    4 o* |; o) b; m# Q               if(p==-1)
    $ r* N. ^! g! k               {. n; h; Q0 {1 Z* q
                       pre=cur;s.pop();
    ) d0 ?, {' D$ F/ J! ~+ [                   break;
    7 t: S4 s* m- {               }
    ; K' L8 {# z1 ^% z! s, g               else
    . |4 w' u8 k/ C4 H, C               {2 K9 I- m& E  _& M( r7 k+ ]6 b
                       pre=cur;
    , P2 F- k' M6 h% w" h. N                   cur=p;
    7 c# E% F1 {0 ~4 m4 i+ E5 D, N8 R               }' f1 v* ]" ~3 P9 k6 I+ ]

    7 p7 M9 R) J3 a( s            }+ A, X5 n2 S7 N2 l, H
                while(!s.empty())& {* |9 k8 v& e1 l6 L
                {
      V4 S: K# l: |+ V4 L4 v$ L5 K                cur=s.top();7 e9 |- I; }, A! E8 T+ O- o* C% r
                    p=GetAdjVex(cur,pre);
    % R6 m$ r' T* h! T                if(tag[p]==0)
    . d! F: S5 q* z. D; I5 y                {
    - ?  B2 i6 x2 H. n6 n6 W                    pre=cur;
    1 Y3 D- m5 a) [7 e9 Y6 V; V  o7 |                    cur=p;% D; e7 ^; l" Q- @' I& a% D- }5 G
                        break;
    ! t. K# E$ v; o; i# ^1 n7 k8 b4 v. Q                }
    - U, g8 F4 ^8 C' {* b                else' d4 e  H7 K+ p: W4 T; O8 g
                    {
    ( Z3 N) j8 p3 S4 Q/ M- m                    pre=s.top();- K! Q$ r, Z+ V( P7 a6 u
                        s.pop();
    " A! A% K8 [" h) Z2 H. r2 g                }8 D4 v% t/ I% r/ Q& I. V- ~
    " ^) @$ g! K! g' k' x; ]- O' U
                }, q6 y" L9 {7 H  x# N. q
    9 X; k; U/ `* c  ~1 @4 @$ B
            }
    " W2 B! q1 V! Y/ z5 \    }6 |) b! L9 j3 X; g. w0 x
    }1 z+ d5 q: J' V$ f: v
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    ( N$ q1 w' t1 }{) Z! p; c/ B! r
        for(int i=0; i<vexNum; i++)% k( a. x$ g/ |7 R
            tag=0;
    6 D: {5 ^( w& C' e' @# P8 D( H& H0 s    queue<int> q;
    3 T: d+ m" D2 k7 [9 i    int tmp,t;6 j4 q: C6 @1 H* x9 n
        MultiAdjListNetworkArc<WeightType> *p;& a' n0 z& i8 \6 d: I
        for(int i=0; i<vexNum; i++)
    3 @8 l, ^' _3 e% d    {8 I$ m$ L3 }8 j2 H4 @9 z0 D8 D/ l
            if(tag==0)) ?+ L) x7 O; x- n: d* z% x
            {
    ( F4 V. s7 R: _$ Y8 z; s            tag=1;
    9 L* ~: _+ F& N* D& x/ B            q.push(i);% c( r  z' `1 @
                cout<<setw(3)<<vexTable.data;; N. a+ t' G  H
            }' M" t7 u2 e& N3 D+ ^6 ?
            while(!q.empty())
    ( A' z$ r. Z- |        {
    1 c- ^2 p, u3 O! Q8 m! y            tmp=q.front();
    4 ~1 B5 H& U' x, g) M, L; |            q.pop();, m7 e2 v7 s4 H6 A# c- _
                p=vexTable[tmp].firstarc;
    ; I9 w) `$ o% ?8 x( _; S            while(p!=NULL)
    ; k9 n3 E6 W- S; N6 K            {5 Z7 f0 b/ O4 x7 f0 ?9 A) F1 \; v6 r: j
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);6 D5 E; ]' g4 I
                    if(tag[t]==0)
    / U: U( G$ a* h1 B6 [3 U                {
    0 f/ `2 J. F: |. T& W7 Y                    cout<<setw(3)<<vexTable[t].data;- {) `+ J; `" j5 R! V
                        tag[t]=1;& p4 W! ^7 M% P2 V, D- N
                        q.push(t);
    - h/ u; V) s( j" K                }
    $ d7 w+ n" L/ x  M: t                p=NextArc(tmp,p);
    % r$ J  ]6 ?7 f! q            }3 ~3 r8 a' h: [9 D
            }8 H/ v# d5 F. L/ E
        }( y& y" B% j4 v8 i" d) H* h
    }  L  Z  T4 T! v* i# ]/ y) a
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    - g9 G& V' l* H; B& ?) q{
    $ z! X/ g. V" a    MultiAdjListNetworkArc<WeightType> *p;
    0 c- Q8 ?& p. B8 X2 K3 A6 D# v    cout << "无向图有" << vexNum << "个点,分别为:";
    ; [8 _$ Q9 f7 ^. D' h    for (int i = 0; i < vexNum; i++)4 Z" m) m( E3 d5 t7 p
            cout << vexTable.data << " ";
    3 G3 ?) M% C. }. f% C, m    cout << endl;: W2 h& t( i) c( l
        cout << "无向图有" << arcNum << "条边"<<endl;
    7 R% r7 h. M" z3 q" h) c: A    for (int i = 0; i < vexNum; i++)6 j4 c$ @& ~7 B5 @' X: B% y- U
        {
    1 T' f# `8 }2 h3 z4 E4 q& V        cout<<"和" << vexTable.data << "有关的边:";4 L" X5 y# _+ D4 Y
            p = vexTable.firstarc;
    : x5 V& s4 J) G1 x% G2 I3 P        while (p != NULL)0 i! T8 [7 L# {  o. ]7 f
            {
    - X) H) s2 x+ Y6 {$ S            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";/ ]) ]4 D! t) r* x$ l
                p=NextArc(i,p);/ y1 h! U* |9 M' M5 \. P$ R
            }, c3 X5 `% H) }9 P1 U& c
            cout << endl;
    : s5 ?0 m9 x; {9 r    }
    5 H. I. u* a$ S3 H& `0 V/ |}) J( v& T- [/ I7 {3 K+ Y8 K( X
    * @2 ?0 @( h/ [( s( j6 m5 p5 s

    3 v( o6 p! y3 @+ W& \邻接多重表与邻接表的对比3 {! Z& u% v6 ~% A0 D! c" h& k1 R

    ; q5 P( i, ~* W邻接表链接
    & K$ ]1 L& Z5 o" q+ v. t在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    - A0 _9 y+ }6 V* H  e% c7 Z在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。- H: c' g9 j/ h/ ?0 i7 j" L
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    " B  r3 A: k0 \+ x* l+ O/ L& K) Z( j7 C————————————————5 k5 L" Z: U3 K/ I  y( O; m* @# ~, O
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。( |$ K$ y' {: t# J
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958) I+ W  g  y2 N: X
    8 A7 `6 Q( C+ _3 R: R

    - e1 V* K" Y; a) q/ F" P% s- D4 c( Y- s, c
    ! C0 X* p6 }  S) p+ K, \
    ————————————————2 H. g- [2 P2 x- g$ E
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
      c6 a4 c& J3 |  Y原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958% s9 \0 Y0 z0 i; u8 y

    " x* L2 t2 w0 F; |, n  Y/ ~, p2 J% v9 n
    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, 2026-6-9 10:28 , Processed in 0.383986 second(s), 54 queries .

    回顶部