QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1621|回复: 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
    : X4 f3 L+ o+ ^: Q! J. y* h+ b
    图的存储结构——邻接多重表(多重邻接表)的实现$ ^. C. j: T& f0 E! D( x, A& u
    7.2 图的存储结构# W4 u* n) d1 v! r4 Z
    ! ?2 a+ H, G8 o" u7 d% T0 S. ~; B
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    8 L1 r. I) H' r7 N邻接多重表的类定义4 a9 t* }/ V) q1 A; w! t
    邻接多重表的顶点结点类模板# Q, r; M( \8 o  V/ E
    邻接多重表的边结点类模板
    ( {% t+ I$ }$ k& e( o1 y$ V邻接多重表的类模板
    / o, q: r5 O- @/ h) Q( I/ ]5 w邻接多重表与邻接表的对比
    % A# |& V/ H/ P3 k; S7.2.3 邻接多重表(多重邻接表)Adjacency Multilist9 H  C8 f$ j6 ]: I

    + V) ^& _; @. w& J* V% a$ A在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。8 }( i7 ~; n( t- S
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。; m+ x6 L2 |# v" n' X- W8 P

    8 O" r, I1 o/ W6 p邻接多重表的类定义
    $ d: E- f( `4 c4 I1 h( d) y* {8 |% y 1.png
    7 G0 R' [4 r+ _0 N* z邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    9 v. ]' ^1 E  e' J' Odata域存储有关顶点的信息;
    2 R( J5 h  \% @; @8 K% W8 Ofirstarc域是链接指针,指向第一条依附于该顶点的边。$ f: u" M" Q  U8 p  U9 v  E
    所有的顶点结点组成一个顺序表。

    # g/ t  y6 _# w/ {" d
    ! R' c+ B2 A* h0 E
    template <class ElemType ,class WeightType># t+ N& g5 s) [9 [9 Z1 O1 C
    class MultiAdjListNetworkVex
    1 r6 S& U3 w( R{+ D" I4 u0 V* G  R8 ~" t# ~1 O7 N
    public:% V% }% I4 A: ^: D1 I
            ElemType data;" U& [8 y. O- T+ X3 u, L" w$ H
            MultiAdjListNetworkArc<WeightType> *firstarc;% D5 C" f$ v7 a/ `- y) F0 a

    . Q* y- _, g. Y0 p5 O' U        MultiAdjListNetworkVex()
    8 |$ z8 w: g% e# H* W: |; O( \/ q1 h        {. s$ H( u; C  O6 s% {- S+ L
                    firstarc = NULL;! R1 Q  V3 s3 A" c' P
            }' H, V  ^* e2 Z
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    . X( [+ o1 e) ~9 n9 @0 {2 R* ]8 o        {9 }# |9 G) W) e5 S8 M& j, J1 D" j
                    data = val;
    5 _$ T' X1 N5 B9 a/ i9 d+ h! b                firstarc = adj;1 C9 m. q  y' q7 J' x! b
            }4 N- c* r& w: Y% w' ?2 I
    };/ P  H, X7 S0 H& Z) X! M7 I+ V- y4 {

    6 ~- O( c. S: u! r# ]邻接多重表的边结点类模板
    % f9 K/ t4 N/ Z: q5 a/ g* g% N
    8 F4 f' [0 y, @0 @# S' L在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    0 Q( k6 ~6 p9 g4 m9 v' t' Atag是标记域,标记该边是否被处理或被搜索过;( S  R0 W/ G: F, a$ m4 _2 h- j
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    & V# E. ~* e: J$ x& ]nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
      v: R# G$ O& z. Z& |9 ^6 G! nnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    3 P1 A( m/ [# r" e) {
    * D6 `) d% y0 U" M, K- | 2.png
    $ F  S2 Q( [% a% t! \; g7 Jtemplate <class WeightType>
    : U# f  a$ C4 X- X/ {; ?7 A: e7 ~class MultiAdjListNetworkArc
    & p1 a6 m+ T) r+ H8 _* a+ x( \0 m5 Q, b/ l{
    4 @9 Q# Q, d; s/ v5 u* n5 ?1 lpublic:
    + b5 E/ |- L! `. k( G" [* W! w" m    int mark;                                       //标记该边是否被搜索或处理过
    ) c1 X! U- i% m8 w7 m        WeightType weight;                              //边的权重. w3 b1 n2 b) J) _8 W& }+ @, m
            int adjVex1;                                    //边的一个顶点8 x3 h* I" P$ |1 F0 {
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1* ]! [/ X6 s8 H; O0 L
            int adjVex2;+ i6 M- ~2 b0 C# F) ?2 [, y. {3 w
            MultiAdjListNetworkArc<WeightType>* nextarc2;. N5 U- J+ i: e# p: x) P
      d4 f8 {1 q9 K1 w0 Y$ A, D% k, c
            MultiAdjListNetworkArc()
    , d; I+ L+ k; D6 ]) a8 ]        {4 p; @$ I( Q5 B3 z# b+ N% h
                    adjVex1= -1;  }" j( _4 d0 j! l8 J6 F( k
                    adjVex2= -1;
    . [! a5 [7 x5 b. q, h" X" c        }  g$ Z( t8 r% {
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL); t; i) a3 e( |% r8 M: S
            {
    8 [" a$ m" f' u& _                adjVex1 = v1;       adjVex2 = v2;$ `3 P- Q( E* H3 m& i8 r
                    weight = w;! Y, N, j: a. L4 V1 @. {. c8 V
                    nextarc1 = next1;   nextarc2=next2;! p5 `0 f4 M+ s: j* d8 i
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    * r9 N, n( T9 v        }8 _* P3 n$ t: P8 S0 d
    1 T0 g: |2 l4 l/ y; f2 O
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>8 J! @3 m! R" z9 H
    class MultiAdjListNetwork0 Y" `9 C, ?  Q: h# g
    {; B5 m7 k6 {! V3 s$ Z! ~
    protected:
      H- f# e% M  y    int vexNum, vexMaxNum, arcNum;, f7 t5 x: \% j0 c
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    6 G* z/ l+ Z7 a! f1 B* C    int* tag;
    5 x# X  X- z" ]5 E" N    WeightType infinity;
    % @# K! `* v2 T- X+ i
    : Z3 H% t' F" d% z: z5 Jpublic:+ i& r7 J+ K1 i7 ~! O
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    6 H7 w( o* D/ G% {- V$ D! z5 g* F; ^8 s
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    . H2 i$ x' ~. B2 C- a5 `' l! [# r0 M7 ]& T
        void Clear();/ j4 [$ G7 K/ u1 r! `" ?) {
        bool IsEmpty(), z  a4 m2 C9 C
        {
      W% D& p* r! _1 D" Y- s        return vexNum == 0;
    ( e6 _, D/ v5 S3 r. A6 n    }
    : x( V9 R2 E9 \  M$ U) g) s    int GetArcNum()const+ L# i" Q4 N$ L6 c1 r5 u
        {
    ! p- @! _. n1 [, J2 d3 o9 I        return arcNum;
    & c- I9 G' ~7 d    }6 x, o' N/ Q6 z5 o
        int GetvexNum()const
    * c  u% l9 l4 E, O3 ]    {
    . ?4 c# @& f5 j. M+ O" P        return vexNum;6 h8 j$ m5 ]- x
        }& N1 S  F- n! L) E" y* ]" U9 l) R
    4 @  I: v8 Z9 ?7 L

    ) L5 @0 ~* c( h5 F: o+ v    int FirstAdjVex(int v)const;
    ; n( }- H9 v; S( L! g    int NextAdjVex(int v1, int v2)const;
    6 G7 c) S7 N$ y$ q$ `' l    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;8 G+ }! W& e1 C/ y$ [, {/ m0 j
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    % p: P" E0 `* k# n( V( P6 r7 a
        void InsertVex(const ElemType& d);5 R5 ]% L, V5 z+ }( `: V
        void InsertArc(int v1, int v2, WeightType w);
    3 [+ m: H8 g, B* x3 U0 T6 ?- r, m4 i9 y+ ~
        void DeleteVex(const ElemType& d);
    : H* X4 ?: S3 X! a    void DeleteArc(int v1, int v2);
    0 e: J- p5 }% \
    4 }+ {+ D- ^/ f5 F. n9 G    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);0 b% [- W" m% P, E: f
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);% S4 w: x6 h9 ^. d$ `6 @* H' e/ V
    - c! U. w4 T+ w$ _, Z
        ///深度优先遍历
    * v  p& a- g4 X" O, \    void DFS1(const int v);" q+ @$ y" j: z0 j1 W3 J
        void DFS1Traverse();9 R8 k/ {5 H9 ?( i6 O- T
        void DFS2();
    ' [- p4 E8 d( K: v5 F5 {7 q3 |0 I5 l" w4 l8 s5 x
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-11 w# [# F; E6 E4 p$ L5 }% }
        void DFS3();7 k$ r8 N6 b& [$ B% C5 C& l
    2 Q1 f( V; E+ P
        void BFS();
    / O3 C- h6 f/ g    void Show();
    , P3 }' U, r! m; U- t$ w};
    , g  ^, V  C" l  U& }
    7 o; G/ B8 E) n! e" q2.函数的实现( V( r& A6 b) }2 U
    研讨题,能够运行,但是代码不一定是最优的。
    7 J1 e2 J, |* Q7 B4 q( p! W' L( A+ Z! J* @8 I( J; u1 a: W% `
    #include <stack># l3 Z$ j8 V# |# V" ~, M4 z
    #include <queue>
    0 X2 l6 b6 M* M2 ?
    * \* Y+ e% a2 [; N2 v3 ntemplate <class ElemType,class WeightType>
    8 ~0 L/ s. x3 i4 bMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)& F. s, k6 _7 E4 ]
    {
    1 _* R: P4 |: D    if(vertexMaxNum < 0); u; |* F/ z: b) y
            throw Error("允许的顶点最大数目不能为负!");! d" i* z0 u9 K! r3 f7 c
        if (vertexMaxNum < vertexNum)
    ( w$ ]* l9 M& T- m        throw Error("顶点数目不能大于允许的顶点最大数目!");
    % B* `7 K, e4 k" o& C/ _7 D% a    vexNum = vertexNum;
    ! Z( o/ S; w3 r    vexMaxNum = vertexMaxNum;. ^( X7 r# x: p9 E$ G2 h
        arcNum = 0;( K! }1 E3 k% u
        infinity = infinit;- l' m, x* V5 t* }: T; M& N7 t2 [
        tag = new int[vexMaxNum];
    : W  e" j7 J0 O) U3 k' Y' Y    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    7 {4 a* A& N- Y! |2 i0 ~5 t7 K    for (int v = 0; v < vexNum; v++)# ~1 n& F5 x$ D0 y- D" ?1 ~
        {+ F/ h7 o0 J7 `' w; ~+ o! ~  A
            tag[v] = 0;  A( F' I3 f6 _' [# K* O
            vexTable[v].data = es[v];( m( ]) k# T# z# X, [0 S2 h
            vexTable[v].firstarc = NULL;" n& j! L) }2 U  c. I
        }
    3 m7 v7 F4 [) k/ V8 J4 Q  J0 ?}
    * E# l) W" z0 ?' S# A* Dtemplate <class ElemType,class WeightType>3 }/ f( v" ^5 O6 Z% g" A
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    & J) w4 y3 e0 U7 u! U. \/ D{
    9 D9 k/ k6 D: c    if (vertexMaxNum < 0)# G1 K# s- }( ?5 b% U4 Q; T- `6 S1 W% z
            throw Error("允许的顶点最大数目不能为负!");; y! [% t+ ~- x3 w  j
        vexNum = 0;- O  M; s2 r- o* [0 f$ z- o& x
        vexMaxNum = vertexMaxNum;
    / l" c; L4 h& ]  [7 O2 r7 x    arcNum = 0;
    7 n% j6 B4 P4 h% T    infinity = infinit;" g* S1 w3 f4 c( z7 P$ k
        tag = new int[vexMaxNum];
    & C# Q/ W* y1 r  Y6 a2 X    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    $ R) j0 ]$ `! [  K}
    4 o# D& n$ Z. R: Utemplate<class ElemType, class WeightType>; I4 m5 T4 f! |
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    4 t* ^: I5 @* Y$ V3 D4 I# V% _. H{
    * t! d4 I$ t# e2 @/ B+ h    if (v < 0 || v >= vexNum)6 X5 a# X) y1 Q% N
            throw Error("v不合法!");
    $ T# ~$ l; h& P8 R    if (vexTable[v].firstarc == NULL)# _: X. l% b8 v0 m5 {  \
            return -1;
    ! p  R0 S( X6 O9 E# ], x! A    else
      X4 f  F1 i3 ]( z. b3 C! }: @5 r5 x        return vexTable[v].firstarc->adjVex1;2 ^3 Z7 q  }0 Y# P
    }
    8 Z% d' ^5 {7 h: v, V" D: e( K" y) U/ s1 y$ s
    template<class ElemType, class WeightType>
    , v' m6 x/ u- K$ y3 B& G* d3 p7 _! q3 Rint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    5 ]- t3 c. [4 w) [3 ?{7 a+ z; G% T8 _6 B, x! I
        MultiAdjListNetworkArc<WeightType>* p;3 ]. j  Y& y& W
        if (v1 < 0 || v1 >= vexNum)8 c$ F. d- n0 v0 H6 s
            throw Error("v1不合法!");6 l" T, k# {$ @' S  v9 I5 }
        if (v2 < 0 || v2 >= vexNum)
    - U: V& k& Q5 r        throw Error("v2不合法!");
    + S6 l0 J4 f# I( s, C* s! \    if (v1 == v2), [2 ?( b6 V% u: |- P
            throw Error("v1不能等于v2!");( G% ]8 e5 Y+ ?5 ?
        p = vexTable[v1].firstarc;
    7 g% w3 Q$ ~# `" R# ~* a/ a    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    - p% ?) v% z& ?+ l2 \/ B7 T2 V0 R        p = p->nextarc;% h/ Z4 h& e3 e( w' z
        if (p == NULL || p->nextarc == NULL)8 [3 i% k/ z# R& P- s3 N
            return -1;  //不存在下一个邻接点2 \# i7 n4 y0 H
        else if(p->adjVex1==v2)" `2 `0 e  I) F1 M9 M/ Q! ?9 X2 L; F! Z( w
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);4 ~, a$ i1 a) _) D( p' f/ `4 ?
        else
    $ f8 @' W, F( y4 a. a        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);  x1 e4 w* t, l. q) L) O
    }" X  B$ N7 O1 c* ^. {  O% K
    template<class ElemType, class WeightType>7 o, x0 p7 [5 v' u" S
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()' p" V, X" J  C, @4 J/ n8 N
    {
    6 |. j7 Q1 ^1 Y1 U    if (IsEmpty()) return;
    9 }. O- ^0 e9 b9 b( d/ x# ?    int n = vexNum;& y% q* ]4 R. ^2 j$ r; }% h  e
        for (int u = 0; u < n ; u++)
    0 u3 ^# J) U; v+ x        DeleteVex(vexTable[0].data);
    * a' I9 s% X- V( L    return;
    ( U. H- Y2 M1 N, M6 {5 z}- R. H" n, f/ ]5 c" ~2 x
    template<class ElemType, class WeightType>: X: \# d9 h* y
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()" V  g, {7 k; H5 X
    {; t( u% s) O) {. N) b3 X+ @
        Clear();+ W" O  H. b, ^, O* R
    }$ L1 V: O" }$ V; n
    template<class ElemType, class WeightType>
    " U& S! R2 B- m! U8 V4 z% HMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    - I. b  ?  i; ]  ~# s{
    1 o- v* b& [+ y9 P% x    vexMaxNum = copy.vexMaxNum;. L0 j+ k: ]" m9 ~2 E7 L
        vexNum = copy.vexNum;
    % m+ e6 ~" r8 U6 b, s    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    ; v; j7 L- V! ]5 U6 a    arcNum = 0;
    ! S+ D  a5 g! _  P1 L. t; @' ?$ _    infinity = copy.infinity;1 k8 o& e1 `8 h6 F, G2 x
        tag = new int[vexMaxNum];
    8 X7 n, i8 ^- w/ @$ h5 b
    6 q+ j. A: k  g; @+ ~    for (int v = 0; v < vexNum; v++)
    6 n0 X0 z9 Z, z2 `  {2 |% Q' u  P    {
    , N. A6 X7 u% ]9 O- k; t        tag[v] = 0;
    * n: W1 p' |% a        vexTable[v].data = copy.vexTable[v].data;6 I0 M6 P; c+ k% k6 m9 A' A) _2 T
            vexTable[v].firstarc = NULL;
    + p3 L7 Y9 [% h3 d" y: Y3 ?5 V    }5 G6 L- s& J+ F1 W
        MultiAdjListNetworkArc<WeightType>* p;! n# V' m" g7 M( E
    " D: M$ h' f$ K. H7 z
        for (int u = 0; u < vexNum; u++)
    ) K1 C. R( [, l8 N  m; h    {. x' M8 I2 `, z9 w8 T- ~1 Y1 l
            p = copy.vexTable.firstarc;
    - Q. b8 z3 G5 p        while (p != NULL)
    6 v7 D5 g+ z" K# G1 {0 S, e        {+ P& `) \9 R' f; ^- C; x2 `: Q" f
                InsertArc(p->adjVex1, p->adjVex2, p->weight);- u4 X. w% G( ~2 Z% x
                p=NextArc(u,p);2 ]- S( m0 q( `" h9 W
            }' t6 ?, X" J* P$ N
        }
    ' ~! Y7 B' g3 e4 F6 o: p& M}
    9 G! {- L5 d8 _5 G* `: ]- M3 z7 qtemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    7 j/ q. z; [% h  D$ [# e: ]% ^4 tMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)* L6 Y& p5 y& L& I. a* e4 S
    {
    & A5 R! v: [3 G: F$ T0 l9 ~    if (this == &copy) return *this;
      u! g' J, Q" P/ B8 k    Clear();
    " q9 l* m6 m, ~" q2 v3 [    vexMaxNum = copy.vexMaxNum;3 J. F  }, Z& F5 D
        vexNum = copy.vexNum;
    / s' Q2 K  T) g+ L, A( r    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];$ A0 _. A4 Q0 t& n( N) e' \
        arcNum = 0;
    ; {3 t, y* S$ c3 _' o7 C    infinity = copy.infinity;
    ; j# h+ \* ?; ]. ~6 A5 _* B6 g    tag = new int[vexMaxNum];% H( Y+ H8 z2 T1 w2 i7 @4 Z

    4 G. _5 |: v6 C3 @+ U; m    for (int v = 0; v < vexNum; v++)
    6 S6 s" T' X  V& _* A/ D2 O    {; B# W! y: @& y: J  K( E6 o
            tag[v] = 0;
    9 z0 R6 B7 V/ c5 N) Y1 Y% [( l  a' F        vexTable[v].data = copy.vexTable[v].data;
    " h. z/ {. @+ s9 a1 F" f# _$ N* E        vexTable[v].firstarc = NULL;3 G2 I! b- @/ ?2 |7 ~8 U2 w
        }
    4 p& f9 U" y2 n, ?" ^4 `' B    MultiAdjListNetworkArc<WeightType>* p;
    . j" s9 p6 _8 q2 {, E" l8 J; W% q  x9 {, I# \+ l! @' y
        for (int u = 0; u < vexNum; u++)
    8 M$ h& n  r) `) l$ X  E1 q    {' `# V7 s/ e; \5 _! |3 p
            p = copy.vexTable.firstarc;& y7 V& c% I& `0 ?
            while (p != NULL)
    / n/ I9 c$ \$ O: ~9 F        {
    / X/ S' Y6 K' T' Z! J, h            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    0 Q, O. v1 Y3 R8 @2 q            p=NextArc(u,p);& Y% e5 c& Z3 o' z/ Q
            }! H+ G8 z3 K# e: l* [; g9 w$ l, [
        }6 ]9 `9 I; w7 ?9 ~" ~3 ^
        return *this;% D( A& f7 q. @" N
    }$ }- {6 |5 c8 y$ h9 h
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*5 M9 [* G7 x, L# g  b6 j4 H/ k
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    % \* l+ {' i+ E5 M{
    9 ~& {8 O; ~* F: [+ G- J2 m    if(p==NULL) return NULL;4 y& @4 ^: y8 G5 x' e% J/ U0 }
        if(p->adjVex1==v1)
    / k6 @2 ^' C3 G+ z# U4 f& J- G+ d/ z# w        return p->nextarc1;
    1 V3 M$ @; C/ S    else
    5 x; p5 D2 r1 E. _9 O' F        return p->nextarc2;
    . f' C: {7 Y3 K6 b}8 i6 y6 h7 S4 p- d8 F' S
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    5 w8 o! `4 }% M. e) A5 R5 zMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const) l, g# X$ V1 `* f7 }
    {$ s' P- K, Z' \! s9 a$ N' t4 \
        if(p==NULL)return NULL;
      \; H4 _! M3 _, |( U  \    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;0 l# _# W$ S" z) c( E
        if(q==p)
    # b: q" w: E: V) ~0 ~! I5 `        return NULL;% @9 V& S6 q0 b1 G# E+ P: {, t
        while(q)
    3 T" m6 o; ^* P9 i- X    {$ d- V" U$ J1 B7 ]3 }
            if(q->nextarc1==p ||q->nextarc2==p)
    6 Z! e/ ]0 Z$ B, |8 _3 Q            break;- ?4 e) W# w' d- t
            q=NextArc(v1,q);
    % H' _2 J+ K  C$ c    }
    & j8 n2 D! I& D) U7 Y) p7 ]4 e7 o    return q;
    . K2 E  w, w$ l, p+ o3 i}
    0 \  z& w2 @- f5 r5 Gtemplate<class ElemType, class WeightType>
    9 H/ K  b# J+ O! @void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    . e" C! T% ]+ w" M+ Q% l/ r# q; h* R9 Q{
    . m5 D; }# j9 A) w) m& w5 i6 b    if (vexNum == vexMaxNum)
    : w7 |) Y7 q( P) x/ }        throw Error("图的顶点数不能超过允许的最大数!");0 Z; \: |( }- x
        vexTable[vexNum].data = d;
    0 {# Z0 P* o8 @0 q    vexTable[vexNum].firstarc = NULL;
    / d3 P) Y9 z* a8 K1 |    tag[vexNum] = 0;
    ! j* K; ~$ ?4 X    vexNum++;
    " y4 U# s( f3 I4 l}6 P8 ]0 a8 F9 E! v7 v4 z
    template<class ElemType, class WeightType>$ u. Y5 o3 ]0 c8 a
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    0 m! y1 `$ z  L/ o( |: G' u{) D) h7 x7 y. C
        MultiAdjListNetworkArc<WeightType>* p,*q;
    ! N( `6 g# k1 H+ E2 S, a    if (v1 < 0 || v1 >= vexNum)
    & ]  J) v( r$ S' d: y        throw Error("v1不合法!");) P/ p& f0 u# k/ ~4 V. B! K  t
        if (v2 < 0 || v2 >= vexNum)
    ) D' c$ Q4 |, s) F' Q6 f2 g" h4 C        throw Error("v2不合法!");6 ?3 \; U# s2 ]3 w' ]7 @
        if (v1 == v2)
    " T# B. H% G2 n" X! ]8 n5 K( c* N        throw Error("v1不能等于v2!");- m( i8 w/ d# l. B; I
        if (w == infinity)( |/ D5 i. A% _+ r3 I
            throw Error("w不能为无穷大!");
    # N6 L# R% m2 ^* l9 f# G& O
    - N7 z9 _8 j( m/ ~  n+ e( |0 I* C! _3 D* `2 e2 C2 b3 k
        p = vexTable[v1].firstarc;
    4 B' B1 m# m! Z4 O. i    while(p)
    1 V- ]2 n# c; c3 _' d" X    {
    6 V4 h4 Z$ _7 i# ~        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中; z4 z. x. i! K, D
            {
    : d3 b" e2 z1 I            if(p->weight!=w)
    + S  a; l, l9 t$ d! V- s2 ^. z                p->weight=w;$ y/ W9 }8 n* l# U
                return;- L% H/ @- c/ T4 w9 r# A& @( j, z
            }
    ) @7 {5 g! E0 {7 N# f; j  Q8 u. }: u: G' I
            p=NextArc(v1,p);
    5 _- ]7 E6 \, x    }4 \8 M7 B# R% D0 }9 f+ S
        p = vexTable[v1].firstarc;, t5 b- a! ^7 Q2 g8 m
        q = vexTable[v2].firstarc;) G. Y7 X3 `0 t! o/ i
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    6 w. R; @9 q( B( `    vexTable[v2].firstarc =vexTable[v1].firstarc;
    # X2 o# A" l$ m  j& D  M    arcNum++;
    $ s+ O9 J6 m& k}3 ^; e# t- K3 @/ K9 j

    6 B" a1 P; H* d4 |5 s/ |template<class ElemType, class WeightType>, r0 U0 G5 t' I2 Z) a
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    ' [% u8 x- V0 r$ Z  u0 E{! F' Q" F( y9 W3 t

    . W+ z5 x1 l% b* n# U, M4 o    MultiAdjListNetworkArc<WeightType>* p, * q,*r;; g% F1 c" Q3 p$ K* R
        if (v1 < 0 || v1 >= vexNum)$ O3 B% w" p( x7 h
            throw Error("v1不合法!");0 g9 D% Z* C2 n; Q- p
        if (v2 < 0 || v2 >= vexNum)
    # o' U1 u$ R' m  p, T        throw Error("v2不合法!");8 `2 T+ x" I, d% c& g! _0 ~) h" F+ u
        if (v1 == v2)8 [. Z* w5 I, b; b% ^5 P- B. C
            throw Error("v1不能等于v2!");
    5 }# z% N% U7 J: U* S9 n
    : ?. {1 M5 u$ k/ z- p    p = vexTable[v1].firstarc;
    ; \; {# d+ H* }( _* V    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)+ h# Q4 i8 [$ C! o
        {+ e( F0 ~/ e4 r2 B
            q = p;4 X7 G) J) P: R, S
            p = NextArc(v1,p);
    0 ^) N. H0 A0 {- T; S. Z' f    }//找到要删除的边结点p及其前一结点q- ]; h- E, A6 k9 E4 ^' h! Y) |8 B

    6 v2 c/ Z. [( d9 o6 X    if (p != NULL)//找到v1-v2的边
    ! f3 D7 c% L, f) z* Q8 b" G: a    {
    2 F- s. i+ I# o8 e. h        r=LastArc(v2,p);
    0 H3 ~  E$ \8 h- N* ?        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL# I# t# p) g7 T* t
                if(p->adjVex2==v2)
    0 m* C1 e# j5 a+ Z+ h9 R4 N                vexTable[v1].firstarc = p->nextarc1;
    & X1 M' g" J! I2 S            else vexTable[v1].firstarc=p->nextarc2;) v$ z. a: ], a  o) o6 [( K4 p; n* ?
            else//不是第一条边
    8 a  ~7 M+ V; H0 X; |        {
    1 G  `. Y& J2 y8 U' i) m            if(q->adjVex1==v1)
    , {1 x1 I0 l7 }/ f                q->nextarc1 = NextArc(v1,p);- M( O4 @: V- o) O
                else
    ' k. @3 d( L2 L* ~$ n! B9 o                q->nextarc2=NextArc(v1,p);5 M: \5 h/ G6 ^* L4 M2 @

    ) }+ N/ E/ `+ @! \        }
    , P% ^9 b1 M: H- ]8 Z7 O        if(r==NULL)
    & \/ K4 z+ S' ^7 |% L            if(p->adjVex2==v2): m* ]- s6 U0 G5 f  b
                    vexTable[v2].firstarc = p->nextarc2;/ y% D. g7 v: b' t8 T  H, f: S  Z; |
                else vexTable[v2].firstarc=p->nextarc1;$ _  F/ n& u' C( M
            else. z) s. k3 O* a) V! j
            {1 i: D- ^( c8 G
                if(r->adjVex2==v2), }/ I. m/ ?% \, y" X  f; F2 t) S$ h
                    r->nextarc2 = NextArc(v2,p);
    % ?- ^" @. r" v% b/ d            else
    6 u; W( k  A; I) |4 N9 h, n                r->nextarc1=NextArc(v2,p);" I( n' ?. @% k/ ^4 k
            }
    4 U8 J: c* h0 T% A        delete p;' \6 X. Z# Z9 g2 @# U8 @
            arcNum--;+ G& D9 Q# _' }
        }. |% J8 s* ^  x- ], S: P
    + a3 O. l, i3 [$ \
    }
    4 \1 I' A, s% `$ f' @+ l5 M) _template<class ElemType, class WeightType> void
    5 L9 D. i0 L, Q% X& BMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    5 A& q7 L; j" e. I$ m: P* e{; B' h, P2 ~9 f8 Z3 i" u& Q, v$ N+ \
        int v;; M3 q; R' ~; H. q
        MultiAdjListNetworkArc<WeightType>* p;
    0 J8 u: v( N' ~) m" K! m$ m) q    for (v = 0; v < vexNum; v++)//找到d对应顶点
    , s) h1 K1 K. i- o: y        if (vexTable[v].data == d)
    * i2 T7 n8 B- V3 D" a8 f2 j            break;
    * L; ]" D4 P$ s' O    if(v==vexNum)
    & m9 g0 C% |8 u+ m        throw Error("图中不存在要删除的顶点!");
    1 R0 `7 ]6 P# d1 p5 I! V! s
    + r0 D3 {: h6 l/ X7 s( f/ N! Z& x    for (int u = 0; u < vexNum; u++)//删除与d相连的边% W6 K# Y) d9 x% k6 c4 K8 J7 }5 m
            if (u != v)' }0 f' v6 Q$ ]
            {+ Q3 P  E: X8 D$ d# k* }" J
                DeleteArc(u, v);
    " s/ Q- n, t7 ^% j3 h( l        }/ \; j: P7 K) y* b# U+ e8 C0 V6 O
        vexTable[v].firstarc=NULL;' h! \6 P( g5 e% T7 ?& _2 j1 x

    - @% V' W# j4 A% }    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置! h0 @7 ^% Q. w: K2 u
        vexTable[v].data = vexTable[vexNum].data;: b( v3 m6 E  r& E/ w
        vexTable[v].firstarc = vexTable[vexNum].firstarc;" l/ h5 |  D8 h# [/ u; d+ {
        vexTable[vexNum].firstarc = NULL;3 u8 j( e4 w* d$ M
        tag[v] = tag[vexNum];
    3 L) K  c% A2 J3 ]% u* J    //原来与最后一个顶点相连的边改为与v相连
    ! V8 o# K7 T; [3 z; y! m    for (int u = 0; u < vexNum; u++). L5 h$ f6 O3 q
        {/ M4 o( V% i8 G7 ?7 j# j
            if (u != v)
    $ S" L, L- ~; o) T3 `/ n        {
    3 s" ^$ X+ w) c& ~1 }            p = vexTable.firstarc;
    3 W# V1 N" L& u+ T7 D. P            while (p)' J/ G; o& V/ X) R
                {3 h2 ?2 x. r5 d  `+ f  x: \# m; A
                    if (p->adjVex1==vexNum)8 N) e4 }5 _9 w! I/ v
                        p->adjVex1= v;" A$ n2 z' V8 B4 W
                    else if(p->adjVex2==vexNum). z$ d6 u4 F6 S* X
                        p->adjVex2=v;
    5 B, n/ A( @4 V8 j& K                p = NextArc(u,p);
    ! N6 C0 r4 R: c# f6 K) t+ v            }
    4 `$ K  p( V0 q$ k5 K  ]* l/ w) Z5 Y$ N        }
    # x* m* k! S* _" m2 |( i- n    }
    2 Q) y) I# h* F6 O}
    8 T7 |  V' Q7 b9 _; j///深度优先遍历
    * L( r) \6 U* a& ztemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)7 ~! \1 M9 Y: t" ~6 K
    {9 J6 Z4 _5 q& A' f
        tag[v]=1;
    " a: b2 [' N& P3 @- s9 `% I    cout<<setw(3)<<vexTable[v].data;' b$ Z) l; N: v! U1 P
        MultiAdjListNetworkArc<WeightType> *p;$ R/ s% M6 d+ z6 P* A
        p=vexTable[v].firstarc;
    % |4 r8 c6 }# S0 Q1 K    while(p)6 X% V) L  s) z! e# r6 g3 d
        {& W3 h) O) F$ A# y
            if(tag[p->adjVex1]==0)# G5 E) y& X4 z, w" Z& [
                DFS1(p->adjVex1);
    ' e% g4 f6 L  z2 ]        else if(tag[p->adjVex2]==0)2 N* F" p, F* ]4 P5 }3 R: W
                DFS1(p->adjVex2);
    ! s) \9 e, V. m2 r' I        p=NextArc(v,p);6 `3 A: D7 A5 a, I2 @5 c# }8 X7 {
        }
    6 V' i, s/ E  N3 R/ S}
    9 e, y3 q' V  m& U; Z' Z' P# J+ H% ctemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    0 c" E# E$ N# `$ ?/ b+ t{
    + }! j; p, D: S1 M% h6 Z    for(int i=0; i<vexNum; i++)
    - s- i$ D8 e% m7 y        tag=0;, r. y1 j1 v& m- G% @0 {
        for(int v=0; v<vexNum; v++)+ S; H* f4 Y8 d: D' n0 U
        {  q2 R2 J+ r6 v  M6 g
            if(tag[v]==0)3 a% y! `3 K+ j4 |1 M$ T
                DFS1(v);# ]" l4 [+ I# @
        }( e  V) z3 e( N$ i/ h" s( g  f) L
    }: X! r' k# h0 y( D9 v4 E2 x/ a" P
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()+ h+ H) w! D6 P
    {/ @% @* z6 b1 X
        stack<int> s;
    % d+ C6 f6 U: V& M$ q    int tmp;
    / ]' A! i. o) m' s    MultiAdjListNetworkArc<WeightType> *p,*q;* |2 U: V1 P! |5 p
        for(int i=0; i<vexNum; i++)7 @7 O* a. x0 Y  i
            tag=0;# v& i% ]3 g! N# J7 g) E
        for(int i=0; i<vexNum; i++)) w) f8 a2 @3 Y. A/ N+ M; A' f2 G
        {
    - N# }; t0 [3 a' H; G        tmp=i;
      v9 O$ B$ w/ k' g! V5 C. }2 E  `6 z        while(tag[tmp]==0||!s.empty())9 |- t; S, q$ L
            {
    1 ~% ~8 ^0 M! W$ c  }) y1 b            p=vexTable[tmp].firstarc;9 ]( c( ^  C$ d2 ?) A
                while(tag[tmp]==0)4 ~+ F4 l' ~# u+ `
                {* a! |$ L+ h8 `2 Y3 o
                    s.push(tmp);6 [' C- \+ {; @% m
                    cout<<setw(3)<<vexTable[tmp].data;
    # X4 s6 F: e# K3 S  A* v- x1 Y                tag[tmp]=1;; F0 Y# j6 L1 K5 `
                    p=vexTable[tmp].firstarc;1 S; |1 S, `; U7 W6 Y% U
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for" _1 [2 d9 b- U. G; O: f6 k) n
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);' p- g6 ^' G$ f  u* ]% S2 k
                    //cout<<" 1st     tmp="<<tmp<<endl;: M: _- V" N: J. W' Q6 v6 Z
                }' n* o8 O- w. L* W
                if(!s.empty())/ Q; z$ P( A1 u! i& B
                {/ m. O  E1 V+ `; ~  X3 d
                    tmp=s.top();$ K! q. `5 y- |
                    s.pop();
    $ k* M3 H8 ~, ]' g2 U                q=vexTable[tmp].firstarc;5 ^$ L8 e; N; W& M
                    int t=tmp;. [( {1 N3 ~+ P  X/ ^
                    while(q&&tag[tmp]!=0)5 P9 t, `8 `# Y* B! }/ F" r
                    {* s6 h8 ]/ Z+ J$ P. U! T
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);9 G7 G) F3 u1 j
                        //cout<<" 2nd     tmp="<<tmp<<endl;( d5 c5 C* |$ u. ?
                        q=NextArc(t,q);" Y. K6 |4 o, g3 L
                    }, |1 z3 U3 t4 d! g
                    if(tag[tmp]==0)
    4 X' d9 c2 D! S( I                    s.push(t);
    4 X9 ^* g2 {- K0 A( L; r+ o( Q& W8 q                ///1、对应上面连通分支只有1个点的情况+ [( J1 m6 v) X+ S) J
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈% x( N: ]% `* f3 b) n
                    ///tmp要么等于找到的第一个未访问节点,* l1 L, p+ E2 L0 W% I
                    ///要么等于与t相连最后一个点(已被访问过)
    $ ]+ P7 q! M$ g7 n( C                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点9 A$ c6 o' a  R3 u, s0 H. T% r9 M
                }+ O" `. s9 i. I4 m. ~1 G
            }
    # W8 E7 ^9 l& ?7 g/ A0 g2 s    }
    ) D9 I- {$ `6 Q+ B% s* V}
    " W( U8 h: g% x  f6 Q" N//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    1 h# g4 \: K3 I5 Ptemplate<class ElemType, class WeightType> int
    ( V8 Q9 a1 a* X3 H8 s: ~# ~! ^MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre): x, {; X3 _0 R& }
    {
    1 E8 F1 d( Z/ K, C' E2 h" Y  h3 \    if(head==pre)
    8 t- s$ M) E$ i( J, \        return -1;
    0 \, q8 w9 f! H! p
    ; N% N: b( g- t" W' A# ^    MultiAdjListNetworkArc<WeightType> *p;
    + P/ o1 ]; h) {& i/ k9 ^4 _    p=vexTable[head].firstarc;
    2 j: P: }* B, J& C( q! A6 E    if(pre==-1&&p!=NULL)$ }* Q( U+ i: f& ?
            return p->adjVex1==head?p->adjVex2:p->adjVex1;4 I/ O/ C; K/ ~8 F( j
        //pre!=-1&&p!=NULL& R" c+ J2 d1 R8 u* V2 U5 B
        while(p!=NULL)8 e; V' G; J1 V8 W" H  X
        {
    8 c* H+ r) g2 R' E: g        if(p->adjVex1==head && p->adjVex2!=pre)
    2 s( r6 X3 q$ Y- Q0 V) C8 M            p=p->nextarc1;) }9 j: O+ {, x1 F
            else if(p->adjVex2==head && p->adjVex1!=pre)
    0 w2 Z) \4 Z5 p, i1 w7 B) K            p=p->nextarc2;
    0 @8 g- Y) {+ V; p% C        else if(p->adjVex1==head && p->adjVex2==pre)
    2 z* y8 x8 Y4 _6 E        {, B( d6 a& R9 L. l9 H) H4 B
                p=p->nextarc1;
    4 i! O* G: F4 D            break;& b5 p* e. Y) W0 I$ Z9 o
            }
    . D0 w* I: m* s! r        else if(p->adjVex2==head && p->adjVex1==pre)
    6 h. X$ s2 `0 R4 ?        {6 L0 ]/ w; C2 i
                p=p->nextarc2;# x6 o' P) E0 d( d* h4 f, K
                break;7 u# b$ e6 y6 a4 w- A9 I
            }) u% t2 D5 M* L0 C6 L  U; A$ s
        }
    ( x% s7 H) I; W4 f# h    if(p!=NULL)
    7 y  s9 j1 i' ^; ]5 B' y3 y    {6 \6 h5 O* Z% X- l4 E; ~4 G
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    0 t& N1 m; H% J/ R( E    }# s+ E) W1 ~6 M2 p
        else
    ( @' ?1 c: G# c* X; u+ `: U; i$ u        return -1;# x! ~2 Q. m  F. h. N3 m
    }
    , Q; a; i# O2 V& z' {0 X- H9 m7 s0 h0 \1 Z9 }9 l$ F

    & f/ R0 \: l7 o/ x, ~; d1 w' I' Ttemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()" T9 P2 s$ B: Y1 X! N0 g( _
    {0 b. O. i9 @; P! |
        stack<int> s;
    7 R3 m: A8 l4 K3 ?6 O' ?' m) U0 p    int p,cur,pre;9 M, ~+ u5 P$ C0 Y
        //MultiAdjListNetworkArc<WeightType> *p,*q;
    + Q) T5 r$ Q! C' v    for(int i=0; i<vexNum; i++) tag=0;//初始化
    6 `2 g; I5 ^' x' X
    % l, r: `* E# L! k5 v. x. r    for(int i=0; i<vexNum; i++)
    ) U4 x1 P2 D' h1 m8 \    {( J4 [) F/ }; a# g/ w
            cur=i;pre=-1;/ B* a6 x( X2 |4 H, M9 T4 }$ A
            while(tag[cur]==0||!s.empty())
    " h. ]/ o- m& Z6 U        {3 Z- e% P% K. P3 I2 R
                while(tag[cur]==0)
    ) f; d) b! R# A  K            {
    8 M" g% K. {. T                cout<<vexTable[cur].data<<"  ";
    3 r- W" B' u6 W                s.push(cur);8 H, {4 o9 {, m8 N( C& C" \
                    tag[cur]=1;) O! |0 e9 N% k* j' G' f
                   //初次访问,标记入栈; k. B3 k; O5 d$ {" o
    $ g2 y3 {* r  R; O
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点
    5 B' z+ O, s. ]2 U! t               if(p==-1)/ L( y- G0 B3 S+ }9 J
                   {1 F6 a6 r- ]5 v
                       pre=cur;s.pop();( d7 g; O) s( f, t7 B8 F
                       break;4 x! ^# \; V, w% n% z
                   }# q1 w& @; z7 c& U7 q- T) t
                   else
    & F# h4 m7 N+ g. B8 r; [               {* K  G. M7 E, r9 v) r$ _
                       pre=cur;7 U# @' Q* h7 L% a6 M3 p0 f! Y
                       cur=p;; ^- E5 N, x8 j3 e1 i* d4 ?5 c; R2 `
                   }
    ! I; Q7 ]% @, R3 e% Q0 Q9 r' h# R# l5 S
                }1 j/ J- ]- P2 e% Q$ q' x3 A3 S
                while(!s.empty())
    9 ]7 W0 u- k$ c4 ~/ j5 x0 _            {
    5 W: }7 [  q8 S2 T2 ~- v                cur=s.top();
    ' d% w- {5 @! V. d( d! O4 \                p=GetAdjVex(cur,pre);
    4 J1 z- M" E) A2 K- y+ o0 s: N                if(tag[p]==0)
    * D+ e0 I+ q) S3 L2 I- @                {5 L7 v% @6 z% \' ], }
                        pre=cur;0 o) F  \! L2 U) w3 ]+ h
                        cur=p;
    2 r& d) s/ A- |  ]                    break;
    7 v' G* A5 C7 u                }
    ' T) T/ @$ G9 o$ g' t* i                else2 x  @8 [- c$ J4 O+ I( S
                    {
    8 q" B3 x. R5 W% L                    pre=s.top();
    , ~3 \0 S3 G2 X/ ^( D6 p% R4 g" d" k                    s.pop();1 u) f: {: F* y' I
                    }
    ' `+ x* U- Q9 ?) w- u" ]4 Z0 X" {
                }
    2 I8 K% C/ L, g# Q( R# w' n# N- O5 v% l& H1 K: a
            }3 ?' H5 w  h- m$ j
        }
    8 c) S$ f- N4 v0 \4 \}
    + ?0 N7 a/ D! p1 ttemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    2 w3 Y7 |4 I! t5 e" G5 z, x{
    + a! S+ x1 i" q: ^" ^$ c/ _: k0 v    for(int i=0; i<vexNum; i++)( Y  E  W; S  n2 a. l
            tag=0;
    0 T! z! O5 {! a0 U" ?& r    queue<int> q;0 U5 u+ t& s* B9 c& q3 p" v7 f; G
        int tmp,t;
    4 ]: q  Q9 w3 a- f    MultiAdjListNetworkArc<WeightType> *p;+ L9 U$ c; O. s+ M% r8 v0 n: i7 W6 f$ \
        for(int i=0; i<vexNum; i++)0 y# K/ \3 k1 Q1 a' j1 Y9 E* B1 I
        {
    5 n6 P4 n. q8 N2 B        if(tag==0), t( I5 F( d+ C. h
            {
    : }) t7 H/ q4 \8 r            tag=1;5 k8 c0 q6 J$ w- Z# P
                q.push(i);
    6 S. {: {( r- c) z/ h            cout<<setw(3)<<vexTable.data;. b  `9 s3 @9 ]+ o
            }
    , J3 ~4 W. z: J( I        while(!q.empty())$ s( o0 s( g' a- a- D& l* @# ?
            {& h% e% Z1 c! X# @7 p
                tmp=q.front();
    , m6 Z% F# N. Z# c) v            q.pop();8 V7 y& c7 m1 U9 p4 i: }
                p=vexTable[tmp].firstarc;$ ~6 Y0 R# K0 n/ }' b( K
                while(p!=NULL)
    + j3 i/ q- b. W- D, K1 D            {: D6 f# _; @& _6 O9 n; j
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);0 g: M+ q0 D. `+ h/ y% t3 [! \
                    if(tag[t]==0)
    , c" ~, @% m' c8 ^/ o8 l                {) L4 L* x! Y8 k' f2 V$ R
                        cout<<setw(3)<<vexTable[t].data;
    ( k4 D" P. c: T4 |" t8 d                    tag[t]=1;0 h0 [8 S2 p7 r5 x
                        q.push(t);- W! i. ^9 v, u
                    }! E3 p! ^1 e" z5 k" {
                    p=NextArc(tmp,p);
    5 y7 j) A5 _( ]# J' c) o            }  C+ E1 _* p0 @: v, `6 Z
            }
    : Q. ]7 w2 c1 Y8 `7 B; c- K! n# g    }
    : A8 l6 o% T% m# Z1 I" f}
    ; W! a5 F: B0 c. E1 U4 Y" }* @template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    2 r  R& [2 e9 I{8 Q+ c) E& Y+ X% u& R
        MultiAdjListNetworkArc<WeightType> *p;2 q3 y/ g8 T$ \6 l) y
        cout << "无向图有" << vexNum << "个点,分别为:";
    9 E! r3 l- N7 }8 Q, x5 d/ J* X    for (int i = 0; i < vexNum; i++)
    - l  Z$ @9 \8 |2 }& n2 _9 Y' ]        cout << vexTable.data << " ";4 T# E9 |- W7 d, ?+ g3 H2 w: [* s
        cout << endl;
    / u& R- S/ W8 R, J) z    cout << "无向图有" << arcNum << "条边"<<endl;4 x1 K' K, R4 A: B8 W- d+ D. G
        for (int i = 0; i < vexNum; i++)
    2 J: b$ B# n( i: E    {
    9 R' g# T( J- A        cout<<"和" << vexTable.data << "有关的边:";* F( ]6 U$ T% m/ U  \  S
            p = vexTable.firstarc;
    5 g/ r5 d7 Y5 M5 L# R& ^3 }2 R        while (p != NULL)4 H+ Q* {+ F# ^! F" s. s) c" W
            {! c- H, r. Z, K: B3 B: [
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    ' Z; I) I0 L! q' M            p=NextArc(i,p);
    + z* ?% y' U8 [4 K3 v        }
    0 U4 Z: G. d3 P- a) h& C' L        cout << endl;4 @9 f* ]. m! M/ d
        }
    ; t, d( `) r& L1 v# b- M6 f}
    : q0 ^9 [" x0 N  m: s
    6 @$ r% J( S* y' L& I& H( s. |# Y" _2 n! r
    邻接多重表与邻接表的对比
    8 H; b$ L$ K& O$ y% b
    0 F  [7 N! Q" B' U. G9 i" B邻接表链接
    6 u3 b2 V5 A6 l$ W( G8 y, k在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。, F$ b/ H' w$ C1 O, {
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。* p# l* K+ G  X9 U$ O
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。, s7 N# W8 B) o' c) [. k% Q1 @
    ————————————————
    " O4 M5 s' e3 k版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ( C6 M+ G. P5 `! C9 [- S原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    0 k" N6 [; C* E$ M. J
    1 ?2 u0 R" m$ z1 s" x9 z3 i
    ) T% n; M. z! B/ j: l. M) b) v) Z/ I7 P: ]0 u  M
    1 f/ j" X" {5 a
    ————————————————
    ' b5 e7 U/ H+ L版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    9 @! r. X- L* n7 w% B  P原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958. S; c3 b, A1 o7 ~0 C# }9 q, \

    4 q) g6 \. m2 ~! G3 J; G# f* w1 A6 Z
    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-6-9 13:20 , Processed in 0.471692 second(s), 54 queries .

    回顶部