QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1660|回复: 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 V2 b! c' N; ?8 \# [
    图的存储结构——邻接多重表(多重邻接表)的实现
    , i: J/ _, c0 q7.2 图的存储结构
    9 {9 H7 z& a2 d
    4 ]# a  [; F" J! d0 [7 B7.2.3 邻接多重表(多重邻接表)Adjacency Multilist# i& ~1 u$ T! [# \
    邻接多重表的类定义
    8 x5 G9 O1 n- m邻接多重表的顶点结点类模板
    # I" p2 h# |- x- h& x邻接多重表的边结点类模板7 x# F/ [6 Y0 u' U- [6 l/ t$ r
    邻接多重表的类模板. u5 p4 X+ H# s; u
    邻接多重表与邻接表的对比2 I4 F) ~/ R+ T# L9 g7 ~
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    & \4 Z: x& O: J1 ?4 p9 O* A
      Q) p- ~+ i6 j" \  |在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    1 `6 V% e- y% Y0 j& x: w! q6 e* h& c在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    . n$ H+ A8 ]. ?: p
    9 f# i& d/ h! m* z( b) }: w邻接多重表的类定义3 ]. t* a$ k* ]$ [' \
    1.png & H# e9 T" v9 t# s' X* s
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    ' X* Q2 P6 q) ?" Fdata域存储有关顶点的信息;
    0 g* O. ^1 `+ t# Ffirstarc域是链接指针,指向第一条依附于该顶点的边。. H2 R7 h$ L  L4 U6 j1 S
    所有的顶点结点组成一个顺序表。


    ; U8 ~) F/ J' q3 d* h. u/ x9 S2 T5 }$ u4 _" J* t+ ?( Y- H
    template <class ElemType ,class WeightType>
    * q4 A, r; p. }& s8 @class MultiAdjListNetworkVex( a' l/ q3 e  q
    {
    0 \9 V* V' i7 b5 Qpublic:
    1 B* ?, |# Y1 ^# k3 i5 _        ElemType data;5 l% W/ j8 u/ g9 L* @) m( h- ?. {
            MultiAdjListNetworkArc<WeightType> *firstarc;/ Z( H5 k/ {0 {; u5 x
    ' h" L2 p- B$ M8 Y: F: k: ^  @  D
            MultiAdjListNetworkVex()
    ; z2 s) H6 L9 d: I        {' z5 |2 I9 l9 s
                    firstarc = NULL;. P3 f& X( N% j' i6 `7 v
            }7 i/ H9 A! Z- f' ^
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    , b! R% j4 L0 u+ }5 T        {
    1 c. q1 d5 {' S+ k                data = val;
    - G- K! U0 v, @$ k                firstarc = adj;& p- ~( r# g/ d
            }3 r( p3 X2 W8 L8 c: H- p( l4 p0 j; w7 ^
    };
    + J' w. A  @- K4 N+ T- v5 ]0 i6 f$ e: m' U0 a  b) }* ?2 G6 l% D' d
    邻接多重表的边结点类模板
    ' r; w9 c2 B( {4 b5 E9 K$ O& I5 Q4 U# k: A, Y" ^
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    9 `6 @3 N9 I  `) L. Ltag是标记域,标记该边是否被处理或被搜索过;
    ( A; R" U: d/ Z; bweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;/ b" m+ i+ I* J" r0 `5 {; k
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    ( ^: {. l( w4 [6 d3 k8 ^  gnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    8 X) U% s6 K5 r5 S5 E1 O" T5 j" ?2 W' T; b
    2.png 7 @& U1 Y8 n% g" [  [
    template <class WeightType>
    2 h& ]' }& ]9 Nclass MultiAdjListNetworkArc
    ! g1 r) C5 ^  E% z$ q+ c0 V$ C" Z{1 O" l: S+ K/ r+ e4 I- E0 l: X* s
    public:1 Q; h2 B" r. R1 ~- J4 d8 \
        int mark;                                       //标记该边是否被搜索或处理过6 S2 D. W8 M. G& n  b+ l: R3 N
            WeightType weight;                              //边的权重, w! B( C$ Q+ j) R
            int adjVex1;                                    //边的一个顶点$ c, g1 X6 b0 e( ?9 N# P
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1! k9 f  d- E; a) T
            int adjVex2;
    1 z" D* ^+ W& l, |# R5 _        MultiAdjListNetworkArc<WeightType>* nextarc2;* Z& |  i; i3 h% g

    $ Z$ O7 z: o1 S        MultiAdjListNetworkArc()
    ; _) v3 a1 A! O; O# a        {8 ], h, d, @1 G/ m# Q
                    adjVex1= -1;! W# t6 s* t8 {! M
                    adjVex2= -1;
    % e' r% W; z- g0 w1 B        }
    2 k5 G( u3 B# W, ?        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    & k1 I1 s7 D* b2 B* R9 _  A# o        {+ g4 ]! I, K( c( S0 R# }& W3 N
                    adjVex1 = v1;       adjVex2 = v2;
    ' R/ L/ n  s5 W  r, k$ Z7 j                weight = w;
    , Q# B3 y) m0 o+ G# r                nextarc1 = next1;   nextarc2=next2;
    ; K- h5 r1 i% ?  Q                mark = 0;           //0表示未被搜索,1表示被搜索过7 n  J! a* w5 s
            }( U) L! j+ O5 Z- N( j

    6 m3 Q: }2 x5 ]3 G1 `' h5 D3 }" Q0 \9 x7 Z邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>4 C6 P8 q, ~% v
    class MultiAdjListNetwork
    " W" V# X2 b8 L- P{: v8 A, e5 J, v
    protected:
    # s* M+ ?5 t& C9 J    int vexNum, vexMaxNum, arcNum;
    # Q7 ?$ W# W' l% U    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;1 Q" ~* w/ f7 J( H* e
        int* tag;
    % w+ f8 B& @! y2 O- V% @/ Q; C5 @    WeightType infinity;- T+ j. f+ T. U; r
    % y! r# z/ i. k! f! [4 f
    public:
    ' k2 ^/ i/ K2 ^) J& X    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    8 A; H4 E8 K$ N; k; ?0 s7 p7 B' a  F, ?
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);, ~, ~8 V& \3 j9 j6 R% G3 ?( ]5 l
    7 J+ A8 D: ^! Q4 ]6 k3 B
        void Clear();
    , G' `4 G+ J( \' x% ^    bool IsEmpty()
    % r2 ]- e: ~) C# ]    {
    5 b- U5 W! g0 m% c9 T9 m8 @( q7 n# C        return vexNum == 0;
    : K1 t5 {- b# k+ t5 w0 L0 n8 X+ A    }
    / b, O5 t! a+ ~  \; u  ?    int GetArcNum()const
    & j7 p$ F2 W9 D: t  R1 }% u% j    {. ^8 I0 B8 N. Q# q/ H3 d$ b
            return arcNum;
    + B9 Q  R3 [; s4 N# N8 p7 _    }9 v# A, f; B+ A4 O1 s
        int GetvexNum()const9 ], X) A' i: r' f
        {3 h0 T' u. A# B$ ~! ~
            return vexNum;! e" v- @2 b  @: ~
        }
    3 v, h! B; o+ h8 u, A
    0 a3 [/ G) j5 G+ C- ]7 d% f4 p9 i- ^* [: h* p! |# U+ u* w8 w
        int FirstAdjVex(int v)const;/ d  |4 K! T4 o* h
        int NextAdjVex(int v1, int v2)const;
    ) |. B5 Z( Z7 V* a3 H0 Y8 A% O% T0 F    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;2 U2 t$ R& ^2 A, G+ t9 g9 Y
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    + j7 V2 w* H' d) r+ _3 e7 m9 r7 {$ V8 {0 i
        void InsertVex(const ElemType& d);
    ! }& [) r6 ^, u: N7 U    void InsertArc(int v1, int v2, WeightType w);: T/ P3 a9 n, W+ v2 d
    9 l1 P& v' ^! J( p$ Q
        void DeleteVex(const ElemType& d);
    4 F3 Z1 H. g1 \: [# C    void DeleteArc(int v1, int v2);2 t, F- n1 o- ?& W* H
    ( r0 i: l% _9 d' ]0 S* H/ O
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    / M5 ^, A+ z8 D- N7 J: F    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);+ s9 L2 w7 K2 P# k
    6 E% L; r7 X; h9 k
        ///深度优先遍历( H# ~, T( C. k) ^. C
        void DFS1(const int v);+ b3 {% }9 f7 t) h+ X
        void DFS1Traverse();
    1 z# v! t) D* |" g. D, d  k    void DFS2();
    - C, N: l$ u4 R6 S, `
    . t0 C. I4 y. ]! ^' S; ]    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    2 u  Q& A% C6 s: d/ g    void DFS3();
    # G; R9 d$ g  M' |# M5 ]- Y, @% }
    ( x2 \: K* C  m" ?! U6 w    void BFS();
    6 b/ e" Z( M2 c' i    void Show();4 p+ Q* |% [+ ]* V
    };
    6 o  V0 i0 h$ o* q* B" k! P
    ; w- G1 s! f1 t' k* a2.函数的实现7 o8 H( S5 w* G& M# C3 u& [6 m
    研讨题,能够运行,但是代码不一定是最优的。/ P" H8 K. w7 n4 C8 d( ~
    , X  u. ^/ J' h% y; q% z; f0 e
    #include <stack>; v8 P  i9 x) w+ J* t, Q4 g
    #include <queue>5 g2 m; }9 C% G5 u! D) y
    & J, s# E# ?+ I' V( R3 }9 H
    template <class ElemType,class WeightType>
    , R- _8 d' m: P! TMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    / }; E( V' ~" z. a6 r1 f  s{
    $ P. A/ `) z$ R    if(vertexMaxNum < 0)5 {3 d. m" W. `* H/ R9 S- p
            throw Error("允许的顶点最大数目不能为负!");# b5 b+ }0 c: u
        if (vertexMaxNum < vertexNum)+ ^$ C2 k, B; Y3 y$ M
            throw Error("顶点数目不能大于允许的顶点最大数目!");% N" R+ o: O4 I2 l
        vexNum = vertexNum;. P7 a0 r# n1 e) e
        vexMaxNum = vertexMaxNum;. f; D- m8 r) b" N1 t' S+ a
        arcNum = 0;/ @: Z) W% a" p
        infinity = infinit;6 @; b  R" F1 ^7 [% X! K  m8 k- H" {
        tag = new int[vexMaxNum];& v  i# X+ L% y0 a7 [8 O. S
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    # `( q8 J5 W, _+ y& h$ ]    for (int v = 0; v < vexNum; v++); t' O( v' ~/ V! N
        {
    0 R6 l1 Y7 r6 d) {. t        tag[v] = 0;
    + S1 P# b0 _& w' o, l" @4 H0 n        vexTable[v].data = es[v];
    9 [; h& Q5 c* ]0 }. |        vexTable[v].firstarc = NULL;
    2 M2 l. t: ~: g  ^- R3 S$ ~4 d    }
      V+ d( ^. O" t' p}
    4 b4 t. Z4 l2 T8 v& Utemplate <class ElemType,class WeightType>2 R0 b% R, E; E" c
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    ! N+ v; P8 m7 i0 v{
    7 @0 F4 B* ^1 n7 P9 A+ c$ J. K    if (vertexMaxNum < 0)
    ( D9 s8 D$ a* f6 C        throw Error("允许的顶点最大数目不能为负!");
    9 T) o$ C: Q( O, ], t! n    vexNum = 0;
    0 V5 u. `8 D1 X- j    vexMaxNum = vertexMaxNum;
    ( W' ?6 e- N' t# e9 ]& E" @' {    arcNum = 0;+ M- n7 \- |) v+ D  q
        infinity = infinit;
    4 C+ k' R4 C8 L& d, x, _0 i    tag = new int[vexMaxNum];
    2 z* y/ N2 ~( ^: i) K    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    ' B! @- `* {  k+ N# ]) J}7 \' c9 ]: k7 Z, e4 I
    template<class ElemType, class WeightType>
    # S% D" X  F5 X# C1 P! k- Lint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const; `  ^( m* a) c/ A+ \; O4 N1 u3 f5 ~
    {
    . q( w$ }6 M1 ~% t: A    if (v < 0 || v >= vexNum)
      H/ s2 o- s$ @  H* ~$ W5 q( s8 v        throw Error("v不合法!");6 c3 K! I3 R2 v  S' `8 F% e, Z- @5 _! `
        if (vexTable[v].firstarc == NULL)& X: K5 g9 B) g. ]8 ^
            return -1;
    % b. R) s! j  [+ s    else7 G4 \! `' H" B% x
            return vexTable[v].firstarc->adjVex1;7 e+ g& z2 s% [" t; [0 h
    }/ r/ G) C0 }# x1 d

    7 O* N4 j. r" o: m/ L8 R+ btemplate<class ElemType, class WeightType>
    3 x6 U! i9 r, l/ ~3 H8 nint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const5 r7 c" r/ m' h% c8 `# h/ d% K$ K! Q2 E
    {8 @  D% E7 y4 h! n- `. l/ i
        MultiAdjListNetworkArc<WeightType>* p;
    8 E( v7 x& I7 d* E& k3 C    if (v1 < 0 || v1 >= vexNum)
    ' a) l) h! n( \: ?5 i0 {% D# o        throw Error("v1不合法!");) s, p, W1 i0 C
        if (v2 < 0 || v2 >= vexNum)
    2 g, }; S7 x& p9 s2 B6 l6 j/ B        throw Error("v2不合法!");; N& y3 f+ x* G# U9 ~+ l
        if (v1 == v2)
    # s- D, U# t  Z4 ~        throw Error("v1不能等于v2!");
    & `) |: t  O5 t$ `    p = vexTable[v1].firstarc;5 l' |! J; p4 G+ S* [0 [
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    & n, q# r9 D( K2 ~! a/ u        p = p->nextarc;* f; |- t; u6 v; ?
        if (p == NULL || p->nextarc == NULL)
    ! l+ R2 X' A9 T" x! S* A+ K4 D        return -1;  //不存在下一个邻接点6 l* a% l& j) c, v- W6 f
        else if(p->adjVex1==v2)
    ! E9 G- G/ i, f# P        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);2 G1 s$ x7 \$ A$ X
        else
      f6 M+ o4 `) e1 I1 l        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    3 P( O2 A, e& K9 B}" v1 b4 X% E* H) @3 B, [6 s
    template<class ElemType, class WeightType>, ~$ \$ a- e7 k& H) S$ o- b
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()
    ' u5 p+ n( I) z- }{
    0 o  K; J! Y% Z# L7 [    if (IsEmpty()) return;
    5 {0 ]. v  P  R, i$ O- W! s    int n = vexNum;8 p5 I! ?' |6 i3 ^% i9 R; b% [
        for (int u = 0; u < n ; u++)
    ! `( t& T$ M/ p5 o  n: V        DeleteVex(vexTable[0].data);3 a$ ^: i+ `7 Z. |
        return;
    . d4 ]! ~3 V! ]/ W4 B% Z}! j8 ~' L7 C0 h  y/ j9 @: S2 \
    template<class ElemType, class WeightType>
    - a- z" M  `# F. P; [2 v7 u8 XMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    ! ^0 R/ a5 P8 B- i+ r{) u" Q' b! y6 z  B! K- v2 U
        Clear();* h- U7 _2 Y+ [; p$ c* d
    }
    8 D. F8 W7 ?# M+ m; F7 Ptemplate<class ElemType, class WeightType>
    : d0 R5 g8 _2 ]" n, ]* FMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    - f( i0 \* x5 p1 A# X# o/ X5 |$ ^, R{' W5 Y- z/ z$ G- u6 I5 G! d3 v4 f: c, k
        vexMaxNum = copy.vexMaxNum;
    ( o# U8 ~4 X9 `    vexNum = copy.vexNum;2 f, g. b. P% s' X
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];% E  Q: d- s- E
        arcNum = 0;
    3 T$ v3 Q$ N1 C" x+ H5 W0 ?9 a, B    infinity = copy.infinity;: _) N$ j& ?7 x+ g0 u
        tag = new int[vexMaxNum];
    0 `: c9 [4 c9 ?( n: m4 j8 D. v# j: Y) l$ E% z; `# j. m
        for (int v = 0; v < vexNum; v++)
    , ~% _5 p& S$ e! k    {
    # o% r, j6 J: A5 o* }; A7 W        tag[v] = 0;! A7 }) p( n/ n+ L: L
            vexTable[v].data = copy.vexTable[v].data;( J0 m6 d- w$ m) f2 O
            vexTable[v].firstarc = NULL;" B6 s1 g2 a; _( Z2 x% i  }# d1 `
        }2 |/ b8 |$ z: C2 z
        MultiAdjListNetworkArc<WeightType>* p;( g$ v$ o1 d! g- a# N7 K& n1 N9 ^
    ! |! `: y+ k9 z+ T7 v
        for (int u = 0; u < vexNum; u++): ]% R' _: A1 b$ {
        {
    $ ]8 i7 C5 M( V! a$ I        p = copy.vexTable.firstarc;
    , d9 M4 L/ Y8 N8 |# c% b        while (p != NULL)
    7 g+ M7 F8 g6 G) D: l: Q        {3 w& W. C/ a8 I- s5 [
                InsertArc(p->adjVex1, p->adjVex2, p->weight);8 c4 `- u6 n7 e4 m
                p=NextArc(u,p);
    5 U1 e( Y' A" F$ E        }
    8 ]5 k" `6 b1 n+ I+ v7 g    }
    + |- q+ P8 b0 ]3 |' Z" W}( ?$ \2 y1 D! l/ O
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    ) Z! b* B8 z# X% J5 |MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    + x9 L) f# @; H" B{
    ( M& X$ x4 U# a1 v: r0 Z. J. t8 w9 p    if (this == &copy) return *this;
    ! _: w9 H) W" h; z% v& m& K/ n( z    Clear();/ c9 o) j5 R+ {: V' B  k+ B  i! }
        vexMaxNum = copy.vexMaxNum;
    / T! _' k' A' e- n! r3 ^) X7 k, z    vexNum = copy.vexNum;
    % o7 \' {; |% r& ]& [5 N    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];1 t; ~/ v9 C; F* o6 i
        arcNum = 0;2 \, S6 N& K) y3 u( @) q7 n
        infinity = copy.infinity;) F) ]3 k; N# |9 H  n
        tag = new int[vexMaxNum];! R0 |0 y/ F- Q

    & E1 U: i5 m2 [& a    for (int v = 0; v < vexNum; v++)) k: Z) W3 Q; O
        {: U" h% o4 l2 T% N0 N) U" F
            tag[v] = 0;" O) w8 |# A- I  |  l. O
            vexTable[v].data = copy.vexTable[v].data;
    8 {) E4 e$ B- a1 h' g        vexTable[v].firstarc = NULL;" f, d, L- O# ^5 }) q
        }
    & u  Q/ }6 p8 Y4 Z5 s% Z' U    MultiAdjListNetworkArc<WeightType>* p;
    # ~- }* W5 e6 Q7 c( D4 ~2 j  R
    + L2 D" y( t3 J! A3 x    for (int u = 0; u < vexNum; u++)
    1 q4 s6 K" l: }$ R! K    {4 b' d; i& u6 p, C. A! d
            p = copy.vexTable.firstarc;
    # V( z# d) a( k' z4 m% V( l# z        while (p != NULL)
    ! `3 h! Z* l/ {$ S  G        {' g5 w+ o9 Y) Y$ [/ L7 A% Z
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    - \2 I& I" ^+ a! j2 I' K, H( K            p=NextArc(u,p);
    * ~+ S7 I* l. X' {3 ]        }3 N; }/ y; n4 O( B, O
        }
      E: T& D; g7 _; S+ G( n' I* ^( ]  C    return *this;$ D5 |9 a7 `7 y5 r( ]  H! o
    }
    2 n2 n' q0 `: M4 w5 ~template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*% ~$ e) N3 P7 x4 O" j
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    ! p9 E( {$ S; g5 n, K9 h  a{
    ( B5 G3 c. H0 k5 Y) p    if(p==NULL) return NULL;
    0 N! e0 o9 w7 Q! o" k7 A0 o, O    if(p->adjVex1==v1): [$ w% O0 i6 a8 o6 L
            return p->nextarc1;
    ! f) |8 H2 V, F& H    else
    7 W! V; @  O; I7 g2 M        return p->nextarc2;' o% o/ L7 G6 r; e7 u  X  O$ ?
    }
    / q) F4 X7 X$ {3 M3 @template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*3 j6 u- K, V. k: j! K
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    3 s$ ?7 h9 r& U7 R; z{; Z8 m/ i3 G. L  p
        if(p==NULL)return NULL;, B% f8 r: Y2 ?2 |) H, g
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;- n# _# n  \! n, _% [5 J
        if(q==p)- u/ J9 E2 w# l  I( |  s3 @' @
            return NULL;. {; o3 f0 L$ R" G: c9 z4 Q9 j
        while(q)0 k6 V7 h, L: Q! F2 v
        {. Z3 y- H& q, ^, M6 R2 f" n8 U
            if(q->nextarc1==p ||q->nextarc2==p)
    & J$ q+ L/ {/ t# u            break;9 O  K- r( P, V! T3 e" {$ n) V
            q=NextArc(v1,q);1 X% S! u& I/ K; D& x* e
        }$ q2 ~9 d8 L% b& {
        return q;
    ( T/ F- z* d, N% |; K0 f; p}+ }9 W; [1 B$ P1 z, D# D
    template<class ElemType, class WeightType>. ?% d2 V; e3 p
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    2 t; z& z5 d/ q( a8 }{
    & u3 X  ^0 C/ ~2 W    if (vexNum == vexMaxNum)
    ! [9 g9 t4 v, U" X- f2 \        throw Error("图的顶点数不能超过允许的最大数!");
    5 ~: W+ I& ^1 c' i! T; D' |" I    vexTable[vexNum].data = d;( ~) N( m2 d2 {! E/ q& w6 U, o# q1 W
        vexTable[vexNum].firstarc = NULL;9 J3 z3 @) Y9 M4 U. G5 h
        tag[vexNum] = 0;, f7 T5 A7 D5 v, u. w; E% e
        vexNum++;
    * E  H7 j. ~  ?6 x  |6 _" Q0 |( P}" p$ d/ T4 u3 W( a9 q
    template<class ElemType, class WeightType>
    # k. g5 j. q, i+ N$ evoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    1 u7 ~2 K4 f1 p8 @; b) s# n{5 H$ p9 ]# u) \6 B8 h; p* u7 H
        MultiAdjListNetworkArc<WeightType>* p,*q;
    0 u0 j% E7 w- H$ r" q& E! m    if (v1 < 0 || v1 >= vexNum)
    4 d5 U& p) A$ h7 q2 ], s  k        throw Error("v1不合法!");6 u" @4 [9 v/ j2 S! _, x
        if (v2 < 0 || v2 >= vexNum)" x4 q; m& Q; ^6 `$ ]5 h  h+ S
            throw Error("v2不合法!");
    " \/ t- K9 D4 c  @2 p; A4 `    if (v1 == v2)! ]: C- M% W4 E, M2 o3 B9 i) V
            throw Error("v1不能等于v2!");
    % P9 ^/ t/ J* B    if (w == infinity)
      v% c) [& c! f' y* z) @2 P8 _        throw Error("w不能为无穷大!");, d: t1 ^* ?8 ?/ A, i: G0 e

    + R2 m0 v5 Y7 d) j7 g& S, a( u1 L6 j6 L/ l2 v. Q. t
        p = vexTable[v1].firstarc;+ G. w5 w/ q7 n) B& Y
        while(p). z6 R' x2 S& x+ b) d6 m
        {& q0 O) D* c7 I$ R+ S3 o& b# L
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中% e4 V$ L3 P3 U. z
            {% i' n/ @; f. b  ^7 w6 J0 l
                if(p->weight!=w)& X4 v. D& o: C  O8 U
                    p->weight=w;( @8 l9 S" T+ O' k
                return;
    / z* T% ]; i. d' q        }- e  _: Q2 c; E2 n: I! \0 f* n/ T; {

    - l2 `4 f3 t& k8 a; w7 ?6 {' |        p=NextArc(v1,p);
    7 N  {% _+ T0 T5 m    }# Q9 n. V' n5 d" G
        p = vexTable[v1].firstarc;8 C+ C7 i3 u; t
        q = vexTable[v2].firstarc;2 F1 C3 Q/ Q* a: F0 \5 l
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    1 B" G" S8 i% w% T    vexTable[v2].firstarc =vexTable[v1].firstarc;
    " q' }0 m- d( k+ q    arcNum++;
    # a) k3 {/ ?! j- f: {}
    ' i! D& }# ^' b  [2 v, X; V( R: ]4 j' w0 E, j5 `' r% O6 e
    template<class ElemType, class WeightType>
    $ Y% ?- N) W) Q3 P4 ?5 [3 |, Svoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)- ]9 K( Q3 g2 }0 E" B! z4 L9 b
    {
    8 p" C; K/ G( s: O' P* `& |) D, i, A% v
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    + `9 M; f) Y' G# ]& `. @    if (v1 < 0 || v1 >= vexNum)2 W  T3 G4 s, l
            throw Error("v1不合法!");
    ; S7 D( q: }/ e- X5 w    if (v2 < 0 || v2 >= vexNum)
    : b5 z; Z- Z9 L- |( N4 _% i# @! b        throw Error("v2不合法!");: p* J$ ^9 m& a7 J2 h
        if (v1 == v2)
    & I+ g2 k/ K) y# U4 [        throw Error("v1不能等于v2!");
    7 h; |; m3 P  T2 k, {: Y. L; b: r7 |. C) D+ A  z
        p = vexTable[v1].firstarc;: U8 E7 c& K- ~: I
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)" {& w* m9 j# T8 n
        {
    . D- R7 j0 d5 ]2 S4 K; }- k6 B        q = p;. |1 K: F: U. `9 Q( d1 v1 \8 f
            p = NextArc(v1,p);
    + N& `: W1 T& l' X8 c5 l    }//找到要删除的边结点p及其前一结点q
    # V$ a6 J! W8 E6 C2 T' P# B) y1 y4 K" f4 i2 E' ?
        if (p != NULL)//找到v1-v2的边3 |* a, S- R" N4 g+ p
        {
    # u5 D0 M. S. q6 Q9 V" _' s        r=LastArc(v2,p);  T% L3 Q& w/ w0 l
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL9 Z* U# o. n& l" z# G
                if(p->adjVex2==v2)0 W4 B2 S7 @/ X- j) `' ~
                    vexTable[v1].firstarc = p->nextarc1;- K, o  K# }2 d$ K
                else vexTable[v1].firstarc=p->nextarc2;# R$ P1 V, F- @, b2 j* l) M* ~
            else//不是第一条边
    # q% J% x$ d2 Z4 o9 G% i        {
    $ [; k4 f1 f7 K7 X0 L3 M0 @0 \            if(q->adjVex1==v1)
      }8 F% g8 O* ~2 u                q->nextarc1 = NextArc(v1,p);
    7 h8 X# k1 a5 i" T            else
    2 Q) V' ]6 D& E& z9 B6 I! R                q->nextarc2=NextArc(v1,p);' ~6 j2 [' J: H
    + M5 w) L, M' ], v0 S
            }
    " Q, [- L9 F) a. `        if(r==NULL)9 r9 ?: |4 c5 q% U4 G
                if(p->adjVex2==v2)0 s, J( O. f1 _8 k- S, C
                    vexTable[v2].firstarc = p->nextarc2;, ^! S1 B* I% _9 S
                else vexTable[v2].firstarc=p->nextarc1;1 q6 Y0 i9 g. y" A0 F
            else
    9 c3 P- P8 s( K( @* }        {
    ; ]9 P8 S8 l5 h3 r            if(r->adjVex2==v2)2 s4 c, R; ?/ V$ ^
                    r->nextarc2 = NextArc(v2,p);) b/ Y" z- W2 e  T. \9 B) R4 S
                else/ k7 R' K/ m9 M& P3 h
                    r->nextarc1=NextArc(v2,p);
    / t5 o, r& C% ]' Z. C        }* [' i* t9 u6 ?- H, _  N
            delete p;
    . d9 W( K- L. I1 p) A        arcNum--;# e8 C. l4 f% @6 {
        }3 c- J2 I. u7 [

    : d0 ~0 @6 O" j0 Y}
      c7 i. _9 Q1 w2 u+ itemplate<class ElemType, class WeightType> void7 [' G) ~! J' C) v7 n
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    - T/ c$ b! d8 ?2 K0 e, e{2 i5 f( `9 `% ^) l, G, U  G
        int v;5 x  p5 O$ G6 `% f. T$ R
        MultiAdjListNetworkArc<WeightType>* p;& A- P* Z; G1 x6 _" k# O
        for (v = 0; v < vexNum; v++)//找到d对应顶点: n% `" Y: j7 c
            if (vexTable[v].data == d)- i& H" ^) k/ i! i) W+ C
                break;* A2 d: G# h4 E2 h  b* z
        if(v==vexNum)5 {6 W$ [5 S  \4 `+ h/ H$ n2 b
            throw Error("图中不存在要删除的顶点!");+ s5 s$ K6 r/ D) t: ~' }+ D

    & i6 s, l4 u" T' H4 c( t    for (int u = 0; u < vexNum; u++)//删除与d相连的边; p; w* T8 X& l2 ?" C3 O7 h3 z
            if (u != v)
    9 b) \" l) `( o9 O6 c$ g        {
    ! o9 O% F; S7 b            DeleteArc(u, v);
    . H; ]) R1 u( D5 A' J        }& C; v7 q" @) w* y% U
        vexTable[v].firstarc=NULL;* q1 d1 C. C8 }; L
    9 d. x( G, a' t+ n+ I# W( D
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置. J- R7 v: @" I, E  ~3 ~: r
        vexTable[v].data = vexTable[vexNum].data;9 g0 w: w) A8 l: b1 W
        vexTable[v].firstarc = vexTable[vexNum].firstarc;
    6 |" D+ P$ A& f0 h2 A# ~- I# B1 s9 H2 V    vexTable[vexNum].firstarc = NULL;
    $ k5 W2 c, W# _  g2 _! y5 @, B+ `    tag[v] = tag[vexNum];
    ) @1 ]) k1 V& B7 A$ P6 t% C    //原来与最后一个顶点相连的边改为与v相连
    & [& k' f/ J( C9 y2 L    for (int u = 0; u < vexNum; u++)
    8 D' G$ }7 ^8 }* m8 Z    {
    / |1 k9 z5 K* N" N        if (u != v)
    ' X$ ?" k9 Z) S2 I$ ^( V        {" j" Y, o( E7 v+ o
                p = vexTable.firstarc;- `& E. S- ^9 n3 F; [6 \0 [2 M
                while (p)- S6 o6 S6 U, L1 ^; |
                {5 H: L+ a. ^8 a( Y0 B0 p& R* m- T
                    if (p->adjVex1==vexNum)! x  G# w  \& n, \
                        p->adjVex1= v;; H8 B: F0 `2 t2 B/ v
                    else if(p->adjVex2==vexNum)
    * Z- w0 h- n, \' M+ r  \5 i                    p->adjVex2=v;' e4 v1 q( U: v/ v% o& S
                    p = NextArc(u,p);
    6 t* E. [; D0 k2 I" f            }( M+ b. W: C9 u5 @
            }
    , \. K# w" ^; z  S) T3 r5 y    }  |5 {5 `. |8 C" K' V
    }  W  ]# E0 Y) h0 @
    ///深度优先遍历
    4 k; [8 r% L1 h0 ytemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    1 a) f) k$ Z6 @3 p' H; T3 p{- T8 }2 {, ~' Q# a! ~
        tag[v]=1;
    7 l& {1 }( q/ N/ @    cout<<setw(3)<<vexTable[v].data;
    . x* I' `: G/ {; B. T    MultiAdjListNetworkArc<WeightType> *p;6 ?% i0 L) s: i: j/ B
        p=vexTable[v].firstarc;$ R% @. ~1 I7 e# X3 s' c
        while(p)
    2 @8 h( m& G. Z# a5 o, |    {
    ' o. b4 W/ ]+ u4 Q2 K        if(tag[p->adjVex1]==0)+ C! k8 L( ?; c! l/ K
                DFS1(p->adjVex1);
    ! p! v# r& r# P6 Q9 E. b& i        else if(tag[p->adjVex2]==0): A$ _( e+ M) Q7 n2 k  D/ I" J
                DFS1(p->adjVex2);+ J6 h* y) H. g$ ?2 N
            p=NextArc(v,p);
    . ^  Q0 g( V. w$ j0 f9 W    }. s) ~9 h2 k; i6 X
    }2 b$ q: k& a5 L: H4 d* E
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse(). X4 w( X/ @* b4 D( ]8 r
    {
    4 g7 M" c' @" b5 I    for(int i=0; i<vexNum; i++); g7 g  [1 ]9 k5 ^  j
            tag=0;
    9 l0 p8 G$ _* w3 M$ e. K  @. I    for(int v=0; v<vexNum; v++)
    ; W8 w; y) N8 X4 v    {
    ! @, p2 e' D3 O$ p0 m( E/ `        if(tag[v]==0)) U0 O2 f  ~- {4 w) y) ?
                DFS1(v);
    + w( l4 S( u- Z# d0 o0 g    }6 o/ m% Z5 b7 B/ }  C6 H
    }3 P; q0 u: W# o4 M; k) u
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()" m7 z$ P9 x$ w8 p: u0 U5 B
    {
    4 ?7 ?1 h. J' K- q$ i- \4 c    stack<int> s;& f7 f3 E6 g5 _: G
        int tmp;0 H  z* d/ D9 y( y
        MultiAdjListNetworkArc<WeightType> *p,*q;
    1 u5 f. S: n0 d; [% s/ [    for(int i=0; i<vexNum; i++)
    % [  w+ R+ T2 S; K        tag=0;
    ; R, a# U. a& M5 P4 {! W    for(int i=0; i<vexNum; i++)( }" t% Z/ d" S; m" `
        {" W" ~+ h8 s$ X) B6 o
            tmp=i;
    / E  O. l; y; U        while(tag[tmp]==0||!s.empty())/ j$ Z% ?" Z; W9 X* r! m
            {
      A8 E. f' b' s0 L6 J# G            p=vexTable[tmp].firstarc;
    7 M# {) Z5 q$ D/ ^. V            while(tag[tmp]==0)
    ( S8 t1 _& J/ ^) u' e& q            {
    9 i2 Y7 {' y' M& D7 c# p7 h                s.push(tmp);
    " g9 R5 T! L* [3 r) s5 w                cout<<setw(3)<<vexTable[tmp].data;9 Z2 |4 h" q  M$ k
                    tag[tmp]=1;
    2 }  v3 k, H3 p9 y                p=vexTable[tmp].firstarc;
    1 \4 Z  j6 V, U                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    " j# U) @0 ~! r- M                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);( {$ |8 E: j' E- j9 z1 ]; D
                    //cout<<" 1st     tmp="<<tmp<<endl;
    3 ?: \1 C3 a+ y7 d+ {% n            }3 G7 X$ A7 I3 J, J% J+ ]
                if(!s.empty())
    ; w# q7 w! [) z3 f9 a            {: P+ H* r+ i1 ?
                    tmp=s.top();
    - ~& o' R7 n! ~$ H( K% E                s.pop();7 L% P+ J# N# K, c0 \6 Q' Y* l
                    q=vexTable[tmp].firstarc;
    $ f8 ]4 P# K/ s6 S                int t=tmp;$ V% f/ r# q* d1 }. p% ]0 P2 T
                    while(q&&tag[tmp]!=0)
    8 s& {+ N0 @6 [  E                {8 e6 j8 A# g4 w
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);! ?# O0 T5 g- s
                        //cout<<" 2nd     tmp="<<tmp<<endl;* h! `' @" r, |) r; {' U& v, r1 _8 _
                        q=NextArc(t,q);( X0 w9 N1 ]: W/ e2 j# K
                    }
    9 X- q+ S' f$ g2 H. d5 ^                if(tag[tmp]==0)
    8 S) w: m; @/ M4 n$ W                    s.push(t);& l; J' G, @, P  j  L3 X  T$ \  L
                    ///1、对应上面连通分支只有1个点的情况
    2 }/ k2 J  n' g% o: x. U  t                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈: N0 o3 O' M; M1 g0 ?! R
                    ///tmp要么等于找到的第一个未访问节点,  a6 @6 ?& [* ~2 l1 G1 g
                    ///要么等于与t相连最后一个点(已被访问过)( t" a8 ^0 X+ o! I# |; |
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点2 y& d; i1 _7 L7 W1 ^2 N4 o. ]6 [5 S
                }4 G) B1 I) z0 @/ q
            }4 ~) z; E9 p4 |3 U4 _; W, O
        }
    5 x5 M, ]* K% ~1 }7 v}
    / n' y1 H  y6 _" h% `# r//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-19 V, j$ ~8 G* y9 ^" T3 J- k9 H* R
    template<class ElemType, class WeightType> int
    0 _  q# d5 S( `! u+ a! k" }MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    3 B% w  j, M% V0 c. Z$ j6 d{
    % Y8 O& A1 S/ q% y    if(head==pre): h1 V" e) z+ k; V9 r3 }6 q7 r. I
            return -1;) c$ H4 `& E3 V( L- a% g7 K
    5 R0 J8 f1 W2 p+ P* t0 p  _9 O
        MultiAdjListNetworkArc<WeightType> *p;
    ) [- @4 _0 ]# Q3 t3 S8 [    p=vexTable[head].firstarc;2 Q' h5 Q/ y$ S* K: {
        if(pre==-1&&p!=NULL), M/ ^2 P: }4 q! W
            return p->adjVex1==head?p->adjVex2:p->adjVex1;) v8 l2 a& J' ^, d$ G! x
        //pre!=-1&&p!=NULL- t* F5 p& x0 U" b. E
        while(p!=NULL)
    - R4 O$ j- ~8 }  y8 J    {
    7 d2 L6 R9 U. Y) i6 @* u. @        if(p->adjVex1==head && p->adjVex2!=pre)% M" j  t' X. d- [" s+ J- {
                p=p->nextarc1;3 i* g& Z- d- @7 v6 w: B) E
            else if(p->adjVex2==head && p->adjVex1!=pre)
    6 |: Q! M# u+ ?+ L+ C            p=p->nextarc2;$ `% R' I1 H6 h& f5 _6 s, u
            else if(p->adjVex1==head && p->adjVex2==pre)- @7 O; T! `1 g6 Q. A& I7 p
            {
    " `9 @# z- \. y$ o5 O            p=p->nextarc1;& ]) h: h2 }7 i  N! E5 B2 I4 z
                break;
    0 J- x0 Z8 z. y" h        }
    & Q3 [1 Q# l  ^% |2 K        else if(p->adjVex2==head && p->adjVex1==pre)% l: ?8 J& F" i2 G/ ~
            {
    6 |, I4 g% b( p2 K% n! L$ A2 [3 ]; i            p=p->nextarc2;' m" N2 O( }8 Z
                break;) i6 `7 j6 W; Y3 R8 R. u
            }! o" p: X, P3 a
        }
    1 U& x; _) u" I# v    if(p!=NULL)3 j. ?9 T9 A- H. R4 J
        {
    / h% l+ Z" e9 {" e0 }        return p->adjVex1==head?p->adjVex2:p->adjVex1;6 _( G8 y: c: S3 A6 d  q# O$ H
        }
    6 I- g: P2 q0 G. \2 b7 m4 F    else% d2 W# a0 ]$ b8 [. c
            return -1;
    ( Y" e1 P/ h4 G% y3 L}  U" o. z: q% i4 S

    1 t) v7 N8 |6 O9 x* h/ u. E7 l$ K0 X( C/ O+ i. f, B. s5 A
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()  J; m0 K3 t& R6 K' \- C( y
    {
      D' I% g/ ^* A+ x6 M/ `    stack<int> s;
    - _4 p+ S# V5 X; I# y4 K( I( u6 H! n' ^    int p,cur,pre;7 h: T9 y/ q: I2 A
        //MultiAdjListNetworkArc<WeightType> *p,*q;
    ) [+ a1 h( L, E5 P& W$ O; u    for(int i=0; i<vexNum; i++) tag=0;//初始化
    7 j/ j! ]5 i& H
    ! {) a; ]9 f) j    for(int i=0; i<vexNum; i++)
    2 z6 O* c6 y1 ]: A( a& P- q    {( P5 K  Q( \, p" ]1 R1 U* F; o5 N5 f  ?
            cur=i;pre=-1;( q/ W3 X; u% L
            while(tag[cur]==0||!s.empty())
      q: |* O( N3 P$ I$ V3 l- A        {
    2 u5 u8 a6 U# ~  Q7 e/ N7 @8 i, a6 t0 M( H            while(tag[cur]==0)) s2 w/ h" I( f2 i# {6 X( U
                {' r4 Q3 z  h5 S2 `2 N
                    cout<<vexTable[cur].data<<"  ";
    ( z9 ~- u- P4 z9 J  J/ \" a* E; z4 N                s.push(cur);1 e2 ^" e, D* O! Z# A' W! U
                    tag[cur]=1;
    6 S% H% a' u0 c% M9 y- \( l. l               //初次访问,标记入栈
    * H  S! o' F6 `* P  F# k( V/ G$ R% b, e7 m
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点
    2 s2 f8 r" B* [: X               if(p==-1)
    , I9 s9 @' X0 h3 n               {3 D% k7 @( M! w" q
                       pre=cur;s.pop();
    1 l; _* l6 s  h+ r1 f" L                   break;
      Q5 m! I! l3 r% n* J( Y9 b' i: e  H               }
    5 j2 U3 i- x" k: U$ x! ^               else/ W: f! G: z' s) h7 I' M) l1 _" E
                   {. O; a4 Y7 ?  z( t$ [
                       pre=cur;
    - t" I/ V1 r# m+ H. \! t8 g. {* }                   cur=p;1 M! _" Q9 s7 N3 ^
                   }
    % h' b1 M* L" c! i- B
    $ k! a8 ]3 D% s* I, z! I/ D+ \            }0 `, X. m( T% }8 V
                while(!s.empty())
    1 ?2 Q, F1 q8 n            {  d- \; Y) Z7 u5 P: Z
                    cur=s.top();
    4 P4 L% S0 i9 s! Q5 y                p=GetAdjVex(cur,pre);
      \; t9 Z8 v' E* n1 R. b  v                if(tag[p]==0)
    & p- b6 g: t) w% l" U$ f. X                {
    " J8 P3 b1 |' j9 c0 ~% V3 e                    pre=cur;
    / n- g+ \* _, |  V) ]; }  K                    cur=p;
    / I, |8 t# C$ K* B4 H* b: S                    break;
    $ I+ V* _# ~& t. h7 b2 v                }5 u3 ~: q3 f( g* |' p% d
                    else% E: F& p4 U5 q( W+ z! t! ~8 l
                    {
    1 \6 C: J1 O) p/ H9 G                    pre=s.top();
    8 a. y/ R2 s# O6 E" z+ w                    s.pop();* p2 N: C1 w3 w4 V
                    }6 e" o% \" }- p2 s: X

      j+ a- u9 G" X. R- v( J- P            }
    $ f& e+ s. S; o3 {; A1 J) K, g$ b- Y9 }
            }( J: \7 c8 W& g( o; G
        }' o9 L4 I( P% D* p: U2 P* h
    }
    : u9 d! \- I: r9 U8 Xtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()% S1 S8 ~! d, n$ s
    {
    9 r: d: Y. o8 O. q$ S' Q. s    for(int i=0; i<vexNum; i++)$ v0 R1 U2 f, J" b
            tag=0;
    3 \! @0 h+ r) F8 z% r+ r4 ~    queue<int> q;; d7 X& p- q# c3 Z2 p
        int tmp,t;9 j- s6 {5 S/ q+ w7 S! N6 Z
        MultiAdjListNetworkArc<WeightType> *p;
    2 ]: e% N0 F4 v/ J9 b# u    for(int i=0; i<vexNum; i++)
    1 U. k6 w1 V/ E! x# H7 P    {
    $ M0 |: V5 B  P; a        if(tag==0)* X; x8 s9 O7 S' d
            {% ~8 Q( t2 R% H1 T! h  ]5 g
                tag=1;
    & m, X* Y/ w* `  p2 u            q.push(i);
    # k% o; G5 s$ ^" `+ ]            cout<<setw(3)<<vexTable.data;9 v; u! v9 T& W9 }+ z0 T/ R
            }* |( j+ z/ ~! ]& |+ b; x
            while(!q.empty())
    " \- `- O4 ~# p; I        {& n0 K2 f! ]3 B+ H
                tmp=q.front();: [( q$ [! k1 a! F4 h/ [
                q.pop();& p- L- k6 n  }7 `# }5 Q
                p=vexTable[tmp].firstarc;
    1 G; f2 W- H9 `* @( {            while(p!=NULL), h2 d) I+ V9 {# y  w, L( {6 n
                {
    ! y2 ]( y3 ~* r* l3 J) m% K0 c                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);9 H- z! ?( z) }4 e" M& y
                    if(tag[t]==0)
    / L1 k7 x( x2 _$ u                {
    ! j% X! J- U1 Q) {2 p, {                    cout<<setw(3)<<vexTable[t].data;) b" e* x* j- |) \* O
                        tag[t]=1;  y5 w7 s2 E4 ]1 |
                        q.push(t);
    . Q" d+ `/ N% Q8 y, W                }% q; M: n7 v. @8 w
                    p=NextArc(tmp,p);
    * z; o2 ?* N1 N. l) H# j            }
    ) O2 K2 j+ M6 k  N& b        }7 G/ l' I$ h4 ~8 ^; J1 Q
        }
    5 [3 V0 v. @% x- ?: T}
    + [. R1 ^. d% W  _1 C& B* Ktemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()( U7 w+ P# U" Z6 u2 u: A
    {
    8 O& c( p7 ^7 l8 a$ \5 L. {' b    MultiAdjListNetworkArc<WeightType> *p;5 a  U. J, S9 ~" |/ F6 E: }
        cout << "无向图有" << vexNum << "个点,分别为:";
    # g' x% s3 e' |8 _1 B    for (int i = 0; i < vexNum; i++)- {) X/ O8 q7 L
            cout << vexTable.data << " ";
    * i+ m0 [! ~3 ?' i8 |    cout << endl;$ D  `. K  r9 n
        cout << "无向图有" << arcNum << "条边"<<endl;( ?- C$ n7 P  n' X# [
        for (int i = 0; i < vexNum; i++). @+ n3 Q7 C& L- I: q8 U
        {$ s# B5 k6 }! m* F/ p; Z
            cout<<"和" << vexTable.data << "有关的边:";: ^2 \3 i/ I2 F
            p = vexTable.firstarc;& b- t$ p" V* o
            while (p != NULL)
    - Q- Q; p! O5 l; n7 ]        {" k8 M, h1 W9 ?" t$ s. w* V
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    - ~5 ~, P* J7 k7 B4 H# C            p=NextArc(i,p);) m$ C9 I% r% j2 P* g  a
            }
    7 T# F' j4 L. T- |& @        cout << endl;
    8 ?+ l! ?4 f) m$ @8 N! z    }+ h$ |5 m. d/ n$ s  [. G9 x
    }
    1 L( ^7 ~3 ^5 y4 Q, m  k! Z4 c5 k0 o7 R

    + O" S# q- W/ d0 t/ f( U- s& N邻接多重表与邻接表的对比
    " y1 {1 \: k% M, |8 Z, p. ~3 P
    8 O) X, Q% U% B邻接表链接0 Z4 }5 C' Q7 A, O, u: O
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    5 ~5 P$ e1 B/ n' R1 i, N. ?9 ]在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    . ?# ~2 [5 V4 K, Q3 a/ M/ O% L, B为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。( q! n; b3 ?- d$ I4 w/ F; P
    ————————————————
    5 w5 Q5 O% d. R. V( f5 s版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    1 V4 B1 t' x. G8 V/ A原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    ( }' L& S2 e* [- Z! d" M
    2 }% I' e% @3 H5 y0 t: w8 G
    5 ]8 ^1 {! G) h: W: x7 j, o  N
    # w4 y, E- h# w  R/ z8 O; l. q( }4 ?0 x5 B$ K/ k/ A
    ————————————————) ^: E; f! `. a/ a5 s
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    % {; n1 e/ [' _$ u- M原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    5 Q$ h. b/ H9 Z; c1 ~, L
    ' x$ b% S0 _3 ^0 o4 v  f/ _% z0 c# E  C7 ]
    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-9-10 12:03 , Processed in 0.454739 second(s), 54 queries .

    回顶部