QQ登录

只需要一步,快速开始

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

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

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

5273

主题

82

听众

17万

积分

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

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

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

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2020-4-26 15:26 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    0 b: a8 A4 l7 O) I
    图的存储结构——邻接多重表(多重邻接表)的实现
    & i4 R) P. y6 I' s8 W4 n7.2 图的存储结构: K6 W" [$ K" O! V
    4 D6 x  M7 ~  S( M. c
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    , D: C4 H* y2 m& t& g& K邻接多重表的类定义
    : G  M8 Y; ?- T: P" e$ X邻接多重表的顶点结点类模板
    5 e0 p& }) z; {" `6 ?" {1 p7 x邻接多重表的边结点类模板
    * v4 k3 H! x0 e- G邻接多重表的类模板3 n7 i/ `+ O( @  g2 z2 l/ G! ~
    邻接多重表与邻接表的对比, n" }3 A/ G: [- y
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist/ p' V" b" ~( |9 L% H  h

    ' z3 ?1 Z; O4 }在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。" n3 H! R4 ^1 J# ^+ ~; f5 d9 t9 m/ @( M/ L
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    9 B- f7 |9 B  j/ m4 x! C' T( I! \1 E9 A
    邻接多重表的类定义6 ?$ Q' g) y3 V  u- e
    1.png # L" F9 T2 g3 h. K
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:0 O1 s* c; O$ Y0 L; ]/ \$ ]( {
    data域存储有关顶点的信息;) z* a, R% p2 D% D
    firstarc域是链接指针,指向第一条依附于该顶点的边。
    , u* V2 _6 g# K* p4 V所有的顶点结点组成一个顺序表。


    ! y+ E9 t  R; y6 [3 J2 x0 C8 |$ ]0 U+ T. B$ X6 g
    template <class ElemType ,class WeightType>7 y: u) b- i" h9 t9 f4 M: q
    class MultiAdjListNetworkVex& ~" E& n: N) n
    {
    : n6 |3 C. ^+ E7 U2 r- ?& q. o: rpublic:' l6 @. X- A+ j9 F4 q) {
            ElemType data;! I5 \+ ]. `, Q' x4 j2 ~7 a
            MultiAdjListNetworkArc<WeightType> *firstarc;
    . [2 V% ^8 ^# K5 D6 a/ `6 D" |3 m2 j/ J6 C# j$ [& Y4 _6 ?- C9 e. S6 m1 t
            MultiAdjListNetworkVex()
    6 A, L0 v, m" H# \        {, d% j% R2 E6 U. w2 S( I
                    firstarc = NULL;2 Z: H4 C" G4 e. H  \; T
            }
    * b. j1 s. u9 m! H4 [2 Y) ]1 r  M9 X0 K        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)* |' v3 Q, W) [. `. n
            {' T0 [. }; b1 l2 u4 A! z! U
                    data = val;4 i; V' h! e3 M' `# f6 q: j" @
                    firstarc = adj;; ~) N1 f* n* h" P$ J$ |
            }
    8 T& ?; b/ k% v& k3 Q& M};
    3 ]7 ]0 U5 {1 h$ [1 X( c
    , D' j- u2 b8 o6 _6 b$ F邻接多重表的边结点类模板8 r. ~1 x. ^9 D% T' f# i

    3 n# U# o4 k# O3 n在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:: a/ @# `6 w; B: K# Z% v/ }; p5 z
    tag是标记域,标记该边是否被处理或被搜索过;& u9 X" O9 I- K0 z: ]
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;3 B- Q/ p  ^1 p
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    , R) u: Z8 J2 E/ ?3 A. `nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
      t  W: s& _% }* D2 Z8 F( r( X' Y
    2.png
    ( ?. S) b1 a) \  s5 B. mtemplate <class WeightType>0 `4 D# I; I; _& p$ G
    class MultiAdjListNetworkArc; i0 C5 E. v. J' P* ?2 n+ r
    {
    % S! f% n+ t$ Z7 `1 Y7 Y( Gpublic:
    2 W  v: r: u0 b4 Y: C) e    int mark;                                       //标记该边是否被搜索或处理过
    ! e1 _; b  b" ~& J        WeightType weight;                              //边的权重
    1 a4 s  N/ q) y& L        int adjVex1;                                    //边的一个顶点
    & f* r; Q3 C: N& o( G        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    8 h5 W+ _. C: L$ d0 e        int adjVex2;
    ) A& s( R: F- G6 G4 T& J        MultiAdjListNetworkArc<WeightType>* nextarc2;. s8 F+ s$ m* A6 z9 E0 C

    8 N  i* \1 A" {        MultiAdjListNetworkArc()
    9 b, N9 @1 ^& o. I5 r3 [: P        {/ Q! z6 n8 n) ^+ q
                    adjVex1= -1;* r( }, k: J  Z+ x: I# g+ u2 V2 \& i
                    adjVex2= -1;. q9 P$ ^$ H6 t" q' J
            }4 J% H; u8 f* J
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)" X% u2 N1 p% I: l+ x" ^
            {
    ; r2 u2 z. r' a7 S- ~8 I! D2 j, v& x                adjVex1 = v1;       adjVex2 = v2;6 i( H  b/ c, S/ ^
                    weight = w;- x! k; `$ {( B. [/ Z$ K
                    nextarc1 = next1;   nextarc2=next2;
    8 B$ K; e/ J* V# F6 d0 X                mark = 0;           //0表示未被搜索,1表示被搜索过/ d. K! v1 _% n2 F8 G* M" T
            }3 S4 g! R- b1 R9 e- x/ b

    6 w( c6 b7 g& n9 {2 L7 P邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>4 \% r9 G. w9 T% b. ^
    class MultiAdjListNetwork% X  }3 W* j2 i
    {1 Q  c" K* q5 J1 S8 y
    protected:
    ) f1 ^3 F2 Z$ g    int vexNum, vexMaxNum, arcNum;
    5 m+ {, m2 o2 p( p& ]2 g2 [4 a# e    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    . o$ o1 M. V3 f6 }+ i: ^7 D8 d    int* tag;8 z: @/ O0 ?7 {1 Z( H- f
        WeightType infinity;9 V; }& g6 K& t+ V& N/ X
    . O* c& H; ~& [5 {
    public:/ C! w& e+ o2 G: M: F% J
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);5 x, Y. ?" {5 D" y& F$ u2 }9 q

    , u  Q" r4 g; p+ g) C    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    * R; x3 e1 w  n3 [6 C# ]* n: _% o2 T$ @# Y: T1 g: y, [  {
        void Clear();: O$ n% t% o9 i- m& l% P8 b
        bool IsEmpty()
    5 y( w/ Z1 W! ^+ \. Y    {
    - w8 M) j: a0 p+ Q1 q        return vexNum == 0;. q0 V! j" z5 ^1 ]
        }
    & z+ B# J6 b% a6 B. k    int GetArcNum()const
    ' s: m9 K: S  H' [2 h1 `2 F    {: n2 v; J' ]; o" X4 I5 x
            return arcNum;! [3 m: K6 @" o9 k, ]. f* w
        }$ V! g8 y4 d4 m4 [% u7 C
        int GetvexNum()const
    ) e9 G) F) E* v    {8 n+ O( [# c7 {% q! z
            return vexNum;
    4 e4 i8 D+ I* y: `3 `    }% F4 H8 x, Z- y9 Z  l7 k: a8 [. Y
    5 z' R0 K1 o7 V" E, b# h% }

    : Q8 ?/ M; w* [+ q    int FirstAdjVex(int v)const;$ U6 J8 b' E/ b" R& C
        int NextAdjVex(int v1, int v2)const;
    9 z9 R+ P5 w/ E. o. V) F- _    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;! o9 v; i) g$ W# I3 Q& O
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;( q  y9 \: M2 N6 o& t, e
    ) e0 B( ^% i, L- `! q
        void InsertVex(const ElemType& d);
    ! s: r. x4 r7 T! A! o2 a: t    void InsertArc(int v1, int v2, WeightType w);# X9 U: g" Q( ^1 `7 a: b9 _
    6 p" [0 r: I( d; ~$ K/ E, t3 X
        void DeleteVex(const ElemType& d);
    , y6 {& G: _6 c* i    void DeleteArc(int v1, int v2);4 [" w" H8 o  F! R, A* M1 N
    " P  k7 V& A  C& z# T* S
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);' n$ P% i) b; m4 ~9 a. A
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);2 @  F; q; P6 x1 u& Z7 c2 r9 ]7 z
    0 a* o4 Y/ }# Y' O' z
        ///深度优先遍历
      c6 c8 s1 `8 D    void DFS1(const int v);* _+ e* s/ D/ ?8 B
        void DFS1Traverse();
    + ~- ]. o8 M8 j    void DFS2();
    , J/ U$ \  d( \7 e6 [  l" T* `/ f
    * |. {. \0 ~9 ?0 B/ M; ^9 t    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1" y/ w% }, A/ p: ^1 _( w6 j
        void DFS3();; B) l0 V! r# z+ w
    6 \; @/ ]. F. B* }4 n7 `- k6 \! [' [
        void BFS();
    . @  }! d4 C5 {; P3 }( D0 M0 i    void Show();1 V$ U' z& M; J: o: b6 z) u
    };
    6 Q; C8 I3 g; k4 E9 K' C* R& U( X& _9 `6 P  o
    2.函数的实现/ N& Q. ]1 T% ^: a0 X2 f+ R* {
    研讨题,能够运行,但是代码不一定是最优的。
    3 x% F. r0 b( a$ ]5 W8 `7 W
    . E) D  c5 c( ]#include <stack>
    5 K% v4 y6 [$ d3 P5 @+ M; S$ J#include <queue>
    + J0 p) e4 ]. c* ^6 ]4 Q% u7 C; u1 G; n) \# {
    template <class ElemType,class WeightType>
    1 S3 A4 }6 q( q* M3 tMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)6 D& v+ A  V# ], f% I8 \  |1 b
    {! G* k( O: P! q$ }" c
        if(vertexMaxNum < 0)2 E. r5 Z) n0 v" @
            throw Error("允许的顶点最大数目不能为负!");
    # D) ^" f5 D5 e% w% [" ~! _    if (vertexMaxNum < vertexNum)1 X" `$ t( H& \: ]8 ]" n* H. Y5 R2 c
            throw Error("顶点数目不能大于允许的顶点最大数目!");
    ( y$ ~/ p$ k! D( N/ |4 ~4 O8 l, B    vexNum = vertexNum;; i& f/ }" J8 g1 A; Q& o6 O
        vexMaxNum = vertexMaxNum;
    : V. z5 Q0 m! T- U2 j  A! {! Z! d& M    arcNum = 0;* z1 d+ ?3 J/ T: w
        infinity = infinit;
    ; A( H  ?3 @( V2 z    tag = new int[vexMaxNum];
    , G) V) q& A0 f- n    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    ; o% f* `% k/ g$ V& n/ s  m, s    for (int v = 0; v < vexNum; v++)! t" r5 u# L, o. P6 A
        {
    2 v; }& ]3 `& q: X# c8 c        tag[v] = 0;2 U; b7 s7 ?. ~* S( C4 R3 |
            vexTable[v].data = es[v];
    6 R  n# o& G  k  N) M        vexTable[v].firstarc = NULL;0 X& b- i4 ^+ ^. t/ I
        }- {  e2 b* y! I0 |- Q
    }
    % x% c" q1 ]# m. v. Z" l' F. utemplate <class ElemType,class WeightType>* |: V; u2 I+ ^: B
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)0 ]( k; t- s  K6 ]
    {- [  w! U  y% ^( x) g) k. s
        if (vertexMaxNum < 0)4 M. L0 @' g7 u) k/ p
            throw Error("允许的顶点最大数目不能为负!");1 C$ v$ V5 n4 Q
        vexNum = 0;
    . m/ P  G" Z( [  c" Y5 k4 G( b4 [    vexMaxNum = vertexMaxNum;
    $ {! W# r* ]8 G1 G    arcNum = 0;
    % C1 q! I6 L3 v: E) y! w) [    infinity = infinit;
    - i" P0 H" q  Y1 Y) e  I! f    tag = new int[vexMaxNum];
    , u% Y5 y5 {2 x( Y$ i" \: ]# d    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];1 w4 Q  M3 r2 `1 I- [+ i0 |
    }# ?2 g! L. L3 X- r8 R+ [! T
    template<class ElemType, class WeightType>& A6 p8 J( w+ U/ G# E  m- q5 v) q
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    " I2 e5 x$ S+ k' p/ e, ^{6 M. @, b2 r: {
        if (v < 0 || v >= vexNum)
    + y! T- z) b5 V$ ]! j' z        throw Error("v不合法!");6 [( ?: l8 {& l/ o: P( x  H7 s
        if (vexTable[v].firstarc == NULL)6 ]# ?5 m/ `- q( F9 C
            return -1;
    * v& Y1 q6 |0 x2 O' |    else
    * d0 R+ T/ t& [* M5 l3 M        return vexTable[v].firstarc->adjVex1;2 o4 M9 @+ I, ?
    }
    ( n/ Z4 e0 h' l5 B+ q3 o
    , h  v( ?. |; y( H$ {template<class ElemType, class WeightType>
    ; Z' {8 Z6 c- D# e& eint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    * Q3 f8 @6 X# O8 b* b/ S{
    & S$ Q  y4 {- T    MultiAdjListNetworkArc<WeightType>* p;, T8 K4 M7 p. t; T6 W
        if (v1 < 0 || v1 >= vexNum)
    * Z2 `% [9 ~- }4 d1 F7 @        throw Error("v1不合法!");
    , c9 f- ?! ]1 s9 I    if (v2 < 0 || v2 >= vexNum)% _8 x  p3 y( c9 \  y! R
            throw Error("v2不合法!");% V& K1 B/ K! t0 D. y8 v* p) h
        if (v1 == v2)
    ) g7 j' P7 ~( t% D/ O        throw Error("v1不能等于v2!");
    / w4 k' F6 \  C4 ?* B    p = vexTable[v1].firstarc;
    ( D% K" e9 \/ O, ?    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    2 R6 c1 u0 ?% P6 N' Q4 Z9 X- [7 ]        p = p->nextarc;
    $ X# L. g% H: v2 J# @    if (p == NULL || p->nextarc == NULL)) d4 ]+ d' s) S9 S" f
            return -1;  //不存在下一个邻接点; }. l. S7 c# \: {' t1 n
        else if(p->adjVex1==v2)
    & R+ l3 |1 b, Y9 e: a        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);* W0 N! E5 N+ o9 t! R
        else
    ! a: |8 }9 f3 n8 U4 |5 w        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    1 `" F' c& K/ p. F- |: w9 D}, c3 Q' s& y* K: k
    template<class ElemType, class WeightType>; @/ E( d, b7 g3 O9 g( C  X! `
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()6 w) x; H; L* B- I6 |  q" w
    {  D7 e; ^( F4 r% i/ j: p
        if (IsEmpty()) return;7 ]( I% N5 Y# ?' W# I! _, ]( ]
        int n = vexNum;
    - V4 F+ X3 a* q; r) |% H5 Q    for (int u = 0; u < n ; u++)+ G; H- s# m. r2 q9 h* ?2 m
            DeleteVex(vexTable[0].data);  T4 H+ O/ I' e3 t  e5 T) K
        return;: |; E$ {9 l8 U8 \
    }
    / u$ M! K* N9 G# y6 X3 Wtemplate<class ElemType, class WeightType>
    ) J" G, o$ ~- n9 f% ~8 bMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    / {- h4 K3 A. W3 C0 U; f{2 u. X1 y* D4 C
        Clear();, H. c) s2 e! ?0 X! Q0 w
    }$ R4 {7 _) h$ j) ?* |* @1 }
    template<class ElemType, class WeightType>, D# n. E- z: I+ {3 c
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)$ t# O' |5 [' Y$ _0 L/ G) i+ M
    {9 w4 A- z& Y' g5 m4 A
        vexMaxNum = copy.vexMaxNum;
    0 f' \: b8 Q; ?3 S- v    vexNum = copy.vexNum;0 z' }; M: w- P& @- i6 Z* L
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];$ k" l* l. b1 b2 }- ]# B
        arcNum = 0;
    0 h% i1 ~6 W* A% _    infinity = copy.infinity;
      D+ Z7 b) i% ^5 j    tag = new int[vexMaxNum];' T6 i" C$ E; [  @% t3 a3 C/ n8 r" N' _

    " x; S2 [( E2 ^$ F( A& f    for (int v = 0; v < vexNum; v++)$ B7 Z7 I  T; [; \* Z* Y# ?( c
        {' ?. w: g7 y4 ?9 I* s4 _
            tag[v] = 0;: ~, D; c& t0 L+ m$ x6 S8 `
            vexTable[v].data = copy.vexTable[v].data;; f6 N. y+ Y8 ~: o
            vexTable[v].firstarc = NULL;
    / L8 d7 S# J4 p4 @    }  Z. x; ?6 A7 Q- D$ n
        MultiAdjListNetworkArc<WeightType>* p;
    : a2 C! [) M- |" b8 R; V5 Y' y2 y3 G( T5 m. m/ n
        for (int u = 0; u < vexNum; u++)
    4 K, A6 o2 @' d" l- i9 R    {
    / t$ S* |  ^9 s+ I9 K( ?/ f, U        p = copy.vexTable.firstarc;
    8 ^5 W; V7 i' ]% T. g        while (p != NULL)
    2 I0 I. O0 i& W7 f, M8 `, r" n; `        {
    7 R5 Y8 z& P! W# d            InsertArc(p->adjVex1, p->adjVex2, p->weight);& n* L' B% a2 k# N0 j! n
                p=NextArc(u,p);
    % V' Z* M2 W; Y5 H* F1 l        }, \6 G8 o8 {7 _& E! J' O
        }
    ; \& d2 q5 Y4 `: ^}
    9 |' N5 `, f% V7 |) U/ i4 y: etemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    : A5 {" g: x  P' @: B" h9 RMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    0 j1 _$ Z6 C" _: B' k/ \{* q8 `' n1 d# v( x/ e& }% m
        if (this == &copy) return *this;, C5 P* h2 w( z) Z9 D, _+ I4 x. F
        Clear();2 ^3 B6 Y6 B- |$ j
        vexMaxNum = copy.vexMaxNum;" b3 D0 f9 p3 i0 {' K$ ]
        vexNum = copy.vexNum;
    , c4 M' V0 @. Z( N- E5 \$ M( l; o    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    3 e# p: J# [/ u; f. r- ]7 o9 k$ T    arcNum = 0;
    0 r% p. y# c3 i# C3 i+ e    infinity = copy.infinity;
    0 t! @1 R0 O( w2 N    tag = new int[vexMaxNum];3 A9 T% r/ }/ D6 f- E" K+ K0 b
    " e* {# T, A7 P# L$ v" ~
        for (int v = 0; v < vexNum; v++)5 I, e: _  e3 u. A! N5 m( J+ e
        {
    : l4 m5 @% y0 z( @1 I5 t        tag[v] = 0;( [5 u; y" G$ J* q& Q3 i  P
            vexTable[v].data = copy.vexTable[v].data;( P# G! q0 q- f" v$ `- f
            vexTable[v].firstarc = NULL;" a, v2 y$ J6 s% y' M  Y
        }* C/ z0 z3 d& D  J
        MultiAdjListNetworkArc<WeightType>* p;
    $ t2 `; K: @3 i" J. G, A- {
    9 D9 }! H+ P" i7 g    for (int u = 0; u < vexNum; u++)
    $ v8 S% D2 q& e' |* u    {
    ! B+ T- ~2 J1 ?/ n        p = copy.vexTable.firstarc;$ N6 q- p/ o, `9 v
            while (p != NULL)+ ]: M) z' {, ]$ z- e  J
            {
    & U8 Y0 J' d- M5 E: V# x5 S            InsertArc(p->adjVex1, p->adjVex2, p->weight);% i! e$ m* ~0 Z. P- n; U8 u
                p=NextArc(u,p);& |/ R0 b6 r5 s& U3 J% Y
            }
    - D$ E- i! C7 ~  e# E+ P! e    }
    7 C7 y" D8 _- v* i, w/ Z    return *this;
    8 o9 X4 C6 ^# S8 }- }& e}3 }) Y/ F* z6 b
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    : o+ b9 ]  W) F* u# oMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    % j, `4 [9 D' I/ q{) t, Y! i9 E' A! V! g, A; r
        if(p==NULL) return NULL;
    * v4 o5 u3 t- X* T  ^; L# T7 h    if(p->adjVex1==v1)* }$ ]7 q7 `3 h) S4 W9 U
            return p->nextarc1;$ p! A: m3 C/ E0 C/ }8 X
        else! ^3 M, a6 M% _% w0 L( w2 V
            return p->nextarc2;" J- m& r2 X* x1 ~1 T2 x! h
    }4 t- u& q+ H% o% I# l
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    * c# C* c+ E- P' |, OMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    5 N( U0 K: k6 A8 T' {/ z: }{- Y1 g9 K* i4 `$ X4 R
        if(p==NULL)return NULL;; B* U: Z( [* N. g8 U7 p
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;! d$ L. K+ A1 H) L6 B& u9 p8 W
        if(q==p)1 |4 d- z* j, c+ v
            return NULL;5 F7 y# U' V& G
        while(q)
    * {5 z8 J! E. l/ ~    {* \' d. F; \8 r& Y8 t3 L
            if(q->nextarc1==p ||q->nextarc2==p)
    ' p3 L4 u/ E+ e            break;
    # f" `) F3 I, J7 K. g        q=NextArc(v1,q);: x) s9 r. E2 y: y5 S; R
        }
    2 l! `8 F$ v9 z8 _% H5 _  O, u    return q;
    $ N' z% m& O) g8 v* s; I& J}
    / `1 A6 v* m, ], r0 w" Stemplate<class ElemType, class WeightType>% p; E( r0 |) P1 q
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    ( w+ R5 f" x3 t. @* M( W9 b9 q{
    , r' f2 Q6 g/ ^0 J+ K# `    if (vexNum == vexMaxNum)7 o/ q) B  c/ H9 ]
            throw Error("图的顶点数不能超过允许的最大数!");' u8 R% F# A; ~$ Y# k2 ^
        vexTable[vexNum].data = d;# d, K$ A8 B; w
        vexTable[vexNum].firstarc = NULL;
    , X: R9 r+ X6 V3 i: w: k6 R    tag[vexNum] = 0;
    ; |( A: l, Q/ J    vexNum++;
    0 U2 B8 S* y' w3 F% ^}
    4 e. o- D# I% e0 i; Stemplate<class ElemType, class WeightType>' P; e% k1 Z: }  a8 V  B
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    5 J2 H7 D/ v/ [! h. K, Q4 _5 D{
    5 k9 _8 S* d' ~% f/ M4 w2 @    MultiAdjListNetworkArc<WeightType>* p,*q;# m6 \* O! n9 b% M
        if (v1 < 0 || v1 >= vexNum)
    . L! l; q: F2 l; X2 D1 [- E' h        throw Error("v1不合法!");
    , [- X. ?8 e+ @& u4 T7 F6 ^    if (v2 < 0 || v2 >= vexNum)
    # Z- Y# C' W9 e% O1 O4 l        throw Error("v2不合法!");
    1 |' N% |2 m) f: X9 Y. M    if (v1 == v2)  D  B5 F+ b9 {+ J* o
            throw Error("v1不能等于v2!");
    ( n# a$ d' N# T& k    if (w == infinity)
    * A" p4 e# X, k% B1 n  U2 \        throw Error("w不能为无穷大!");
    4 b$ H0 X! x/ E3 a$ S  r* U/ y* Y) J- W
    ! @5 P9 k- B- }3 u
        p = vexTable[v1].firstarc;$ `3 e3 c" r6 r* \8 j
        while(p)
      J% @, a6 X# Z; \6 V3 N- M2 ?    {
    ; _) D* Y6 c8 O        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    4 ?4 S& k( t# k2 I/ f3 X1 b  v) B        {
    4 Z3 F# q2 e; j* k  @  d            if(p->weight!=w)
    9 Q! l7 E( G: ~7 z                p->weight=w;
    3 M$ u# ^" G1 N            return;
    7 _' v# V; I  ]        }
    " Y9 t, o% S1 i4 |& h: U
    6 E" J4 S! D5 D$ r4 ~9 k6 `* l        p=NextArc(v1,p);
    - c  w- ^$ V# y/ ~0 m6 j: U    }
    + I4 c4 q& B- D/ `, r    p = vexTable[v1].firstarc;: z7 g! }$ ?* i( o# I
        q = vexTable[v2].firstarc;
    ! m2 K( Q# M: |6 u4 g7 z/ P    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    $ q+ z6 o3 a% R    vexTable[v2].firstarc =vexTable[v1].firstarc;
    . _. T5 _6 f, J; x, `    arcNum++;1 _; I: k, ^% \: w  S
    }$ k& c% @* o& `& T8 V$ o

    ) G" Q9 q/ J$ C2 m  l8 O! v5 |template<class ElemType, class WeightType>
    # J8 @) E) `  C1 V; Y% a1 L$ X9 e2 ivoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    ( R8 s- Z$ G# Z{
    2 q8 C/ ^; ^5 V4 `9 a4 {) ?, v! M# V
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    $ }' ]- g# \+ }$ |7 R+ K  i0 T9 Q3 ~# q    if (v1 < 0 || v1 >= vexNum)
    2 H. ~1 R0 d% r6 H% ^        throw Error("v1不合法!");0 ^+ s7 U4 J! D5 U5 {2 o, U% j+ K' V
        if (v2 < 0 || v2 >= vexNum)5 e' [! D" w1 V1 n/ Y
            throw Error("v2不合法!");1 ~, _( m2 d& J/ s% Q: K
        if (v1 == v2)
    0 f" T7 c7 r3 K# N; Y" q. t0 |$ J        throw Error("v1不能等于v2!");* |7 b+ N# k. Q1 {+ k
    3 e2 a4 i- }( E6 ^
        p = vexTable[v1].firstarc;. r/ l. X* E- e4 V) @3 m7 `
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)( ]0 I+ D5 J' h* @) `# s, o% S
        {0 E9 z+ a# _3 N/ p2 o
            q = p;8 ^( D$ D9 q' F: b
            p = NextArc(v1,p);( F& k' w/ i( }! a8 ~
        }//找到要删除的边结点p及其前一结点q9 b' m6 h) x  Q1 x
    0 H7 I& m6 B0 Q0 w- L2 c: u5 O) e9 S
        if (p != NULL)//找到v1-v2的边
    - `( N! E5 @; s% y& s    {
    4 o! A" s% S. u        r=LastArc(v2,p);/ m2 u3 M/ c: h/ C
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    / b3 }; p/ h& _& X: R( V5 k            if(p->adjVex2==v2)
    1 A1 J4 Y' _8 W: v* N5 G5 d                vexTable[v1].firstarc = p->nextarc1;
    , s- F( O' V( X9 w" c, E3 c" `            else vexTable[v1].firstarc=p->nextarc2;, F/ ]! q' F. i5 t
            else//不是第一条边
    - Z; F  d' ]- }/ X4 m        {/ F2 q8 m& W9 P6 T
                if(q->adjVex1==v1)
    1 g) }. ^* W) E" z$ Y                q->nextarc1 = NextArc(v1,p);9 i* u9 M* v8 H$ b* W
                else
    8 d& O4 Q. f  r                q->nextarc2=NextArc(v1,p);2 ?5 d0 s% [- L6 E* D2 g" R# T

    / u9 G9 M" h/ G+ l        }
    . B3 N6 j& m  Q! ?0 r        if(r==NULL)
    1 _+ ?% V1 T( S: _+ J+ M0 s3 k            if(p->adjVex2==v2)
    & F+ G9 C  z/ k! C8 s                vexTable[v2].firstarc = p->nextarc2;6 f7 R* @+ q5 A# O% T
                else vexTable[v2].firstarc=p->nextarc1;
    0 L6 r/ s7 b( m! _        else5 b* o8 m% v# f1 ?
            {% H% Z# B% G$ t* d; ?  s
                if(r->adjVex2==v2)
    . j" F: v6 B# T8 Q2 P) a. h9 N                r->nextarc2 = NextArc(v2,p);
    3 D& l' [8 N% a            else; w3 P. N$ p# r1 z
                    r->nextarc1=NextArc(v2,p);
    2 x) P7 s* u8 [! O" I        }7 |% [  K6 m/ }' |; V
            delete p;: l; f9 |1 s2 }$ m. w
            arcNum--;
    1 H$ ]3 S8 g: A1 n; _0 h( I    }
    4 [; T& Q# O2 I  k
    & o% H+ Y0 ]/ W) ?: \/ R! L& q3 d( H2 r}
    1 t5 N$ L  U1 N+ Ptemplate<class ElemType, class WeightType> void
    6 r; a* N8 f/ [6 e& `MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    7 O) `4 Q0 g: s- t* Z{' F: d% k% Y( z
        int v;
    2 i+ ?0 H% x  y& Q    MultiAdjListNetworkArc<WeightType>* p;
    9 ]# J" ?9 P% s5 a    for (v = 0; v < vexNum; v++)//找到d对应顶点! x  `; t$ w# ~1 k& ^8 ~
            if (vexTable[v].data == d)( b2 v* V% y; N& s% b( e
                break;
    " @* F2 l9 G" G+ q2 x    if(v==vexNum)
    9 ?( x" C% a/ M' ]        throw Error("图中不存在要删除的顶点!");
    7 c8 T7 {) D, p' L4 ]# C# k" b* m& M5 w" {1 g% t7 D& y
        for (int u = 0; u < vexNum; u++)//删除与d相连的边9 M) h% K& f( O- N
            if (u != v)
    . D# ?1 F$ G9 k+ h        {, {1 z4 ]" f4 `1 v, v& }& L* C1 A5 ?, W
                DeleteArc(u, v);
    * |! L( J! G+ f% p6 h        }7 ]( i3 ]' Y* L4 }
        vexTable[v].firstarc=NULL;# y0 u7 ?' m  r$ Y/ s" v' t
    " j0 D: B% g' n! X$ ]
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    $ t6 H. a; n% m    vexTable[v].data = vexTable[vexNum].data;* i) V# F: E2 a
        vexTable[v].firstarc = vexTable[vexNum].firstarc;* {- L0 u& E- o9 S1 l0 J5 m
        vexTable[vexNum].firstarc = NULL;# W: B  Z# S$ b( M- {# a
        tag[v] = tag[vexNum];" D! c% h" C* Z$ O- f& |  ~
        //原来与最后一个顶点相连的边改为与v相连. W% }. U( E3 S) X* W5 J3 T
        for (int u = 0; u < vexNum; u++)
    1 i0 ~$ C$ q, |7 q# b    {4 J  a9 u9 R& I( `& F) I! d- T4 z
            if (u != v)0 w0 b( T; _* e3 d5 [0 L: A
            {8 n0 C5 ^' i* U7 u7 T& I
                p = vexTable.firstarc;
    6 Q) q/ b8 T: R- O            while (p)# @/ V. r# x7 Z6 H9 }1 H
                {
    " d4 x# y- s- }1 e3 m                if (p->adjVex1==vexNum)
    6 _6 e. J7 X; h                    p->adjVex1= v;
    7 K% K6 s; i2 n- A' [& e5 z3 d                else if(p->adjVex2==vexNum)
    , X$ Q$ C0 B# A$ z! U/ f                    p->adjVex2=v;: s! Y  U. }9 G
                    p = NextArc(u,p);4 N4 n$ f/ a5 l2 a: p. b# G1 |
                }
    0 `$ S& \5 p5 V3 g5 ^7 L        }4 Z; E3 O7 _3 w* P4 ?- n( ^
        }+ b1 q: y8 i- ]
    }
    3 i) W+ i: D+ S4 P8 A///深度优先遍历. L3 v, J$ P4 e8 X" `$ v
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)8 d1 f% X, g3 N! T( l" n
    {
    ! I3 ~8 U& [+ _3 k$ D9 m: s5 w    tag[v]=1;
    7 t/ Z" k' G) x+ ^" ^    cout<<setw(3)<<vexTable[v].data;1 y0 q5 [9 P" s- e* [* F6 C
        MultiAdjListNetworkArc<WeightType> *p;: x! C5 J2 N% ~( I4 w- m9 k: R
        p=vexTable[v].firstarc;
    6 D3 L/ q  B7 q9 s6 Y    while(p)8 P6 o% W# E- u
        {
    ( D8 T& n1 E6 d6 G7 w        if(tag[p->adjVex1]==0)
    ) t5 D2 q: i% _" l            DFS1(p->adjVex1);
    ; W- F3 x7 {( A. I* H% {  K        else if(tag[p->adjVex2]==0)' Q5 Z: M+ M/ u3 n
                DFS1(p->adjVex2);
    , c" ?: V9 ^5 F# x        p=NextArc(v,p);0 j  ~( h8 E9 a  I2 v( h& Y
        }
    0 A, h8 P7 }/ v7 |; u% [}
    2 z6 {- N7 O- s3 k5 I2 Utemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    ' K" t9 m8 y: V7 L{/ {$ H( M& L8 F% T8 w( p- ?, H$ j
        for(int i=0; i<vexNum; i++)
    7 G6 X8 I+ |, }% E, T6 g        tag=0;( y" g. a( L* o7 O1 V( k
        for(int v=0; v<vexNum; v++)" g, S4 k: G$ m
        {: `5 _$ K# @' S# a' V
            if(tag[v]==0)
    ( ]; _) |9 R. K7 j% |            DFS1(v);; m& U2 Y7 ]1 O/ s1 k. l( V2 r7 v$ x
        }" ?2 `& L  b5 l( z8 O- X
    }2 b' F6 k6 \& R, N5 h- H
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    * V  |8 y' H  A% M" q{3 J1 ]( n  N; W/ X( x8 R% N
        stack<int> s;3 _) [1 R( s6 P+ G
        int tmp;; X: u4 M1 q/ T- T) h/ `) `+ D( {# o
        MultiAdjListNetworkArc<WeightType> *p,*q;+ _5 e# G+ t' K/ z: M/ l
        for(int i=0; i<vexNum; i++)# t# @" P: M# Y2 E
            tag=0;0 _+ ]% h! K. F4 y" |7 g+ H
        for(int i=0; i<vexNum; i++), I- t2 V9 S+ x8 T  Z5 k1 y8 P
        {% p! g3 i. B) v
            tmp=i;0 a& \# b' E! h3 O4 {  t$ F) x6 O
            while(tag[tmp]==0||!s.empty())
    ( U0 `5 }1 y0 @: |$ g& a$ G        {
    & g, V0 c8 s5 u$ g. s+ U            p=vexTable[tmp].firstarc;
    7 H3 [0 |2 ]2 d8 v            while(tag[tmp]==0)
    4 H0 h4 p( k# F4 R0 Q# c6 K" J$ Q6 E            {/ u& H" Z, [- m8 L: p: ~5 w" G/ ~- f
                    s.push(tmp);
    ' j8 t$ {4 j! I& H$ `8 g8 J) {                cout<<setw(3)<<vexTable[tmp].data;8 a8 z: Z: E$ e0 n4 H+ x- ?
                    tag[tmp]=1;
    3 L0 e% s6 }0 [. u4 \1 v                p=vexTable[tmp].firstarc;
    5 L! F! z# F% F9 l2 C% {0 x# ]                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    4 P% V" V% ^; ~' J* R# S: K) `                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    2 Z$ Z- w& K8 k, |+ s                //cout<<" 1st     tmp="<<tmp<<endl;- |' x4 y/ w, H
                }0 P( \: k6 H: R1 U" Z: ]
                if(!s.empty())
    * Z" w; J! \' n4 c' N            {
    ( o  _' G+ {) S6 U+ Y& n/ [                tmp=s.top();) K* J. W2 s4 c% `7 l
                    s.pop();0 N; R$ E/ N. i. j
                    q=vexTable[tmp].firstarc;4 S% {$ W. W5 P/ A# P% m
                    int t=tmp;
      K3 r% A& m# J! L0 e! h* s                while(q&&tag[tmp]!=0)0 }6 c) P5 H$ ]7 b8 g' [9 o- f% `
                    {
    - X( S" F! s* l3 L; [                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);- t: @9 l$ X$ a  ?' |& e4 f
                        //cout<<" 2nd     tmp="<<tmp<<endl;9 |& x! e. g" L2 X: [/ t
                        q=NextArc(t,q);8 t1 [6 k: Y0 `3 ^
                    }( `  y: `2 g# L$ m8 z! a, Z4 O5 F4 g
                    if(tag[tmp]==0)( H1 I$ ?' k7 F9 V5 x3 t
                        s.push(t);
    3 \( H9 C0 u' J" e" H) k: S                ///1、对应上面连通分支只有1个点的情况
    7 Y$ b% V2 Y3 c3 u, I1 `                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    - `! E0 w+ ^, \5 v                ///tmp要么等于找到的第一个未访问节点,0 L- L' t# X2 I: b- ^
                    ///要么等于与t相连最后一个点(已被访问过)3 P; O4 y4 ^0 j# E& w/ n
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    , J" Z# v1 v% y: R            }3 i3 b9 _5 f, y+ }; Y
            }
    1 ^: @: X( U! c! e    }% ^) p4 {* m: c4 k
    }! _0 I$ O# B# O7 {2 k0 e
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    : \) W6 W  q# |+ F: f) {1 jtemplate<class ElemType, class WeightType> int& U' @2 S' E  J" C- @6 U7 b
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    $ x$ y  k1 l& M3 s2 ?9 F; [, I{
    2 U/ U" F: H( H    if(head==pre)5 n4 f, s2 G% F3 a$ L3 b
            return -1;& e' [9 g7 P; H" U

    6 A) |6 ]' C& w    MultiAdjListNetworkArc<WeightType> *p;
    / z8 q" V8 i+ I" n: `- ^    p=vexTable[head].firstarc;, M8 F6 E$ ^; ]  [$ K6 J' J& N
        if(pre==-1&&p!=NULL)
    2 f& P: U, Z. C$ Z8 y        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    ! z; j: M, d  x( w2 i! |/ v: V    //pre!=-1&&p!=NULL! }/ s( W, C- C' \/ V! {
        while(p!=NULL)! x8 A  T: c6 k! J2 x5 y$ C
        {
    . J9 ]! @- g  k: p5 o7 m5 ?2 q* J        if(p->adjVex1==head && p->adjVex2!=pre)
    ( v$ o9 m$ o$ t+ h# H0 {            p=p->nextarc1;
    : o- u6 e* Y8 Y, R2 L        else if(p->adjVex2==head && p->adjVex1!=pre)
    6 }. E( {) r3 Z& T5 T. h            p=p->nextarc2;3 J! z+ u9 l4 D1 n2 ^# o0 Z
            else if(p->adjVex1==head && p->adjVex2==pre)1 Q( Z: c- E$ n0 j
            {
    ; W  v- \  x5 x6 ^$ k            p=p->nextarc1;
    ! j/ S# N  m& F0 g# ?% J4 D7 U/ m            break;/ y5 B* |# ~, m% V/ H. L/ U
            }) I! G, p3 z% k+ v' Z3 O* P
            else if(p->adjVex2==head && p->adjVex1==pre)
    9 t/ _& B: O& d# L5 A6 ]        {" p  z& c: U* a( a- l
                p=p->nextarc2;
      H/ q- p0 l1 w9 q            break;0 z  U0 a# @- D- ]- `6 z0 V
            }
    # ~. v0 ]# X! q0 H/ K    }5 W4 X" w8 z) O
        if(p!=NULL). Z2 Y' y5 o3 r0 _
        {
    , B0 N, m; ]. I        return p->adjVex1==head?p->adjVex2:p->adjVex1;  R4 ]* R2 u, ^5 z
        }$ o0 @1 S  p+ |/ m/ T8 l4 j
        else) v* W( s2 m$ Z+ w5 l
            return -1;0 A: z8 D0 `, G7 a2 z9 q
    }
    5 A4 u8 l  b- L/ Z2 f; E4 K7 k2 O4 c7 S3 Z

    0 r; e/ o) D* F, J! ~template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()5 Z# q( H3 z* i9 E
    {8 K4 n2 n! k( C% ~
        stack<int> s;
    & \2 C8 T7 x8 n* j; p/ ~    int p,cur,pre;
    $ s5 ]7 {; {& d$ u. n" C    //MultiAdjListNetworkArc<WeightType> *p,*q;
    5 [$ z/ q0 G6 T    for(int i=0; i<vexNum; i++) tag=0;//初始化
    / L3 c, k3 i1 o6 @6 z, _' Y7 e9 Q0 y2 p  V
        for(int i=0; i<vexNum; i++); g2 o: U, j8 d! m+ Q9 u9 q
        {! o2 R- |% _' V0 x" P9 Q; d
            cur=i;pre=-1;
    $ z$ k0 I" x, W! r" ^/ S        while(tag[cur]==0||!s.empty())5 `/ l: A8 J6 v
            {
    ; r0 g. }5 ]* O            while(tag[cur]==0)% _( S: |4 ^/ {, S5 p
                {
    2 c) Y# [0 q( c, Q                cout<<vexTable[cur].data<<"  ";
    ! w2 F& q& N! W                s.push(cur);
    6 T' o6 F5 d. |4 O& {                tag[cur]=1;
    " |7 l, o3 }6 ?5 Q+ B               //初次访问,标记入栈, Y# A- z9 ~/ D0 C- G& |

    8 ~% o% Y, `5 |6 v1 m3 g3 ~               p=GetAdjVex(cur,pre);//p是cur的连通顶点
    ( ]. R8 O6 _% x% O, K               if(p==-1)7 Z1 }/ O/ g2 O" e
                   {
    % l8 S* S* E2 G7 x* ~3 P                   pre=cur;s.pop();
    $ M5 {7 Z. y# R$ ]. R                   break;
    8 Z  s9 A& t8 W. ~6 [8 ~6 h, E' _  v, z               }4 R( s4 [. i5 S: i4 d. N
                   else2 o, X! l# ~5 \+ @
                   {2 q$ V3 |6 Y- L3 ]7 w8 R) Y/ S3 M
                       pre=cur;
    % F: h+ T2 t1 ^( N5 L5 F' c  p                   cur=p;" f+ d. T6 E* `& y0 |4 m9 Z
                   }
      L) u' k9 f6 C# N; w
    & l, s1 y, d9 \) B# c" f5 P6 ~            }* [5 t$ i( O5 o2 G( ^& {
                while(!s.empty())0 x. X2 Q% n, C/ Z
                {+ g& q" R  `" z3 _
                    cur=s.top();% E- Z9 U  Z4 Y$ |+ p5 b
                    p=GetAdjVex(cur,pre);
    ! w  E0 _6 A4 a+ ?2 d# o* D                if(tag[p]==0)
    1 M1 H) }6 {( P& {                {; p/ a5 ?  y  D: z, Z/ x
                        pre=cur;
    0 c: l. x' M! {6 D$ H+ H& l                    cur=p;* x; ^/ B; p0 l
                        break;
    & v6 B( h6 g7 S) D1 X                }9 k+ D, \" Z% [, @8 ], q' `
                    else
    4 m4 B0 A  f9 D                {" D) ^0 m0 A7 j
                        pre=s.top();# ?2 i! w- Z9 I+ i8 k
                        s.pop();1 W  o( w/ S1 B  b- U
                    }
    3 [; S1 X  F, u8 w  `$ h& K! h
    ! z$ s, |( E5 F' V            }  S7 O4 M' q1 v" P2 v) }
    7 s9 C, t) D5 }$ {: c
            }1 L0 R0 ^6 S. I1 n. y
        }
    / C& b* a# g$ C4 r$ X}
    7 T  O. u" B. }3 Stemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()# K6 i7 |% Y5 Q7 q2 ?4 g
    {' U3 w/ t9 f# b! k
        for(int i=0; i<vexNum; i++)
    " e4 h0 O& r' [" W; a  s. a        tag=0;
    ( \/ u% [* @8 a1 G- E    queue<int> q;2 R: P8 s+ c1 ~* x
        int tmp,t;
    " O0 @) T5 @* C* b* O$ G4 \2 L8 P    MultiAdjListNetworkArc<WeightType> *p;
    " W! A5 }7 u# V0 T7 c+ j% {9 j1 e$ @    for(int i=0; i<vexNum; i++)
    " \1 ^/ ]$ L. S, e2 S) ?4 o. Y! {    {
    / P7 S' U, y, M' R        if(tag==0)
    6 ?$ J! v. e) h& E$ n        {
    9 m, H4 ^+ M: V3 F# b$ U            tag=1;/ G+ ]2 Q$ {$ a& a
                q.push(i);$ ~6 t/ n- d$ c$ F+ t
                cout<<setw(3)<<vexTable.data;  f: a* ]7 y) b8 _0 l6 y) C
            }/ w) l- k8 K" G& `' H
            while(!q.empty())
    ) m) z4 q# c# S        {  I% s. U! D- J2 A
                tmp=q.front();1 [# h) Z" I6 ?7 ^
                q.pop();1 C+ @: N. p& {  g* @
                p=vexTable[tmp].firstarc;* V3 f0 @6 }3 J0 e7 u3 C
                while(p!=NULL)
    , O! D, D% |. x5 M5 Y& I            {
    7 C+ \. c( Q/ r: y2 i                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);) U* K6 M( X8 A2 U, H
                    if(tag[t]==0)6 w8 Q, X8 N6 G, _! t0 z
                    {3 D. H% `! A% u4 B) ~. l/ f5 J
                        cout<<setw(3)<<vexTable[t].data;5 C) N% Q& M7 V  R
                        tag[t]=1;
    : @+ J9 h# Q" b- w                    q.push(t);/ h3 j" R& H  ^- S8 u- c& U' p
                    }
      x4 Q* q9 ~! `' v7 }$ |                p=NextArc(tmp,p);
    % t% Y6 b# K/ u1 L1 m! X2 k            }2 F4 F$ P, _- m0 x
            }
    ) }) r% ]" r7 q" g, ~    }# |4 v; b" _2 `1 d; t
    }
    - K. y5 X  I* b) w& x& S3 A! L% p* stemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    : U4 N2 b% Y- P$ `5 u4 Y3 q{( {' u: O4 k1 s+ D. i- K. v4 r% N1 Z
        MultiAdjListNetworkArc<WeightType> *p;
    : D6 @# o9 u! f& H    cout << "无向图有" << vexNum << "个点,分别为:";6 |* ^) O- `) k
        for (int i = 0; i < vexNum; i++); Z6 J% i/ K8 e6 p3 A( }
            cout << vexTable.data << " ";, M: H0 K2 x' B8 ]# E) ]1 h& l
        cout << endl;7 B& B. A" c! v# O0 H7 V# w
        cout << "无向图有" << arcNum << "条边"<<endl;1 b# i3 a. ]3 Z4 d- |5 l, V
        for (int i = 0; i < vexNum; i++)
    3 [! ?5 x. ?+ G! i: p" \    {
    5 T& E1 R5 v2 |. \( k' h  p7 A, R        cout<<"和" << vexTable.data << "有关的边:";5 Q8 x: L% n$ s1 V+ S  s! R$ A
            p = vexTable.firstarc;
    ( @! I' H8 G) n: i$ R3 f4 A        while (p != NULL)
    " B! w! I3 {- ]0 M+ n, S' R: J        {
    . E' D/ H/ |+ h$ _- D            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";7 c' H. h" Z9 r- W
                p=NextArc(i,p);
    6 j* W; _, }9 H- H0 g9 K        }
    1 Q$ k* K. V/ k" B        cout << endl;1 F  G, o( f8 m* q! T; p& j7 o- ?
        }
    # B- s; a: u1 H7 P  v% @}
    ' A# N( d: a3 j9 g2 r& ?- j) z  ]& B$ t; ]. L# B

    ; C$ l& p$ @+ N. o2 Z8 p; B邻接多重表与邻接表的对比. C& e- F+ U4 v2 r

    . ]1 N& \! S; j( C6 |5 l邻接表链接8 o+ }- C. ?, I  G7 q2 W7 F& M
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    ) z% R0 ]$ @- n7 @在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。+ S/ {# [. r0 T! t$ D  C
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    1 o# z' N* B9 l9 C/ p& `————————————————
    , r$ G& S) o7 _+ q5 p( q5 w. s: z版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。6 n* _8 ^% y6 ~5 o+ ?# G: e( {9 u
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958! s6 D5 g3 s# a: a1 Q$ l

    3 ^' e; }" c  x7 U9 y3 A' Z8 J# s- H1 J7 T
    7 K. }9 Q+ ~/ ~; Z/ l- H; U3 F

    " k( Z1 ]" S+ P% ]————————————————  K& T- [3 R- o/ w$ I% u  D' x( B
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    4 R$ R' M, j/ b. O2 T原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    % G' R" j% }  q' w( v7 l5 }9 b4 e& q7 `' G. V, z) I; p4 p
    & l, g4 C6 N& \8 M
    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-1 22:46 , Processed in 1.434289 second(s), 53 queries .

    回顶部