QQ登录

只需要一步,快速开始

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

    ! B8 f3 z& `# K+ P6 b图的存储结构——邻接多重表(多重邻接表)的实现
    ' L) }( ~/ R3 k7.2 图的存储结构
    : p  ]$ S6 X9 ?0 I* @
    7 X2 e* K1 L9 \$ Q5 Y7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    - j8 i9 q: H; [, M8 o' j邻接多重表的类定义
    ; l' x- d' H2 k9 l( Y5 J# I邻接多重表的顶点结点类模板3 m" p8 f: S/ a, T3 u
    邻接多重表的边结点类模板
    - k. y3 o+ x" x0 E2 z# d* ]- b邻接多重表的类模板
    ( ?+ H  A5 v, D' S  t邻接多重表与邻接表的对比
    : m3 g/ p6 \- V7.2.3 邻接多重表(多重邻接表)Adjacency Multilist) x5 ]9 e% X( g+ C8 d7 J( J. k

    # r; I& r: S. G/ A, i$ T在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。' v; V, o+ _9 F# x7 q" s7 d" H
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。! T, ^* k# \9 k8 e3 X) q
    / ]& {. c  z2 X
    邻接多重表的类定义
    ! ~0 N: B4 z' Z 1.png
    9 |5 v. P. x8 \7 }邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:% e' L4 Z/ Q. v$ L4 n1 H, n1 q
    data域存储有关顶点的信息;
      Y9 D0 X5 l6 U$ x1 n0 E$ \firstarc域是链接指针,指向第一条依附于该顶点的边。
      U8 N) X1 m. z. S1 w5 U& O所有的顶点结点组成一个顺序表。


    . K6 D& ~6 V0 d, T5 @
    . K5 \- I! K& f3 f* gtemplate <class ElemType ,class WeightType>7 D0 O1 T$ V0 o
    class MultiAdjListNetworkVex
    0 k" l' i  x' F4 B. ]6 `. B7 j- l6 A{
    / l  m3 U# H6 Y5 L. N/ Z; Cpublic:
    + Q6 J1 c, P2 q* B        ElemType data;
      o" \1 X( ~& r/ e7 P- s1 |, K, ^  X        MultiAdjListNetworkArc<WeightType> *firstarc;3 u0 s% ?' e2 P8 E
    5 R+ X7 i+ N/ j4 S) w: u1 E
            MultiAdjListNetworkVex()* l; w' z1 u: a* s" V0 c- Y
            {
    / V& K2 W2 J3 K0 e3 A                firstarc = NULL;8 U1 v1 p$ d, C
            }. p! V% I5 x6 x6 z# n7 i
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)$ B6 @( K+ B2 B) [7 s5 w# A* \
            {/ k: D% n6 r% Y5 Z" m* d
                    data = val;
    1 k0 T8 Q+ N  O                firstarc = adj;
    4 |" l/ A  E6 T9 V. l+ A. L2 l        }
    7 X" \! ?4 L$ m' t$ O0 k1 _( l};
    * b4 O- j9 [2 E/ J
    ! y% x9 Z3 s2 ^* n& u6 X邻接多重表的边结点类模板, F7 k% D: q# x+ a* k5 C6 |# y

    ! g) @& w7 ^& x  c' }3 A在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    % z7 d) E: B8 R( Atag是标记域,标记该边是否被处理或被搜索过;$ ]! \/ G# z2 ]; Y: D0 u
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;5 T8 a, Z) C) @7 \: G* l
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;4 o: o9 M9 j( H$ s, h+ y
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    4 |- f/ F% y3 W7 k+ {: I/ R, Z
    % K2 ~! d  n8 @ 2.png
    : g; }! K2 p& f+ h! G8 C/ Ntemplate <class WeightType>- s1 K3 x1 L4 O% t6 X& L
    class MultiAdjListNetworkArc
    ) ~: q/ D0 W7 V7 t# ]{, |( F$ |  w- l
    public:
    - u+ s% V( h0 Y4 M2 l    int mark;                                       //标记该边是否被搜索或处理过
    & o. l8 i6 F6 d7 g( `        WeightType weight;                              //边的权重
    # s# B$ {" f5 i$ x        int adjVex1;                                    //边的一个顶点2 `1 I3 L% g% g& D
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    7 b. v: Q. {0 O$ E( n* X' L4 L/ f) {4 G        int adjVex2;
    9 t0 }$ r' x2 g0 q" R: e        MultiAdjListNetworkArc<WeightType>* nextarc2;
    , \/ s0 |( Z7 B5 l
    * o$ V" q1 r" h6 `* ^# h& [        MultiAdjListNetworkArc()
    # u8 W! ?# m. x  q# E        {
    7 H8 c; ~$ m% y0 f/ f) A2 a4 c0 l                adjVex1= -1;
    5 @( A% ]4 d8 N( u                adjVex2= -1;
    6 \+ e4 D6 e( p        }
    , _/ \2 I! s3 q  c( P* r1 j/ v        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)1 f: g- S- i) ^
            {+ o2 ]3 }7 t6 k( q) ?0 R# W
                    adjVex1 = v1;       adjVex2 = v2;4 n) y) ^  w- g' |' L; {  t. F' T
                    weight = w;) @( H( [  [- j$ R
                    nextarc1 = next1;   nextarc2=next2;" K7 ~! j) ^: a; |7 @
                    mark = 0;           //0表示未被搜索,1表示被搜索过( Z9 y9 u* e! Y
            }* |( P" m: e; \* b
    4 w0 E6 l. |) U4 l0 t1 I
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    ( V  l) N1 \  r0 l- R; i# kclass MultiAdjListNetwork8 N- ]- d* G  V& y
    {
    ' d  Z. A% X& Y; I7 f8 Rprotected:% J+ u( r' m% I+ r, s' l- J
        int vexNum, vexMaxNum, arcNum;0 b( H) D; f) j
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;$ K5 s1 W" w/ {& [  B& E% V- q' {
        int* tag;
    + R- O0 c; c5 {; K    WeightType infinity;
    - @1 O& \, e, B9 E
    7 X* ^# k- r2 o+ ~3 Upublic:
    " h- U7 a% D; c& {" K$ N0 c    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);- n- p* R; t5 Y3 Q9 P: m7 v5 V

    / q; w  w1 @/ e! ?: f5 ]. H8 \* J9 _    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    3 p" B+ `3 a) z& l" i& s) z% Q
    ' D) I6 O, g! a5 E* Z% g4 B5 F    void Clear();
    * W0 A) @' H7 L8 y5 e% H8 X    bool IsEmpty()
    * F- L) x9 a  J' E    {
    2 t3 a2 j0 F4 w/ n; A, c. o+ R        return vexNum == 0;( ~# A- a0 p' W1 b0 _
        }" y6 j4 ?; X2 x6 [; J
        int GetArcNum()const
    8 D/ G6 T. C# [4 r7 H. d    {
    , x0 r1 Y$ F2 E; A( ~7 l        return arcNum;
    2 H' z! b. x* O9 ?3 x8 ]* h% }/ b    }
    9 @: y: I+ Z  t: J1 [' _, Y    int GetvexNum()const
    9 p( B6 {/ N5 L- ^& \    {+ H% k1 J4 e1 d8 V' h
            return vexNum;0 p# {, y9 {* D, a
        }2 t) F$ y3 O# t

    2 B/ G; e4 G8 C" B( R6 B
    % _( C7 e& k: P3 [9 k, E4 U; R    int FirstAdjVex(int v)const;
    $ k+ ]: f" t  R* Q    int NextAdjVex(int v1, int v2)const;8 e$ U1 x" o7 ]9 M( @+ u& Y
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;% g% O$ H9 ^8 ?- {
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    6 a3 G; K- Z5 Z, L5 d% f
    2 l& `9 [" M0 N    void InsertVex(const ElemType& d);+ K2 u% u" Y7 ~" ^' {' a% a- P
        void InsertArc(int v1, int v2, WeightType w);; z; g# E& g, N7 y& U5 l+ ~
    " ~9 ]+ g/ b: S: m
        void DeleteVex(const ElemType& d);4 g. @+ H1 q% Q8 f& ]- |7 ^, o0 {! U
        void DeleteArc(int v1, int v2);- ]0 C5 S: }  Q3 {5 B0 @& Q

    " J1 F+ r" x0 w$ r    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    % L3 I: M- i) @% n1 ~    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);3 s6 J( ?* n' V4 N
    8 [% O# ?  k8 N3 y
        ///深度优先遍历& z* Z7 @- ~" z& S5 t2 w" K- e
        void DFS1(const int v);
    - d# {6 J6 m" ]    void DFS1Traverse();
    ) h: u" L3 Y1 H4 N  `0 p    void DFS2();" G6 G7 X! w' E+ Z* a1 v
    1 j! e/ G6 d1 e3 Q0 a, y
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    2 H# n7 l- p. k( i    void DFS3();& c  g' n4 F/ S

    # d3 L' ~8 O5 }2 Q7 A' z    void BFS();: m0 h4 n/ Y- {- v4 v) j
        void Show();- ?9 y5 @# K' M* J1 M9 `! A7 H" J
    };
    ! D3 K) x$ U( U7 ^) F* ?& j
    $ ]& o2 n6 l. P$ I" z2.函数的实现9 y8 r* A, M6 [* [
    研讨题,能够运行,但是代码不一定是最优的。
    + u( |5 I/ N3 a/ A* h* W" S; d6 }# D$ ~
    #include <stack>
    1 ]2 c# f; e5 n, a+ I; L: c#include <queue>
    6 k: h; b. x8 c9 A# ?3 T3 R* j  h* Q, N
    template <class ElemType,class WeightType>
    3 D) R3 q7 C' O; ^: U' aMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
      I. U9 V! N* N% r8 V0 z{4 i. r' y  s* C( T8 v
        if(vertexMaxNum < 0)  I2 C3 y* o, P% L# Q0 n
            throw Error("允许的顶点最大数目不能为负!");
    7 ?( y/ N/ D4 f3 U4 l    if (vertexMaxNum < vertexNum)- s& |7 u+ M1 H" }0 [: d) t
            throw Error("顶点数目不能大于允许的顶点最大数目!");
    6 O. M1 T+ w  G; Z3 ^4 ]    vexNum = vertexNum;
      ~9 x0 I/ V, N% C9 U    vexMaxNum = vertexMaxNum;
    , s$ J1 _1 L* ?: L: H    arcNum = 0;
    ) w! t" }: Q% a$ D6 E    infinity = infinit;
    8 v9 b8 u, p1 S- ~    tag = new int[vexMaxNum];
    : j! P8 H% _1 P/ \* M5 @  L    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];- u" `0 l& u& _$ v+ C% N' T
        for (int v = 0; v < vexNum; v++): w3 g2 N8 ?5 z* `
        {
    8 M" z: p4 O# M4 |: |4 @' N9 C        tag[v] = 0;
    3 c  G: n' N6 F% w1 K8 y6 {        vexTable[v].data = es[v];9 [; ?& }& O" {" `  R; W0 e
            vexTable[v].firstarc = NULL;+ e) S+ [8 v: Q* r3 ~- d
        }0 c7 N' e- \/ B% h7 J
    }
    % I, A! u/ Z/ M! N0 F8 |1 O6 Ytemplate <class ElemType,class WeightType>
    6 d8 _2 \2 J$ ]MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    % @* L; J. d0 r$ N& W{& m8 L. q' P4 r) a( v
        if (vertexMaxNum < 0)
    + R3 {4 y( g# V( F  a9 W8 C        throw Error("允许的顶点最大数目不能为负!");7 ?7 U8 \" W+ Q! q% `* z
        vexNum = 0;
    8 [" w" _. M: `& V+ A  J# p9 g    vexMaxNum = vertexMaxNum;+ d1 o- u1 B7 u+ H6 o; q
        arcNum = 0;* J2 y1 s, C. @* F) a
        infinity = infinit;; H4 n1 N) U3 @: u
        tag = new int[vexMaxNum];
    2 k, }8 X6 d; u0 h0 f    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    ( c) \" z: w* i" P) f3 {" \( i}
    # C) L) H. b; m, E( Utemplate<class ElemType, class WeightType>3 v" d& f$ L( k- T# K5 {
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    & p* @/ T% \! `# I2 {: Q. r/ A{
    7 q  n; R1 ^4 x. ?5 X+ E% z    if (v < 0 || v >= vexNum)
    . L5 J0 F# m# r" a$ P8 s        throw Error("v不合法!");- b7 _) e' t9 M$ U: R# O5 l
        if (vexTable[v].firstarc == NULL)- W5 z! ?' X; ^6 _' m  U: Y
            return -1;2 p& X% l9 I2 b5 n) F" @
        else
    ; {% _' |0 M! ~        return vexTable[v].firstarc->adjVex1;
    0 v5 k- u: I7 ?! Q" O}" k- \/ R6 F/ q) X0 P1 Z
      J8 r$ N) }/ w$ R* T! }
    template<class ElemType, class WeightType>
    6 g) k8 v2 S' k7 Yint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    # {  A: V6 b5 P{
    $ T; Q# f) m9 _0 O    MultiAdjListNetworkArc<WeightType>* p;0 r. r4 a+ [! x# O4 j; ]$ Q
        if (v1 < 0 || v1 >= vexNum)
    + `6 n9 y# F, b        throw Error("v1不合法!");, [$ [/ x( e$ f" M
        if (v2 < 0 || v2 >= vexNum)
    - I$ @* H* a" G, B        throw Error("v2不合法!");
    1 B3 i+ M. S1 r$ i6 W" C    if (v1 == v2)
    + Z, G% ~0 r- z        throw Error("v1不能等于v2!");
    3 ~$ @4 W7 M: J( p* |* ^- j    p = vexTable[v1].firstarc;, [3 s: d7 C4 O
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    1 {) I9 }7 M$ l        p = p->nextarc;
    9 q) }- [5 c" L* x: f    if (p == NULL || p->nextarc == NULL)
    3 u6 d' n( Y: E( {1 i        return -1;  //不存在下一个邻接点( p* x& [0 C3 ~% p- ^
        else if(p->adjVex1==v2); f: [+ i' b* O2 A5 M# |" H4 q
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);! H( P- _( @% `2 G
        else* l. _: J2 A1 `2 Q# }
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    - H' w  T' x2 r* h8 X/ A}
    - N# Z& X/ L5 }9 U' G) G; Ftemplate<class ElemType, class WeightType>/ `/ p% W$ z( H' C2 i* Y) d
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()" D: Z( e8 }9 B5 W" y
    {& s! Q% Z$ l! c
        if (IsEmpty()) return;- i9 r# h; L( {9 i. J0 \
        int n = vexNum;
    / l7 d1 R' K. e: k, z( v( E4 ?    for (int u = 0; u < n ; u++)/ U: l/ o/ f' M& h$ P
            DeleteVex(vexTable[0].data);+ y. Z" F4 u, _% o; s9 Z9 z
        return;
    + W4 E: K: M  _8 [  n$ ?1 G}
    ; h  K$ C4 _' Q. @  stemplate<class ElemType, class WeightType>! j) Q2 E) f4 X" M; ]
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()9 C: p8 u0 e+ x$ K- W$ L% W
    {# p+ ?" g  k4 d2 ]8 N! y
        Clear();
    ( V# ^7 x" K, a1 A6 N}
    9 t) \" c/ {$ f' s* ^template<class ElemType, class WeightType>; W4 L% U; x3 x
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    5 j# _; ]. O: F3 I4 ]1 [{8 a' `5 d, N% O
        vexMaxNum = copy.vexMaxNum;/ t$ z6 l) _8 Y) l2 k
        vexNum = copy.vexNum;
      n% x9 M# j: @6 _    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    ' `3 r( R$ \, i( a* u& W0 A    arcNum = 0;( i2 D1 k, n5 s! E  d; ?2 V! `  t
        infinity = copy.infinity;1 L. k7 E1 h1 l8 W
        tag = new int[vexMaxNum];: l$ n1 W' o+ Z7 f$ h5 o$ k5 Y* W

    + W1 _1 C$ v' Y5 n9 l, c3 o0 ]    for (int v = 0; v < vexNum; v++)/ r+ n# {0 n1 K2 V, q+ o2 [
        {! ]# c# o: g; h4 {" a' ~9 j0 Z
            tag[v] = 0;5 l6 C% E- l: T  `# [
            vexTable[v].data = copy.vexTable[v].data;
    ; v# `5 Q. ?; S/ D$ Y& M        vexTable[v].firstarc = NULL;
    8 a' o0 K" a+ ~9 Y1 C' {% G: L9 |, P  ^    }
    : y3 V/ T: I3 S- C1 I    MultiAdjListNetworkArc<WeightType>* p;! h9 O0 G3 G# t; c
    2 [" }* M9 Y& w9 X( a# p
        for (int u = 0; u < vexNum; u++)6 t: [7 S# }" a& ?3 A
        {; t6 K' x0 ~$ k& X' Z
            p = copy.vexTable.firstarc;
    # M" Q! a5 R1 {( k3 Z        while (p != NULL)
    ! c5 a( X6 J) Z        {
    4 q' S* ^$ u0 I: C* k- X9 |            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    ) q+ }  k& Y, L. R+ u            p=NextArc(u,p);. S: h# F8 @1 E+ M& v
            }0 L$ `4 ^6 M$ i) S3 K- [% {9 N- [+ h: B
        }
    ; S: ^, `/ @0 v9 f  F}
    ) `% X$ @! o3 f7 V* _3 B* ktemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&( ~6 x" Q6 B# d
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)* I0 I: \6 q$ U. W8 f/ H4 h% N% k8 v
    {& k# N0 e0 G. C* Y+ D9 Q5 m# |/ g/ H
        if (this == &copy) return *this;
    $ i  c& W3 D9 ?1 h) t' Y( G5 ^    Clear();; ^. w, U! m" j! F4 }
        vexMaxNum = copy.vexMaxNum;$ u, E& R0 Y* a5 T
        vexNum = copy.vexNum;: Z3 o& E; O- p+ x4 V! X; t
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];3 B/ e, a9 Z$ t7 V7 m8 ^- L
        arcNum = 0;
    6 C7 H, A! B6 F  g    infinity = copy.infinity;% b0 _+ E5 d6 t% Y/ Z
        tag = new int[vexMaxNum];
    - @: Q) |6 `) s8 u& U4 t, u+ U4 k: z: O, C+ K
        for (int v = 0; v < vexNum; v++)/ T+ F) f# T: ]; ?2 D6 ]' U
        {, W  h' }( j2 r
            tag[v] = 0;
    : w2 t% u8 h. y% Z1 C+ Q5 @4 x) ~( q        vexTable[v].data = copy.vexTable[v].data;9 z% j/ I8 Z% T) [3 {: O
            vexTable[v].firstarc = NULL;
    ) i) j8 t7 v) ~" m4 ~2 G5 a    }% @+ c2 n- H* L) v
        MultiAdjListNetworkArc<WeightType>* p;
    ' j4 K3 m" N5 q' T' e4 o& K
      f" w9 \- ?& A! o3 ]    for (int u = 0; u < vexNum; u++)
    $ q4 `" p1 u1 ]) [2 ]    {
    , b0 u# Y( c! i        p = copy.vexTable.firstarc;
    2 i- h( q7 I$ y8 z# t        while (p != NULL)
    " H$ T' ]' T; ?' s1 z        {
    2 [' r! K7 E  M" T( t: H            InsertArc(p->adjVex1, p->adjVex2, p->weight);6 T' M4 X; d$ w* c5 J
                p=NextArc(u,p);
    0 M9 g4 G: d- I" L. U: W        }: f1 K. J* q& A+ U% x( t# x% `
        }
    / ~2 G0 J1 w% k/ J; W; s8 H    return *this;1 K; C! E3 `: {4 e8 d
    }
    % F" ?- ^/ J0 ^& s9 m" xtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    8 D  e% |. ~* |/ e, H* J' T' vMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const  s+ |; a8 a# {: h
    {
    3 k! s1 U3 l7 ~9 B/ L    if(p==NULL) return NULL;
    ' `+ U+ Z& O9 t. E# }- d    if(p->adjVex1==v1)
    $ Z, k0 K( @% O0 H0 }/ k$ C; T5 ^        return p->nextarc1;
    1 L* ]: Y" M# ]5 u) T9 U# w6 ^    else( V$ R1 ~6 R  V, R/ f0 [
            return p->nextarc2;* R$ e; j9 c' Y4 V2 @7 d* a
    }; S: n0 D3 m/ @% g- |( x
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*/ r3 L& p4 S8 w4 S& l1 t8 g, Q8 u
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    : p- Q- s3 Q- K{
      v5 R% H8 i5 U/ w$ v; f    if(p==NULL)return NULL;
    * F( ^# P5 ?; k" a    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    : T9 p8 p5 Z! ^* q4 R1 K    if(q==p)
    9 W! V1 W7 j) u& z        return NULL;7 m3 R; o) ^; y. ~- L
        while(q)
    & q* a% }; O9 j/ b% ]) g  |    {. j; R" v* j" ?/ x% Z8 S+ u
            if(q->nextarc1==p ||q->nextarc2==p)$ Y2 j2 U3 r, P0 G7 H# t# V. c! i# n
                break;
    ; a; _9 H/ H, D& g) g        q=NextArc(v1,q);
    % }* X! {4 b7 w! a% |    }4 A$ G( {) `& R: g" P
        return q;
    ) z' a+ P+ c% s. R}8 }" [3 c6 E8 n. s8 ^8 `4 q0 g' `+ I
    template<class ElemType, class WeightType>4 a* w, y; j( S/ ^/ ~  L
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    6 B* i( ]+ y6 e, X{* x/ u9 _! v  b3 V: Q4 b5 ?
        if (vexNum == vexMaxNum)
    2 U; j8 l6 u4 ?0 X  Y) f1 [' f        throw Error("图的顶点数不能超过允许的最大数!");$ w0 s) q0 Z0 O9 x2 s
        vexTable[vexNum].data = d;
    " z" T  ?; P/ m    vexTable[vexNum].firstarc = NULL;
    2 X3 u' s3 V6 n( N* N    tag[vexNum] = 0;
    & @/ }5 ?. r2 B9 u3 ~    vexNum++;
    ) t" [5 V+ U( c8 [& u5 |: o& g}
    3 O$ E. O( Q1 {template<class ElemType, class WeightType>8 e. X( F/ r: G/ W$ a+ h
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)7 X; z3 N; y+ B' U9 a9 ?+ v& {- @! H
    {
    ( V( h, H, c1 e0 n$ s    MultiAdjListNetworkArc<WeightType>* p,*q;
    1 Y% u% {- h6 l, ?& A) s% E& [    if (v1 < 0 || v1 >= vexNum)
    3 l- ?/ |( J+ G& g& I" y7 l        throw Error("v1不合法!");$ [, s, p* {/ c! d; u: R. i, J. r5 R- w
        if (v2 < 0 || v2 >= vexNum)+ D6 U8 K8 i: o. F9 F2 B# C
            throw Error("v2不合法!");% ^* G. m8 L; P0 N1 @9 o
        if (v1 == v2)
    3 T& u" ^, h6 ]& Q! j7 R        throw Error("v1不能等于v2!");, b( l  z  y* t. f# @' `
        if (w == infinity)
    * b' K' X! H; [$ d& e' Q        throw Error("w不能为无穷大!");
      S* G" ~" D+ z1 g
    - ?; T9 b2 N1 W  \& j; Z, B. w" J
    0 K1 z6 M& x. ^8 \    p = vexTable[v1].firstarc;
    / [" P8 m% W6 G5 ~' g( J# z1 p6 @! s    while(p)1 E* K$ ?, ?5 l1 u3 ]7 }3 v
        {+ I  B$ ^  B8 |- `* t+ o
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中* u# T: t$ Y( Y1 [8 q+ U5 Y
            {" T6 U) y) `& l  A% _( ^5 K
                if(p->weight!=w)
    & }5 K& W' |# ?                p->weight=w;( @8 W* @2 o7 ]* A
                return;
    / c5 z% f7 C+ k9 U" F2 Q' W8 l' i        }7 O7 o9 d/ z/ \
    ( U. \. @. F  N( S# E& q
            p=NextArc(v1,p);
    # G9 q0 T) q' |0 u    }, V0 c6 s1 H4 _" V" u. l3 {
        p = vexTable[v1].firstarc;
    % n# k! {/ E$ S    q = vexTable[v2].firstarc;, S7 e7 L/ I' g5 \! }
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    / F: G5 [' ]# e* x* y' L    vexTable[v2].firstarc =vexTable[v1].firstarc;& u3 z- H% x* y  `5 x: U4 F0 q- a7 Q. t
        arcNum++;
    6 j0 i; |0 ?# m9 z}
    6 \4 [2 m" w5 g7 r! W" N
    * {6 F+ I3 I, v& v+ _+ C6 ttemplate<class ElemType, class WeightType>
      n" a; [$ N! _8 {+ i! Q5 dvoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    & C" ?1 C+ d# u$ d8 ^{
      p* u0 ]) X7 b( H
    6 S- j$ A! u# v. G3 k  c3 u( t    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    . R" {7 T/ }3 t    if (v1 < 0 || v1 >= vexNum)
    , c+ l( b5 w5 L4 C9 c  L& i" L        throw Error("v1不合法!");
    0 U$ {. e+ l$ {' F2 _3 d    if (v2 < 0 || v2 >= vexNum)
    7 C4 F0 E! T' S7 n) ?5 i* z# i: D        throw Error("v2不合法!");/ V9 q% ]4 L; z7 h- b5 g
        if (v1 == v2)
    ; o" j2 o# f+ R! E$ y: N6 \3 G        throw Error("v1不能等于v2!");- V( o1 ^5 a' F! T9 m

      ?5 S! ~) e) n4 p7 v) a) H0 W2 B8 e    p = vexTable[v1].firstarc;
    7 U6 [3 u/ n7 N* h    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    ; a7 l0 J4 `2 L# F    {- {! {# E' h; \1 v3 V; t* C
            q = p;
    " u! l/ I% @1 ?' d- n0 S        p = NextArc(v1,p);( u. J+ F" `% k% J8 O9 N
        }//找到要删除的边结点p及其前一结点q
    $ A5 E3 _/ Y! }' W( V/ p& I/ ]) R# c9 Z: F" _
        if (p != NULL)//找到v1-v2的边; z  u' U0 O- M' F! S% C
        {
    3 K% o. U/ F9 |  t2 m        r=LastArc(v2,p);/ u, Y0 N5 [" J8 P0 w6 o- p; R' w! y
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    " _0 R( R, M/ J+ [7 F            if(p->adjVex2==v2)
    & r3 z: Z- _* |  o  F2 E% K                vexTable[v1].firstarc = p->nextarc1;- `, }1 j0 d6 C7 Q
                else vexTable[v1].firstarc=p->nextarc2;& L& p1 Q, v. q$ {
            else//不是第一条边, f/ y6 B( N# e
            {$ }8 [& K" B* \
                if(q->adjVex1==v1)2 V  ~1 f; c& S) P' Z- y
                    q->nextarc1 = NextArc(v1,p);
    ( {+ G% \" p/ a# G  D            else
    0 o5 y2 b* v+ G  n0 D: q                q->nextarc2=NextArc(v1,p);
    % {; \+ G! `# e* ]$ x' [, N  ]; y8 Z, p
            }# K' E0 G5 i3 u. k% S3 Z
            if(r==NULL)
    0 O3 ~5 }) Y9 R3 L+ f) e            if(p->adjVex2==v2)/ ]6 }$ T3 [/ B7 F
                    vexTable[v2].firstarc = p->nextarc2;
    ) H4 p# t& L! O/ f            else vexTable[v2].firstarc=p->nextarc1;
    . ~. l' C8 t& E  W4 ^        else0 |) n# o5 l3 k6 O2 C
            {
    # g) [) R# q2 [3 Q+ v) R- B            if(r->adjVex2==v2)) }. N9 m( ^: E/ _# c( N
                    r->nextarc2 = NextArc(v2,p);
    " h$ u$ H/ s9 t: ]9 F. N            else  C  D. U2 H) B; `. O
                    r->nextarc1=NextArc(v2,p);
    $ e6 T# B/ m+ V) t% `9 M        }) q1 L( e+ e" A% M' d7 j( Q/ v
            delete p;
    ! m2 }  {9 {" ~1 b! g3 f( X2 e7 _        arcNum--;
    : [' k0 e4 C. ~    }/ C6 L- @, P9 S: g0 K+ U

    , N# m* i- w. p# S}) m+ B7 r( L* v. s  O8 h! I7 D
    template<class ElemType, class WeightType> void" J0 k' W5 X. N
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)  S8 }" x9 k# x. ^
    {
    3 k- U3 o% x' K. c    int v;4 y  j/ J! p  _8 D3 }2 s$ s+ M
        MultiAdjListNetworkArc<WeightType>* p;. z- d. t& _: C: y$ b
        for (v = 0; v < vexNum; v++)//找到d对应顶点
      y; ~# L/ s/ h& I7 A6 \  i        if (vexTable[v].data == d)+ q6 S0 _0 x+ m: t+ o5 k
                break;
    & e6 e# y. O1 I( g8 [5 J8 w    if(v==vexNum)
    9 I- R7 U" B$ N7 K$ A  |& f        throw Error("图中不存在要删除的顶点!");! {. d0 r; d/ q+ ^% {
    + |- d7 S8 X( H6 a* P( Z, B* e, m, |
        for (int u = 0; u < vexNum; u++)//删除与d相连的边: f6 K  c/ L2 B* {( z
            if (u != v)
    7 ?! G+ ^9 r3 ~$ I7 F        {+ ?' l( t1 Y+ d' w% c$ {; L5 I
                DeleteArc(u, v);) X. u5 T+ z& o/ p, W
            }
    & V- v3 ^: |, p" Z, j    vexTable[v].firstarc=NULL;
    * Z& I; q7 p7 G! |
    - i6 `8 h5 a1 {7 z  A    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置1 i! l7 V0 g6 I2 H2 V9 k9 ~; J
        vexTable[v].data = vexTable[vexNum].data;
    % v5 z) L- k6 q' s# H  ^) U9 {* m9 H; p    vexTable[v].firstarc = vexTable[vexNum].firstarc;
    9 e' @) s/ W! b    vexTable[vexNum].firstarc = NULL;
    0 T- Y% ^. x) O3 O% {8 |    tag[v] = tag[vexNum];0 ]& T9 |+ y8 i  X9 `1 s
        //原来与最后一个顶点相连的边改为与v相连% m- U. r' C" ~& c$ s: p
        for (int u = 0; u < vexNum; u++)8 _6 z( r) L1 K. Y; u
        {6 |/ }0 q! d9 }( h0 m1 d9 D
            if (u != v)
    % R' L4 I5 L* R' W. H% g        {
    9 O3 n, F: Y9 f3 b, m7 ^            p = vexTable.firstarc;
    % y' |2 S3 C7 s8 Q& X            while (p)
    , s3 m0 J+ ?$ M! ~! y            {7 a$ x/ N* Y9 b$ v6 ]! P6 K
                    if (p->adjVex1==vexNum)
    % j6 T' @8 Q5 _5 Z                    p->adjVex1= v;
    1 v9 G5 n$ ^( |1 R9 N                else if(p->adjVex2==vexNum); t$ F! N6 c3 g4 ~/ R
                        p->adjVex2=v;5 s2 V' H+ i. M7 n1 n( u  Q
                    p = NextArc(u,p);# ]8 v5 \- m, Z' O0 {' d
                }! H7 x. r; ~& h2 Q
            }$ j# \  g. e9 m! P& R7 M
        }: ^5 @3 |, b7 H, U$ `' _% \
    }# Y' u4 Z' W6 C( d6 U* _% F
    ///深度优先遍历$ v, ]- i, o' N/ U% V. E
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    . l  r1 Z( }. a; n# F{' k1 d2 `2 r0 K) Z% p
        tag[v]=1;
    8 Z3 S, W: N1 d% o. u1 V9 u7 o    cout<<setw(3)<<vexTable[v].data;( B2 I2 t: _. i, v9 [7 N
        MultiAdjListNetworkArc<WeightType> *p;
    6 f7 O- M5 Z" u* M    p=vexTable[v].firstarc;
    & \# r& ^" r" I' o    while(p)2 z3 P3 I, W0 G  s
        {
    % F3 J' g1 \( i; o2 x% j  |' H        if(tag[p->adjVex1]==0)) Y7 u' t6 W* R# u6 t
                DFS1(p->adjVex1);
    7 y0 q8 y! c5 p' n1 w6 i3 z1 ]/ e        else if(tag[p->adjVex2]==0): N( u2 w) S# Z8 O/ H
                DFS1(p->adjVex2);
    - M. w, i# Z4 a5 d5 w        p=NextArc(v,p);8 ^! I4 y# d4 N- R$ J7 i2 H
        }4 F5 y7 M3 ]. D: q' Z4 K
    }
    & B; q. q) P; m9 ^template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    ! _) K6 O: X; }{
      Q! ^5 @: _- Y; Y( r$ \    for(int i=0; i<vexNum; i++)
    + D) r' g( t8 B  r, T3 l        tag=0;! H6 D5 {: `  i
        for(int v=0; v<vexNum; v++)
    ! ~- y) d0 z$ f" X    {4 ~5 d+ ]0 Q+ E# c% w
            if(tag[v]==0). e' L: f; F% ]: {% H  P5 }, O; m! Y
                DFS1(v);
    1 o# Y! M& f3 {& A- e/ `    }$ l4 j4 T* a* J. N( l! V2 U* X
    }" k$ m3 y% x0 d+ }2 `
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    , o$ t% O- j7 q7 D{- V. O% h; w% G) C5 s; L8 A3 P8 X2 p
        stack<int> s;: p' {2 W' R" A, w# I* H
        int tmp;' l# ^# [3 _. j8 e; n" |( s5 e
        MultiAdjListNetworkArc<WeightType> *p,*q;% B3 Q8 p" q" d" x! Z" s( ^# p
        for(int i=0; i<vexNum; i++)) Z" O) ?" X" o
            tag=0;
    ' d1 ^3 O' z% i; s) d) u    for(int i=0; i<vexNum; i++)
    " s& I# {- U  V! i+ H    {
      L$ e0 h/ v0 Z0 a& @        tmp=i;
    9 x* u/ }5 e- V: Y        while(tag[tmp]==0||!s.empty())
    ( b2 G& {/ D1 ]  R* ~! v        {
    8 f9 z0 e, ]+ w2 L0 K            p=vexTable[tmp].firstarc;( Y- \/ S# v) d" v) T
                while(tag[tmp]==0)( s% z# }  {; p% I, a' }
                {' E& K4 q2 L9 t& f
                    s.push(tmp);
    / }* m) @  a6 }4 d& ~8 J( Y3 d6 r) o                cout<<setw(3)<<vexTable[tmp].data;  s  O. {; }; m9 Z& M# m
                    tag[tmp]=1;
    % Z/ R/ A6 m5 [: p1 g" ^3 {                p=vexTable[tmp].firstarc;( c+ m& p8 r+ O4 R, E1 f
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for' y: J$ r. o1 b, o- p8 \+ [* Y- F
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);' T# z2 E- s: K  A* U" t4 M5 Y
                    //cout<<" 1st     tmp="<<tmp<<endl;
    * S& t" X* X1 w) y8 n9 J( g            }; ]$ e- G+ q+ @, f% A. Y
                if(!s.empty())8 K* c3 r5 A1 H1 k  i3 S9 \- @
                {
    4 ?! b& {& A0 {4 C3 O                tmp=s.top();! S* Q0 K# {4 P
                    s.pop();; F* a" g4 I2 r8 A
                    q=vexTable[tmp].firstarc;1 q2 O( p+ h- \9 z1 n$ N
                    int t=tmp;) @, m: q$ D3 K  o/ H' E) Z; f
                    while(q&&tag[tmp]!=0)3 ]8 M; `" P% z& l) t; p
                    {
    + g* e9 M9 M, z                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);* M- }( V  q9 V/ Y8 G
                        //cout<<" 2nd     tmp="<<tmp<<endl;; s0 C$ c) V$ E3 R% C) f
                        q=NextArc(t,q);
    + y$ ^5 `& M' M. Z2 k' h                }
    * W7 D3 f5 g- T- B! ^: P* c                if(tag[tmp]==0)
    $ d! n% P: P- r! |8 @( T                    s.push(t);
    ' N' V  V3 F3 f% s                ///1、对应上面连通分支只有1个点的情况$ @. s$ I8 [) p! {! ~7 J
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈' q2 [, G2 G8 G6 |% c) L1 v4 M
                    ///tmp要么等于找到的第一个未访问节点,$ d: {8 B9 O* S6 \9 N# [
                    ///要么等于与t相连最后一个点(已被访问过)
    & S' x8 p# w: ~1 \                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    5 b, k' x7 T8 a% U) Z            }
    : X. m$ _0 V4 L2 W7 I) s2 I        }; r8 j% T/ e1 C. }% k
        }
    ) B9 m  e7 Z; s% x; T+ |% t}
    9 z/ e8 L! @$ c# m//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1' F1 {, ]. B. |3 }" M8 X  m
    template<class ElemType, class WeightType> int
    9 ]$ g6 R  _. S- d1 c( A5 TMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)4 ], P- Z% D6 j  e  l
    {- {4 M7 z% p2 H( d* {) ~
        if(head==pre)
    3 ~* Q  D0 W: ?( a: Q0 p, O9 n        return -1;
    / |1 ]4 x! k, l3 }: K; P2 X' |
    7 R0 I( R+ A$ A/ t    MultiAdjListNetworkArc<WeightType> *p;
    $ B- F( w! F/ q/ a" V0 l% s    p=vexTable[head].firstarc;1 F( @" q2 |% s
        if(pre==-1&&p!=NULL)% X" W0 ]) k4 {! T
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    1 f( n% e) n- W, G8 P0 d5 B    //pre!=-1&&p!=NULL
      _* v0 u- ^! D7 X) R. @    while(p!=NULL)
    , T3 [; l4 K* t# ~& f. V    {- X# n0 [4 ^+ s0 W0 K8 Y
            if(p->adjVex1==head && p->adjVex2!=pre)
    ) e. F9 E8 o) F& Z; T/ l6 g6 ~) M# C            p=p->nextarc1;
      g0 s. r6 r4 |! J( R' M1 d- A        else if(p->adjVex2==head && p->adjVex1!=pre)
    ! s, I  A4 \; e6 p( ]            p=p->nextarc2;
    * N% u; a) r2 |+ i4 }        else if(p->adjVex1==head && p->adjVex2==pre)5 h  z) n6 q" U
            {
    + P& d1 q* W3 x* N+ Z$ Z- x7 T$ n1 }            p=p->nextarc1;( Z2 t5 ~& ]; g  O5 s% G# l: ^
                break;
    ( Y% Z, y9 W# d4 M; B4 S% I, c        }
    3 Z9 R9 b1 M1 V) n% H$ {  [" w, a        else if(p->adjVex2==head && p->adjVex1==pre)6 T- i  G% q6 x; X) `% I
            {
    ' j- t7 U% }8 |. y            p=p->nextarc2;7 P! A, N/ \* O% B0 L% I9 x; v
                break;
    : f. `% f+ H3 X+ u. D8 l        }  n  c( y2 n3 ]/ @5 G
        }" @( [# T- ~9 |( \  c! \1 j
        if(p!=NULL)8 N9 x5 I0 x+ d6 k
        {
    & u! H3 T% ]% @, a8 L6 `6 Y        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    ' `- i. S9 }0 [. ?. g) g$ o    }1 B% ?$ ^9 Z4 I  W
        else
    , n1 c8 l" H2 G- Q        return -1;
    / j) ~% g) N/ h$ @* h}
    , ^  Z% Z8 {/ W4 Z2 j3 [9 `
    $ m) ~  b, Q: y3 c# r* F& |1 o% X9 s9 K
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()6 Q* J# d1 I- u2 y' X
    {7 ~: h" L* N. o! J; A
        stack<int> s;
      u* ~3 ]) R7 O- e5 c4 `9 A    int p,cur,pre;
    ' h: e& D# r4 \" m8 @6 K! s! y" S) a    //MultiAdjListNetworkArc<WeightType> *p,*q;0 @5 R  e( w8 G
        for(int i=0; i<vexNum; i++) tag=0;//初始化
    + X# D( |5 [' o6 w) m* Q) @3 P' T' i+ n. R: D8 k1 \
        for(int i=0; i<vexNum; i++)
    7 j7 y4 x5 g5 A: h8 z: E; a    {
    8 r  c. A) D9 p        cur=i;pre=-1;
    2 j6 w3 a( @0 m. M: S0 O        while(tag[cur]==0||!s.empty())7 R3 j- c1 m& r, o  x9 s0 u0 Y% z/ |
            {, m$ M$ W; j# O& G$ e% U. r. c' Z
                while(tag[cur]==0)
    - H/ Y$ r8 s* }. b# x6 V* u6 Q! k; z2 X            {
    ) N! ?- F2 b) t+ _) c; |                cout<<vexTable[cur].data<<"  ";- v* u, p- L8 o- i( W# s
                    s.push(cur);
    , ~, G* E/ a! }. ?6 w0 s" O- Y                tag[cur]=1;3 e9 ^" l& S6 D
                   //初次访问,标记入栈. h* h  Y! d5 ^- w* A5 R1 f1 @
    5 ^. \: t3 K) U, B
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点
    / P; B3 x2 e2 z$ j: O               if(p==-1)
    5 r7 b7 h. d  s. h               {* B1 |- O9 [/ W: R& e
                       pre=cur;s.pop();6 Y' f3 [0 |9 H3 x  V' \! i
                       break;
    6 Y# D. v4 _+ ^/ N               }
    2 c% B5 g# a. _/ U( X  }6 f% m! n9 R               else0 ?, u0 `/ Z, r: [" o
                   {. w: e' w) U7 _( o0 K% A9 D
                       pre=cur;
    ( M5 b! `, u0 w: |7 m  z                   cur=p;
    0 F2 a. I  H6 F8 y4 [               }
    + A1 X7 G: e7 n- X+ t! Y' o( e# `6 C, ~* Z: W; ^7 T2 [& W
                }5 x7 E4 ^& ~+ G
                while(!s.empty())2 K; T. w" X8 C9 F! v1 n. u; T* [
                {& t- z! @8 X: a  q
                    cur=s.top();
    : e/ q# e) k6 {1 Q( U* x  A                p=GetAdjVex(cur,pre);
    : w6 d' C' G8 r, k( W4 ?/ z& {3 w                if(tag[p]==0)
    ) G/ |( W5 e* @& z, M                {4 f4 @) t2 d- |
                        pre=cur;
    & b8 W- l& c+ Q+ Z4 F                    cur=p;
    $ U* [6 }' k. A- x( h3 [9 p                    break;
    6 J4 v! }9 u# [5 M& ?- b/ ]                }* r9 w/ T  [2 A8 k# Q# t5 ^  }, \
                    else
    - r# [' x) Y1 h" O2 J, ^                {: b" |' d0 p- `  @8 G: e$ N
                        pre=s.top();9 ]& ~% r+ J4 q
                        s.pop();
    7 ~$ c& A* r8 @                }/ x  H5 H: b2 c, U3 c- \
    % Q- y$ c5 d- a# d* |6 w3 f
                }
    % Q  k& t6 E/ H( U# ?: ^8 G/ s, T2 ~, ^5 h( @4 \
            }  [1 ?3 c. F0 A4 e
        }
    , l$ s. n9 r: D9 P}3 t. ~$ y8 |/ r9 g" x: j. \
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    + u- C/ y: A( e( [6 i- R{0 x3 C. R8 c) K/ d
        for(int i=0; i<vexNum; i++)  b4 J( T+ ~1 `' \- q! W( p- g
            tag=0;0 q! r# j5 U1 |6 e* N. j7 r
        queue<int> q;3 E! ~+ }/ s, {1 j
        int tmp,t;
    ) J1 a8 y" F3 c8 u5 e9 W4 Q! \    MultiAdjListNetworkArc<WeightType> *p;  X5 |8 w: A2 v/ v
        for(int i=0; i<vexNum; i++)0 b; `8 K5 n: H1 `: y. o
        {
    2 D8 A! D  w# _" K; g        if(tag==0)
      I4 w$ {5 B4 z& z2 V+ `: `        {
    % z* n# ^: v* ^8 ~9 ^0 l! g            tag=1;
      @& t& i& ]; Q; c3 y            q.push(i);0 i$ I5 r: U9 W
                cout<<setw(3)<<vexTable.data;- w- S8 C3 c8 U, e
            }
      a' ]. D! B3 r( F; M+ h        while(!q.empty()); Q0 K" P% z6 r2 |# @
            {  B8 H( m/ c/ [8 z: F
                tmp=q.front();" p- O7 [9 ^1 i  _* o5 Y4 |- N
                q.pop();
    0 u& T& J- t2 x6 \+ c% E* V            p=vexTable[tmp].firstarc;7 G* S- o! m3 v
                while(p!=NULL)9 e6 \0 X5 `" E
                {+ X+ o  t7 G6 u; l, C& J* u
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);" ^3 E9 E, r, U+ _
                    if(tag[t]==0)
    9 c/ V" h& E/ L+ R! Y                {/ Z9 D3 T; V7 ?
                        cout<<setw(3)<<vexTable[t].data;: Z! E$ ~6 q5 `) L
                        tag[t]=1;! y/ X& e) v( M
                        q.push(t);
    : U. y/ ?# l' ?6 t9 r: D' w* I& s                }
    2 Y  X- D# {, B* O7 U9 k. C                p=NextArc(tmp,p);
    " @7 o. ~2 k/ P            }
    8 O" x/ b$ t% m  D# N        }
    ) y" P) L- U, }6 G. R    }4 W( k0 t! J  ]. X* @
    }
    7 I# t5 y$ s- B: U& ]6 o4 Gtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    # [+ M' w2 ?0 s) |{4 R" f4 F; Y2 E; b" d7 \/ x
        MultiAdjListNetworkArc<WeightType> *p;) z6 Y0 m0 z5 M8 s2 V2 `
        cout << "无向图有" << vexNum << "个点,分别为:";
    + `: ]" r( O) e9 w; ^- W: e    for (int i = 0; i < vexNum; i++)
    ( g8 P& U$ w+ O0 u        cout << vexTable.data << " ";
    0 l4 Z- z3 P( ]# i& L$ R' k: t    cout << endl;; p. C3 s9 m7 c% D8 G+ t
        cout << "无向图有" << arcNum << "条边"<<endl;
    & J+ m! O# p% [8 j$ f* U( r, G3 F    for (int i = 0; i < vexNum; i++)' E, R: {) Y+ D* K- u- W# D$ O
        {
      q& w6 p5 }5 t# s0 }6 ^        cout<<"和" << vexTable.data << "有关的边:";
    ' _- q% ~3 o% x! V- `3 w        p = vexTable.firstarc;: h0 U; O8 V- X$ v' t6 p2 M
            while (p != NULL)
    ( J9 a3 N6 T& y# Q! h8 S' F        {; X$ z  Y1 p( m% o- o* ?
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    # U9 m$ ^6 H$ y; S4 k( j  ?# a            p=NextArc(i,p);
    ' q  A6 ^2 e. ~' j8 c: e1 y        }
    6 ^1 H8 h2 u8 h        cout << endl;: @$ U7 Y) a# I9 j- O& u
        }
    6 l5 j! j8 }8 l}
    ( }9 o5 [* i4 v6 G* P, z$ }- r. A

    0 l" N' L! T! M8 F邻接多重表与邻接表的对比: E5 ~, _  E9 p3 J
    ; B' m* F- X/ W( A% `/ n6 f
    邻接表链接  `. l+ R! Q4 ^" _) b6 O
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。0 I) v. `3 n* E/ R4 ]
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    + ^" S+ U5 |5 y7 o/ M4 e为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。0 _: K8 x" G/ \' y
    ————————————————
    . y% p- |& A# ]版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    3 @6 |# U5 T" u* o: }原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    ; n% L7 x7 r, U5 E! \  {( v
    % Z& O: ^6 y  Q- v( I6 M0 N$ P" {% Z6 ^, j3 C9 @- ~8 g5 g. R
    , r9 r3 S) W$ w' j
    # B$ q1 x; n$ z2 R9 Z/ w9 y8 {
    ————————————————0 N! P3 L* A, r. R; {$ V
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。% a6 l* v; \1 t/ k8 u
    原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669587 _1 @1 \8 T8 w9 `

    $ \9 t3 T- B" i8 a% y- I+ s: ^
    # M$ {) ]6 N2 g) G7 C7 s. c6 D
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-4-21 02:33 , Processed in 0.468823 second(s), 54 queries .

    回顶部