QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1600|回复: 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
    3 O& }0 c1 D9 Y' o  T
    图的存储结构——邻接多重表(多重邻接表)的实现
    : |( E+ Z; E& d, K+ G" V0 H8 n0 R6 R7.2 图的存储结构+ z  e- B$ d* m' r' R
    # u6 J  z. M* n+ P  B3 h- h
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist  ]" u9 s5 ]& f  R- `
    邻接多重表的类定义
    * d6 {/ r- B+ Y* O! [% P, w+ b1 M; f8 O邻接多重表的顶点结点类模板8 H' j3 H5 K! u6 ]$ f! ]
    邻接多重表的边结点类模板
    1 H1 Q3 S) q$ d, l; ^0 K) y邻接多重表的类模板
    3 W7 U, Q4 X' Y) G+ H" S邻接多重表与邻接表的对比0 a5 n. X4 P8 I: T. D; V0 L
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist3 a' D% d  f- r/ K, L0 A: k

    6 d5 M* D" z+ u! V在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。/ W# [: s. H/ P* {, |5 L5 a
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。' U  d- n" x$ z( ~6 B

    ( N5 K! X$ r  ?" w. N, H邻接多重表的类定义) y5 b+ }% D" x) l- o
    1.png 6 q: o( R: [& q( [0 f: x
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:2 X  Y, C+ P) @0 h; q
    data域存储有关顶点的信息;7 @& P1 U3 L6 W9 C+ Q
    firstarc域是链接指针,指向第一条依附于该顶点的边。6 `8 ^% H1 V$ R& H8 s2 z5 q' `
    所有的顶点结点组成一个顺序表。


    - E2 Z$ U8 ^- l
    0 L( o! i1 I. |! H$ \% w' q; o% ttemplate <class ElemType ,class WeightType>, _! N/ ?2 e( p  Y! u
    class MultiAdjListNetworkVex
    / g* N1 G$ h( O1 d* E& Q% n{( Z0 Q+ u0 m( O/ H' p1 C
    public:; `+ a5 P9 j% t
            ElemType data;3 O* H( {8 o) t/ u
            MultiAdjListNetworkArc<WeightType> *firstarc;
    , `# [; F( n; k" I6 H* j8 j. d0 M. H( n) `/ R
            MultiAdjListNetworkVex()
    : Z6 f9 ^& d8 m3 g! g        {! B6 F/ ?9 ?1 s8 x7 \
                    firstarc = NULL;; L9 V  g4 Q+ C' S8 s' j
            }
    0 m7 w: u' j/ N; `        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL): u5 A2 u) y/ x% v& c% r! g2 y: Z
            {
    ( U. R( j, z! s4 M9 q7 s                data = val;/ N5 Y- \3 w. ?" m$ Z
                    firstarc = adj;
    * [' s, g7 _- F/ t* S4 m        }% A  v: @6 t$ g
    };
    : F0 H& e& a/ W" f% _6 {/ `: O7 u" @! [
    邻接多重表的边结点类模板
    8 s- i. f- N7 a" l/ T# _
    6 T5 f' _7 t( H* |; r  P在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:  D* {' J+ q  j" Y1 R7 x
    tag是标记域,标记该边是否被处理或被搜索过;; i3 E; \$ |5 y- |2 K
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    ) i: m/ X9 T, D' K& t" pnextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;4 W9 A7 I) [: L4 l
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。6 @0 i2 V" T. i% g

    2 s& b# {1 \& G* o( g3 W. N 2.png 6 N8 L+ f+ j/ P+ C: A! q7 T
    template <class WeightType>9 e& J6 m9 Q1 N1 A! ?, H
    class MultiAdjListNetworkArc' @& z$ @7 P3 ~! g
    {- |0 a: Q$ n$ V4 H0 {
    public:8 p5 ~0 K3 X) q. ]$ c) }+ U
        int mark;                                       //标记该边是否被搜索或处理过
    / E, a0 u) l! Y& \# z1 t        WeightType weight;                              //边的权重
    / `# k3 B0 {: ?1 h% H        int adjVex1;                                    //边的一个顶点8 b' D5 p; o: |0 |) p7 [
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    . {% S' c& e; v$ z3 \) K        int adjVex2;. H; ~, z+ \/ h: s  h$ m6 w# N, `
            MultiAdjListNetworkArc<WeightType>* nextarc2;6 b5 i( I( ~% I, Z* {2 V0 \! C4 q; j; C
    5 S$ t6 x+ `! E; ~3 K7 J2 F
            MultiAdjListNetworkArc()% x7 ^3 B: y! v" _, p4 p
            {& v$ U# v; @5 m0 o- X4 z
                    adjVex1= -1;8 ^/ i! f8 [3 T$ t/ M7 r' z0 A
                    adjVex2= -1;
    - ]- o5 \7 ?. {! I, Q        }$ f" ^8 p) g; U
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)" C% d, F7 U1 L+ T. l
            {, V# }' A) ?7 ]. x! O% `( ~) _4 |
                    adjVex1 = v1;       adjVex2 = v2;
    9 I( V1 M/ N" E                weight = w;" x, H! C! {) _/ G$ r
                    nextarc1 = next1;   nextarc2=next2;
    7 C: Q+ J, i6 r" B3 W                mark = 0;           //0表示未被搜索,1表示被搜索过6 I$ @; o( P2 v% e5 l
            }
    , k3 ~7 s1 \9 V  L
    0 L2 T* s: N9 N4 [邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>' s' _. _. ~: s$ |( k2 ^: P0 @
    class MultiAdjListNetwork! \' r2 `7 D7 o$ ~
    {
    2 y: M: r6 V) \6 u  Q. l1 tprotected:
    & P4 ?: T: K% h- j6 x+ l% m/ W    int vexNum, vexMaxNum, arcNum;8 I0 F" x8 u1 v) i) Q( r
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    6 l! J4 ]# u' w1 b* V7 \5 t3 i( a    int* tag;- L3 E0 H1 T. P% q& T: l- a; n% K
        WeightType infinity;
    2 [; [/ G* E5 r" y8 K$ d) G
    2 f2 a( O% I3 M  N" h4 Tpublic:
    0 i) N% R+ C) O    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    ( Q' k9 E2 \6 h( G4 E6 c! d" x$ M5 B# z; c
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);& V% r+ i$ i: A& g5 K
    " ~8 @/ i' A2 a* E; Q
        void Clear();
    " [9 \, m9 H4 u" R/ h3 _8 H    bool IsEmpty()
    . `, k6 [- j( I    {( ?$ Z. G, L( A/ t) F7 ?  ]  V) N
            return vexNum == 0;
    ) ~& S" C1 e/ I) G) {    }6 M; x( {" Q1 \- S& M7 w' ^
        int GetArcNum()const3 ?( {& O" j" e
        {
    5 U( L9 C! x6 V- n        return arcNum;
    1 A& A& O) @) a: ^3 x4 a4 |7 l    }
    3 V) C" {5 e6 s8 |$ T    int GetvexNum()const& ?4 z9 k- d, b
        {3 v! A2 F& q  }. ]" ?# q2 @/ @
            return vexNum;' x# y: f: l" S- t
        }5 C5 U, Y- T3 j2 P" H0 T
    * k) j0 j& m8 ~9 d' n
    + E/ Y! U' n6 d# p- N" h& o
        int FirstAdjVex(int v)const;
    0 n3 m% P7 o9 Q! z# n+ B( b( V+ g    int NextAdjVex(int v1, int v2)const;
    & B- K. K1 q$ Q+ P) y% z    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    ! }+ v9 F& ~. I% L4 J7 P& r    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    - B* j3 i1 Z* {- A# T  r
    0 f) a5 F( n" [5 e; E    void InsertVex(const ElemType& d);& G/ d6 E2 g  ^' W; V" B: O
        void InsertArc(int v1, int v2, WeightType w);$ g. a; e$ N6 t, i

    1 O9 M# j, m# l0 W' @    void DeleteVex(const ElemType& d);
    3 A) @% j1 d1 T! n# G8 b- D    void DeleteArc(int v1, int v2);
    6 u5 l3 U+ E: s5 H% ~
    " S4 C9 u1 g7 Y4 c4 g    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);* Q# n0 j* e/ f* A/ x
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);. d7 c) b2 b1 j. _8 p0 R

      w5 H' h8 Y0 v% A' s9 c) D    ///深度优先遍历3 q7 t" n4 q& X& o
        void DFS1(const int v);' N3 \, o0 n; T: [9 r6 K6 t, K
        void DFS1Traverse();
    # J* c, W3 Y7 X7 `    void DFS2();
    - M5 y+ V) x! }- T3 `' ^  v$ ?( }( b( V' Z
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1+ c, e# q  w6 B% O! t
        void DFS3();, B1 ^. r6 o6 z

    & y( R6 q& s( U    void BFS();, H2 r( D2 x0 O1 L- n
        void Show();
    & [3 O$ X3 @" @/ |2 U};+ |, L' A8 R; ]& w. R8 L" A
    , V  L+ N+ N' T- W( R  f& s
    2.函数的实现0 t; o% ]/ R1 G/ ^% R- ~
    研讨题,能够运行,但是代码不一定是最优的。  P4 s0 E# G: q0 q0 L
    ) I7 W7 N. {1 `5 Q  y. G
    #include <stack>, R9 m( k0 L* c% O
    #include <queue>
    0 Z' `, }( Q  Z: i# J+ S- _, K
    5 M( ]" d3 F6 R% I; B7 Ntemplate <class ElemType,class WeightType>& [9 O0 ~% a3 r9 z3 C
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)3 c% {: Z7 z4 L  R$ @8 ~
    {4 u6 o: |7 s. E9 z" Q
        if(vertexMaxNum < 0)- U" Y5 a- r. P" H, m6 X5 T
            throw Error("允许的顶点最大数目不能为负!");
    * b$ |6 X1 @5 }0 y8 f2 U5 e    if (vertexMaxNum < vertexNum). A) k0 y! @8 X0 R
            throw Error("顶点数目不能大于允许的顶点最大数目!");
    % |  I0 U9 D7 X) h! j- a    vexNum = vertexNum;5 J6 b7 G# o5 F: a% r. B
        vexMaxNum = vertexMaxNum;
    4 T( i) Z) Q, v    arcNum = 0;
    . F  ?# L/ t/ t) R    infinity = infinit;
    1 y9 y: P  h; m7 I8 T    tag = new int[vexMaxNum];
    4 U# p% Q2 R( N/ C    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];& c% A- o$ R# s1 X) s
        for (int v = 0; v < vexNum; v++)6 t7 Y6 o. z) O3 c  q6 p
        {# D) {0 _4 K9 m: Y6 Q7 e2 b- {9 M
            tag[v] = 0;
    ' t1 A5 P! y% A9 s# i1 g        vexTable[v].data = es[v];% `0 `; e( o5 M/ |+ k/ G8 M+ Z
            vexTable[v].firstarc = NULL;3 I5 z9 g% l* ~5 _# o" I4 h7 Z
        }
    + j; R! p. k: E- v1 C9 t}
    7 s) g4 D( v( }" [0 N0 l% V5 atemplate <class ElemType,class WeightType>
    + t! D& u* E3 KMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
      i9 \4 [/ V2 y9 _- E% z& V6 p5 E! i{
    * k6 ~8 J- o) e+ y. u    if (vertexMaxNum < 0)3 z1 W+ T: {* B- Q9 c
            throw Error("允许的顶点最大数目不能为负!");
    + K1 g( f4 J, ]3 O    vexNum = 0;
    $ f5 p: P0 o. f5 B3 Y. Q" }* O0 q    vexMaxNum = vertexMaxNum;
    ; j# k3 O$ n: D9 J) e6 c    arcNum = 0;
    + g/ i1 S/ P9 O7 _2 \    infinity = infinit;
    , ?7 A8 N  U" l    tag = new int[vexMaxNum];. R: \0 f& b8 ]* Z8 S6 b' X. h6 e* `7 _9 J
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];1 ?0 {* X8 C4 q, h( L! ~1 b
    }  e  p- R% E# |; W" C
    template<class ElemType, class WeightType>
    ) j, t. \/ o4 L8 _5 w8 ^' O8 \int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const, g4 B/ f4 f4 m- W& S6 n
    {, T* B3 n3 Y, Z! v
        if (v < 0 || v >= vexNum)& V8 A( r4 S1 g
            throw Error("v不合法!");
    7 A) i0 k& L9 b7 G' K    if (vexTable[v].firstarc == NULL)
    % i! c% j& _" v5 v+ x9 }( o        return -1;+ f- r9 C9 R* f  N* E
        else* D. ~! G, t- f* \( Q8 Q
            return vexTable[v].firstarc->adjVex1;3 \0 \, {1 Y( v: S+ g. d3 q+ J
    }
      r1 Q) o5 e8 n$ e+ }& ~6 m" k6 i. `" p$ s, ~  v( F- @( ~0 G
    template<class ElemType, class WeightType>; m5 o4 Z/ ?) \
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    & `" n+ R7 q4 a/ i: G6 ^& ^{
    ) t  A' K# x& z" w. U    MultiAdjListNetworkArc<WeightType>* p;
    / x7 w2 ?8 u5 R" i0 `    if (v1 < 0 || v1 >= vexNum)
    % G1 I5 T* M, F9 a. p        throw Error("v1不合法!");
    + b( n! U/ ?& V7 c5 \' ^    if (v2 < 0 || v2 >= vexNum)
    ; S  L* j4 F( L5 h        throw Error("v2不合法!");
    + J. _7 K& ]- ^    if (v1 == v2)+ H: r/ _* m9 W
            throw Error("v1不能等于v2!");
    7 o* q/ F# m& _% _! c+ O    p = vexTable[v1].firstarc;
    8 f( M6 l! [" ]: M6 W    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2): j3 C4 s9 i( d- ?3 S6 P8 G6 ~
            p = p->nextarc;, N2 K5 o" p' m
        if (p == NULL || p->nextarc == NULL)% f: ~! D- U; `7 e  Q+ ^1 q6 i; E. \( e
            return -1;  //不存在下一个邻接点
    0 P7 e% A! S) u/ ^. P( ~  J; z    else if(p->adjVex1==v2)! D- S' N8 M: k. L3 C& ?4 {( a
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);6 c& N* q, U, ?) |# C% A- w6 c
        else4 _3 n6 G8 U; x( k, L
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    / d+ `9 w9 D( D, g" L& [}
    5 \0 E( g7 u. T: ptemplate<class ElemType, class WeightType>0 t- F7 A- ~! F, ^6 l
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()
    3 v% Q) y9 }+ g6 r, s{
    1 n  }0 b& `' X% X    if (IsEmpty()) return;% Q- W7 d! @" I( x3 d' `$ O8 L
        int n = vexNum;8 a+ o$ w: y; q( |
        for (int u = 0; u < n ; u++). r3 }7 X! @9 P, e* Q7 P, S
            DeleteVex(vexTable[0].data);' m5 V' @5 _( u
        return;
    , v- E- u4 _7 J2 Q& t}
    ) ?* `! S: Y% i* n* K$ _template<class ElemType, class WeightType>* I; y2 g* {- ?/ n4 J
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()! A# i, H" \, I& O8 _3 `6 C, N
    {1 g9 }# Y* q, e5 r2 y! G
        Clear();. F: T) U: i% \4 Q8 l
    }
    ) o2 N9 @: h& ?+ U  w) Vtemplate<class ElemType, class WeightType># r& H8 {$ o1 b; _' B
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)+ P  N$ S( `: n
    {
    " |0 a; F* o+ F0 v6 v    vexMaxNum = copy.vexMaxNum;7 u2 B! v9 b) ]2 W
        vexNum = copy.vexNum;, o9 ?6 a, E* h: ~5 A) m7 w
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    . a2 ?9 y! |8 U( x- T$ M" H; z& Q+ {$ O    arcNum = 0;& d& {0 ~- p* W* y: T  x# ^# `3 f
        infinity = copy.infinity;
    # G' @5 a$ R4 ~! U4 g    tag = new int[vexMaxNum];0 r5 |1 J- U; o2 k7 j
    % W" c5 d; }2 E
        for (int v = 0; v < vexNum; v++)4 e+ P; ~4 K! \  k+ B
        {* r2 D1 U3 B3 U1 b1 Y5 ~
            tag[v] = 0;
    . i- a' C. v, \3 a  z2 X2 e" b        vexTable[v].data = copy.vexTable[v].data;
    , Q( |6 m6 b9 |5 Q3 [+ ^3 G6 U! m: ^1 ]; {        vexTable[v].firstarc = NULL;; \5 J5 J% X5 @' q4 m8 W
        }0 T2 @$ a* c  K0 A$ D: B
        MultiAdjListNetworkArc<WeightType>* p;
    ; }9 X( [6 x( o" Z. V% V0 C6 b7 T) T6 R! x: t8 B6 N! k
        for (int u = 0; u < vexNum; u++)7 H7 r3 Y1 }; J8 D' f
        {1 R( A" c4 h' G- q! v
            p = copy.vexTable.firstarc;+ C+ a7 N7 A. S/ W
            while (p != NULL)
    $ n; S0 h+ i0 ?: `0 Z0 I        {
    7 O7 f7 A4 q+ [& K; M+ k8 k( b6 s/ v            InsertArc(p->adjVex1, p->adjVex2, p->weight);" E9 t& U! \+ E
                p=NextArc(u,p);
    - u9 d: ~+ d! S        }
    5 e3 P( ~4 _3 _- K. k    }/ y# a/ R1 d2 V+ V: E. P4 z, {( h
    }8 S; f- T$ ]0 L; ~- X) |
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&. i+ J2 }: c9 n8 D% T% a! Y! j
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    4 e9 |$ @; z& D8 M! o{
    * i4 v* A" c' x* P# `5 {    if (this == &copy) return *this;
    0 P8 v* x( A) l  q    Clear();
    * o9 U8 ^0 L: f9 p2 P8 {    vexMaxNum = copy.vexMaxNum;
    # O& C) z. S% ^' _    vexNum = copy.vexNum;
    # e3 D9 [  i! L4 W$ `" g& F    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    $ X* z; Q5 |" m3 p2 R3 O2 w6 z    arcNum = 0;
    ! `- z7 l- X! j5 L    infinity = copy.infinity;$ j/ L# {$ f# w$ e
        tag = new int[vexMaxNum];& X* M1 G7 H9 T4 P& {
    6 D6 _/ v! U, D
        for (int v = 0; v < vexNum; v++)+ R4 @. q* r" a+ J
        {- ^/ L7 _! i' h4 H5 s  T+ ~
            tag[v] = 0;
    9 K" j* G0 n0 [+ j2 e        vexTable[v].data = copy.vexTable[v].data;7 ?7 p+ Q( n2 }) p8 _
            vexTable[v].firstarc = NULL;
    * }! S8 {4 k8 A/ n    }
    ; T, @' }! O. F    MultiAdjListNetworkArc<WeightType>* p;! _5 D: y' h" b9 {8 X# a
    3 l- |/ j: g# R$ C3 Y! b9 l( x
        for (int u = 0; u < vexNum; u++)
    # d- p5 l' w7 T% O! e" B' y    {6 ]2 A* J; y6 j( q, T: W, [2 Y. w
            p = copy.vexTable.firstarc;
    1 C1 w) ?3 z# ~5 J        while (p != NULL)
    6 B1 }3 |/ f: v        {9 h( v: U5 q5 ^$ Z3 B" n0 y9 @
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    " r' G# k: V; h- i8 F; l            p=NextArc(u,p);: g9 ]. {. K( c
            }0 a: [- l! {7 r
        }8 a: D! V! ?; m: V; X5 L7 @
        return *this;
    0 M3 B/ @( z. }0 D' _3 c2 k) {}
    ! v% b8 m" [4 T0 m! B6 Btemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*, m' f. m8 X! Q9 r
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    & g/ I4 Y0 N3 _( \- W. Y{  y; b% b) I$ r
        if(p==NULL) return NULL;+ f( w& P" m# ~( W
        if(p->adjVex1==v1)
    6 S" M5 r! b, k$ H, H$ s        return p->nextarc1;, `7 i& w) `8 N) `5 n; a+ f
        else+ @' {  \) [- x* q0 k5 |# |4 n8 l
            return p->nextarc2;# P: q: o# f0 `0 p
    }
    0 d, r# C  X1 p* ]! H! x9 Etemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*4 {; Q8 O4 y/ t* n7 P9 S5 M
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    $ y& O; k) N6 A{" O/ b4 P1 k! S2 G) B9 E
        if(p==NULL)return NULL;7 {# e5 P# p( {: p" P
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    7 {  k" l% r9 p8 q- [" A    if(q==p)- a; C/ U. Y! b# N
            return NULL;
    ! x4 {: R$ j4 ~7 i    while(q)) R: Z3 |( U* F+ H8 S8 \
        {
    1 W# i. C0 R& o5 C, s; }' @        if(q->nextarc1==p ||q->nextarc2==p)
    % E5 `" J: L1 @2 \            break;. f" P  x! G7 n' \3 R
            q=NextArc(v1,q);$ N* F) O  ]5 e/ [
        }
    / \" _( I$ m- }4 @    return q;
    ' `1 g' n7 D4 a: h/ s# u. U}: j7 X" w9 m$ r
    template<class ElemType, class WeightType>2 E) v2 r9 b* Q4 l0 Q' D7 a
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    : z3 R. h" A% X7 W# P{7 R% t5 ?6 v" J+ A0 L& e) M
        if (vexNum == vexMaxNum)3 I/ C1 f! \7 f
            throw Error("图的顶点数不能超过允许的最大数!");
    : `8 y* a3 P: i# b) G2 i, Y9 y5 c    vexTable[vexNum].data = d;
    & ]* y$ x  ]) o4 v. R7 v' g9 y    vexTable[vexNum].firstarc = NULL;: Z2 ^3 H% y* l' K$ R4 W$ o
        tag[vexNum] = 0;
    + I1 F. }+ n! N" k" v2 v    vexNum++;0 t6 p& \; w4 N8 t
    }
    , c' N2 j6 J& u8 Atemplate<class ElemType, class WeightType>
    ; C7 L; H3 ?  F: G4 a4 L$ @void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    9 L7 k+ P8 u" f4 d' B$ N& I{
    & A9 ]6 G9 X6 T8 P    MultiAdjListNetworkArc<WeightType>* p,*q;8 n( ]# ^- m# e3 C8 b+ K, O
        if (v1 < 0 || v1 >= vexNum)
    ! {/ x$ k. U( q! Z& p4 i        throw Error("v1不合法!");5 y5 f: D% s3 m# S9 S
        if (v2 < 0 || v2 >= vexNum)
    / Y% a- \: ?- w        throw Error("v2不合法!");
    2 r3 @% H2 O2 V+ J$ a9 R& o/ A! [7 ~    if (v1 == v2)' W2 `4 M( M) w8 |3 G
            throw Error("v1不能等于v2!");/ V, z/ m5 |. |+ Z
        if (w == infinity)
    $ t) m! D" k4 z; B2 F        throw Error("w不能为无穷大!");$ O* D! B: {: Q8 d. n

    & C: H' X) s* h$ _% c( k+ F
    7 X# C$ Q" A4 \. A% U    p = vexTable[v1].firstarc;* L& \- T$ F; k: l
        while(p)
    & Z9 [" Y: @+ X+ @3 ^' u2 U    {
    9 p# l. r( T3 R& v$ X0 ]' R. p- x        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中; n/ C/ A6 R$ I8 i, Q, z
            {! d- w/ K( w2 ~% |9 k: n' G
                if(p->weight!=w)
    % D' q8 F% s. l$ T# i+ m6 P                p->weight=w;
    $ U3 Q2 @, N5 ~9 c: O            return;
    9 ]  a3 A2 N6 D, p2 U        }
    8 d3 r  W1 G2 X# o( |3 ~/ L; `& \9 k# `' I+ N. X
            p=NextArc(v1,p);
    ( v8 R, u/ q, u    }0 r! A; ?6 M# a6 X6 ]
        p = vexTable[v1].firstarc;
    , A+ Q2 r3 K6 F7 d/ G  ~% Q1 H    q = vexTable[v2].firstarc;
    7 B  [* c$ i; A% w6 I; \- v    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    # {9 b1 X) j$ Q8 ]7 }& }; ]3 K    vexTable[v2].firstarc =vexTable[v1].firstarc;
    3 D9 J# r  {7 b/ v! r; T5 d7 F+ G    arcNum++;* n5 X$ f. A& _1 y( Y1 Y/ X3 ]
    }5 q, X0 d" M2 {0 R+ N

    + O6 w9 o$ E  x, i$ p4 ~template<class ElemType, class WeightType>
    9 t. z) A7 N& tvoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)+ O  Z& P4 G1 N4 c. Y0 V
    {
    4 j$ `% |5 U' N: Q& L1 s+ g
    ( I  t$ }: @; T7 ?7 C( d- F( r# o    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    . N/ W. ~( ^7 R" j    if (v1 < 0 || v1 >= vexNum)
    2 Z6 r' ?" f/ T        throw Error("v1不合法!");0 Y9 l1 P. {, s* q* G
        if (v2 < 0 || v2 >= vexNum)
    * x$ P" ^9 m% B% h" X        throw Error("v2不合法!");/ Q, t  ~/ o3 ]- F
        if (v1 == v2)
    & x3 ]! V. a: e; C  z        throw Error("v1不能等于v2!");
    7 b. F* W" B- H9 A' {5 c/ M2 N9 Y
        p = vexTable[v1].firstarc;
    & B9 V7 Z" L. C  ?" B/ h( i    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2). j& X8 z# E% g& O
        {) X% r/ R+ g, z5 N/ t, |
            q = p;, _" P9 `+ D/ i% \1 Z0 r) _+ d
            p = NextArc(v1,p);/ p- |5 t& F2 m
        }//找到要删除的边结点p及其前一结点q
      u9 d, R0 }. @( w. l1 ?- p
    2 z& V) R/ w7 \1 V- k+ ]/ j    if (p != NULL)//找到v1-v2的边
    : f9 G. {5 q! R& T, i6 p    {
    ( @! c' t7 ~6 v5 f& y        r=LastArc(v2,p);
    * z& k( l! g1 a# W) _& R0 u        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL6 _/ a% K- P3 @
                if(p->adjVex2==v2)
    + N. K3 _0 k5 P; y1 U# q                vexTable[v1].firstarc = p->nextarc1;6 l, l) f! j8 ]3 z* @
                else vexTable[v1].firstarc=p->nextarc2;5 d3 a; B2 c! R1 M+ V
            else//不是第一条边+ |+ P9 ?; I2 S# @) L: M5 I
            {
    : o& ^" j) d  B/ x- D& W- s/ \# a            if(q->adjVex1==v1)* p$ I6 E' D4 {2 }9 w8 x( T
                    q->nextarc1 = NextArc(v1,p);
    1 P0 _9 x. B9 c6 E9 u            else4 j; j) r0 I3 O$ Y% m5 \+ w4 ^4 x
                    q->nextarc2=NextArc(v1,p);- ^9 g) d! v5 ^8 E! _- J
    ! W: K. V. a, |( [! ~- d
            }
      }+ @* `2 s. H& w( w3 y        if(r==NULL); c2 |( ~& n7 A8 a$ Z3 e& C
                if(p->adjVex2==v2)
    " d& Q9 q' _9 S5 _                vexTable[v2].firstarc = p->nextarc2;, g7 {3 Q& A% Q( g: j
                else vexTable[v2].firstarc=p->nextarc1;" M: m" Y- G' c9 _/ m8 b
            else8 A5 g$ k" x0 X
            {3 [8 A4 X* c0 T6 i! N
                if(r->adjVex2==v2)
    ) L' o& j+ o5 l" C+ |                r->nextarc2 = NextArc(v2,p);) P0 k9 c5 A2 c0 _
                else# `- G* z: W" t
                    r->nextarc1=NextArc(v2,p);
    . L& f6 e# c) Z9 j! w        }8 K5 q( [% g3 }# [
            delete p;
    2 p3 y4 h4 L. q- e: _5 Z9 F7 h        arcNum--;
    ) p/ `$ @! C1 t) d3 Z% G1 A( E    }6 G0 s. x) ?2 I% f/ d
    ) t1 S. }5 h; A8 F; b
    }0 B- {* I% N- X* v$ ^' {, d, _
    template<class ElemType, class WeightType> void
    0 [0 `3 w5 t3 I5 U+ w. y, Q" M! H" {# ?MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    5 X! |% V: o* _7 ]" J{
    / X7 T$ W" r: g- w* m    int v;
    / _% W: d/ j& k1 ^$ H    MultiAdjListNetworkArc<WeightType>* p;
    & Q6 Q' R8 Y; c4 Q( b8 M    for (v = 0; v < vexNum; v++)//找到d对应顶点; p  V5 H# ^  U: I/ k$ @
            if (vexTable[v].data == d). Q7 `+ I! \( h
                break;
    % @3 i9 s8 J& }7 J% Y' a6 i- q: x7 p    if(v==vexNum)
    + A' u6 U  W  a* k% P        throw Error("图中不存在要删除的顶点!");$ i, e" j% K5 I2 J4 a9 L
    ' g! k  x, e2 V2 O8 P) k% t: K
        for (int u = 0; u < vexNum; u++)//删除与d相连的边: G6 d- s" f% \8 D; X
            if (u != v)
    ) Q) j, U2 K7 z0 V        {
    ' J% z8 e8 i; W. @            DeleteArc(u, v);
    ' n! x# Z  U. [! d! E1 K        }# C" M/ F! c- W9 j4 r
        vexTable[v].firstarc=NULL;! j( z# j$ b, Q3 d9 C7 G3 S, r( h

    4 G' A/ g) Q) [% B; i  Y    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置. a0 d, ^  r$ K& }$ f/ _! g2 A
        vexTable[v].data = vexTable[vexNum].data;
    - S. S4 b5 M- W) w3 N8 H    vexTable[v].firstarc = vexTable[vexNum].firstarc;
    . O# D! C2 M  {2 X    vexTable[vexNum].firstarc = NULL;
    3 P. S9 j( o4 J- a, m0 g' U9 _* `    tag[v] = tag[vexNum];  ?: F4 F1 G0 E
        //原来与最后一个顶点相连的边改为与v相连
    ) ]9 p$ {' L& t+ A% `    for (int u = 0; u < vexNum; u++)
    3 U1 R4 l5 L' Y* }3 T' [7 b    {
    2 V% W$ |+ P$ @4 p( M6 G        if (u != v)5 Q2 }9 T+ Z2 p) |2 z
            {
    . E1 S7 t2 l' t0 [+ Y            p = vexTable.firstarc;
    0 l/ `8 ^" i- R( c7 F            while (p)
    " P7 A/ T* b) {% z            {3 K) }6 c3 }$ a
                    if (p->adjVex1==vexNum)
    - G' E- I% e3 m6 I3 D6 f) V, W                    p->adjVex1= v;. ?# u% I: ]8 f4 v
                    else if(p->adjVex2==vexNum)1 b  o* t* f9 \5 E1 @
                        p->adjVex2=v;
    ( e' R1 ]* _% [: l+ M  k& c                p = NextArc(u,p);# {' y% ]7 j. g+ C5 D$ I: T0 L
                }
    * t5 W: `( _6 i+ G        }
    4 t1 z" t$ W9 g3 [7 r3 _    }5 K/ R+ R& E0 z9 b7 }- J. ?5 G% H
    }$ r8 c: V) j2 b4 w7 ^$ R( N& V4 o
    ///深度优先遍历
    2 L% p. v$ i# X0 atemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    6 D0 v8 j; R. C- v9 k{3 B$ _/ W7 n. `/ G$ P0 {! b6 o+ \
        tag[v]=1;
    4 J7 Q/ ^; \0 H1 u9 {5 B" j    cout<<setw(3)<<vexTable[v].data;
    0 \5 T% }0 B. N0 x    MultiAdjListNetworkArc<WeightType> *p;
    8 t/ d2 D  `- X5 A9 g& n" b    p=vexTable[v].firstarc;
    6 F% t* Q8 P: ?" G    while(p). r+ w$ L! F" U3 F
        {; h8 P, ~7 T3 q! x3 Q9 p0 u" P
            if(tag[p->adjVex1]==0)
    3 ?5 a! Q. p* l            DFS1(p->adjVex1);5 L3 y7 ]/ }: u* q
            else if(tag[p->adjVex2]==0)
    ' a/ q$ R9 }; ?' q. b& ~1 k% [            DFS1(p->adjVex2);' j7 l  L& x; Z
            p=NextArc(v,p);5 ?) j- d, D7 [- ?1 ^
        }
    2 u8 X  @' f0 k+ f}
    ' H' T- I2 m- {template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()' M" \4 R7 Z- @3 l
    {
    / s( A4 s$ C6 ]' W0 ^    for(int i=0; i<vexNum; i++)9 L7 d7 W  W& G* y
            tag=0;' l+ y5 K- A/ Z% u& O( W) u
        for(int v=0; v<vexNum; v++)9 e, W  I( |. y. e) ^( A
        {
    6 f1 s& q3 W) W1 e        if(tag[v]==0): ]0 ]0 E0 P: }& p9 \! [( F
                DFS1(v);+ _0 n1 _4 o3 e! a4 t9 s2 J. c
        }1 ?; M( M" z4 R  y7 c- X
    }
    / X! t$ n' _3 T+ }template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()7 B% C2 Y; R* g0 _5 }, U+ i- z" n# e, g
    {3 B" x. Z: j% c
        stack<int> s;. _: q: N5 v/ O' x0 h& t
        int tmp;
    , `% `6 H7 C! b% c: P/ f    MultiAdjListNetworkArc<WeightType> *p,*q;
    - P& J" l: v& U1 V    for(int i=0; i<vexNum; i++)
    ' @" W: D$ r- q5 f; G        tag=0;/ t. Y9 H+ {2 g+ F7 A6 o" ?0 x
        for(int i=0; i<vexNum; i++)
    6 I: E# d! r3 q: `1 s    {4 ?* b0 Z$ o: t
            tmp=i;- a" C5 H* Q3 ~) T" ?0 M& B0 i
            while(tag[tmp]==0||!s.empty())3 ], F/ v. a0 t, {
            {% z* g+ P0 d; K# I! p5 e
                p=vexTable[tmp].firstarc;
    , m4 [* c, x/ q, Y3 l            while(tag[tmp]==0)
    : ]. _) e4 ]7 i$ G            {; L. r2 D3 r( t, A  _
                    s.push(tmp);$ K' e8 N0 F; R2 X* k
                    cout<<setw(3)<<vexTable[tmp].data;5 I/ |1 l$ G! C1 k- i8 G# g
                    tag[tmp]=1;) X: C7 `' d* A  F4 `
                    p=vexTable[tmp].firstarc;
    6 u) R# M+ v- l  j0 g                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for) D1 J9 A" a5 P( h6 U3 ~: C: A
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    8 H/ h( a" p+ M                //cout<<" 1st     tmp="<<tmp<<endl;% d. V5 i4 P+ ~+ O, l8 \! D7 j
                }
    + v  E1 T; l3 H5 Z% o' \) a            if(!s.empty())
    6 o. X/ ^3 |) t; t% p            {
    , T, I# K# [! z                tmp=s.top();0 @& D$ U/ C! C0 U  Y: D: O8 ^
                    s.pop();. l" J0 N& @" p) k: U; Q+ Z
                    q=vexTable[tmp].firstarc;
    * ~: B3 ?8 i5 E# B: ^' K0 M                int t=tmp;
    - G- |6 Q3 g; p0 R4 G/ e; q9 \                while(q&&tag[tmp]!=0)2 j" b! e% ~6 b) _! L( ~/ Y" |! N
                    {
    * E2 N0 P0 A4 y- ~5 l9 v+ Q0 B+ w                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    + A( X: Y4 g' r) W- C. F- u                    //cout<<" 2nd     tmp="<<tmp<<endl;4 P3 `- R6 R; W
                        q=NextArc(t,q);: E0 [- F" `  ?/ @! Z
                    }
    1 I# W. ~6 V/ O" R: [( v- B* \                if(tag[tmp]==0)
    5 F! A- l. R; \8 W7 l1 o( @; t                    s.push(t);% a4 g0 S9 k1 C/ q2 @
                    ///1、对应上面连通分支只有1个点的情况
    . N; a. M! ~$ M+ E. z                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈4 I9 ]4 f' D2 ~* p+ A" p3 f
                    ///tmp要么等于找到的第一个未访问节点,
    ; \4 m9 U* p0 d                ///要么等于与t相连最后一个点(已被访问过)
    $ k* ?) _# k: ?2 e                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    9 w8 i1 g% {# \% ^/ K            }
    ; a  E# z% d' ]  g        }+ j$ r; e5 l3 _" _' W4 p4 U: s! Y3 Q
        }  Y) ^2 {: u' |! @/ |3 Z7 J8 C
    }/ W, ?/ F; B% @% P" H1 s
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    ( Y; ?$ Q( Z3 ytemplate<class ElemType, class WeightType> int4 Y3 ^1 B# T$ o! ~" i
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    + F5 d- I$ Q- w{$ j1 I7 i+ Y; q, p
        if(head==pre)/ ^- J1 P* W7 i6 {% C2 H
            return -1;
    5 [5 P- J6 k$ f  p8 n
    ) g. {/ m9 o; b. w# G1 z4 y# I2 P# b    MultiAdjListNetworkArc<WeightType> *p;
    7 }( d9 a  q% b1 [0 I; M2 e$ A    p=vexTable[head].firstarc;
    ' t# r' f* e5 y; Z+ ^    if(pre==-1&&p!=NULL)
    , `0 w* r, D# K2 [" V        return p->adjVex1==head?p->adjVex2:p->adjVex1;$ l0 e% k, R5 N
        //pre!=-1&&p!=NULL# I( a- H0 k" u  s& V8 f
        while(p!=NULL)& {5 C& f, L3 |  L  t! C% ^# J* P
        {
    5 i  c- t& [8 k3 Z& |- k' y% n        if(p->adjVex1==head && p->adjVex2!=pre)
    $ e/ K# o9 `' T1 s$ j            p=p->nextarc1;, P) ]6 j7 V) N
            else if(p->adjVex2==head && p->adjVex1!=pre)
    " Z0 F7 w( o3 Q6 A. y% g: A            p=p->nextarc2;
    ! |! H6 m7 L4 H' m! o        else if(p->adjVex1==head && p->adjVex2==pre)- H2 w# R/ p( }
            {! E% a  v4 j6 f: l, R3 `7 A5 D5 z
                p=p->nextarc1;; ?1 M. B& R1 M3 n
                break;1 P: B% F1 z! v# e0 L
            }- |& @6 `  f4 @$ v- C$ N
            else if(p->adjVex2==head && p->adjVex1==pre)+ ^* e6 U4 t4 K6 Y( b
            {9 Y9 e, E' \2 d% l  v( w% q6 E* c
                p=p->nextarc2;
    ) p+ `) ^4 E7 z6 c: f2 I" x            break;
    9 V6 ~1 _. ^; X/ x        }6 x0 |/ u% M$ S! q( B( X& T% A8 V
        }
    8 A. n* F  |6 b: b9 D    if(p!=NULL)
    7 F4 o6 F9 e7 A% ?9 F: z$ J: Z: J    {0 h# o# m' c7 t: l, u. i* c9 A  m
            return p->adjVex1==head?p->adjVex2:p->adjVex1;* D" K+ w* E# V7 B" k& [" K1 }. [
        }; T: _( p) {" y$ N! L
        else
    & U5 E; @/ c5 s& f6 V8 W) F- M        return -1;$ Z: z9 L: o( T6 f0 _' O
    }
    & M) C( K( y. `  B2 x/ s3 [/ D" ~  r
    " C$ _0 [' I; s& z/ q7 f
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    2 x4 A( N, F; e6 `9 ^! _" \/ Y% W{" x" ?8 U. O& j4 {' D6 N9 N
        stack<int> s;5 Q  e) ~  n! s
        int p,cur,pre;5 x4 o7 Z( P' a0 S- }
        //MultiAdjListNetworkArc<WeightType> *p,*q;
    7 O" Z! y3 d. [    for(int i=0; i<vexNum; i++) tag=0;//初始化
    ; R( L7 Q8 ~- b8 V+ V0 C# p4 g  B3 `" ^6 ]( E
        for(int i=0; i<vexNum; i++)! d" F% f3 d( J/ n# V- X( }+ N
        {: D/ d# R  S' G  N5 X, d& R
            cur=i;pre=-1;
    1 \7 j0 n! r7 e1 v, [, G7 J. [        while(tag[cur]==0||!s.empty())
    2 a: Q5 a& [1 k5 [1 A  y5 n0 h: Y        {
    1 h4 z5 @1 V: S3 W            while(tag[cur]==0)' S: f' `" ~$ _+ Y  o1 k
                {* m0 X- L/ b1 H& G7 \7 K( r4 f
                    cout<<vexTable[cur].data<<"  ";
    # b. `# G( ?$ m5 F% @' E2 g                s.push(cur);
    ; _/ q; G& {9 Q  w                tag[cur]=1;
    4 v. ^% q) r* g' O               //初次访问,标记入栈$ N9 @  ^1 g6 h* Y4 z

    0 D, c6 `0 d6 [2 c) U$ [, t               p=GetAdjVex(cur,pre);//p是cur的连通顶点
    ; @( A- G) q1 E" i3 c. [) }3 H               if(p==-1)
    : J4 b' w0 N( P3 N( @6 d: a               {
    $ J; j7 \# }6 `! b6 C; s                   pre=cur;s.pop();
    + ^6 A7 F7 t' E& f& `, R# E                   break;' s8 `- \# K4 m( H1 t( h) l2 |, j
                   }3 O4 ]  H! }: V0 E$ N
                   else# m6 [8 i5 d% l1 a7 ^
                   {6 V4 N, T' C5 d# d
                       pre=cur;" x# Q6 O  w3 X: T. i% J
                       cur=p;
    0 C3 r+ e0 |" |) k/ `4 X               }. H0 x. o3 ~. e4 A7 z; _+ l2 ^0 [
    8 j; I. T. N; \( I% e5 Q$ R
                }
    - Z* N* ^  P4 U4 N+ X            while(!s.empty())$ \+ n' x* o+ a' q/ I% u) ]
                {
    , d5 p) m  T) G. W                cur=s.top();
      k6 y7 I6 j, @3 Q                p=GetAdjVex(cur,pre);
    0 o9 m5 z: B4 A; i! U                if(tag[p]==0)
      o0 d  Y7 p: `8 ?* ~, a                {
    7 u( F# i+ j! L' U: }$ t2 y                    pre=cur;" |7 D& y3 ?3 V! K# I4 K6 w  v
                        cur=p;# I" i) S7 |8 E7 Z
                        break;
    - y7 T5 r' T: [2 u                }
    ) P* S7 y+ V, o+ W/ h/ M                else
    $ t7 t( U; Q9 k9 _/ Q+ m                {/ c+ T: x/ r; u! H4 t9 R
                        pre=s.top();
    ) Q3 Q' ~% `: e* L5 ]* F                    s.pop();
    - W2 V1 `/ @; |# v& M& w3 M% m; x                }9 C2 [6 D2 Y# N' U! O

    8 r$ W3 o* W2 D! K            }" V$ E+ D/ f8 F& I% F
    5 u% F1 C  ?1 v! ?3 H/ \( E
            }
    ( n3 `3 ]- H* k4 N, ~- p3 S5 r    }
    ! M) Q- a% @! R}3 i% w8 E6 |2 a, v! Y4 [* q% ?2 B
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()* e5 U" f1 {4 a% [4 m$ m* h
    {- n  c. [  s4 o0 v) I3 v4 i. `
        for(int i=0; i<vexNum; i++)
    , W# t8 p2 _5 O        tag=0;- v0 F, `7 R7 m) O
        queue<int> q;5 N- S+ s! Y. L- D7 l) r; [7 K6 p7 n
        int tmp,t;! }% B, @0 x$ {! G
        MultiAdjListNetworkArc<WeightType> *p;9 b% U. `6 C% @% j+ A1 Z& H8 L% N
        for(int i=0; i<vexNum; i++)/ o0 K7 Z) b8 \( c
        {) u4 Z6 L/ ~3 `  n; r
            if(tag==0)
    0 ]- K. S4 k4 S* N+ }, N        {3 e' m& P* }4 W; l9 k
                tag=1;' l1 K- M, w& x1 i# L" E/ J) L
                q.push(i);% c# @2 V! W0 U9 r! I/ _5 Q
                cout<<setw(3)<<vexTable.data;  n' c: W: E9 F( j9 Q  R5 [
            }) }& a# R3 N/ m2 H/ V  V
            while(!q.empty())" \' h/ d0 j( M' ]: U' \7 j/ d" J
            {+ t" X! j% V0 ?5 \# q5 o
                tmp=q.front();$ d9 W- f1 E" q9 _4 J
                q.pop();
    / y0 ?8 V, H2 S7 ?/ n, {; e            p=vexTable[tmp].firstarc;; q* [2 y" I# w/ ~7 ^
                while(p!=NULL)
    # p: ~% }, {- t# p. A: @( {  g            {/ E8 O! {! \9 D0 m1 n! v
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);% i) o* U5 I$ O1 G5 h( S
                    if(tag[t]==0)  o+ Y7 \/ i  d$ [/ u
                    {
    , X9 K2 p/ O; J: H                    cout<<setw(3)<<vexTable[t].data;
    - q+ }8 H- u0 u                    tag[t]=1;% K& `6 K1 a9 {8 w4 |3 i; a
                        q.push(t);
    $ f. `- B% v' ^0 ^# i+ D2 L1 W' O                }
    " E8 F& A5 W. {+ }7 T9 R$ j  J                p=NextArc(tmp,p);9 G" R* ]8 }/ y" a  j2 c& j
                }  y+ j6 M) B/ z0 ]7 J
            }
    ; i! O; O9 x' d' ~% T    }9 c* j1 h! {% R
    }
    2 y9 Q# D6 J8 h$ }- Y% L) D7 o. mtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    : z6 E. {2 d) z3 v{! b; @+ J( [; Q# `/ |% o
        MultiAdjListNetworkArc<WeightType> *p;
    1 I7 v  U! H4 M    cout << "无向图有" << vexNum << "个点,分别为:";$ o+ n5 W9 _" G2 C" [
        for (int i = 0; i < vexNum; i++)
    " O8 v; K9 v1 N1 W2 _        cout << vexTable.data << " ";
    - a! l* d& [* R+ L9 ?4 X! r: v. ~4 W    cout << endl;9 \0 {  e9 q7 i: H
        cout << "无向图有" << arcNum << "条边"<<endl;$ Y3 {/ j. z* i2 @9 e( m
        for (int i = 0; i < vexNum; i++)6 J$ q% d! k8 z) Q0 o0 m
        {- \( k! p' p" H$ _
            cout<<"和" << vexTable.data << "有关的边:";
      O: {3 ?! `; ?8 h/ A' N        p = vexTable.firstarc;
      n! X4 u0 l( Q6 D7 q        while (p != NULL)
    ) ?5 a6 M+ w* j" a! b, t* ?        {2 ~! S& l. R6 x$ j
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    7 ?# l9 _3 Q9 q# u( q            p=NextArc(i,p);
    7 n  Q% y  s# e/ F3 ]7 G        }8 a3 T, _" v$ q' s  ^
            cout << endl;
    / d; |% e) B& ?1 l    }
    2 V( F( t5 b) t8 N5 c}
    2 r5 h7 z, x7 [2 F
    / j& z, p: k$ D3 [. r* o3 y9 X0 G1 I. t: M! V
    邻接多重表与邻接表的对比
    , `3 C. F9 `% a' L6 K7 M, p0 M$ j
    邻接表链接+ r& @2 R9 Z* C& G: d
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。( T4 G. |- j8 j: Q- _: u) ^
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    0 e& Q3 K0 e' A/ j+ {* L( H- Q为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    1 ^, i1 n5 ?/ J/ u% o' @————————————————
    & L* _7 U  n  r版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    , U: j2 M, ?9 C. x8 G1 J- J) n原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    # U+ v' E: W  X7 V6 G
    , N/ V: }- g7 Z4 X
      {( w3 S4 ^5 Z& ^0 g3 X/ r! I! E; C# H/ Z' T. T
    " T. g6 i; q) d- |1 }
    ————————————————
    ! ^- |0 L* I' Y" \+ S# L版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    . m/ x( ]4 z. d原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958- M" a3 D, ~# q% ?* H. U- P1 b! R
    4 k1 m* M/ y/ o8 |, L; V# C

    % u  X  F% i! 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, 2026-4-20 13:32 , Processed in 0.348276 second(s), 54 queries .

    回顶部