QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1505|回复: 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

    ; d+ W& I  ^8 M. x图的存储结构——邻接多重表(多重邻接表)的实现
    3 S6 x* L: T9 u5 i7.2 图的存储结构0 z+ y$ [3 k7 z, M
    3 T5 i& S$ J- O7 ?
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    " A) C" _! e' i' h+ `* ?: P1 B' Y邻接多重表的类定义, h# L6 d6 Q& p: c6 ?
    邻接多重表的顶点结点类模板
    # v# c7 S1 }- O' v$ M3 O, K, R邻接多重表的边结点类模板
    8 d2 ?9 G0 n; {' }1 F邻接多重表的类模板% S3 b) ^4 \) s
    邻接多重表与邻接表的对比
    6 L' e+ |2 ?8 I& T7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    8 L+ k6 h4 L! X: e8 j, w) V! x5 L' g
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    . J+ }1 J4 o+ I' O; V8 ~在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    1 H8 k) R' O4 T3 l6 a# p
    . ]2 g5 Z9 L7 N3 J+ F邻接多重表的类定义7 F7 Q' c4 v& C7 ~% I
    1.png 3 p9 P1 @# \5 `# T
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    . K7 M% q8 y( Mdata域存储有关顶点的信息;
    % `, r. p. z" E; X- D) V2 S4 a: dfirstarc域是链接指针,指向第一条依附于该顶点的边。2 P( S! @: E0 O) b
    所有的顶点结点组成一个顺序表。

    ) H; k& O; O$ P7 d2 Q3 h3 ?

    6 z4 J. ^% P# G  q2 ?. [, @template <class ElemType ,class WeightType>7 i: J' d7 ?# t1 W
    class MultiAdjListNetworkVex
    . E0 J4 w# c3 `3 B{1 J& I! r; f3 ]
    public:
    . p" ]  o4 M/ v+ G6 C8 q        ElemType data;
    2 i& O  L/ v  k        MultiAdjListNetworkArc<WeightType> *firstarc;
    ! `+ C2 r$ Q# q+ w) _6 d
    ( }4 L" K: w* S! [( G        MultiAdjListNetworkVex()
    3 n2 t" ]. j5 x2 e% ~        {
    3 @: t4 E& T! _" O# V3 p6 n                firstarc = NULL;$ G* H6 u& e8 R2 v
            }
    , e$ @5 U: m  G' c0 s  A5 g# J        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    ( C9 x* ~, H- e6 ?# K9 K4 n        {9 J; j" ?' h5 v/ u; {
                    data = val;
    8 h5 v; B" r; G( x6 M+ D4 G1 z' b                firstarc = adj;% J, r" b3 W$ I  A
            }3 l" ~$ S/ Z2 n' V
    };7 X* X# N5 Y1 Q0 h$ w
    9 N3 n9 t. r" L0 m& |
    邻接多重表的边结点类模板) l/ ^. k" o( X1 t3 M, N

    , E: C: p& }: h3 S3 t( _在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    $ D) {. l. F( A  A- D9 F$ btag是标记域,标记该边是否被处理或被搜索过;
    # x. _2 L2 _. e7 r3 S& x6 s2 |$ U& wweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    2 d4 k4 ~1 q5 |6 Q& ~- E6 ]nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;- g/ I( q! K' R/ m# t1 p
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。1 q7 [' b2 c+ F- ^/ R
    $ G5 G( R/ j0 u* b$ R2 G
    2.png
    / |. q' A- \" \9 `template <class WeightType>
    ) T1 p/ C7 K& N+ }/ @# k; p! [+ V' sclass MultiAdjListNetworkArc
    4 V: l) W! y6 ^; t2 [* t{
    # q0 j5 ?. d1 }* r9 Ypublic:2 B& L5 k& e* K# t* w
        int mark;                                       //标记该边是否被搜索或处理过( k7 {1 s4 }9 z: q
            WeightType weight;                              //边的权重
    3 ]: z$ A9 A4 G) \* G' y8 e        int adjVex1;                                    //边的一个顶点! D. e- j8 x( p4 s
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    # G7 U* d+ R9 o; \; ^8 P' K7 Q4 t        int adjVex2;9 H$ p$ c# r  N/ z5 _3 b. D
            MultiAdjListNetworkArc<WeightType>* nextarc2;; q( _0 }/ M: [, C; J  A
    - |0 j9 Q4 c* d0 V- a; B
            MultiAdjListNetworkArc()
    6 v$ r. M4 c8 v: }$ h2 K* y        {
    & I& X  x+ V! a) ]2 b) n+ Q                adjVex1= -1;
    . p$ D  V. v, l* `" j& k( v9 D! r                adjVex2= -1;
    8 C! E/ N: R4 A  D8 r3 M% A# v        }
    ! }3 y8 {+ U! X* G2 r        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)! e( \: i0 K. v
            {
    0 g. Z0 P; n, w- B3 Q                adjVex1 = v1;       adjVex2 = v2;
      w4 I& `8 T) A  p# o% ?7 a* ]* j7 x5 t                weight = w;
    ) [5 H) Q. `: g- r3 y6 P                nextarc1 = next1;   nextarc2=next2;
    . ^" e6 X3 w8 @7 q3 ~' }                mark = 0;           //0表示未被搜索,1表示被搜索过
    2 A+ e1 x6 W7 o% r7 k% K) u% e; D        }  ~8 w1 k5 @/ B
    9 d7 ~; ^! X( a2 |
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    . E* t) n( s' c' V, x8 Mclass MultiAdjListNetwork  {* g9 P- i2 S  y+ H
    {9 C$ L4 u1 H* [5 I7 D' f+ M% U
    protected:% S+ \  i  D6 W9 d! R3 x9 e# G# ~
        int vexNum, vexMaxNum, arcNum;) U; S# ?9 b5 _
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;0 J% X* w$ t0 k% l+ y7 t0 O
        int* tag;! e% h2 N  L) |, b, ~+ b
        WeightType infinity;6 y* }; w! E: [$ |" ]0 ^

    ; X1 h$ L: t% U0 m( ]' A( n+ Upublic:
    2 U& @9 X2 t" |6 }    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);( R/ B) X2 V1 `& F0 F2 r, [

    + ~3 H2 w% F. X  R3 r$ k    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    2 q' z3 ]9 `& U  [' K6 ]! O( n: ^1 M, i' l% h$ {
        void Clear();3 o1 `4 A- R. g3 R  \
        bool IsEmpty()* L" S8 S" R& E% t/ K
        {
    2 k$ E! v. ~, u# f        return vexNum == 0;7 K6 x! F; I$ y0 a* s; J9 n0 v
        }
    ! Y% m6 L1 g# J3 f    int GetArcNum()const
    2 w! H% P- w$ ~5 b4 f) e1 M    {
    ( a. {( _. q- D. @        return arcNum;
    0 d" p/ H: k- ]  _2 Z2 J+ K( k    }
    7 P% g( ~1 ^5 \8 z0 \: \    int GetvexNum()const3 g: t" R# E0 s! g# ]$ W
        {
    % a% r- f3 M/ P8 n        return vexNum;
    , E( a& ^2 x: }8 ?3 o. X; n2 u6 p    }
    ( [! v6 V0 k* t8 y8 x
    ; i& X% u: n+ J  L2 \0 H8 L4 J( {- k' s; H4 o& l( o
        int FirstAdjVex(int v)const;
    8 r- r5 P2 @& q4 [+ S2 F8 v( E: Y    int NextAdjVex(int v1, int v2)const;- Y. `9 K3 F* z5 U
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;: r, t: I/ D8 v; x
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    4 u5 _/ X1 V- [( ?) a# j
    - ?4 ^' f7 O" }/ W    void InsertVex(const ElemType& d);
    , G) P! J1 z3 D& a" p/ {    void InsertArc(int v1, int v2, WeightType w);) l' y* Z# ~, K1 |
    * t) h' g( \3 `% B
        void DeleteVex(const ElemType& d);1 Q. R. q7 q6 K) C4 E' {
        void DeleteArc(int v1, int v2);
    7 n: t1 `7 w/ X* Q2 {: X: P; {
    8 N1 n* z9 C, D3 J, t& p5 |* Z    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);7 ~& p, s. m, H( s3 ]/ s- t8 Y
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);+ z7 i' c$ m9 }" K+ A9 Q
    ( R" ~7 T; D) z* Q! M3 ^! e8 R
        ///深度优先遍历
    - ^  k6 |- V9 [9 t0 A. J4 M1 m    void DFS1(const int v);+ T. T5 i$ W1 y" n% w& F3 f( g
        void DFS1Traverse();
    5 Z! I5 j% j' \: {    void DFS2();
    & g6 H6 D. T) K6 o8 ~
    3 U; y& O2 K4 c0 Y3 [% }+ A3 Q4 D    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    / q+ c. k7 n: Y* q    void DFS3();* ?5 }1 W% s; N, M. ]# Z% w- a
    / A7 v) f- Q/ C( @3 [) i  P# B+ Z
        void BFS();. e! P3 D/ V1 s! {: N
        void Show();! ]( @8 h; c- Z4 k* u& ]
    };; J. t% O" f/ j, m1 e$ {* M# W1 D

    ) i' M$ l2 g0 R. F# y2.函数的实现% f) N' i; J) K2 n/ E4 X
    研讨题,能够运行,但是代码不一定是最优的。' W- f: s+ L0 H5 [$ [% H6 N

    0 j1 y) E- \+ b3 C8 i5 q5 u#include <stack>
    5 q$ v3 e) F- T- s( D7 u; z5 M! y#include <queue>$ |! T: }7 l$ c& J! c6 [# k) T/ X- G

    $ c) b) ?$ a' ?6 otemplate <class ElemType,class WeightType>
    ' Z* X: z+ n% l+ ~( H7 R$ O% }9 ^MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)5 @7 H- j, F" }  H) y: M
    {0 D5 V  ^6 k0 B4 [4 {
        if(vertexMaxNum < 0)& v4 `) X$ h% a$ ?
            throw Error("允许的顶点最大数目不能为负!");6 G, S" Z, U  ?. d4 {7 Y
        if (vertexMaxNum < vertexNum)
    : ]2 d, q4 O1 r" }        throw Error("顶点数目不能大于允许的顶点最大数目!");
    ' h. [+ `; Z3 ?9 e3 V" {# y    vexNum = vertexNum;
    , F( U* r( _/ R3 D  ?) M    vexMaxNum = vertexMaxNum;
    0 K# p) {( o7 ?0 ?    arcNum = 0;6 v+ Q7 N5 ?. u, h, y) K! K
        infinity = infinit;2 U" z4 x' X' z
        tag = new int[vexMaxNum];
      p/ d. m4 X4 ~2 O( h    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];. M: v7 w# f- Q% I% f
        for (int v = 0; v < vexNum; v++)6 t! C: H2 M( k: U, o  L; Q
        {
    - I$ A0 L9 H% ?8 Z; C# f8 r        tag[v] = 0;( c5 x9 t4 A- l! ?- _
            vexTable[v].data = es[v];/ y& z( X8 E- _" c3 u# B
            vexTable[v].firstarc = NULL;
    6 \6 [( P, y& }7 Y+ I2 v- y7 ^, k: \    }1 {  n5 v/ z6 Y
    }
    . d: T! ^: C( q3 P0 gtemplate <class ElemType,class WeightType>
    1 P" k4 A( J. z4 n1 \MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    0 t. K# O6 a" {# o- Y{" F8 g3 j( @" G% J9 V% [, L
        if (vertexMaxNum < 0)1 y1 t7 w& G. y* t
            throw Error("允许的顶点最大数目不能为负!");
    9 H* l1 c. }5 w2 ?8 P/ t7 }    vexNum = 0;& |) M5 h. H0 c: @% q
        vexMaxNum = vertexMaxNum;: ~7 f% X* w/ U+ s: O* t, n
        arcNum = 0;
    ( t" r4 v& C) ?: V+ a    infinity = infinit;9 r2 }8 ]# f( K' j4 e
        tag = new int[vexMaxNum];
    # {8 {6 A8 e& {# S0 P, }! l    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    0 d6 a2 W( Q" e9 b. e}
    5 v/ `9 ^' Q+ m, b  @5 |template<class ElemType, class WeightType>
    ) L% q9 d' ~) Mint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const) g* W+ _" D+ e- w) {/ m2 I3 [
    {( N7 Q$ h# T( A; D- t
        if (v < 0 || v >= vexNum)
    , u8 \% u2 j- T' Z- Z7 p        throw Error("v不合法!");
      |, W: U% W) d, O* M7 w* x" _9 q- l    if (vexTable[v].firstarc == NULL)) m( \/ E: D/ V8 y
            return -1;) C8 P* J) l% v
        else8 n1 u& a1 @" F+ W0 p
            return vexTable[v].firstarc->adjVex1;
    ' k. N3 t9 }! t/ g4 T}
    : t9 z. O) X! |' H
    : c6 z) M& H8 ^template<class ElemType, class WeightType>
    % ]; @- G( |4 Tint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const1 x0 ~/ Q) g1 n2 Q
    {/ X$ u8 i0 I( c$ i5 _
        MultiAdjListNetworkArc<WeightType>* p;" S4 }4 P0 {0 r
        if (v1 < 0 || v1 >= vexNum)6 i! I- [1 o3 D7 E. V  g* w
            throw Error("v1不合法!");
    8 t' X8 B: E3 M0 }    if (v2 < 0 || v2 >= vexNum)
    9 p- |7 P4 M+ Z  k3 X+ \        throw Error("v2不合法!");  J4 a: S" p0 s
        if (v1 == v2)0 J8 F$ {$ Q* C
            throw Error("v1不能等于v2!");* ]* d* p+ c: B# F. f. n5 \
        p = vexTable[v1].firstarc;9 M* R0 v  P9 x. R6 k$ e
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    2 l* \# {: _6 \2 _        p = p->nextarc;
    % D/ @' o! b5 Q' i' L; p# n6 n$ b* l$ ^    if (p == NULL || p->nextarc == NULL)
    9 P& `6 N6 t# K8 \  v        return -1;  //不存在下一个邻接点
    $ L: E; y& m' `% r    else if(p->adjVex1==v2)
    0 Q8 Z$ K1 U, ^/ t. Y# m3 h& Y        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    : J( E( T9 r6 ^: s3 x* l; m7 ]    else
    0 ^' n- a" w+ O2 N! I        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);- d; C0 Y' M: g$ Y9 E) E& I
    }
    1 P: Y/ p$ o2 M# W" t, T! w! _template<class ElemType, class WeightType>* t- B4 v8 K2 F; t2 k
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()
    - {" \( H2 `/ O# M$ z: D{
    - ?# S* ^( A5 r0 {! B8 E    if (IsEmpty()) return;. R$ q; I+ M6 m8 `
        int n = vexNum;
    . k$ n/ @+ o' W7 n% Z# n* t    for (int u = 0; u < n ; u++)  J9 X, X; m& [/ o: K1 }
            DeleteVex(vexTable[0].data);
    * Y  C: w' J! j7 L2 E+ z  O    return;2 s% ]5 S' z& Z5 a  }
    }" S8 j& D# A" u8 F- P
    template<class ElemType, class WeightType>- m* N5 \' V$ f* U
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()8 w/ o. R, k3 w) e$ K# P# B. E
    {
    " A  B% G7 ?, D; v' o* z2 j! C    Clear();
    & \/ c0 a1 V4 _+ `2 Q}5 |! K  g/ C  u3 u. f
    template<class ElemType, class WeightType>
    " v9 s7 S% h5 T3 `* o3 {6 ^$ hMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    # n; ]. i9 p" W2 ~% ~& `{# b; J8 R; b* e6 J' `3 g! l
        vexMaxNum = copy.vexMaxNum;& }8 J- @6 |7 J6 A
        vexNum = copy.vexNum;# ~+ ]/ ?( [* Z& R% F; c7 ]  J7 D
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    0 c" o% [3 Z% u4 ^* ^/ D    arcNum = 0;
    $ Q9 D1 }! E; n9 g, {4 o    infinity = copy.infinity;
    9 e, B" b0 n7 |2 y& R    tag = new int[vexMaxNum];
    2 O( S! W/ @" g. l
    9 i- v; o; ^; K) U    for (int v = 0; v < vexNum; v++)* p% p2 V* i2 _6 L( r0 C1 {3 p
        {
    8 |7 E- k& h* E  J0 I' w: R& a        tag[v] = 0;
    " q: P) I0 V- M6 \1 J        vexTable[v].data = copy.vexTable[v].data;
    / E4 M4 ^: E- X! t: J        vexTable[v].firstarc = NULL;
    6 p( j; a, e5 {- A; v+ w8 x    }5 g" L3 p& T8 h9 s. z2 L7 R
        MultiAdjListNetworkArc<WeightType>* p;# ^: }4 a( ?( m1 D) M( z

    , j4 Z5 E; x* u* q    for (int u = 0; u < vexNum; u++)
    & ?/ w( ]: P3 g  }# f    {
    # Q9 {/ Z" i* }+ H" V        p = copy.vexTable.firstarc;
    ' r8 b& y: g  I& t        while (p != NULL)/ E- a" Z% j. H; ~1 D: M( o& X
            {
    / c5 R  O- v' R/ ]% V. k+ i$ c8 t            InsertArc(p->adjVex1, p->adjVex2, p->weight);3 b/ c) v+ h0 x! ?, ~
                p=NextArc(u,p);" N9 ]; `& c3 M( n1 B# h0 X
            }& C8 v9 {3 d% p& {5 O/ l
        }) u2 e; }3 _8 ?6 n: {
    }' b; T2 N9 ~; ?' R* b7 x# J: k7 ?
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    / z$ i; B9 W) S' i9 z1 NMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    : K8 u! K8 ^6 {( ~, e  v4 q* ~7 R; u# o{
    % ^) \6 @6 F7 z    if (this == &copy) return *this;
    0 t0 A7 ]8 K. l4 x8 I    Clear();
    + {1 Q: N% W: e: f    vexMaxNum = copy.vexMaxNum;
    $ q5 h, @8 N" R" K    vexNum = copy.vexNum;2 f: H" D$ J5 W8 }8 y$ q
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    ; C$ I8 V" {; W0 l( f! `    arcNum = 0;
    ' V* a5 {8 D) [2 g& z! G) k$ l/ T3 r# p    infinity = copy.infinity;  B! j; f9 y+ L; W4 A9 B
        tag = new int[vexMaxNum];  I; ~5 @+ S" X

    ( m5 J8 z# y( Y; u; S    for (int v = 0; v < vexNum; v++)
    " m% J4 X7 \( u! Y  q4 p    {3 o3 }) n7 r+ k
            tag[v] = 0;5 ?. b9 i! D- h' J4 H
            vexTable[v].data = copy.vexTable[v].data;+ {- v* ~9 D& N2 H. U; ^
            vexTable[v].firstarc = NULL;$ Z+ N# i3 m4 a9 y  U2 P9 l
        }: r# @, r1 g0 \* T+ j
        MultiAdjListNetworkArc<WeightType>* p;
    . n( N7 N+ j( J: k" B" X2 [; Z# U* y% C* i! Y
        for (int u = 0; u < vexNum; u++)) x/ u+ S9 U) W$ H& Y
        {: A7 x4 D  j# F. G
            p = copy.vexTable.firstarc;
    - O8 [& i  R/ P* J        while (p != NULL)
    2 R' C/ R0 e' k" ~, j8 W        {
    : D+ \# L" K5 Q            InsertArc(p->adjVex1, p->adjVex2, p->weight);2 \* |; \/ {! c4 m8 s
                p=NextArc(u,p);
    2 e+ u- Y. p3 o" C9 h% J! u        }: R5 N" J. W% N/ u* ]5 V; Z7 S. \
        }! n# o( H% N# z8 k  {3 `$ z
        return *this;
    8 a2 }  i; W0 q) n/ V& G* I0 U% [3 P" f}
    - o/ A+ S! j/ \9 u4 htemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    9 L  S8 A' R" @: e+ M% ~MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    2 W" k% {) m+ E{
    7 A4 z, ]' x( B+ [  r# K& h% h    if(p==NULL) return NULL;
    $ H) S/ D+ ^: V5 i( I    if(p->adjVex1==v1)5 g) i2 y/ {" y* N
            return p->nextarc1;
    4 y# B8 K- ]3 X0 |6 X# V    else
    - Q  e5 V9 @7 S+ _! n3 l  J  T        return p->nextarc2;
    5 w: A7 N' G4 P/ B}
    8 a6 p2 K" R% qtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*$ p7 G# i$ P! V3 }/ R
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const/ t% f8 Y5 c- \  n. {
    {. J, W7 f* U/ J5 j) j+ k/ c+ I. Z
        if(p==NULL)return NULL;/ c/ F  ~+ m- |
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;3 O  m8 [/ p: b$ W% E" W- {) Z
        if(q==p)
    ' U# I" p; ^: p$ I. x        return NULL;/ L' X4 c% _6 F9 G# z% C
        while(q)
    & [- Y% B5 l1 R2 \$ g, G    {
    ) S& W7 y* j3 M, C4 L8 T2 B        if(q->nextarc1==p ||q->nextarc2==p)3 d: C* |4 A$ T# m( d
                break;; [- L  P% L, z. ^& F3 V- L1 K
            q=NextArc(v1,q);
    ( q; l1 C) l4 e8 x" G    }
      P% @2 \9 ]! s1 N- y+ ?3 [7 l0 ?    return q;
    & G. S$ E! D! `8 m}
    5 w) C# S' e; ]! u, l0 r, {, [( J! ktemplate<class ElemType, class WeightType>0 K' q2 X5 `0 Z* h
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)+ {: l  E1 e7 `5 U. z
    {. d% C8 e8 ^$ ^4 S- Z* H8 G* l
        if (vexNum == vexMaxNum)1 A+ A  J! X4 n0 A6 d4 G$ W
            throw Error("图的顶点数不能超过允许的最大数!");7 V9 E& I2 u% }! L/ l
        vexTable[vexNum].data = d;
    ( J5 s/ P, Y# U+ `4 E    vexTable[vexNum].firstarc = NULL;
    " O2 n4 j9 A) d* O    tag[vexNum] = 0;
    ' V  n+ f' v% C; Y; \    vexNum++;3 E" V- `0 d  P$ E6 K1 Z
    }. @0 S% Y) I/ C  v3 c
    template<class ElemType, class WeightType>
    3 h# G' U$ R6 G$ g: F; m- cvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    : P3 c( M* _* w: w2 k0 X{$ r0 H6 E( u! S. b- Z5 }* T* @
        MultiAdjListNetworkArc<WeightType>* p,*q;
    , ]6 A( M! }$ ]; P) g    if (v1 < 0 || v1 >= vexNum)  q6 c$ f$ I4 u: z) c
            throw Error("v1不合法!");
    0 h- W, K6 ]+ N9 s    if (v2 < 0 || v2 >= vexNum)% @. P1 Q; P2 g  W9 Q' }
            throw Error("v2不合法!");& B+ [* N( `: i4 D
        if (v1 == v2)6 c+ t' t2 M/ b. J; l. |8 g
            throw Error("v1不能等于v2!");
    8 v+ ~, U8 j  T    if (w == infinity)
    8 S0 u& i+ p" {- `" W$ j1 @        throw Error("w不能为无穷大!");
    , ~4 X( b2 t, g4 a/ ]
    3 R- n% Y) _. e3 V" E$ }3 P
    + ?0 y$ \9 j9 |- {' N8 Z    p = vexTable[v1].firstarc;
    * D7 S2 I6 o' E( ?: Y    while(p)
      n$ b! ^7 \. y$ D+ X2 F! Y- ?8 b    {
    3 @' X0 Y2 z1 l% J8 J. F0 P5 W8 G        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    , m: g: l! @. k! M# c        {
    ( m* L' i" m9 O- K5 V            if(p->weight!=w)# d$ U2 M+ q% x  I0 s' M9 ~
                    p->weight=w;& V4 N' v9 r4 c3 r: t- i
                return;
    - M7 b# L$ }* a" |) ]4 n6 q5 H5 p        }
    ' U' O" ~/ V+ \7 W- Q  a
    9 [/ _; a' D/ F  Y        p=NextArc(v1,p);. C: ~1 s' B$ Z6 o0 d
        }
    . h  J; M$ `# k( W2 C) d    p = vexTable[v1].firstarc;
    6 B/ G6 x1 T5 T% F6 `" \$ {1 G0 d    q = vexTable[v2].firstarc;) ^  d4 T) \. J4 F" X# P, b1 E$ e
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法! u4 D1 Y$ m5 }) q
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    7 {6 c  _7 |/ ]) }    arcNum++;
    - I' h" V0 n) \4 N  e+ R0 Q}
    4 i1 B' Z) r5 M# O6 @- }" A# i. T, D$ R9 Z! ^! t3 v! }+ g
    template<class ElemType, class WeightType>
    0 |! O. }% X% f: V" k5 O2 t' M  |void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    4 R) E; F- Y, ~' ?: T; I{
    * l0 B" v% P7 h) a5 z
    7 q0 z  d  ^+ N& |. A    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    $ p! ]. P, h9 i8 Z0 Q    if (v1 < 0 || v1 >= vexNum)
    ' _+ b' c, Q; ^0 d# [7 g& m        throw Error("v1不合法!");" J( y/ M+ Q0 k* M6 m! @
        if (v2 < 0 || v2 >= vexNum)
    ) F; [8 j; }) F! j( S* d. u        throw Error("v2不合法!");
    1 U" T. v- \# ^3 I: D; P: ?) D    if (v1 == v2)
    0 P: L2 y- @% a& T2 C2 X        throw Error("v1不能等于v2!");
    4 d5 L$ x- c+ y3 d5 \# V$ m. o# n, G* B* A
        p = vexTable[v1].firstarc;# y! B) ~1 y" J  s2 r3 ~
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)7 r) d1 v& _% U% L( V8 c
        {
      `' n$ e  L. |        q = p;
    " Z* O8 c  V- F" Z) B" \. `1 w" [        p = NextArc(v1,p);
    & X2 H0 e9 V, T! @0 l: Q    }//找到要删除的边结点p及其前一结点q
    9 d' ^! `! B- j+ f% T- d- M4 I$ ?% j9 h
        if (p != NULL)//找到v1-v2的边
    5 U( S( s; x; G/ ]7 A; l    {
    ( C; j& K& ]+ H) N3 w! {, Y. F        r=LastArc(v2,p);
      L$ H, ?; ]) I4 `) g, Q        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL/ U. G  q% K5 z! Z
                if(p->adjVex2==v2)* S2 O; @, b6 H, Z- }
                    vexTable[v1].firstarc = p->nextarc1;
    % L$ h& U( ^- r2 y  ^0 X" ?            else vexTable[v1].firstarc=p->nextarc2;! e. a* |: e2 O" \) z
            else//不是第一条边
    ) Q7 {6 l& H, {9 c        {( n1 I' F. x" d( b! C
                if(q->adjVex1==v1)8 B2 g% y( a, j2 Y/ L* O
                    q->nextarc1 = NextArc(v1,p);
    ; m- n9 D' ~5 I            else
    1 ^9 Z- b0 q8 Q2 e                q->nextarc2=NextArc(v1,p);
    % {* t6 O! S& ~+ u/ D; w) J/ D  z2 W0 T9 _" g5 T
            }3 r) y9 |+ x9 A  y; Y( o
            if(r==NULL)  _# \4 J/ a$ T2 ?8 b- O5 y
                if(p->adjVex2==v2)
    # z- U' \- u& r                vexTable[v2].firstarc = p->nextarc2;
    7 z0 s0 g0 Z3 L6 @9 x, X7 t            else vexTable[v2].firstarc=p->nextarc1;
    - P( u3 j: Y2 s% p- Y2 `9 m        else
    0 ]& N2 X; a4 i; V% c5 @3 v        {9 L# n8 ?! |9 D' z
                if(r->adjVex2==v2)
    + L' N- @) Q7 O1 r) W                r->nextarc2 = NextArc(v2,p);* K4 C! `$ m$ `, e
                else% l' j/ s9 P( N2 V8 M
                    r->nextarc1=NextArc(v2,p);
    4 y# v( k3 P3 d: L% \        }
    + [" Z1 ]( J$ Q  E' j        delete p;
    ; e3 o' [- F. q        arcNum--;
    6 l/ {& N7 Y2 g* k0 `    }5 N, Q7 p2 G; g3 _2 B" f# y$ c

    0 x  j/ E' g* {; @5 D- b}+ z5 G! g3 J3 b% w
    template<class ElemType, class WeightType> void
    % W* ?9 @* l! }$ p7 C! M& h  mMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    9 h9 e- s6 Q/ Y8 i1 L{/ ?: j1 q6 W# v, n6 t
        int v;
    : h; m5 @* t) I    MultiAdjListNetworkArc<WeightType>* p;! c/ s/ w2 w, d7 H
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    : \; F4 c, J; s5 G% p        if (vexTable[v].data == d)
    8 w+ v2 }, n) t4 V6 p+ W            break;
    $ e5 }1 [4 X; l! V. ]3 X5 k0 E    if(v==vexNum)" }6 I) h& p* D
            throw Error("图中不存在要删除的顶点!");
    , u! q2 S5 F8 \# V$ x* T6 R' E/ E2 O7 V4 D8 ~
        for (int u = 0; u < vexNum; u++)//删除与d相连的边
    + p: n9 e' p2 l        if (u != v)
    * E, S3 E0 R& h( ]        {
    : g# ]( k" ~  s' M1 Z1 ?% h            DeleteArc(u, v);
    ) |& S! X& }0 |( _2 q- G        }
    ( d$ h+ E0 a# M' ]6 P7 E    vexTable[v].firstarc=NULL;
    ! B3 m* z4 f0 k" {) G/ s  g* }. R$ b3 e4 h4 E
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    $ r" o* v" o7 `3 M+ s# v) J( W    vexTable[v].data = vexTable[vexNum].data;
    + D( r" \9 t# d    vexTable[v].firstarc = vexTable[vexNum].firstarc;) I8 Q8 u3 x; A; l* U
        vexTable[vexNum].firstarc = NULL;! n' s0 r0 P' F. X2 q+ F$ C
        tag[v] = tag[vexNum];
    : ~6 M: d* T$ ~0 f    //原来与最后一个顶点相连的边改为与v相连
    % A+ u8 w0 C* y# H7 K8 [$ t    for (int u = 0; u < vexNum; u++)
    7 Q" Q9 Z- U4 C/ ^# I" x/ [    {: ]6 J' w! F& A. ]6 v: a
            if (u != v)
    / B% k/ |( a' g# E  _        {. E7 T  c, @3 ]1 h* I2 j
                p = vexTable.firstarc;
    4 s# b7 F* a4 u7 X2 ~            while (p)
    ( R2 Z* R6 C0 s! n4 H            {0 |" R0 m3 x6 t2 G; V. q7 q
                    if (p->adjVex1==vexNum)
    * d/ U" w1 s; T( {                    p->adjVex1= v;6 m4 p: i! [/ T( f: h& R
                    else if(p->adjVex2==vexNum)
    9 \7 g# J$ q. m! t/ k" @( F) v                    p->adjVex2=v;
    ' D5 `/ V$ n( }& i& G: I                p = NextArc(u,p);
    / ~& S+ d, T: I            }
    " ~$ @0 T; F" O; N9 T        }- P, Y1 `! w: q) f, \
        }
    # `) _2 r3 T; o2 }}  P5 m8 n" Y1 C) o
    ///深度优先遍历
    8 k+ H9 d; w5 P" a. _& g' jtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    & F( n5 ^& z9 c1 c& `1 k{
      _0 q% D5 a8 u1 B    tag[v]=1;
    ) \( J8 f9 C9 V3 }! h7 P' \" x2 j    cout<<setw(3)<<vexTable[v].data;
    5 _" j7 l- z0 N. n5 G% A0 P    MultiAdjListNetworkArc<WeightType> *p;+ {3 k5 E; C& h* T( N+ H
        p=vexTable[v].firstarc;
    , {+ D$ n" s& P( z8 E$ }    while(p)
    ( @# _4 p* {$ j8 [1 G1 U1 @* i    {
    8 d2 U6 s9 z! y7 [        if(tag[p->adjVex1]==0)
    # o& p, z# z) C: Q            DFS1(p->adjVex1);
    / k6 z7 l; G+ d        else if(tag[p->adjVex2]==0)
    ' }! X9 B/ Y& w7 ^. `            DFS1(p->adjVex2);% l  `6 [* \3 k# F4 E# T1 D9 Q
            p=NextArc(v,p);0 n% q( ?3 g  ?. a% R) Q
        }
    ! @8 g4 A7 O5 Q+ j}9 m( h5 b7 {7 D; x& m
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()% V5 Z" _$ p% Y! V& Q4 D' D* d# ~
    {
    ) h6 ~8 T3 T6 u* L0 k$ G6 `3 {    for(int i=0; i<vexNum; i++)+ ]$ W: |/ |! h. A1 i
            tag=0;
    1 O2 ]4 g! L# b! E( ^2 a    for(int v=0; v<vexNum; v++)( c/ C6 ^  \& X8 ?
        {
    ' N6 [0 k7 R- {( B        if(tag[v]==0)1 Y: {2 x" n, l. G
                DFS1(v);
    2 M4 E* X" R0 y- J4 g9 Y    }
    / E1 p# _, q' K6 m( q) K}6 s$ k, u* s# w, ^; G
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    ( {4 M% g8 l9 k4 Q1 Q9 H$ h{
    ; @( V, v; x& e) B    stack<int> s;
    ( q. F; r) Q0 q6 B! Q& z: V    int tmp;/ q; k2 @, S; {3 _
        MultiAdjListNetworkArc<WeightType> *p,*q;  o$ o& E2 f1 v3 A* ?6 B
        for(int i=0; i<vexNum; i++)
    ( O, q0 h: c  h2 l4 C        tag=0;
    5 B7 ]5 ^5 P  s( F: c- K& q    for(int i=0; i<vexNum; i++)# K8 B" U/ w# x- G! N& g( d
        {
    . M5 C2 w$ G- p& B% r        tmp=i;/ n, J$ x8 |9 k9 V
            while(tag[tmp]==0||!s.empty()); H3 {3 z/ z( s" `4 A
            {5 |1 G. k% U' f8 J; w) {
                p=vexTable[tmp].firstarc;
    : p9 r9 {1 V, ?/ |# o            while(tag[tmp]==0), a5 L( z  V/ P) Y/ J
                {8 {( V# t  ^, X/ F
                    s.push(tmp);" V+ I* R4 A3 Q' v6 ^4 E1 p& r/ o
                    cout<<setw(3)<<vexTable[tmp].data;
    ' Q  k* _8 U; I, T* h8 m! v9 j( R                tag[tmp]=1;$ M2 m3 r' C7 i* S9 f* \5 N
                    p=vexTable[tmp].firstarc;; b/ F6 R/ `. V# k7 _
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for8 F/ I. G. `' n
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    4 B* T- s) k& s                //cout<<" 1st     tmp="<<tmp<<endl;& A' A4 e7 u# j* P' A7 y0 f# L# V7 [) U
                }
    0 {, u1 b) g' u: ?: c            if(!s.empty())
    # O" S% m8 W6 F7 }6 h  ^. L9 m            {
    5 ^2 a8 x, X) A" {+ a% l$ \                tmp=s.top();
    . T% |+ N1 Y4 @% g. i; ?                s.pop();
    ( j' S$ @$ ]' O( y* I& w                q=vexTable[tmp].firstarc;
    9 N+ M1 d) I# f- Z. x$ o0 U                int t=tmp;* |( i, w3 l  A' L/ A. C$ p/ i
                    while(q&&tag[tmp]!=0)+ Z9 ^+ {2 u) U: E3 I) j& H; M
                    {& P0 ?6 l+ H, g1 D$ D3 a9 ]
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    - a* ^, f3 h/ K6 D' W                    //cout<<" 2nd     tmp="<<tmp<<endl;) _. K2 v5 _  X5 \, L$ Q
                        q=NextArc(t,q);' R1 L6 t9 b6 Z* k# A9 [1 c0 V, G
                    }
    2 Z, \9 W/ y- h1 n4 M                if(tag[tmp]==0)
    * p9 W, v, F. Q- L                    s.push(t);) _* S0 F# B* E+ H: r7 z- m
                    ///1、对应上面连通分支只有1个点的情况7 ?2 _3 R/ o* [* q! k/ @2 ?
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    ; z; b+ X: t% y4 F! E; e                ///tmp要么等于找到的第一个未访问节点,
    % r3 F3 r( P8 ?6 Z( X; ~                ///要么等于与t相连最后一个点(已被访问过)
    ( t1 j+ P* ]. n3 C: n( @8 }; i) {                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点2 H0 s3 C- s. i% m* B
                }" a/ x2 y/ S8 h
            }
    4 c9 s# j9 _5 {2 _8 U    }; h  Z  z3 |9 x2 h+ n+ L. y2 _! F* |
    }
    ; M9 _. w0 d- u3 c/ w//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    2 l# Z5 E8 Z6 p6 Z* p  ~. a$ J) }( mtemplate<class ElemType, class WeightType> int5 e9 d9 u4 v# m3 u
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)/ ?! H( i$ w# u- Z4 t: S* c' K
    {% c4 Q  a9 o) ~! ]$ `
        if(head==pre)
    $ S3 O4 I- v! g9 q% N6 [1 J6 \) C        return -1;
    $ g! p3 b' t: x( [2 f2 b2 U; U7 {" E. v) u
        MultiAdjListNetworkArc<WeightType> *p;7 r" V  ~: J/ i% Q% v
        p=vexTable[head].firstarc;! p, `6 S0 _: }; }3 c
        if(pre==-1&&p!=NULL)
      Y# k- c9 P* }& N        return p->adjVex1==head?p->adjVex2:p->adjVex1;1 @+ Y. S; \  K6 y; Y
        //pre!=-1&&p!=NULL& R+ c7 l# a: d8 I( e3 J
        while(p!=NULL)9 G5 W. p+ O9 `
        {
    9 [$ m" q) @% y        if(p->adjVex1==head && p->adjVex2!=pre)
    # s* {, b8 ~- |( p. g6 O" @            p=p->nextarc1;
    2 k. V* d0 O4 d3 Q& m        else if(p->adjVex2==head && p->adjVex1!=pre)
    ( |, E& @! P. K( {0 U/ L8 \# [0 J            p=p->nextarc2;7 F% C( g0 A6 |
            else if(p->adjVex1==head && p->adjVex2==pre)
    ) P  i" l' [% l6 h' T        {
    / T# N! G1 L; G  q* p) O            p=p->nextarc1;
    / \7 D+ c) ~! t( }6 c) ?            break;
    ' _9 v2 i* f( w" g2 |        }
    ! w7 C! o- I5 A  \1 M" w$ g' _        else if(p->adjVex2==head && p->adjVex1==pre)- k8 E! u) b, @( e
            {
    $ L6 V2 |5 F0 m( w5 C; v            p=p->nextarc2;
    7 Z. `& Z) y! A- B            break;+ y+ W* j! S6 ^, \4 A' I
            }
    $ \. [7 C. J# \    }. m' t" N% `% c  S
        if(p!=NULL)/ T/ n1 l/ D( R% Y% T- C
        {/ Y, X# f; {, ?1 Y% H7 T8 {- w
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    & {6 _$ H7 l. W1 u5 W8 ?# x    }9 w$ ^5 W$ a9 w: Y6 y4 V
        else/ G# S6 a. O: u& X2 E; t+ E: Y. f* A( V
            return -1;
    : D# z8 o& \$ d5 h}* P; G7 \! J" i( E/ L, b
    ( R2 B4 _7 Y- G& I7 k/ o- V% V

    5 C  Q6 H- N) ]9 itemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    5 ~9 k4 P4 K) w# `; \{
    ( m" B- Q2 y8 }  o5 ?    stack<int> s;0 E- O7 U( n0 F
        int p,cur,pre;
    : z0 R1 m) v( B' s. V: X' i* ~    //MultiAdjListNetworkArc<WeightType> *p,*q;( h9 D; K/ r) X1 p- f$ ^
        for(int i=0; i<vexNum; i++) tag=0;//初始化. e+ m! ~/ O  }# X7 l! p) R
    ; X. N( m( T8 M7 @6 @
        for(int i=0; i<vexNum; i++)
    + \6 M. |/ i% k, c    {
    9 ~. y& M: b7 O) e9 T% a; B3 V        cur=i;pre=-1;
    5 c* U& W4 ~! b# x; {# _. p, }        while(tag[cur]==0||!s.empty())1 S, `6 E8 S5 K6 h2 F
            {7 D; L6 g% `& H0 y+ B  a/ k- O
                while(tag[cur]==0)
    5 m0 a1 m& I: K0 w7 f            {
    ! S: o$ y3 y8 I3 L. D                cout<<vexTable[cur].data<<"  ";: ?8 j6 u& y5 u* _* e
                    s.push(cur);
    ( ]8 k, K* f' j. L                tag[cur]=1;4 Y0 @8 U* j0 o- b6 t- z
                   //初次访问,标记入栈2 P. i/ f( Q2 R% z  ^/ W# ^9 P

    8 h' h5 k& B% h7 Y9 x# K; W- g9 M! D               p=GetAdjVex(cur,pre);//p是cur的连通顶点7 [% b7 p0 T9 B# y3 n
                   if(p==-1)9 E* q$ A; E. \
                   {5 V9 d! o! |* J& Z
                       pre=cur;s.pop();# c9 r7 ^7 m, E7 C
                       break;- U- g4 a% E1 `4 k
                   }% @/ @0 f# A0 k8 P9 _
                   else+ S( h: s) A4 u- j8 A# p
                   {% h/ j+ }( b0 z* G8 f
                       pre=cur;
    " U: P# C( v0 r* a                   cur=p;
    % n+ G" R. l7 l  P               }
    4 [' [: Q0 {6 g& k% q* {  ]
    - @& p  g: \7 d# F, T# ^; n( c            }
    . ~: k, W  [4 G9 d% u. t            while(!s.empty())) g+ b; j3 |" k' v. R; g' D7 L
                {. P+ e" C& k+ g$ @) l: Q2 F  z1 k
                    cur=s.top();& N7 ?! ?8 ?- Y8 @( H
                    p=GetAdjVex(cur,pre);
    - b) Z/ K: x7 s                if(tag[p]==0)4 y. ~* G& G7 h2 \+ S4 @& y2 J
                    {. `# @  E1 @/ V1 C$ C$ w! s* k
                        pre=cur;( B0 l, c3 @! u8 H. q
                        cur=p;
    ! a# J7 o; |: I, l' H+ w                    break;  g4 B* L6 B6 |# D2 V+ o9 y7 X' T5 Q% j
                    }
    7 v4 V( V" {/ h7 u                else$ o) f. b" _- [. g; v! e: w
                    {
    2 ^; c, K' m) A  q5 R- R                    pre=s.top();
    7 j2 X& d  `. ~" Z                    s.pop();, A5 u& j6 e. I' V% L
                    }
    . E# g1 X$ ]+ k: V* s+ d# O$ q, N8 ~" N
    1 c! j. E& h9 q; [3 r' w0 a            }
    , V1 t( w0 z( }' b
    " L8 I: H( {3 c. l        }
    5 w( c+ ?) W- Z1 e  o% W    }
    $ e! P- O& \* l1 u}2 l! ^. V+ v' ~$ n' q
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    0 q2 q2 ~* l5 ]5 M7 o' O{
    & a& T* t3 o$ W7 J3 s    for(int i=0; i<vexNum; i++)
    9 e* t/ M! u( Q9 I        tag=0;
    ) A( ?1 `( M: V( C    queue<int> q;- _* ^7 [% k4 d& I1 d- f
        int tmp,t;
    5 M" T+ g& j# B: H. ~+ k0 p$ A    MultiAdjListNetworkArc<WeightType> *p;
    8 q4 ]5 s, Y; \- V, j# B    for(int i=0; i<vexNum; i++)# v6 A. I8 E8 _) d
        {
    6 q- ?' C+ h( `9 _        if(tag==0)! ^9 m& E  O3 j# `" J  Q
            {
    3 F3 ~2 _' D  U" ~5 T2 _; d            tag=1;
    3 V: M" d0 G4 V4 d5 i            q.push(i);: c, R" D$ f; C) g, f
                cout<<setw(3)<<vexTable.data;
    % t# B4 u! ]' p5 Y: W1 ]' j0 T! G) y        }9 M; O3 @: \% o' U; t, X
            while(!q.empty())
    3 d5 e% R* H! s: D4 O- u  U: v        {
    0 o! w% g! V# \+ Y4 v            tmp=q.front();
    0 e$ u- g" ]3 i8 Y& G) l) y$ p            q.pop();
    4 p  X! G- R9 E2 b5 C            p=vexTable[tmp].firstarc;
    + I$ ^: a( t6 T7 U            while(p!=NULL)  a0 d6 v2 s4 S* ^: \! s# V
                {  f8 v. U" ]# r* R5 g- F
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);5 a. _2 A% W% U4 d
                    if(tag[t]==0)/ E1 J( K* D% ^. c4 G( D, ~" ~5 [
                    {1 x, c+ j' I& D3 z
                        cout<<setw(3)<<vexTable[t].data;
    ! G8 i6 ]  l" A& |+ Y                    tag[t]=1;2 o3 O: t9 l+ H* F0 i; F# |! q' Y
                        q.push(t);
    6 c; m+ a8 Y4 p& \) B* M                }0 `! |! I9 q4 j- j
                    p=NextArc(tmp,p);
    * x7 J- E) Y& T            }" U! ~$ I5 ?8 x$ b+ G$ G  c5 ~
            }
    - O& |$ _0 [1 v; K    }) q  o& W5 j% M9 w4 N
    }6 y# ?# `( f/ r. X& j
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()* C7 {0 ?2 \2 c. x. ?
    {9 ~! D: F. O# p/ K) u
        MultiAdjListNetworkArc<WeightType> *p;
      C! d# E$ c$ E    cout << "无向图有" << vexNum << "个点,分别为:";7 W9 Y8 i. b0 g; r# O
        for (int i = 0; i < vexNum; i++)
    & J5 r% x0 s* m        cout << vexTable.data << " ";
    , t, o+ x* ]2 K! |; {/ b    cout << endl;
    2 j4 v& a- c$ |% z4 _) f    cout << "无向图有" << arcNum << "条边"<<endl;$ T2 H  t, h$ g, c  O
        for (int i = 0; i < vexNum; i++)
    6 w: i( }" r5 F6 V; M8 i* n8 f2 c) ?    {
    ! d  \# |; T' K" m        cout<<"和" << vexTable.data << "有关的边:";) d0 }7 o  n3 R# w* h
            p = vexTable.firstarc;
    + q, Q& c2 R. ~/ D' t' ^        while (p != NULL)
    7 S) @5 h7 d7 p; ^9 p3 C        {' Q1 z+ W$ P  O1 n, a6 B. T# q- J$ {
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";2 E; V* Z4 \% A6 U
                p=NextArc(i,p);
    3 Q" y5 F/ l9 x( A% j# K2 l        }+ O- m% e! b0 |' X! U
            cout << endl;0 @; x0 Q  F( {6 L' ~
        }+ u( K4 @. w0 u: T5 X7 m
    }
    6 \& T) ^) d( ?6 L- J/ A) h# f- l: n% P# i

    2 f, e) U" R  I0 W( L5 [邻接多重表与邻接表的对比8 Y  Z: V+ f4 @  ?( L6 v5 A

    4 G# y3 F' D- m/ V3 N3 T8 H. _3 M邻接表链接
    6 a& i$ b. U; U' P5 `4 m5 e( a9 j- I& a在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    ( X2 \& z2 f8 b7 r2 |; g在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    6 c3 X& v& h  I为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。4 D  ~8 i% h! W. Y
    ————————————————6 k' I# Z3 i$ r( I5 Z" r
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。) L# T8 _/ b5 M' h- }8 o
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958+ b- N6 {! ~$ R

    / P8 F+ t3 W* S5 S3 Z; r* e- A8 g9 k
    & E6 M  R& o/ j; z
    - x6 n: Y  \5 R( \! n  d
    ————————————————
    4 P  E# k3 p3 e; O3 h% V版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。; s3 H" O/ D% }4 r
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    * G" H+ F2 G2 ^* W$ k8 ~' V4 ~  I6 }4 Z7 w

    / q" W$ f( G# M' C
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2025-12-2 21:38 , Processed in 0.697201 second(s), 54 queries .

    回顶部