QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1590|回复: 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
    6 \6 x& `2 G8 `" x/ S, k
    图的存储结构——邻接多重表(多重邻接表)的实现, j0 M' `# K6 Y* A. {
    7.2 图的存储结构" E' Q% e) a; y, W5 t

    . H7 t% _, A+ W5 G* _! O7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    6 y4 N; w4 @( R/ Y: m邻接多重表的类定义$ r: ~& Y3 d: M2 P9 h
    邻接多重表的顶点结点类模板3 x% s5 c/ s( e/ {. Y4 q9 K# M1 c
    邻接多重表的边结点类模板4 u; {; ?9 R8 b
    邻接多重表的类模板  G- y; m- T: C9 \6 C- `7 F
    邻接多重表与邻接表的对比8 r/ H* V/ w. F5 T- @
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist7 H1 {, u0 {: y  v2 s
    " k- ?$ @/ Z* j6 D% Y  c# t
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。0 B6 q- @; J- o8 R3 R/ S! @
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。+ @( |. l  I0 ]
    2 y+ w$ c# y& _+ W: ]( \
    邻接多重表的类定义0 \5 f2 s0 b4 s! \9 E" c/ Z
    1.png
    3 @- z" J, {- Z" p, l/ v5 ^# s邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:" [3 V( H& {3 U4 k1 N
    data域存储有关顶点的信息;: W1 n( ~( j( o; {+ ]2 f; S
    firstarc域是链接指针,指向第一条依附于该顶点的边。
    9 ]: \0 q1 Y9 x. S所有的顶点结点组成一个顺序表。


    . f1 r) o6 D# v: R- u! E0 n! D2 ]; ~2 M$ A4 g
    template <class ElemType ,class WeightType>
    ) k0 B, k( W* Y! S/ Sclass MultiAdjListNetworkVex+ j! h! ^3 @' |* S+ g, U3 A
    {
    ( q& p/ N9 l$ G" G+ B" _; t4 Cpublic:
    3 G: c3 j$ q& k* W6 k1 y; C        ElemType data;
    0 E! k& i+ o. _2 j        MultiAdjListNetworkArc<WeightType> *firstarc;
    0 Q: N# ?/ j' o. H
    9 n6 k8 S6 [/ d        MultiAdjListNetworkVex(), j2 A" o8 b& {
            {
    / L; c9 ]0 W- p6 \3 _& K9 n                firstarc = NULL;) G4 c6 M" n6 h
            }
    / ]7 ]. F0 d" c3 z* j        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)* K) h+ I; t5 e2 e, u5 U
            {
    . y+ c2 _; _1 c. e4 h* z                data = val;1 l. D8 t8 I  R- N/ q
                    firstarc = adj;
    : E9 N( w* [. h$ j9 ^        }# S. L4 H$ ]1 Z  K) T3 J
    };
    5 L0 Y! q8 ]6 F/ {% |2 S) y* L: H" a' i. {0 T2 ~# F" ^6 T
    邻接多重表的边结点类模板; `0 p6 R1 s2 a5 @' w, H
    $ W+ L" w$ D0 s& P" u% Q4 r5 g' M* v
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:8 L! k2 c7 f0 ^; f# H/ O0 \' z7 o
    tag是标记域,标记该边是否被处理或被搜索过;" z, F" c: ]/ W& x  O$ S! C
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
      m6 w% i$ o  x+ l8 r8 Jnextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;8 K1 ~* p9 k2 M$ n/ }6 k3 J3 a2 C
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    + N% J$ Z" c7 ~  b2 m/ t; w+ M% g9 Q- u+ [' Z/ \* g1 F
    2.png
    1 v. m' x8 s. U$ Etemplate <class WeightType>
    + Z" u: O' ~7 ~9 h; D6 g7 M7 Bclass MultiAdjListNetworkArc
    / t! X: W- `% Y( t1 z3 m" W( X, a{9 q4 ~7 X: y+ g" Y
    public:
    0 {3 A5 K5 }- R7 O    int mark;                                       //标记该边是否被搜索或处理过4 z- w  w% x5 D" F
            WeightType weight;                              //边的权重
      o9 d0 h! {2 H% f6 X" [        int adjVex1;                                    //边的一个顶点
      o2 r# c( D) W) ~# g+ P+ V6 o' R2 X        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    " W* g" k: P/ U( j$ N* O$ b7 i        int adjVex2;8 P3 l8 h' R7 y2 }" [, T- C( x
            MultiAdjListNetworkArc<WeightType>* nextarc2;8 B/ ~2 [( f" Y  S: b2 {5 a

    " M5 S! l% y+ j# H1 y6 x" h% n        MultiAdjListNetworkArc()7 }# C" n5 J& P
            {6 k& a/ {7 q- ?$ [0 w6 p
                    adjVex1= -1;
    5 a$ s/ Y( e& H. r. K                adjVex2= -1;, c4 K0 y" I8 ]6 n$ x
            }7 ?; A  W: e, d) S9 ^
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)" P: R+ O5 Y5 ?  D* v7 q
            {
    7 e1 R/ i4 i4 p                adjVex1 = v1;       adjVex2 = v2;
    , ^7 ?0 U& Y: S/ j& ?                weight = w;
    / c( j9 j# O1 R% a" q9 ^                nextarc1 = next1;   nextarc2=next2;
    4 F0 i* g- E; V+ Y                mark = 0;           //0表示未被搜索,1表示被搜索过6 P7 z/ X4 A1 p2 |$ l1 o9 V
            }
    0 Z! X4 T  S( U1 b8 g' X
    4 j4 i8 s/ K, }+ T2 i邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    5 k' Y5 w! D# s. T, Q% k3 Xclass MultiAdjListNetwork. R9 U4 g7 ^4 p( m
    {
      X% b) j5 J3 e; e  c  ~protected:
    $ J- \/ D. M7 E$ E, I1 {' ~4 C    int vexNum, vexMaxNum, arcNum;
    ) V1 L4 F  `! N, r% G+ {    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    3 |& w* X* l8 o! ^. O8 X, @    int* tag;8 H5 e. s1 m/ r
        WeightType infinity;
    8 F3 k8 L7 h0 s9 X$ S$ ^( n5 V5 q& [/ v; p
    public:
    2 }' F  }! h) Z3 J, h% l1 F7 \    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    0 @5 X8 J: Z9 q5 b& m1 n, W" M9 W! K
    . D0 U" e0 d! G* |7 l0 z) {1 J    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    " q! o9 ?+ q; t3 r2 l( K! N5 P! a. z/ C: ?  [# E# b, H
        void Clear();
    ( N, ~9 T/ b) n    bool IsEmpty()
    6 w2 `( C* e! G4 c$ A! x    {! U9 O* Y* E: T2 E- e" F
            return vexNum == 0;
    : z9 L0 s. m1 b' P+ n    }
    1 W. \" I% \* R6 ~# r    int GetArcNum()const" E2 u# g1 C. L0 C, }; s: s
        {. M. i9 F% A& S* b- U
            return arcNum;
    1 L: `# X' g; S2 z8 m    }% e  ^6 i0 X( R: o5 I
        int GetvexNum()const. F) |3 S& D" b5 n, m7 @
        {
    ; t3 [& S2 {  `. }/ j9 Q4 Y        return vexNum;5 d5 Y  _2 f8 A1 K. {
        }( O* ]6 \2 p; i" Q3 `& x
    1 Y" Z: W5 P& |/ I) U

    ( T3 q4 s- z, ~5 ~0 l& e( y    int FirstAdjVex(int v)const;" k; s* h, c+ m' k+ v& l7 \7 L
        int NextAdjVex(int v1, int v2)const;
    & a4 P& r9 l. _2 o) S    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    " n9 b* J. X! p    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    + d. J! r- v4 S. S
    0 @* ?+ p) x* t' X1 K3 Y& k    void InsertVex(const ElemType& d);
    ( v& n; W1 v# P1 R    void InsertArc(int v1, int v2, WeightType w);
    + Z: A( d( v! s/ |  \. Y) }' o- ]+ _
        void DeleteVex(const ElemType& d);
    $ H. h: g5 _. p( S1 B( f    void DeleteArc(int v1, int v2);; m& p0 H  e6 j4 K; B- s. [$ k
    ' t3 X* x6 h  I6 N  D0 ^; R, z9 L
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);5 y+ N. e$ g0 t8 z5 }
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    4 i/ S* b0 q2 i0 k$ p
    ( t* n: V0 H" c' w    ///深度优先遍历0 a( T  v# U( ~9 y7 R
        void DFS1(const int v);! e7 A3 K  S. S+ d) l% V, `. V
        void DFS1Traverse();
    0 n" B8 b/ @- T5 f) r5 Z* w    void DFS2();/ r+ W3 V) ]. J% f" \; a- G- @0 A- D5 u

    + g5 C# W5 B# A0 e, z* ~$ {    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1  v  T0 `7 @7 h" w" @
        void DFS3();
    / Y6 Z7 Y, E' i* e4 \( e" t, [- M1 {! B4 S" b
        void BFS();: t* A/ I, x: ?5 L, _
        void Show();' K# G/ A( w7 ?
    };( k9 F1 }6 l0 d3 f! R9 n

    4 Z& F. v3 b( I- d* ]2.函数的实现
    4 C- |8 w( U4 D2 }2 k, C+ R+ e/ T1 b研讨题,能够运行,但是代码不一定是最优的。+ s8 y& p8 V: U! M1 M% q

    8 O( l  m4 `2 O9 [, v  u#include <stack>  q% }$ j1 h$ J( [. f
    #include <queue>+ B4 I+ v/ E/ _* Z9 \4 @. E% \, g1 P6 }
    $ w* J' r& x( x+ T0 P) F; k
    template <class ElemType,class WeightType>
    ( |4 F& n1 G7 iMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    2 @+ ?. g, N/ g( Q5 N7 q# w{
    ) Q5 r+ Q4 n0 v    if(vertexMaxNum < 0)
    % w* Z) @) D$ C0 J        throw Error("允许的顶点最大数目不能为负!");! j. q+ Y$ F- f* h% t: L2 y
        if (vertexMaxNum < vertexNum)5 \* T1 u( b, J. b3 H3 z/ t
            throw Error("顶点数目不能大于允许的顶点最大数目!");( l! o0 o4 z) U% ^6 E
        vexNum = vertexNum;
      r4 \1 t5 y: v2 a9 J" r    vexMaxNum = vertexMaxNum;7 F- f: A0 k0 {7 k. L
        arcNum = 0;5 E( d# U. `4 E. d- X5 [
        infinity = infinit;5 x# o" b& }2 p
        tag = new int[vexMaxNum];
    4 L9 I% \$ K( [1 q) b    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
      d0 R8 L& T' f8 H5 _6 M- O    for (int v = 0; v < vexNum; v++)7 c3 {/ d% W! C/ K+ ^9 C8 K
        {
    % l0 v2 U# H1 ~        tag[v] = 0;
    0 {( L! ]" [* Q$ [4 Q8 U# c        vexTable[v].data = es[v];
    9 T2 j& d7 z0 @" K3 }* T        vexTable[v].firstarc = NULL;
    7 D% S8 A0 I3 y    }. r1 W3 X8 x3 w4 Z
    }' x8 G+ s: k+ u1 h  N) D9 t$ h
    template <class ElemType,class WeightType>" E# B2 z; S2 p% k5 U4 r
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)) T6 Z2 n3 _9 l. D
    {
    * N5 I, C* s/ a% z    if (vertexMaxNum < 0)
    4 L9 T3 d8 o: O  A        throw Error("允许的顶点最大数目不能为负!");
    & b+ a9 U9 ~/ s8 Z    vexNum = 0;
    ) O4 d- K1 K7 i9 I4 i0 H    vexMaxNum = vertexMaxNum;  j+ ]" o# `' ^) E$ F
        arcNum = 0;7 w1 }; ?+ _& B
        infinity = infinit;! M" A" I! C* X- _) Q, y& j1 R$ S
        tag = new int[vexMaxNum];
    ( G* K8 n  U: U, }    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    4 {; H9 u4 A9 p2 m! D2 B}+ i) Y) Y5 R; I: M# h3 S7 E* ~
    template<class ElemType, class WeightType>
    2 S" l9 K: s3 p% lint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    6 z; i# D3 I" S/ g{+ c7 ?$ b! _) ?  I6 e0 S# |  a
        if (v < 0 || v >= vexNum)8 Q! g, O" u" A9 _
            throw Error("v不合法!");! k& I) b" D: L
        if (vexTable[v].firstarc == NULL)
    " ?, A8 V/ d; |& H2 |$ e        return -1;5 @* G4 x# I! S+ D/ \8 W
        else
    $ B- U7 Z# @& d, ~( i  p0 z        return vexTable[v].firstarc->adjVex1;! C3 r3 d! @+ k$ }9 t' Q
    }- t2 @2 ~: y" r" K, Y( M* [
    & r- G% q' r! q" B& e/ X& i9 Y( @
    template<class ElemType, class WeightType>5 X3 I1 I, p; H9 L; m
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    * d1 {  W7 f4 A% N* h5 T4 j% J) A0 l' s7 w{- R6 t) `+ h: i0 }
        MultiAdjListNetworkArc<WeightType>* p;- K6 g- q$ K- T1 e
        if (v1 < 0 || v1 >= vexNum)
    0 e  ]  R, w5 i1 A7 p4 x        throw Error("v1不合法!");& Q6 y! O0 n  e. {/ j
        if (v2 < 0 || v2 >= vexNum)- ^4 @3 r6 l; m+ D
            throw Error("v2不合法!");" G, X# ?7 z5 [$ Q
        if (v1 == v2); E! {$ S  L. ?5 K: X
            throw Error("v1不能等于v2!");
    ( }) I+ a9 w! o' G    p = vexTable[v1].firstarc;
    8 x8 r9 o% v/ e    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)# `+ I8 a$ ]* b4 ]8 m' X
            p = p->nextarc;, n$ F  l( A9 `  Y; Q7 [0 ?
        if (p == NULL || p->nextarc == NULL)! R5 c8 G! V, s: N
            return -1;  //不存在下一个邻接点: ~: O, J% Z' ]: J  r- ?/ S
        else if(p->adjVex1==v2)
    + N! R) F% b) R  z& k; y        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);$ U: a, ~: G/ b) ?( b
        else- Q$ c! l+ J6 E' v. C" b4 T. F
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    5 L7 R! G# }0 p+ M8 `- P2 s}: U* Y( G( n+ _0 `+ r
    template<class ElemType, class WeightType>5 |9 a* F4 L' g
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()' U; d5 D: L1 _4 c1 ?$ t
    {
    * K# w! Q; q. C: m* y    if (IsEmpty()) return;. o% |0 H) J! c( F
        int n = vexNum;* U3 I8 e3 T6 h: E
        for (int u = 0; u < n ; u++)
    8 b, k; t; J4 o# a        DeleteVex(vexTable[0].data);
    ! A5 v) c1 @! t9 L1 L/ Y    return;
    ; c. t( k' x- c! {( ^}
    # Q* D: \6 t" N5 \0 \, M; u8 B) Ztemplate<class ElemType, class WeightType>! g- e8 A+ X" o- R1 s
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    8 @; h" x* E$ y5 a, _3 a2 E{
    * _+ J$ B) l# r2 p8 g    Clear();- [1 ]! i$ \) L* K+ m5 R
    }
    1 o% h  A5 s0 |3 Ltemplate<class ElemType, class WeightType>% \* U; ?0 h2 C* z$ _  w" F! ?9 ~
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)1 W/ o% s( n8 H' m
    {
    7 H) ^3 ?- T% p0 ^$ @    vexMaxNum = copy.vexMaxNum;
    8 r; T  d% [% E. O4 w- i1 g    vexNum = copy.vexNum;: R+ E- u8 d% c/ M- @! e4 p* o4 C
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    * ^3 b1 K. g1 m- E2 g    arcNum = 0;! k9 @; o2 J, w
        infinity = copy.infinity;
    5 e2 k9 z: a/ H7 g- `    tag = new int[vexMaxNum];' {# H1 U; {7 `
    " p( A# ]  O8 A; x
        for (int v = 0; v < vexNum; v++)
    ( _' f* f! c* J" [* s& s: o    {
    & X  _7 L6 I0 q        tag[v] = 0;3 e1 n+ }$ @+ b% S
            vexTable[v].data = copy.vexTable[v].data;* {3 J% V' n! |& X; I% v! _
            vexTable[v].firstarc = NULL;
    8 H4 r$ ]2 N- o$ Z3 _1 u4 m8 q7 w    }
    / A& |- X; M9 B: U8 J- ], b+ }& S    MultiAdjListNetworkArc<WeightType>* p;
    . P$ s9 Q( c- |1 F" l+ t) _3 S2 r) ]5 |- _4 U5 H8 \
        for (int u = 0; u < vexNum; u++)4 {" f: M, m5 i
        {
    ) @4 P& k& C- e8 c1 N        p = copy.vexTable.firstarc;
    5 a# r- Y" t2 Q% ], J/ E        while (p != NULL)0 m+ f; C- t3 [3 G8 H
            {
    # e! K' L" D0 \; v1 [            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    - n6 {( O( r9 k$ u4 }& Z+ [9 j# R            p=NextArc(u,p);2 H" u7 U3 c3 Q  Z% n$ t5 T
            }4 n) Z( r* }) a7 X* A9 u1 N+ W! Z0 P
        }
    0 W# N  q( H8 D* F& K}1 y: s, [  A. x2 t' I, K  J& z
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&+ U* P2 \( `7 n& r$ L! D
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)- o3 B6 C9 P( |1 t# J$ x
    {6 @  Q  p- E$ f8 C
        if (this == &copy) return *this;
    9 b" k3 w7 x1 l6 _0 b* j& h8 T% [1 v    Clear();: n  j7 S- I% f1 _/ h
        vexMaxNum = copy.vexMaxNum;" C  F# a0 Y$ F
        vexNum = copy.vexNum;) j1 V- b) `% ?# X
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];/ c. A/ X2 c: Y0 y% T+ v9 \
        arcNum = 0;
    & p$ ]1 A) L, i/ D    infinity = copy.infinity;
    . t  n- k" v1 U: z- d( @    tag = new int[vexMaxNum];4 J2 h' A: X* H& f, V4 p
      t  ~: M4 s4 d! m6 c4 z6 Q4 C
        for (int v = 0; v < vexNum; v++)3 v$ a6 b% l% Z' c7 O
        {" B3 {8 E- g+ X& Z1 |6 v
            tag[v] = 0;
    * a, Z0 V! U1 D8 w$ A        vexTable[v].data = copy.vexTable[v].data;0 I- B4 |3 H, J0 z
            vexTable[v].firstarc = NULL;
    8 T5 A) N: w& l( j& X7 [0 v    }
    : f, f3 L) ]( B7 g, l% E3 Y) Y    MultiAdjListNetworkArc<WeightType>* p;
    . j" i7 S7 f& R& e) n# S
    # [8 u) F# C0 X0 m, R  w    for (int u = 0; u < vexNum; u++)
    9 {; o$ `+ T' Q    {
    9 }$ I1 }5 \3 Q) E7 X        p = copy.vexTable.firstarc;
    2 {7 _( O7 X( g2 l2 D- N4 y& |. u        while (p != NULL)
    3 Z1 ~" X: R" X' Y/ K* Y        {
    / A$ }' U, _" d- ?7 x2 C            InsertArc(p->adjVex1, p->adjVex2, p->weight);8 Q3 i( S) C8 F8 g+ ~
                p=NextArc(u,p);
    * z3 S1 Q- U0 X! l        }; X( Z4 g7 ~7 i. l8 n
        }
    7 v: Q: p, y- o    return *this;/ N2 V2 b. i$ Q) m3 B0 w; Y
    }( _+ D" T# J  T( j; @' u
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>** R5 d6 L$ |7 ?- ]) J; \
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    ) |5 m4 E2 C; W{
    & x) m; m1 F1 }7 ~    if(p==NULL) return NULL;, [! O+ @( B0 J+ ^) p* S3 E
        if(p->adjVex1==v1)- z9 N9 W% L4 n% L
            return p->nextarc1;
    + I/ y! Q: Q& F8 F  {% Y    else
    0 h( E, a/ z; s# _' x        return p->nextarc2;
    ; i) o4 u0 F! g4 x# i}
    $ ]' {0 g) j  {* u( ]4 u, s; J2 `/ itemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*2 A, k8 R- o  J0 G7 p
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const* E: A. }( m% L9 u) W2 B) S7 Y1 ?
    {$ g) }! U* ]6 p
        if(p==NULL)return NULL;9 K' W/ Y; Y9 h3 ^) M- K
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    * Y" w$ h& `1 o) @1 Z    if(q==p)# v0 _# @: A3 s( G0 X
            return NULL;
    ( E4 e/ s* }$ h6 ]+ Z: C& ~    while(q)* ]' q4 A8 p9 I  d% C  |& G* q5 d
        {8 b; _4 N8 @( H9 o% U
            if(q->nextarc1==p ||q->nextarc2==p)
    * N- X# L/ q# f9 o3 U            break;: x7 h, S% a/ \. k! n/ k
            q=NextArc(v1,q);: C% i8 @8 _  B; z( T: J2 Z+ V
        }
    4 Q" F% j+ C, d+ S/ J3 v% q    return q;& R6 ?% M: K; ?- v4 a1 E# [' L; e0 z8 n
    }
    * p. q& M8 i+ n- Htemplate<class ElemType, class WeightType>/ w) V1 v, _" e* p
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)$ a7 n' Q8 t1 n7 i9 ~
    {: W! L5 E8 L; J5 N" c' m. \/ l
        if (vexNum == vexMaxNum)
    , ?% G1 g( v% \) n) R/ E. g        throw Error("图的顶点数不能超过允许的最大数!");
    ! v8 A4 a! G, p0 X  J* e- B    vexTable[vexNum].data = d;
    ( n- Y# U$ [, R$ B5 |. |* h7 Y1 ?* U    vexTable[vexNum].firstarc = NULL;3 X+ c' V8 v* U& ^8 P  {
        tag[vexNum] = 0;
    4 t' {* B5 B& ]- u0 l4 _% t; g    vexNum++;
    ' B4 C( ~- x7 R7 c- e+ `- T}$ X! n: @& d5 [" W0 e
    template<class ElemType, class WeightType>$ \+ n' H$ q0 k1 C& K2 }* H2 O
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    9 V: K' Z' `  l! c/ o" @/ _{
    5 u7 T) G3 v# [* ^  P- f+ a* i    MultiAdjListNetworkArc<WeightType>* p,*q;
    / ]$ i9 k: D/ v" {$ w; U# y    if (v1 < 0 || v1 >= vexNum)
    $ u) W2 U7 h# @' Q9 Q  F5 q        throw Error("v1不合法!");
    ! j- u! N- t. H5 S$ f    if (v2 < 0 || v2 >= vexNum)& G  n& o: z8 ~0 ?8 }" j0 m" R  x
            throw Error("v2不合法!");
    8 p# _8 e3 j) ]; a5 ]% j    if (v1 == v2)1 A  K; W9 Q  O& C
            throw Error("v1不能等于v2!");5 m# h2 L' E$ ?' g1 m
        if (w == infinity)/ {- d% }+ b: C$ O( f
            throw Error("w不能为无穷大!");
    " z, V7 D: e( ]
    1 P: G* }( z( C/ y( A% o& P* w) v* h/ `2 L2 y' k
        p = vexTable[v1].firstarc;
    6 R$ e+ U# Z! L    while(p)* l9 d6 e8 P. K# s3 D; e, S2 |
        {
    " B) A9 ~, P- z3 G/ M        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    1 E' H* E" h  z' a/ W, t2 E( m9 u9 ?        {5 j1 D$ k3 P5 b+ [
                if(p->weight!=w)
    1 g+ z; W, b; n; n/ r9 m                p->weight=w;: R8 _! D# X& [  \7 H7 a
                return;& k8 ]8 e8 x) r- w: \
            }
      q4 M& F1 Q# h$ v4 g% \! k
    % O3 S/ ^# \: E, M) m        p=NextArc(v1,p);
    " h4 ]! C- C2 l    }
    + _7 Y# W6 c: R/ Z    p = vexTable[v1].firstarc;! b, R& J9 v; p  c
        q = vexTable[v2].firstarc;
    & Y1 Z5 C+ J( w    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法& B/ [3 T" O. t5 m% E
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    , m, l# S; R  u, d    arcNum++;
    : g& y; E( p0 c6 O* h! ?5 y}  y# V! @& L  I+ Z4 ^/ m$ X" P
    1 l) Y  D3 y# T5 ]2 _# L' r
    template<class ElemType, class WeightType>* P# K& A" \. P
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)$ _3 Q  D) r5 v! X5 @% h7 |
    {
    ; j8 Q' ?8 |5 l% ?5 |
    : {9 Q: V; ]. p0 g; \% F1 k    MultiAdjListNetworkArc<WeightType>* p, * q,*r;3 ]1 U+ h% w0 j( |$ O2 G) k
        if (v1 < 0 || v1 >= vexNum)
    9 j' J9 `+ N9 a; ]        throw Error("v1不合法!");
    3 S% f, Y. S# ?' @3 l    if (v2 < 0 || v2 >= vexNum)
    ; A8 _9 Y; s3 p  K( L        throw Error("v2不合法!");
    % b, E1 N$ w2 n; A    if (v1 == v2)
    ( K2 j: o3 l: ?. m) c. E        throw Error("v1不能等于v2!");- A6 T3 o3 t7 J: X7 y

    . a2 W1 a6 @) t9 w6 g7 y) l" y    p = vexTable[v1].firstarc;6 v- c5 h% X& b" F4 T( Q* }
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)4 n5 K2 [/ o% B$ w" Q
        {& S" k. _: h! t5 t% n
            q = p;
    5 b# P' m; H5 m; `0 g        p = NextArc(v1,p);
    1 v0 R5 }- W0 X7 L% L1 o    }//找到要删除的边结点p及其前一结点q
    7 d- d8 P9 M9 M& ?5 k6 B2 h& q8 B" F$ |6 o4 q2 |
        if (p != NULL)//找到v1-v2的边  n/ h# V- f, r$ a
        {
    * }1 F" g; J9 Q; J- R8 R        r=LastArc(v2,p);9 M2 [8 I5 ]9 z( I
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    " s! Q1 e% }2 w            if(p->adjVex2==v2)
    - S8 a+ G( P% d: s; c                vexTable[v1].firstarc = p->nextarc1;
      i- N8 m- P' t0 Z            else vexTable[v1].firstarc=p->nextarc2;  w+ @9 _7 u* g8 r7 v2 B+ X
            else//不是第一条边
    ' m3 j& F- j& A+ Q        {! u( B" n! Y2 L7 l* S
                if(q->adjVex1==v1)4 P7 ?+ h% p8 y" _: m; Y
                    q->nextarc1 = NextArc(v1,p);
    ) g5 b! N- ]' g5 Z6 A, P4 i( D            else  f, V3 z$ G4 @/ y  w" V
                    q->nextarc2=NextArc(v1,p);! {6 G* Z" A; u9 Q) I5 }# F5 F" A# i
    8 I4 \" ~6 Y+ A
            }! }' e6 r4 ~# c( k- a+ U# J9 i
            if(r==NULL)
    , I0 W* \$ t7 x; T: C; ~9 ^* _. k            if(p->adjVex2==v2)& [; S2 N, h) H3 d
                    vexTable[v2].firstarc = p->nextarc2;
    / c% H1 P+ m0 N9 t3 ~            else vexTable[v2].firstarc=p->nextarc1;1 e: p. N/ w% s8 b5 r5 n6 T: B
            else
    2 `# ~( o6 F% U        {
    2 K  Z+ U6 G' n: {0 V3 v            if(r->adjVex2==v2)
    ( }% L& {5 |4 V" V, z                r->nextarc2 = NextArc(v2,p);
    $ Z% K' ~8 I+ M( X8 W" v$ ?! _            else9 p5 ~5 q# U% Z+ Z: A
                    r->nextarc1=NextArc(v2,p);/ t' t. z/ d5 c/ X0 s6 T: j
            }
    - Z0 `8 H  f' M; U4 Z        delete p;
    , u- V) N( u$ \2 g5 i        arcNum--;& Q: x4 B- v& y  M/ [) L
        }' ]2 F9 c0 T! M4 W

    ) f) H" L7 z: ]: u2 R}
    6 x, V( [% M. s' n: n: Z( }template<class ElemType, class WeightType> void
    3 R  a( x- i7 J" J/ _3 PMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d). x* n- @! M% R' l( c8 l7 o
    {/ A' Q# I% j4 j+ s- ~: ?. H  c2 ~2 ^
        int v;* j3 L6 _1 o7 u- Q, i- u5 g
        MultiAdjListNetworkArc<WeightType>* p;$ S- ?2 |. t: _* z4 L! E  D/ L
        for (v = 0; v < vexNum; v++)//找到d对应顶点' b% H; p3 h  N7 U7 `' w
            if (vexTable[v].data == d)( Z1 E! B5 K: P( ?
                break;" w4 Y8 h8 }8 x! |+ L9 L
        if(v==vexNum)
    ) e. ~* j3 [! M        throw Error("图中不存在要删除的顶点!");
    2 _% a& g6 r* f1 v( u3 K1 I4 m( [( n$ Q; J; ^
        for (int u = 0; u < vexNum; u++)//删除与d相连的边8 f0 [" W/ P/ R$ x5 q0 O" Y
            if (u != v)- \/ U4 x& c$ f
            {
    ' `# H# N& ?7 C/ R            DeleteArc(u, v);
    ' f; }, k3 i0 J4 X) U0 G& ?        }
    + t! W, m' h& Y& f' P1 W3 K    vexTable[v].firstarc=NULL;3 g6 S! Q% K* N# j

    ) {1 ]0 i7 C( E+ y+ W9 J    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置& c3 G* n( F/ `$ ?: O; R- c
        vexTable[v].data = vexTable[vexNum].data;& v, o$ m3 m/ M1 {$ C3 b
        vexTable[v].firstarc = vexTable[vexNum].firstarc;
    . d% V8 D/ N2 ?2 w6 c5 A    vexTable[vexNum].firstarc = NULL;6 }  S9 n! [6 _3 I! k/ x2 _* T$ y) o
        tag[v] = tag[vexNum];
    3 E9 @8 K" A4 _: Z- s    //原来与最后一个顶点相连的边改为与v相连
    + V4 z0 F+ i2 t3 J0 U8 v- i    for (int u = 0; u < vexNum; u++)9 t! g* _* I$ \1 T- T& N
        {: L2 u# Z- \" Z7 A( N2 r) k
            if (u != v)
    ; A: a+ p. ^+ O7 Z- C* _1 l) ]        {: W& \2 V: Y8 k, X- P5 p
                p = vexTable.firstarc;' M% {, v" a" r
                while (p)
    5 i1 Z* Y2 w2 G8 A            {0 L- u3 V6 E* g: f( s0 X- R
                    if (p->adjVex1==vexNum)
    / e- a- x& a* @- Z, A/ A                    p->adjVex1= v;
    # [( _5 N4 ?0 {, {                else if(p->adjVex2==vexNum)8 ], a" M1 U, {" y8 Y$ O: A
                        p->adjVex2=v;
    & ^. _( z- a2 U* k; u                p = NextArc(u,p);
    : }9 j9 M' ^+ G8 B+ D            }& g# u# s9 ]+ M5 M
            }' o8 x$ A: |% I4 V$ `
        }
    % _( V, E. f( ^" @}1 |2 M+ {. ?& m3 m" ?
    ///深度优先遍历
      s' {5 \5 d# G- wtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
      t. ~2 C0 F7 n1 X, D{
    0 r* l6 V5 p7 W' `; }: t    tag[v]=1;
    5 \! F  {. z8 x; k    cout<<setw(3)<<vexTable[v].data;
    8 ^0 }; |1 k9 ?7 L! a8 Q( L" {    MultiAdjListNetworkArc<WeightType> *p;- @; H  i! V  k; B$ E$ a
        p=vexTable[v].firstarc;
    % h4 s. m! ~0 R& R$ A6 Q    while(p)
    6 H' B" R! V( L' }5 B5 z" Z    {
    ; t2 G7 O( b9 O7 m" T+ b6 q        if(tag[p->adjVex1]==0)
    / [1 ]; B8 \& P2 ^/ c* q- [, J1 i            DFS1(p->adjVex1);
    5 n( B; m: P# z! B; I: G; @% N        else if(tag[p->adjVex2]==0)
    3 {, i# s9 X. o3 z, m' J            DFS1(p->adjVex2);
    . d1 h# S, W, Q4 t+ j        p=NextArc(v,p);( M  W% o, l( e7 U, H( m
        }7 d. T, C5 |: j5 ^1 W
    }( o( J- ~6 k8 U) y, F2 ]
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    ' B! V" |6 g7 r, Z{" ]! g  g9 n( x; ?8 @3 j" F
        for(int i=0; i<vexNum; i++)
    3 [5 S, U# O$ w5 u! k7 f& X: |, k        tag=0;2 r) b* i/ ]: m% B2 A$ v
        for(int v=0; v<vexNum; v++)5 I5 j7 W% ~( |6 X  m" \* R; N
        {
    * X( O/ L: `  V8 H- L0 O. \8 T* z        if(tag[v]==0)1 B, V" K' M5 D: B
                DFS1(v);
    ) T8 }* X' j( z    }/ |6 w: x4 [' r+ l3 F
    }
    - j! d1 O. D( W1 Xtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
      C! V; \8 k1 A5 t* i8 [{4 n- A% H* I7 Z
        stack<int> s;
    9 X& ?- a+ M2 D: Q% j6 M9 `. l0 n    int tmp;
    $ C  V% S( ^: `7 B6 S  T: h    MultiAdjListNetworkArc<WeightType> *p,*q;* E( P( h4 z( O) c
        for(int i=0; i<vexNum; i++)
    1 b, D" m' C* p; i        tag=0;
    $ r. y$ o* x1 r2 x: L0 s    for(int i=0; i<vexNum; i++)2 L5 r$ i( G; v
        {
    4 o% m3 i5 l# i2 ^        tmp=i;
    : q) J1 U; J+ m& D6 B- y: @        while(tag[tmp]==0||!s.empty())
    7 h) K/ u8 D4 c) Q+ D& L+ K# v        {
    1 B2 \# Y$ c) x) g* s% q0 a* C            p=vexTable[tmp].firstarc;3 `) k% T- k; O2 \
                while(tag[tmp]==0), B6 A0 G6 m: K5 c
                {% g# Z) O. D3 `# u$ T
                    s.push(tmp);
    7 m1 g& ]' E2 A& E2 D/ L                cout<<setw(3)<<vexTable[tmp].data;  Z1 o; ]% E- I" d
                    tag[tmp]=1;
    . j# ^: L$ M( t$ h( H                p=vexTable[tmp].firstarc;
    ! D0 N* A& c$ A/ A& t                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for# }1 O( r' j9 }( a
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    - P( m( Y* Z; d. y, i                //cout<<" 1st     tmp="<<tmp<<endl;
    9 T/ d1 }* I& n, P* I3 L. V  {7 Y; N            }
    : C3 M+ T1 o% Q* \3 W            if(!s.empty())
      e: B6 c& j& s6 f" R2 m' G6 D            {
    , I: @- G+ `" [. z# v                tmp=s.top();
    8 I) _( E; Y1 q! r& f# P: T                s.pop();
    # s1 }! f. r2 c( t# z                q=vexTable[tmp].firstarc;
    ' I/ `4 q+ p* f                int t=tmp;0 @( D. i* Z7 Y# y- g4 O7 k
                    while(q&&tag[tmp]!=0)
    9 _% ?: n# z& b: y. A9 ]' Y1 i                {* e4 z( C, r& b% Q3 w
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);/ {5 r/ P6 U* n% ~. S. O" ?
                        //cout<<" 2nd     tmp="<<tmp<<endl;
    ) a7 [$ @% p* w$ z3 _+ a3 J                    q=NextArc(t,q);
    9 S& L$ G9 Y8 `. O1 D- M; I5 W                }
    " W1 e& f" {. ?                if(tag[tmp]==0)
    " H# Y/ y8 E3 O/ z; f4 }2 ?5 m                    s.push(t);* f, V7 C* S5 y1 I. a8 w7 d. u  R
                    ///1、对应上面连通分支只有1个点的情况0 v$ V" S, ~9 K% P
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈% W3 g5 Z: ^# c- B7 u  a( H9 _
                    ///tmp要么等于找到的第一个未访问节点,
    & f# w, k, q4 `# p) l1 F4 y- U                ///要么等于与t相连最后一个点(已被访问过)$ f/ P' h0 o4 C9 k2 N
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点* I" ?" }4 u- K4 x& g0 ]' c* w
                }' U3 z$ K8 Q5 L0 m: K8 O# t
            }3 v0 b5 B& J& O" }, m, W
        }
    4 s2 \* {0 N' f' f& A  S}  p, o% l4 K) q
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    5 i# N$ R! H; Wtemplate<class ElemType, class WeightType> int, c+ j6 \9 m) @) Q7 ]' o: f
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    % e/ y  n' ^- V* S{  g0 Y" \2 v/ `
        if(head==pre)' u# y7 m! O. |3 S$ n8 b: `! }
            return -1;4 }% ~2 P7 k  m" j" E
    $ v* A+ U' q1 v6 n' [
        MultiAdjListNetworkArc<WeightType> *p;! C( n8 h; u" G+ r; S
        p=vexTable[head].firstarc;% ~& [. `  v; A: O! P: Q
        if(pre==-1&&p!=NULL)/ @. q" F4 e+ y3 x$ A3 c8 c; o* o: Q8 d
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    2 I5 x& g, n, [( ^! V4 r  f5 G    //pre!=-1&&p!=NULL
    - v& O# w; A  G( f4 J    while(p!=NULL)
    4 w: y7 e- i4 W2 n    {. f# O) ?- o1 B" g: t0 ~
            if(p->adjVex1==head && p->adjVex2!=pre). J+ Z8 o4 P$ Y4 I9 F, h! Y
                p=p->nextarc1;1 j6 a8 h; p4 N! u& E" Q& L
            else if(p->adjVex2==head && p->adjVex1!=pre)
    / C- o2 ?6 C( D            p=p->nextarc2;
    ! v% s! B3 E' a2 W& a; O/ Q        else if(p->adjVex1==head && p->adjVex2==pre)
    5 N7 T- O& p% n* B, ~7 A        {: E7 U( y6 `4 t% M3 b3 p- }
                p=p->nextarc1;* b. |7 ?+ N% Z
                break;
    # S+ b7 U% W; L4 B: G% {( _; \2 @7 X        }- P5 T( T" t- a& V
            else if(p->adjVex2==head && p->adjVex1==pre)
    1 @/ i1 d# W. j1 h& K; r4 {        {' E" x2 R3 S6 Q* A3 b$ b+ r
                p=p->nextarc2;
    - u# G5 E# k/ q/ s            break;" D+ e5 T7 u! r
            }
    3 }2 O2 b* m1 v& x+ k* e    }
    & t: ]6 U3 M, d+ d$ l6 r# u    if(p!=NULL)
    7 D; u3 N- P1 g' s0 `' d    {
    ( s& }2 J  Z4 O7 ~- q1 ?        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    % |* x# v3 K( h( o% B1 p    }1 b% n5 }4 j- \. y3 d6 l% Q
        else
      U2 J3 V: U  |) t! j" n+ D3 c$ y        return -1;
    ) ]& P! r% {, p}3 N4 r  E" Y* c5 S9 p' t9 B, z
      ]; V" f, f6 y- v+ d' y

    ; K% h$ Q$ s% M9 |. k, `template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()( M, l; L6 C8 s4 X! ]; y: ^' I
    {
    " [* w0 }/ p& ?  }4 E    stack<int> s;
    8 }" E* U+ z) u; x6 G" h6 D    int p,cur,pre;2 h# R) ^" R/ T5 z
        //MultiAdjListNetworkArc<WeightType> *p,*q;* \( h- h0 s' r; R! e& ~+ H4 R
        for(int i=0; i<vexNum; i++) tag=0;//初始化. {4 [1 `8 B9 Z; j$ p% Q

    7 x! x1 U& k: {0 O& B4 A    for(int i=0; i<vexNum; i++)0 O3 z2 X9 Y3 H' X8 y
        {
    " Y1 }, K5 B- j$ O) q: c        cur=i;pre=-1;$ j( y3 q& i4 U+ r# c
            while(tag[cur]==0||!s.empty())* g$ x6 O0 ~" o& t
            {0 W. A8 N+ a+ V- y  x7 D7 ~4 `
                while(tag[cur]==0)
    $ x! g$ u4 ?9 u+ i            {  a3 S9 B9 ?# z) U1 o. Z5 m/ j
                    cout<<vexTable[cur].data<<"  ";
      o; f. K+ a8 Q' P6 {7 ~                s.push(cur);3 H. S# Q, R& J# R8 d+ w: t1 A
                    tag[cur]=1;4 X- n% S, m4 }% ~
                   //初次访问,标记入栈- w7 K7 B1 ?! N8 Y7 V$ c
    : W2 b3 y" ^: Q
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点
    + y/ ]+ s" f* I/ p$ X: O               if(p==-1): e  Q+ t4 m; T$ Q
                   {
    5 R% ~, p5 O2 ?- _0 o9 ^* R                   pre=cur;s.pop();( L8 k9 y4 [7 [3 i& H$ m9 \& v
                       break;
    - e8 r4 }8 c; `! P               }; Z- X: a( E3 A; x/ v* o! W
                   else
    6 D3 y( c, v& Q& `, A               {) _1 M8 A/ t9 F" g+ a! G  ^7 h
                       pre=cur;
    $ g$ h5 I5 z, S% l9 b8 Q/ {                   cur=p;7 Z" e2 y) Z" u  X5 ~( N
                   }
    7 \  Z* f: F" v) N
    & A9 {6 U% t6 t1 y# S            }
    1 @* o: x; b/ k- I8 j            while(!s.empty())$ f( j8 B% @5 ^+ b; O* U
                {
    1 w2 n8 q( M* @2 i- M' ~* o, L                cur=s.top();
    & X3 R- p% K: G; ~                p=GetAdjVex(cur,pre);
    " O3 w6 M; v, r/ P! L) b( b                if(tag[p]==0)
    9 t8 W7 G+ W% o! }                {* q6 F1 O# \) G0 I  y. P
                        pre=cur;
    . |- w- }1 a5 n8 O+ X                    cur=p;7 W1 z( v$ O4 `+ w
                        break;, P  l( k* }" g5 B8 t! w0 [- l
                    }
    3 @7 H. I% r! v) E                else
    3 t, X4 r9 w! c7 X' u2 S                {
    ' ~  A  J8 L' g                    pre=s.top();
    * x/ G1 T$ o6 a4 V* _                    s.pop();5 w; f0 u- {* c# K7 o; D$ G7 G
                    }2 F6 n9 s! n; m  E) i7 c5 F

    + ~+ N8 ~/ \& I) q6 I            }# O9 r2 _9 @: D2 c9 @

    & ]6 ~3 n" z) V9 f+ e        }3 n8 B, q1 D3 k' M8 ?& X
        }
    ( S# \9 _' I6 p# q6 V}
    " P5 i2 O' K( D) ctemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()! ?* y: ?$ I' p* n1 F
    {0 z% {, C7 M3 i
        for(int i=0; i<vexNum; i++)5 p6 a) N, R( C# D+ A
            tag=0;
    , @; q9 h6 C  @$ x' R( |    queue<int> q;2 D8 B9 l: {& C# P
        int tmp,t;' d4 ^5 [: i- T, J3 g- H1 _4 F8 I
        MultiAdjListNetworkArc<WeightType> *p;
    8 |, Q! J* u% @# M& c; E- l2 \    for(int i=0; i<vexNum; i++)
    % s* J0 {- s( I9 E* q! q    {
    4 n8 ?" V. U( k9 S* _' x- t! L' T, D        if(tag==0). @3 O. t  w+ `% ^
            {' K7 [6 d" s8 G  e+ h# k# J( b
                tag=1;
    / L6 E% J, D' N" u+ I1 I            q.push(i);
    0 l7 E9 M  D: L! ]7 x            cout<<setw(3)<<vexTable.data;2 x3 C. ]; s2 S
            }: G6 _* Q4 B1 ~
            while(!q.empty())
    9 L8 ~2 i! G9 X9 |- W( y1 W5 ?+ |        {6 N7 c) d9 Z. x9 \) [3 V
                tmp=q.front();
      I- F. j. p' H8 ?& }( U) h% p" o            q.pop();
    6 ]  k0 R/ n8 |9 Z, U2 ~( C+ p# b            p=vexTable[tmp].firstarc;
    ! ]3 b; F5 A% C) K8 o" f* {( J* ?1 y# S            while(p!=NULL), o- u% R$ N" O& u7 g6 A
                {
    . _, w8 I6 h6 d4 [/ v0 u                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);2 H0 v0 S2 B) k% P
                    if(tag[t]==0)
    - {$ P9 t8 f3 l' w# \. ~                {
    6 |3 H/ J* g" u6 B) Z                    cout<<setw(3)<<vexTable[t].data;
    ) i$ [# u  Y. m  {) `4 P' o                    tag[t]=1;
    # k) q+ Y, I- c9 t; c                    q.push(t);  l& W- j2 R1 o
                    }$ W- L6 F/ ^( A
                    p=NextArc(tmp,p);+ P7 e4 j/ j* v# ~; j
                }' n& k0 z% |# s1 i
            }
    " q' Y) i4 b0 m* L# m6 i    }, x9 C. ~8 Q3 k' Q
    }
    # A, u; {6 t0 H9 L8 ?" g( utemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    ) Q  t6 @: b8 h2 r{
    ' E) c, u+ H" n) x    MultiAdjListNetworkArc<WeightType> *p;
    9 K9 Z: i, G( f" e% T! @    cout << "无向图有" << vexNum << "个点,分别为:";
    + f9 C9 F, L8 @  H8 s! E, E    for (int i = 0; i < vexNum; i++)
    ! j/ E: ?" F/ q: G% a* r        cout << vexTable.data << " ";
    $ m4 j1 l8 q- n# `4 q! f: W    cout << endl;
    & P& `: Z+ K$ [# a0 P    cout << "无向图有" << arcNum << "条边"<<endl;
    + a" r! x$ D: `* U    for (int i = 0; i < vexNum; i++)
    , P* q4 a5 D4 J" \    {* |. x* |  c$ B1 r/ E
            cout<<"和" << vexTable.data << "有关的边:";6 }2 ?* V+ T, n( G% K
            p = vexTable.firstarc;( R: X' u" z- D" p8 u" E2 X
            while (p != NULL)5 u) [9 a$ `6 u2 w- ~
            {2 ~, h) t( _; m5 ~0 Q
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    1 [: |$ z5 L' x, T; A7 h            p=NextArc(i,p);
    8 i4 H: Z# ?2 K1 U2 h2 f+ y4 h$ {# h        }; B7 D# J5 Z/ L- v+ m
            cout << endl;
    5 M! w/ j) v7 P" S/ B1 v- K    }
    ; Z4 ]. g- w5 _7 G! R' K6 ?}* z/ ]8 x  C2 R- C  Z2 e$ ^
    $ _4 P% \0 x7 p8 A# U" X+ J( i

    , Y; Z+ E% I2 k2 E6 c( x1 M9 B邻接多重表与邻接表的对比
    - A2 _0 \: y/ K1 T, I3 o# m) i0 `+ u
    邻接表链接
    ! q: M$ ^8 H1 i: }( c5 ^在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。2 g8 p4 Y/ A. ]! m; X" s% P% G
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    ( j2 D0 v2 E2 m9 `$ X为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。/ J9 x% L# [2 E# K) ^; y
    ————————————————
    6 i0 f* N% I( K. ~版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    9 \' q) D4 g8 Y5 l8 O; r& W/ Q原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669580 O7 {- S; U4 K( v2 j1 T

    ( v+ w& s8 E; v3 N+ X7 ^+ y) w
    ! q8 p. V" x1 l. A& w* u3 c
    ; f! ^! }( I" L1 f- _# _) c- G0 P9 f0 m" n; r$ G/ O3 @6 A
    ————————————————2 h, q9 r' o. x" d3 Y; U- `+ Z, X2 }
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    + {, l. U3 I* g1 O原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    6 s. g' Z. C3 O( V2 b+ ~
    ; r1 V& B" N- o: j' Q& U, `. }
    # _8 `6 c. L+ i+ j, A0 g
    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-1-13 11:39 , Processed in 0.635762 second(s), 54 queries .

    回顶部