QQ登录

只需要一步,快速开始

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

    9 H! e  n. P( g. _图的存储结构——邻接多重表(多重邻接表)的实现, c9 u/ g' }4 Y, @
    7.2 图的存储结构
    & Z' j1 i: Y' v8 O% M/ i$ s0 a# A% A9 Z' |) p# j
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
      }" ~+ P# W3 n9 n  q邻接多重表的类定义& f- ^, z$ F7 e2 @
    邻接多重表的顶点结点类模板
    # [1 X7 w/ O8 K) k1 x) V' @! |邻接多重表的边结点类模板* n- a/ `; j: ?2 D! f
    邻接多重表的类模板0 V  P" y7 A. ^
    邻接多重表与邻接表的对比; {2 Q9 K7 `4 r% u% X1 ?
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist' Z3 c) X$ ~- q. I5 n

    2 K+ d% Z/ s/ |6 h. w9 f$ s在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。4 l. E1 E; Y' K# B* s! P
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    % x$ X; B% e: t" A3 z6 |6 v
    5 O* ?/ ?" f8 _: B3 ~邻接多重表的类定义1 [  J  e1 R* b; ~7 ?" Q
    1.png
    + `) }% I0 S- ^4 K3 H% L邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    * H( `+ z! ^  I* }& k2 odata域存储有关顶点的信息;4 [' a- M9 ]0 f! l2 W( W2 D6 `; t
    firstarc域是链接指针,指向第一条依附于该顶点的边。
    7 p: c$ S& z+ E3 z+ `9 x所有的顶点结点组成一个顺序表。


    + v, k6 H& M3 q. c1 ]6 O* Q8 L2 I$ F) K1 g, E
    template <class ElemType ,class WeightType>- |7 z% M" c8 `* e) m* v
    class MultiAdjListNetworkVex0 u! B; Z! P' j
    {
    . p7 N1 c# s" j/ Cpublic:5 v- _+ K8 o* o  C
            ElemType data;
    . u/ _0 ^5 d1 U( q* {6 Z6 p        MultiAdjListNetworkArc<WeightType> *firstarc;0 l  P' K0 u6 x. Q- B9 Y* x3 P

    7 W- p3 v/ i& N' I        MultiAdjListNetworkVex(); q+ ?; q- v! |# e& V
            {
    5 `9 o# S, V+ P4 e                firstarc = NULL;
    : u6 `- K0 @4 l0 H( u& N9 {# ~9 [6 B        }6 c( a% `( X$ t4 k, m/ Q
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)1 _9 d: l, E6 `5 W, |+ ^+ s
            {) Q  c: b/ t: d4 x! Z0 P
                    data = val;3 \% K6 @$ a' J+ V4 @0 b1 W/ ]
                    firstarc = adj;
    , c: s6 e7 r- \  o7 F% E; |        }6 X" x7 a+ \4 n7 n
    };2 r  q6 Z" y2 S, \

    6 M; y3 i/ H2 T邻接多重表的边结点类模板
    ; T1 [0 C: q: g' M; }' e& \% X4 G+ ]) d! K
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:( Y$ l; C. t7 l) _* \$ t, [9 g' e
    tag是标记域,标记该边是否被处理或被搜索过;
    ( b1 h% E! O7 |4 W$ o! f/ qweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;6 ^9 A. X/ B! P( r+ n- ^) ~0 Z6 T9 Y
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;* b/ w) ^% f9 w6 Q
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    ; [- g8 y% A. {$ Q5 v7 _, Q
    ) b) `3 f, ?" z+ B3 Q 2.png
    ( z6 h8 V9 @5 R  {% }template <class WeightType>
    . V" ]: O6 M( s$ I- x" ?/ Iclass MultiAdjListNetworkArc
    ( q- i* m" F" X3 X3 A) T( h{9 W+ {4 c/ b1 \; Y
    public:5 n2 z6 V1 v2 z% Y, @
        int mark;                                       //标记该边是否被搜索或处理过
    3 X3 ]- b/ j$ T3 X7 [1 K8 `        WeightType weight;                              //边的权重1 p# f4 R! a7 f6 }/ n) N& k
            int adjVex1;                                    //边的一个顶点
    ; B) M+ ?7 v1 Q        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    " h* ]8 b: Q& V" j. \        int adjVex2;
    , @# Z5 ]5 B8 q; ?        MultiAdjListNetworkArc<WeightType>* nextarc2;
    ) ^9 S- H9 t: N  ~/ B4 [$ y) Q' \9 Q. D/ t' i
            MultiAdjListNetworkArc()
    6 K( G$ R; Y, R1 K! [; L( u        {
    1 @3 H5 v" |3 a' i; C  w                adjVex1= -1;
    ( ^. k0 R6 f$ }7 H% R0 X0 a7 S0 T* k                adjVex2= -1;
    2 _/ m+ O7 l! O, H  K        }% H- R  i8 e! h+ H; J% y/ W
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL), K& j; k! A3 U. Q5 l/ N! Z  r
            {
    1 X* `6 @, M7 Q. u3 }8 c$ z                adjVex1 = v1;       adjVex2 = v2;2 n! _1 Y# F) I2 \6 p" e
                    weight = w;
    * Q& @2 o( A- E6 r: Q' A0 q                nextarc1 = next1;   nextarc2=next2;
    3 J! m; D0 [* q* |/ z5 {/ H$ V                mark = 0;           //0表示未被搜索,1表示被搜索过
    + _  c( p# _- Q2 z" b        }
      J& {/ e3 O" `" m: u6 c+ {
    0 K* m  v+ F1 Q: p1 A: r0 T邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    ) |: R+ ?7 ^* b& W! b' h) eclass MultiAdjListNetwork
    + Z8 o$ c) d2 R# k9 V, k5 f{6 K$ {" a6 l" z, v7 U
    protected:
    6 o, h! B) S; P3 g  |8 h4 L; B    int vexNum, vexMaxNum, arcNum;! P) M( W9 S0 q  r8 u8 D
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;8 X: _5 _) h( ~; I: M3 h
        int* tag;
    ' |2 x' W) U" F0 A- O    WeightType infinity;
    ; }) o) ^) t6 c( b) M4 J
    3 M) m+ C5 r) y2 U, _public:/ K/ W  A+ Q2 ?: x
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);; F" c3 o0 Z" W* t6 U

    * J" o3 u/ _  U) s    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);% o2 Z& f, H9 w. H

    6 F5 l" O8 E4 |) R    void Clear();2 o3 |$ }( j$ v
        bool IsEmpty()& E1 N/ F- ^3 [& p- C( _* Z) g
        {6 f  K  u4 L, E# k
            return vexNum == 0;4 g/ e+ u* o$ s: H% |& u8 I( I
        }
    8 i6 n4 Y- L9 r1 A5 k& E    int GetArcNum()const
    ; c! t1 f' a, n7 h6 x1 h    {# d' k# a% `1 [: _3 g- |1 Z
            return arcNum;
    7 ]' B$ J/ _) F5 I/ ?    }7 a0 a5 ^! V# k2 T! I# T
        int GetvexNum()const
    % \; C* Y1 I4 W' N8 }    {+ [* J3 M6 D! M& E8 ^) ?$ {+ ?
            return vexNum;; A4 M8 D5 ]0 W& @2 o! K1 Z5 G' i
        }4 [7 S7 Y- ?, j& u" {0 @3 H  |6 w

    $ C% D( Z( M" Q7 w
    % n+ K1 a5 ]! t    int FirstAdjVex(int v)const;0 R9 k0 ?) w' c: p
        int NextAdjVex(int v1, int v2)const;
      J1 I! l: v6 W+ B$ m8 E7 w    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;6 J0 T# Z4 ]; v. @5 O/ _
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;0 P0 k# w$ a/ _8 ^, ^
    2 k, n' C/ ?' x( |" }0 U: m
        void InsertVex(const ElemType& d);
    ( P( Z; ^: s1 D8 U1 M: b: g* C    void InsertArc(int v1, int v2, WeightType w);) P7 W6 s5 E4 E1 w
    3 U/ v7 Y  u& V  R5 @. w6 n
        void DeleteVex(const ElemType& d);
    4 B" l4 Q2 v+ k    void DeleteArc(int v1, int v2);% z& L. j' t5 |

    ; T- P8 ^; l$ [; ~3 ~    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);9 L* C: |- _% D. a! _: B
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);+ E) R% w" F% \
    ) ~6 ]- ?5 \$ V# k  P! S; B
        ///深度优先遍历
    9 d5 D2 E  e# n1 v/ ?& `1 K" o    void DFS1(const int v);
    * \$ v4 N" j, Y, ?    void DFS1Traverse();
    # K% c  D8 ~* C4 b: `) v3 U8 u    void DFS2();
    4 D% G# u7 E* }2 `/ ~& q! ?0 x7 d3 i) ?& O7 Z
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    ; a6 U  p4 S# e- \* n/ X/ g& I    void DFS3();
    : s4 @9 ]1 S5 v+ q0 k. |
    / E9 X. H" r% a" I/ F    void BFS();! h8 b  ^% m/ f  j" o# \
        void Show();/ L$ q& T3 @% O! U
    };
      P, t6 L, t2 T: n7 z/ s" G1 h# [
    7 K5 M- d, a$ d. E2 p2.函数的实现
    9 J) A* y8 l' c8 S研讨题,能够运行,但是代码不一定是最优的。
    / D" H( s; L/ S; ~% B- n
    1 d, m6 G* J( ^* C$ z) O) g7 b#include <stack>: E% ~- n  x. ]
    #include <queue>& A( b0 R# R, s9 B
    + r. x) }  O; Z$ P3 M% s
    template <class ElemType,class WeightType>
      D7 U% m6 e! Z% }2 ZMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit). {5 I/ n" A# B* [9 @9 P
    {
    + G, N/ [2 o4 T: M- L/ E. R7 U; d    if(vertexMaxNum < 0)8 J3 K- F9 y' g/ o$ ^  g9 `9 H
            throw Error("允许的顶点最大数目不能为负!");3 p, |3 B9 X: b& Q# Q+ E$ _
        if (vertexMaxNum < vertexNum)
    4 k  B# q0 ]- P8 T        throw Error("顶点数目不能大于允许的顶点最大数目!");7 R+ Q7 a0 @: E9 b
        vexNum = vertexNum;
    3 ~2 w7 n6 g+ ?2 X3 Q! m    vexMaxNum = vertexMaxNum;1 |3 o* E  r8 l' h; s/ S1 I
        arcNum = 0;
    * C0 }7 I: L3 p7 }    infinity = infinit;8 F* Y0 Y5 f1 K- i& q$ `! D
        tag = new int[vexMaxNum];& W' q& j3 V( }/ ~
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];$ E9 N2 P9 z- _, _1 t* C9 n- r8 G
        for (int v = 0; v < vexNum; v++): H8 O+ @  V  c+ h
        {1 s+ ^! ]  p5 L* T
            tag[v] = 0;
    ; r) q' ^! W5 [' j; x. s6 n* n4 s        vexTable[v].data = es[v];
      t/ K  G5 y. g7 ?- p5 F        vexTable[v].firstarc = NULL;
    ' k! _8 C. V4 K* J    }: R5 p) Y" ^" I  X& {3 t* Y
    }
    ( R& V: z- n' W4 Ltemplate <class ElemType,class WeightType>
    $ Q( V2 Q4 {1 |" O! Q  H# v! kMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)4 a5 I1 i& Z. T, L6 t, k' U
    {4 r* o, A8 I- [' M6 G7 z  N) V
        if (vertexMaxNum < 0)) X" b  l6 U: {, c9 q
            throw Error("允许的顶点最大数目不能为负!");/ j* D$ j  t  y* X3 X
        vexNum = 0;
    ( x* }; z# v& x% s    vexMaxNum = vertexMaxNum;+ |& w+ f! i! s- d* |
        arcNum = 0;  ?1 W* h( L$ E5 d
        infinity = infinit;8 [( l' _# G; b# K& y4 [
        tag = new int[vexMaxNum];  I8 }: `4 y0 w3 \+ e
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];* b) x1 _0 ]+ _& |
    }& v$ K# P! k1 ]" ]6 q; F3 I# H! e( d0 z
    template<class ElemType, class WeightType>% j& j2 I5 q. U$ F
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    7 ]" A# }/ N1 o8 x: l8 }1 K3 T4 q9 k{# L1 N: `9 k! x6 R
        if (v < 0 || v >= vexNum)
    ' `+ r9 C$ {; V        throw Error("v不合法!");, u5 B* Z# F2 L3 c4 O
        if (vexTable[v].firstarc == NULL)2 ~' O  C/ k0 ?8 D  P7 H1 s
            return -1;
    & q& ^9 F% x) _2 Q& P3 t$ V8 n; R    else
    ) G" @+ i, F" o9 ~* [        return vexTable[v].firstarc->adjVex1;
    1 t# e/ F/ w, H/ V( N* H8 C5 O}
    # ?8 g& u6 ~/ Z& D$ Z4 M8 ?5 @7 y6 W$ Y7 A
    template<class ElemType, class WeightType>
    6 \0 ?8 P4 E: d+ u$ o0 x! zint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const, s5 n( R0 i0 P5 [. R
    {
    , ~: A7 l: E3 m( R8 I, m9 w6 ^    MultiAdjListNetworkArc<WeightType>* p;! j$ e, [. }* f. N0 l9 ]
        if (v1 < 0 || v1 >= vexNum)+ g! {6 h+ `* [0 z
            throw Error("v1不合法!");- u4 v" W1 V  y) k
        if (v2 < 0 || v2 >= vexNum)
    , I" Q. z: C- V% o' \4 |8 H* w        throw Error("v2不合法!");$ J& G" K- X; n2 J
        if (v1 == v2)
    " Q6 v8 g! Q4 N9 i        throw Error("v1不能等于v2!");( m0 I5 ~0 k$ a8 m
        p = vexTable[v1].firstarc;
    ; d) ^6 U# G6 P& v    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)# F2 Y9 R5 H# Y7 Y( t7 I* i2 l
            p = p->nextarc;' W$ C" D( r4 U5 x2 k
        if (p == NULL || p->nextarc == NULL)- D0 ?! P$ ?7 D  j& @
            return -1;  //不存在下一个邻接点6 R9 z3 J7 L5 D: L) A& V
        else if(p->adjVex1==v2)& P; a0 Z( |" R9 ^" V4 Y
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);: p( U- o) ~6 Q( M, ?
        else% A  C3 U7 K# p/ a+ k+ E
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);) N6 k3 q- G) \9 j
    }" i& _6 M- s, w7 w6 ]3 Y
    template<class ElemType, class WeightType>) I' g! [8 }, R4 P$ u) v
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()
    , }: c5 E. T0 L: X0 t{2 D% o5 f7 Y8 J' k
        if (IsEmpty()) return;* @! N8 s# C0 g
        int n = vexNum;
    " z, p+ ^- I5 c( D3 A    for (int u = 0; u < n ; u++)# J( y2 I% B: w; `1 E# }" F
            DeleteVex(vexTable[0].data);4 V+ K* u: t% |4 T5 `! B4 t
        return;. Y1 X' q1 F- A, A$ B0 q
    }8 X/ r  [  W1 [: i$ `& ]
    template<class ElemType, class WeightType>
    4 N  z; P7 Q6 d1 cMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    " v- b2 U' M$ u! p! l$ a5 p{
    $ h! K( ~2 r2 g    Clear();5 q/ A6 b0 X6 \1 J  t& E
    }
    - P  {" C$ X& C3 ]( {template<class ElemType, class WeightType>
    ! u+ ?3 Y* k5 jMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)8 Z2 U( `9 O* E- p) ]8 u& |
    {0 L8 Q3 e" e* ^. v6 G1 W: I# q5 c5 A* D
        vexMaxNum = copy.vexMaxNum;8 @/ H3 G+ [. T9 a* T$ Z5 t
        vexNum = copy.vexNum;7 V/ p1 x6 i3 `8 n: u  x
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    & F3 Y0 e/ q6 }! f! M8 H, j    arcNum = 0;
    7 _$ F* t2 e# |' }- ~. x. ?    infinity = copy.infinity;
    ; {0 j9 \- Z5 ^    tag = new int[vexMaxNum];
    % C9 w) a% V% B, u  F$ T$ e* q
        for (int v = 0; v < vexNum; v++)
    $ X% y$ m  t/ M7 o9 h& X& D    {5 z9 [# @$ G- E1 o- _2 A7 d) G
            tag[v] = 0;
    7 L- s) Y" J  U1 h1 P2 s1 q        vexTable[v].data = copy.vexTable[v].data;9 R7 }3 H+ V' ~% }+ Z. d2 O
            vexTable[v].firstarc = NULL;
    % E( H' X" A. Q% @1 o; ~    }$ P1 k4 Z! J6 g& u2 ~" W6 g
        MultiAdjListNetworkArc<WeightType>* p;. {/ j# }& `- o: P0 }

    0 R3 t7 J' o. ~  E+ ~9 A    for (int u = 0; u < vexNum; u++)7 l  ~( i7 C) q
        {
    5 @: a9 g$ _6 t. w8 t& @; @        p = copy.vexTable.firstarc;+ l& a- ?  I8 C4 C" Q
            while (p != NULL)5 a* u# ^% ]* @/ i0 {
            {
    $ c6 f+ j  S/ |            InsertArc(p->adjVex1, p->adjVex2, p->weight);; |& ^! q: ~+ p5 L
                p=NextArc(u,p);
    , a4 x$ c" O: q1 p7 q, P7 {        }
    8 t6 ]: j( Y- t    }$ O2 o/ ?6 F/ l0 |$ K
    }7 w8 S( s  n6 [
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    2 ]- a7 v! J6 ~+ q2 iMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)" D0 J$ _  x% r& O) [6 a9 m
    {
    4 X! K1 R+ p* @2 I( }1 O0 \5 a7 b    if (this == &copy) return *this;
    + p, o) {" B' r/ V/ z    Clear();
    ( B8 M7 J5 L: B. m    vexMaxNum = copy.vexMaxNum;
    ( l% l, S) i6 E- }: c    vexNum = copy.vexNum;
    7 \+ K0 ]$ P6 f2 Y% C    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    9 S0 r) R+ L9 ?9 H! _3 P    arcNum = 0;
    " k& r3 i1 s. g' g    infinity = copy.infinity;1 {0 j6 ~$ ~$ R/ S& X- f
        tag = new int[vexMaxNum];
    ! P8 c, @' I- R( C% N% p# a$ I
    5 c9 _, c3 Y9 H2 Z+ S  K- b: \6 a    for (int v = 0; v < vexNum; v++)' ?% [: L( c- F- Q$ ^$ J
        {
    , V% D3 Q) g: n" ?        tag[v] = 0;
    : x, p2 a+ d4 U. ~* ~        vexTable[v].data = copy.vexTable[v].data;
    " q2 q; {8 `, H' b7 E        vexTable[v].firstarc = NULL;
    0 m4 y) H0 s% w4 x8 b' |2 ]    }2 E1 _3 L$ i9 K$ V4 V8 L
        MultiAdjListNetworkArc<WeightType>* p;
    7 x: @. V, _9 s! U4 C9 x
      Z) f) B( k: p    for (int u = 0; u < vexNum; u++), C4 G3 ^- m* Y
        {
    0 p3 ~: `$ s4 _! l        p = copy.vexTable.firstarc;
    2 _  d4 H# L! z  z8 a$ a        while (p != NULL)
    / T9 k  C* X4 t" @$ S! ]4 ~        {
    8 p3 E7 J" p7 \7 Q0 q            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    : K4 p+ C3 a2 [            p=NextArc(u,p);. G0 ?) U! M1 W8 {' f& ^
            }
    & P- V" M. ^4 }+ w  e8 F4 k7 j6 \    }: Y" J; o3 P) L* S1 e
        return *this;3 z1 Y1 K3 }- Q8 _
    }
    1 V' p0 G2 A% \7 g6 q( Ftemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*4 C' y: F4 ^. t" a  ^8 _
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    ' L( }" D, _: D4 b8 Z- _{
    * A: g9 Q+ z" O' o1 L    if(p==NULL) return NULL;
    " P2 O! a" J1 X    if(p->adjVex1==v1)
    0 ?2 S( ~# C4 l( y: O$ o5 W        return p->nextarc1;+ F+ J7 a7 b* u1 v( [
        else
    4 ]% B# [, k! |/ q+ z        return p->nextarc2;
    3 N  t( h3 C3 G1 I}
    " o# H1 u" Q6 {/ U  p& \& etemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*8 h, }& w& v9 z" Y, d$ o: j
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    7 R% J+ H/ P" {* ^& B$ m- Z{
    , d9 @% K) @; T% C" T9 @8 |* C    if(p==NULL)return NULL;
    : a) _4 f& M# X* P    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;( Z' K8 w3 H  b
        if(q==p)
    % h& R6 M$ I) a4 h, g) [+ d0 A        return NULL;
    $ M% [$ R# q, T* R$ m5 k. k- R2 C    while(q)5 w, v; n. X& Z5 a. K% _+ O7 r
        {6 [& B/ e4 z; t1 B* T$ _
            if(q->nextarc1==p ||q->nextarc2==p)" h( N5 p  \8 t" e, ?
                break;& Q% P8 I/ Y" O- z/ N
            q=NextArc(v1,q);
    : R1 R! V1 j+ m0 r    }" I! p3 G  C$ d, b; Q- R5 M
        return q;
    ( Y# _& Z# c! O, f  A}) _7 M: J2 V7 V
    template<class ElemType, class WeightType>
    9 O* e- u( y7 U. Y5 j2 Kvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)" Y! p" Z5 o$ Y0 {* a, j' @1 u
    {9 A- D9 K1 i# Y
        if (vexNum == vexMaxNum)) E( P1 M, F" S8 f  d- R6 V; A/ M
            throw Error("图的顶点数不能超过允许的最大数!");/ X1 ^  v, u9 a/ a
        vexTable[vexNum].data = d;
    8 K' v5 l2 t& W+ V6 C7 V+ E1 v    vexTable[vexNum].firstarc = NULL;1 g; z' y  J+ g3 E$ w+ L* i
        tag[vexNum] = 0;
    ) C% `5 w+ o1 m+ O2 X    vexNum++;
    9 m% B0 k9 f/ T# u" g7 C}* @% D; J; f' z* _1 m* A* D
    template<class ElemType, class WeightType>
    / b2 f8 Z) x- C9 n8 U" Rvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    % |4 ?+ C( q) q: Y2 y{
      I' T; E9 _0 r7 C4 M    MultiAdjListNetworkArc<WeightType>* p,*q;( w3 C0 `$ ~9 t6 S3 y1 E
        if (v1 < 0 || v1 >= vexNum)4 a) N) ^6 e  T0 i
            throw Error("v1不合法!");5 M) k: \; v) o( s/ p0 v5 R
        if (v2 < 0 || v2 >= vexNum)
    & `6 G; u) y4 M        throw Error("v2不合法!");
    + D1 j2 @$ Y$ ^4 f! J) ?    if (v1 == v2)" h0 I/ D# `% f  H+ Z  T
            throw Error("v1不能等于v2!");
    ' R5 q: @" z) U, P: D    if (w == infinity)0 R* w" K/ a3 I4 @/ Q4 K8 y. P
            throw Error("w不能为无穷大!");$ m8 a! [' N' e

    * C. R6 {# u$ y
    9 W1 {, k; A+ Y$ R( q    p = vexTable[v1].firstarc;. B# F, k$ {8 ^7 Y& p! j3 e
        while(p)
    ) a. e. e- ~5 H, C3 ]+ A9 t    {
    * u1 m7 ~& K) V* ~# ]        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中# T+ j# _  k" @5 V
            {
    ! @- O( T2 Z5 w9 q" N            if(p->weight!=w)0 e  W7 v" \) Y- A0 c
                    p->weight=w;
    % E! u1 \6 J+ r            return;% R7 G9 S/ a6 `* o+ R
            }
    1 X9 ], U! q! Z$ k# D( h. j' N& A; X7 |
            p=NextArc(v1,p);- b7 v6 M- |, Q) y$ e
        }
    ! A* a5 T$ h% p! ?1 _8 \& g    p = vexTable[v1].firstarc;
    * q4 z+ o: ~7 n8 S    q = vexTable[v2].firstarc;
    # y' w/ ]6 H, U. j+ B$ ?4 O% w! s  C    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    1 b2 I) ]( d  n+ Y    vexTable[v2].firstarc =vexTable[v1].firstarc;( F2 q+ t- B" }% r$ w0 s
        arcNum++;. i9 u1 X& }% w- W7 X9 p
    }
    . F! W3 r% d+ u4 C# T  z! D: }& l  h4 N% U) ?" x- q6 v/ u  x, ?1 [
    template<class ElemType, class WeightType>" z  Z% Q5 q; o( F; x  o# J
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)$ ]) j( J/ O6 T2 L* e- i
    {
    * A% u# \/ k+ i8 o1 f  W
    " `( Y6 F* i1 y1 r- Z    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    / e% V: F7 S) k5 P) h5 J2 D    if (v1 < 0 || v1 >= vexNum)
    2 z' Z) p2 J7 y( e7 v& M  Y        throw Error("v1不合法!");; F  U' ]. o/ V. c
        if (v2 < 0 || v2 >= vexNum)! L- C* P3 V0 K- ?) t
            throw Error("v2不合法!");
      A$ W; ^& p# U7 B, S    if (v1 == v2)! H( M7 e& ]! `7 C( _7 Z+ J/ Y
            throw Error("v1不能等于v2!");
    8 o6 N+ P  X5 P" h, a* J6 S, M2 a) p! u  w$ o
        p = vexTable[v1].firstarc;
    5 O' j  R( G8 A    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    + |, k- y' \8 n" v    {
    , r" B( s' r; y4 x        q = p;  m; x! Y" `/ Y( [5 p! n1 G7 {2 E: I
            p = NextArc(v1,p);
    . J% ]$ ?  P9 j4 `4 K    }//找到要删除的边结点p及其前一结点q
    5 k% l8 |; W6 `7 p/ p7 J5 Y8 o5 P, `# O: j! x
        if (p != NULL)//找到v1-v2的边* o. R7 q7 d$ @- ^$ p) r( _; F
        {
    9 W, D0 R8 |! Z1 `9 R        r=LastArc(v2,p);0 N6 T# q$ h; z9 r3 Q0 P" {
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL/ {3 a2 P0 O( b$ H8 C
                if(p->adjVex2==v2)2 J9 p) K" i1 X! P  T
                    vexTable[v1].firstarc = p->nextarc1;( M5 @8 e# S: P1 j' m/ F& j
                else vexTable[v1].firstarc=p->nextarc2;, a1 k: @9 f( Z! h% ]+ h4 m
            else//不是第一条边
    9 z' n+ }9 ^0 O. L        {3 t+ M  w! v+ W' x7 q
                if(q->adjVex1==v1)' B' e; v/ [& N% r* U) L9 u6 ]
                    q->nextarc1 = NextArc(v1,p);
    9 u9 C) |6 i5 @/ C* z            else2 r! v+ Z2 Q1 p* W' k  ~+ L
                    q->nextarc2=NextArc(v1,p);
    6 _' m/ C" ?1 x+ c- J4 g9 m' u
    6 Y! {% O. o4 Z' c( A& Z        }
    4 a% O+ k4 R  _" d' P        if(r==NULL)
    - v. e  L/ P6 A2 O            if(p->adjVex2==v2)
    ) V$ z% V; U- u4 ]* h                vexTable[v2].firstarc = p->nextarc2;
    8 ?! T/ @4 e1 |9 C4 K& J+ m            else vexTable[v2].firstarc=p->nextarc1;/ p# h6 t1 l8 r2 L" |( k% D/ n( o# W
            else8 N+ K9 J, {) ], y3 }7 a5 o$ f
            {5 u2 e% Q" `6 ?5 B( e2 K1 `
                if(r->adjVex2==v2)) ~: b5 W3 I! q. X$ {
                    r->nextarc2 = NextArc(v2,p);
    8 `( X# h# G& q% u            else5 M5 E$ K" ]# ?# ?7 n
                    r->nextarc1=NextArc(v2,p);. p) H2 @/ E/ M: @# Z4 y8 ^# x
            }9 r5 p* ~# a$ _5 P. x/ L7 I
            delete p;
    * K  k# T. H4 i- {        arcNum--;
    $ `: X- ^- v4 }; P9 Y' ?    }' D. K: d# P7 R  n

    7 ?" a  ]: _0 z6 h# Q+ C}
    7 b7 |7 y. w9 \$ c0 F8 O- @, dtemplate<class ElemType, class WeightType> void
    1 Y6 v; r1 @  ~; X0 ?$ @4 xMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)# b/ Y! V* F0 D' C
    {# d. U$ o4 _" C/ c( j; H! V
        int v;, k2 z' N0 @0 o! |) y/ Y2 @3 r' I
        MultiAdjListNetworkArc<WeightType>* p;/ J9 a' a0 |. d/ O  [
        for (v = 0; v < vexNum; v++)//找到d对应顶点& f2 `2 L  W6 I* H$ H7 H( t  h: d
            if (vexTable[v].data == d)
    - z5 [: ~, x5 j            break;
    - X5 h' @: a! V    if(v==vexNum)' o9 Y% w- u8 L# X
            throw Error("图中不存在要删除的顶点!");
    ' [1 c# a! z9 M* m+ ~5 f6 N. t1 ~: |: q8 ~# m! d5 R
        for (int u = 0; u < vexNum; u++)//删除与d相连的边; `+ j# e0 p1 c% ~- M" G8 i$ H
            if (u != v)+ p; C0 E  R: g$ P
            {' w0 {" D$ [; \
                DeleteArc(u, v);& F" f% G% q3 F! F  y3 g% D
            }
    6 L7 v3 `6 R, P. @: _/ T    vexTable[v].firstarc=NULL;
    ) X' z3 J0 Y. L5 P6 e4 k$ S% T3 X/ z! m% E; z2 n+ q
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    # |; c$ s/ O& `' C" F6 \% i  f    vexTable[v].data = vexTable[vexNum].data;3 {1 j+ h# H$ u& k" L
        vexTable[v].firstarc = vexTable[vexNum].firstarc;
    & g3 i! V( z/ s/ U) y7 ~. q    vexTable[vexNum].firstarc = NULL;
    ! k. r+ P+ U4 J4 a2 F. p8 g1 G5 ?# T0 p    tag[v] = tag[vexNum];
    ) I( w+ `! b- t" A9 }& E0 N    //原来与最后一个顶点相连的边改为与v相连
    , E  F% R, p& o3 k* v- O2 m' x6 M    for (int u = 0; u < vexNum; u++)! E5 \: \# P2 K) K5 n
        {) ]- _( k' [8 G, i! `( a5 M
            if (u != v)" D, p! a( K* h% N+ j6 }1 Q
            {% F* R$ }8 [4 l: ^$ g' t8 U. v- ~: W
                p = vexTable.firstarc;
    ! [, Y- G. Z9 M0 k0 d8 `            while (p)& p9 }( x& s2 v% {* ^; Q; W
                {# |5 k7 N+ J" i, [; `3 d) S& H6 |
                    if (p->adjVex1==vexNum)5 w: w" S* ]) A0 k0 T% Q: L/ ]$ j
                        p->adjVex1= v;
    5 R; K% A. }1 k- W" w% K. o                else if(p->adjVex2==vexNum)$ a" a# @# @) E5 v7 u
                        p->adjVex2=v;  d  E/ M5 D6 ^& P- H: ?* W
                    p = NextArc(u,p);
    0 e- ~0 n) K5 `            }7 W) ^3 G' ~) \* K2 N, u
            }
    / S/ U8 N3 _% j5 m/ c- D  ^    }
    2 t9 u* y/ J, a/ E; h}
      q1 Q1 L8 q* e4 O///深度优先遍历
    ; H- X9 |! o- V$ p6 W3 htemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)+ \$ o6 A% Q9 ]$ O4 ~7 M
    {
    . D7 E2 q& w3 l    tag[v]=1;
    7 g' \) _% m  z5 e, U5 }" S( G    cout<<setw(3)<<vexTable[v].data;7 z/ z( z& K; w/ k$ y& K
        MultiAdjListNetworkArc<WeightType> *p;3 E. J: y+ v( C) {/ b8 Y4 W. L: Z
        p=vexTable[v].firstarc;! h( r% m/ N0 p# d' L
        while(p)
    1 A' L' V: Q7 V6 @% ?* M5 O: N    {0 N6 D0 L/ t% Z3 q
            if(tag[p->adjVex1]==0)4 S9 U( x* ]0 s
                DFS1(p->adjVex1);9 A2 n" v/ g9 Y: [8 i& F8 w/ Y6 R
            else if(tag[p->adjVex2]==0): L% q* a6 Y+ k# s4 X. a: R: d4 t
                DFS1(p->adjVex2);
    ( n! I! |9 m0 L- J        p=NextArc(v,p);% h3 f6 ]2 h* w
        }& {, P; j2 w+ u3 C  J2 {% U
    }/ I5 u6 p# b4 |2 T
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    $ v. {5 p8 r1 \0 q3 T7 w1 D{
    # r% T% \) I, P+ h$ R* {    for(int i=0; i<vexNum; i++)' O- ^8 b" l. T
            tag=0;- T% Y$ I- }7 J1 c
        for(int v=0; v<vexNum; v++)" n; N9 t+ R% }; b9 m
        {+ q: g) q4 W+ H0 M8 R0 \; K, D  t
            if(tag[v]==0)
    6 T* @5 q- H+ ]: R  W            DFS1(v);, a: s: C2 Y) K9 k+ e$ s  `" V! I
        }
    8 X! q( ]5 i- |1 `- S}; Q+ D' [3 K( _, X
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()  Z; l. ^4 j% v
    {( [) w* U3 l% j" k
        stack<int> s;& i6 V3 A. C6 g
        int tmp;8 s5 h; E/ b; n
        MultiAdjListNetworkArc<WeightType> *p,*q;
    3 h. c2 F: ?$ E" B0 s' P+ h' f    for(int i=0; i<vexNum; i++)
      |1 h: H+ h( R4 k% B        tag=0;  O  P3 R2 A6 P
        for(int i=0; i<vexNum; i++)0 I; R- @2 _8 E* {9 Y" I* _5 ?
        {; U4 C3 B0 y6 y; z4 z0 L3 D: H
            tmp=i;
    * h. x7 i( @& u$ t        while(tag[tmp]==0||!s.empty())( d, {0 S  @- `0 i
            {
    / X  v' @6 ~1 r            p=vexTable[tmp].firstarc;: h6 L! @( S( }. G2 i% W
                while(tag[tmp]==0)5 f( }1 H) k" o3 b) S! B4 E
                {. h1 o/ C- }, q
                    s.push(tmp);1 m7 _( |/ G7 w/ T$ c  U
                    cout<<setw(3)<<vexTable[tmp].data;$ g. Z0 _: T* V2 c" A* E- s
                    tag[tmp]=1;: E3 d! J  n' \1 _" a" Z5 K# ~
                    p=vexTable[tmp].firstarc;
    ! w0 [8 E7 Z; z. K  W) n                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for+ V2 j* I3 X; E# J+ `; G' X& \
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    . A, P9 x$ X5 A* Y2 {% T# ^                //cout<<" 1st     tmp="<<tmp<<endl;5 ?/ o3 G+ I" |+ x/ l3 [
                }4 \$ D# |- l6 X4 u% f' u" X3 u
                if(!s.empty())
    6 X; V7 M3 P+ y5 D6 j            {7 z) K' j) b/ v  i5 T5 }
                    tmp=s.top();
    $ z. J2 F7 P5 X5 D                s.pop();
    9 l+ A" i( y& ]- v7 m8 T                q=vexTable[tmp].firstarc;- h, _, @3 @0 T, z$ R" F
                    int t=tmp;
    0 J2 M; J1 h0 E8 P6 C0 h                while(q&&tag[tmp]!=0)7 j: C! U7 h  n4 o0 ^
                    {
    ) X+ X# u7 T9 f. a- e8 l                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);9 ]1 H" z7 g6 f/ {
                        //cout<<" 2nd     tmp="<<tmp<<endl;+ l5 F% A3 L1 {
                        q=NextArc(t,q);
    ; {! l) H* q- M& H; e4 p                }
    8 W9 ]3 I' I" _' K                if(tag[tmp]==0)" k8 L0 L( b. c) w1 b# P
                        s.push(t);
    0 m* E! o( r3 `/ }                ///1、对应上面连通分支只有1个点的情况
    2 n$ [6 G# y* c' I                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈# P) l6 k2 {: L# f" `2 f
                    ///tmp要么等于找到的第一个未访问节点,
    ' @/ |. @( F/ D( F( H3 p" \0 k! h                ///要么等于与t相连最后一个点(已被访问过)6 h2 O# z: Y, t) v- I) i
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    4 q  V) d% r+ j            }- n5 Q0 _1 s1 D, R1 a* M
            }
    / d; ]$ n' ?2 Y& v' {" U" U    }3 q9 U0 s6 ]2 p! O9 `, X5 E+ h
    }) a3 j3 a+ W/ L6 k/ |, S
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    ' h- O9 W; @. l# v/ {+ t& ytemplate<class ElemType, class WeightType> int
    6 k" K9 d7 M  q+ Z7 `/ ^9 [/ P. l8 aMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
      h2 P8 B' P$ c, \+ {{
    - h7 ^( K8 ]" ~' p; y    if(head==pre)6 V" }, |% }0 ~( I+ w
            return -1;
    8 s8 ]( ]$ }- p1 n  R
    4 t9 j. D- q8 \, v( `- ?    MultiAdjListNetworkArc<WeightType> *p;: d3 J$ e" Y& a) d5 o
        p=vexTable[head].firstarc;& U: U/ M( C. L. N" D: n7 @5 V6 s
        if(pre==-1&&p!=NULL): d5 [* H* Z3 f
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    + D* J1 |9 N0 O: s3 S7 Z& X    //pre!=-1&&p!=NULL! n! f7 J* w' Q% ]! n
        while(p!=NULL). G) {) ]  s! I
        {$ c! q0 H+ W& a" s
            if(p->adjVex1==head && p->adjVex2!=pre)! L, y( L+ Q6 A/ B6 K& n% B! r, b7 L
                p=p->nextarc1;/ _0 g, l. W- u6 x0 B6 U+ d
            else if(p->adjVex2==head && p->adjVex1!=pre)4 U1 j- d  f/ y* T3 x
                p=p->nextarc2;  h: ~) \! e& r( H' A8 f
            else if(p->adjVex1==head && p->adjVex2==pre)
    , P4 ^$ H- _3 B0 g0 T        {2 E6 e, K) Q9 \- i  x2 S1 b* c) r
                p=p->nextarc1;
    9 B! \2 \* H5 Y3 a% \8 M            break;
    % X* o; E) E7 ]0 ?1 k        }9 `% J7 B1 H0 J3 F! h  e
            else if(p->adjVex2==head && p->adjVex1==pre)
      b* @  s/ z+ S: S) y* Y$ [        {0 e) R' D& {2 Q3 t4 h0 g8 @1 Q
                p=p->nextarc2;
    * c( p; n0 q4 f1 A# s- ]            break;7 o5 d+ D* M8 Z0 Q7 P4 S
            }2 ~! D4 P: g# S2 U$ H3 i
        }
    $ h; \3 B, c' @- g2 V3 \7 Q7 D7 Q8 g    if(p!=NULL)& ~3 S6 k3 S3 x8 {. O
        {
      e$ g1 t& e* Y4 f, c) o8 \, d        return p->adjVex1==head?p->adjVex2:p->adjVex1;
      i7 g0 C, R5 }  p    }( c! o- v7 A. ^8 e
        else2 g0 E1 p6 B7 {- X5 o( B
            return -1;& K8 j- c0 z# B4 ?/ n* Y- d* P7 h
    }4 n) O) G- m1 }% h% i

    " G+ f0 d/ c" i6 r- w; L' X5 O4 F% p6 ]3 u& ^& I0 `, o  c4 C) k+ N! g5 x
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    ( f# g" }9 M3 N8 Z+ F$ E$ g{/ x: N7 `, O, B4 r0 X+ _
        stack<int> s;6 Y+ [( Z' u$ `  U3 ?( ^
        int p,cur,pre;: S: N& r7 B# E0 g: J2 |
        //MultiAdjListNetworkArc<WeightType> *p,*q;3 W3 `6 w& s4 q5 K/ e$ N) o6 Y
        for(int i=0; i<vexNum; i++) tag=0;//初始化8 \" i) }* a4 |) Z

    1 L0 i$ P; W, e; y0 M    for(int i=0; i<vexNum; i++)
    $ g: ~- e4 X) H# K2 U5 x: E5 n  o1 a    {( M- d% \4 O+ K4 I( K4 t
            cur=i;pre=-1;# q) G9 y' V! Y. S0 C/ X
            while(tag[cur]==0||!s.empty()): M7 P* g0 m$ G! E* A
            {
    - w' }9 {( E& j; I& D' Z* }            while(tag[cur]==0)9 s  p0 ~9 ?: y6 k
                {4 U; O: h# ]; I  y
                    cout<<vexTable[cur].data<<"  ";8 \8 J6 y# x" Q
                    s.push(cur);0 U: D, C- `7 e4 W4 v& N# D7 W
                    tag[cur]=1;) I3 U4 h  _, [8 B
                   //初次访问,标记入栈) z4 x) ?; x2 s
    . w+ @3 z# M0 X. |" \3 h( ]
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点7 D$ c# T6 u4 ]* |. @3 M9 Q; b
                   if(p==-1)
      B" g; Q& r3 q6 x  D               {
    3 o3 i3 g! N' A6 n/ j8 P& d: Y                   pre=cur;s.pop();8 v+ R4 e- y2 ?7 {( y: V
                       break;
    " Y/ z' M$ x! ]! ], d               }
    % Z( I- `+ }: u+ q& H9 `, A               else
    ) O) k- J4 u4 Q/ a! j' _               {
    % f7 f- O7 Z. `2 f' q+ ^* C  h) }                   pre=cur;
    % m- j3 c* \. G1 a" J                   cur=p;
    2 V; W( X0 Y, O( E4 W. s               }4 F8 h7 A& N/ G* W' T
    4 R$ v$ f# p* S* R2 K4 w
                }  Y9 \+ K" g9 _: w& L& o
                while(!s.empty())
    - J1 ]# n  }5 T- v! v% y- a; N& E2 [4 `            {( i, G3 `1 c2 T; c3 }  Y
                    cur=s.top();9 k& W( B; J- r# y7 v
                    p=GetAdjVex(cur,pre);( V! J+ {) H/ n+ E5 r
                    if(tag[p]==0): z0 l; I, _# v' N
                    {$ h* v9 v# m' c0 i* \9 x
                        pre=cur;1 T% F( c* E3 f2 O/ ?
                        cur=p;4 p& e1 {, F: x8 w8 D
                        break;
    8 e* P; |. a5 l; ~                }3 ]0 L- ]) q& P$ ~
                    else. |. _3 _  i( V+ @+ U, e6 @
                    {
    3 o' D$ k$ J' s" A% w  a                    pre=s.top();
      f* U! I' i, A1 T! t* J. W* k3 ?                    s.pop();/ Z' a( B: M! i* e. Q
                    }+ O9 U9 R0 i/ G: x

    ! \9 d' L" g1 t* e( ]! v( V            }
    0 z$ }, s; P! o% Q4 B$ u8 |/ p
    ' i* ]6 B9 e- R% r% E  k8 }: k        }
    2 {& E  Z7 j7 `/ j- _/ y* f/ i    }
    3 G: F& ~5 t$ P! B5 L- R}1 @( p( i- r! y9 g  |
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    ( V) J( ~5 L  I. v$ ]$ w+ J- I{; A/ ]3 A2 m5 t( o1 K1 g3 R% C
        for(int i=0; i<vexNum; i++)
    6 [; o4 c5 Z) S6 X" @4 w' p8 d        tag=0;# k  ^5 V, _, m: x9 i4 c: d
        queue<int> q;
    + o9 e2 G( m- _* b  ^+ x    int tmp,t;* ]( \0 e# Z' @6 v" H  q) j
        MultiAdjListNetworkArc<WeightType> *p;
    . N4 s: B7 R) j9 _2 F$ I# s    for(int i=0; i<vexNum; i++)% M8 k8 A" W6 p& @8 T
        {
    ! W0 D2 }! R/ W1 [/ I. g4 z# b        if(tag==0)
    ) V! u" f: j1 [0 e, M! b        {
    ( q5 U4 I: C8 @% q- I8 R. a            tag=1;4 `+ k1 f* p& i  k" N# P# v/ e
                q.push(i);+ f& n: a6 z0 Y" K
                cout<<setw(3)<<vexTable.data;
    5 R1 r9 Z- U2 s        }, e& e; n! D5 l! C
            while(!q.empty())
    3 m$ J$ {2 z5 @& _! `        {. g6 M  }  P- g3 u( a
                tmp=q.front();
    " p3 {9 u, U, p            q.pop();2 O: n0 m8 c; O: H) ?% C
                p=vexTable[tmp].firstarc;9 p( Q: I# ^3 q5 {3 g, B: j) P
                while(p!=NULL)4 J1 J' E* N1 s4 k8 v
                {. ]7 z) J. }; L7 n$ v" `
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);" Z" y$ Y9 c2 K9 X1 i( _
                    if(tag[t]==0)
    0 O/ r2 U, U, f: A# n- a; L6 \                {7 W! M, S. u! E; H, \/ I- i
                        cout<<setw(3)<<vexTable[t].data;3 v  ?- x* @* }
                        tag[t]=1;
    2 o; q; r. I# J                    q.push(t);+ I) X' f! A8 R/ e4 E' t
                    }
    * K* r  X6 D& U8 `                p=NextArc(tmp,p);
    " [4 m1 _) I7 _& G$ C7 J            }0 W% F/ u, {- _& h
            }/ Y& R' C7 f2 c  x/ l
        }
    ( u. U3 t5 T8 \( G5 s6 `}
    - L( P4 z. O. o8 s% R, E0 [2 dtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    / N9 V. t! {5 v/ i{
    ( [, [0 b' d1 Y6 J8 ?. T! T# r    MultiAdjListNetworkArc<WeightType> *p;
    ) i/ X0 Q1 v5 U5 c6 q    cout << "无向图有" << vexNum << "个点,分别为:";
    7 b3 x" M/ r: E    for (int i = 0; i < vexNum; i++)+ O4 _# U6 J# ^, C# W+ ?- f  g
            cout << vexTable.data << " ";$ j2 f5 ^' Q5 z. I
        cout << endl;
    $ T: j  p  u$ m6 U0 Z1 N. Z1 N    cout << "无向图有" << arcNum << "条边"<<endl;, A/ F9 S% c5 `2 p& [$ d# O. V* ?% {
        for (int i = 0; i < vexNum; i++)
    6 z1 y" a6 a" X& L# i& |    {4 l4 d* g( ]0 x6 Y6 U6 y
            cout<<"和" << vexTable.data << "有关的边:";
    & R& w3 {# C' X$ a        p = vexTable.firstarc;% F/ G) g. f# ]' B( L$ b
            while (p != NULL)
      m  g% {% _; h/ ~! G+ ?! @* l. \        {
    & v: E( O8 U  m  J. y. B1 Q" o2 A            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    & y4 n4 n! y/ R) U+ j, L            p=NextArc(i,p);! a5 i: V# A3 [4 D( i% W7 I
            }
    2 z" Y2 i4 b  W& @0 Z        cout << endl;
    2 K" ?7 ]) y, h" B5 k' U6 F, C    }0 S& X6 |& K; L% D: a  J* f2 o
    }
    + K$ C. P2 A* e) H/ a( H. z3 x- L1 H! ]" k$ X
    - c$ y, A3 C1 J* p$ E
    邻接多重表与邻接表的对比8 d! n  f3 C3 s8 V# \# ^

    + r+ A: {4 v( @+ O" n# o' |3 P邻接表链接& y, A' E. a# p) s- c
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。) R5 w* c0 ?1 r/ M/ r
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。; c+ k, p+ A  }* n, y6 K# ?
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。6 o- v: O! K( g- l( d
    ————————————————  ?+ l" G& p: M+ h
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    , S( K9 l' A  [' t原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669588 s. j* E) ]6 G+ k2 Z) H0 r

      W- J' \6 m: h- d& R1 c6 q4 @, v7 p

    % q% h4 X% y- z# u# Q  A8 `! B) D8 j
    ————————————————
    2 m' v4 Z9 y% Q$ X% O; C版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    5 A% O0 ~. B* n6 Y" [1 f0 Y原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958- \" u# y* x( t! l! ^3 D6 e) m

    + L7 S. t- m5 N  [' |8 ^0 T% Q7 F# G8 g  I
    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-4 11:52 , Processed in 0.470928 second(s), 53 queries .

    回顶部