QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1567|回复: 0
打印 上一主题 下一主题

图的存储结构——邻接多重表(多重邻接表)的实现

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2020-4-26 15:26 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta

    6 ]- E4 M# ]5 t0 y图的存储结构——邻接多重表(多重邻接表)的实现/ U0 a5 {, A. I
    7.2 图的存储结构
    8 W  G9 R$ O. J8 _+ D5 t$ I
    ' S4 j3 z9 c0 [" a7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    / Y1 o" Z8 L; H  l& [( \; X邻接多重表的类定义: _8 q; P# h* N# A, X
    邻接多重表的顶点结点类模板
    $ Q6 O0 p% {* }  K8 l邻接多重表的边结点类模板9 s- d( W% v! D* I( T
    邻接多重表的类模板
    ; i& s( f8 F' U: o9 x邻接多重表与邻接表的对比0 u  Q* X$ o  e3 c: h$ l; K9 b
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist) i" P: C1 y: O8 O4 S/ ^$ P
    5 n- I$ a6 \4 f5 w8 [- a
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。4 u8 T: H9 J! X  k, T
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    ; ~, b. W5 C7 ^% |% _- M% E) T1 m
    1 d& x. y' O& Z6 h4 ?邻接多重表的类定义- X( t+ k4 a2 t. v
    1.png   j4 Y" d3 {- l7 g  K! f/ k+ W
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    6 ?2 a5 O0 H& D8 a  ^data域存储有关顶点的信息;
    7 N3 W2 ?! W9 J  C3 N- S) e, ~firstarc域是链接指针,指向第一条依附于该顶点的边。
    ) d9 q" k, [- p" s  E* L% j+ z所有的顶点结点组成一个顺序表。

    8 R2 U  V7 G7 }& h, e* N

    ) p8 Q( M$ A2 W# E0 B% w9 Stemplate <class ElemType ,class WeightType>9 j* N8 V' H' H6 Q' ~
    class MultiAdjListNetworkVex
    7 r% M$ j! e, {9 f% J{! `# o2 ^2 s+ p4 s$ `4 N; \
    public:
    2 I. h+ a  z2 `/ J: a/ s  \        ElemType data;
    - W3 v( e( R0 G) Q! j        MultiAdjListNetworkArc<WeightType> *firstarc;* q: q! H9 C; a4 R& b6 K
    4 E1 O  ^/ p% a/ m, J: J! X
            MultiAdjListNetworkVex()9 v$ p$ |. s$ s7 H. e) o
            {3 ?) q8 \: n. k3 A" S
                    firstarc = NULL;
    / a8 f8 y, d) J2 B3 \: U        }& p; f2 ^6 E2 w0 F2 T5 a! X
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)- l5 z! g1 O$ T; s$ [
            {6 }' \% v2 o% S, |( ]' Q$ t0 D
                    data = val;
    4 s7 m9 O5 u! o* ~2 V                firstarc = adj;
    # @- R8 z( \: W3 T& `& _7 \) j        }
    . Q( d+ n5 T* ?$ t$ G: @};
    8 }6 N& r& r/ z7 {* T
    ; E. j$ m5 _5 x) M3 J, ]邻接多重表的边结点类模板0 R4 [8 }8 G6 L1 O+ N
    $ ^9 B, ?. L& m7 v
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    ; v' ?/ q1 Z) w2 R5 |tag是标记域,标记该边是否被处理或被搜索过;/ d8 Q# l8 Y/ [3 Z# H- V6 N0 r: u
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    7 U' F+ {4 k* j' h6 {  p, c# `, r' Cnextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;( A' X' t8 n5 R7 k
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。5 j! a- {+ h7 X' p8 h2 j# S
    . V6 f3 g6 Q1 i+ S" m! T
    2.png
    5 _4 W' S& o$ G  btemplate <class WeightType>) e7 i( z0 c% b) h
    class MultiAdjListNetworkArc
    + r$ `1 L. x! J" t) M{+ f5 s0 R0 U+ x3 e
    public:* l5 y6 h- c+ u
        int mark;                                       //标记该边是否被搜索或处理过9 k9 u/ v( U, E) A! I  ~# {# Y
            WeightType weight;                              //边的权重& M0 P/ Q8 S7 b( Z! z( o* _
            int adjVex1;                                    //边的一个顶点; B2 S6 I0 a! x3 d& m
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-17 {8 n& p/ i7 G- m% |
            int adjVex2;( E0 o0 ^; O4 |, d
            MultiAdjListNetworkArc<WeightType>* nextarc2;
    7 @' j9 `" S, c
    ! G; E' s" M. {8 k! M& s0 l) t3 m        MultiAdjListNetworkArc()
    - I- L) }$ {5 b6 z/ M        {3 v3 s3 k! L7 H) a# h3 C# l
                    adjVex1= -1;
    ( I/ _- f7 B% D! {0 H                adjVex2= -1;
    # q  L4 p4 \- I; \8 J( Z) F2 ^* {        }% l4 f8 B4 F- n" G* d- J5 X9 ~% e
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)( B$ r( o* `5 y9 h% \( b, m/ O
            {$ m, E1 Y9 T: W
                    adjVex1 = v1;       adjVex2 = v2;
    # k9 _( J  X% `/ j9 g3 L% }                weight = w;
    ( u- P) Y1 C- G  z                nextarc1 = next1;   nextarc2=next2;2 ]" D7 h( a  R/ p) Q4 o# o
                    mark = 0;           //0表示未被搜索,1表示被搜索过  M9 P/ x$ J0 o1 B
            }; X+ ~- h/ w& ~- ]: b
    8 B- A# _2 ?& [; \2 ~' G  U! F8 F
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    - F- Q/ M* y. Uclass MultiAdjListNetwork
    - q- ?9 K+ F$ _0 Z3 f: X# z/ R& p{6 b  G1 y5 d- a7 A4 Z
    protected:
    - u6 Y/ i7 o2 i& ~    int vexNum, vexMaxNum, arcNum;. p1 a. P- O7 B' q' D; r
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;8 o/ s, M5 K# @8 g. ?
        int* tag;
    + t3 S) S. T0 ^5 J1 q+ b4 [6 S3 G    WeightType infinity;
    1 y; N! N, V" L: o1 @( n& M, i& B
    ' W- d0 c6 P) _- W- Qpublic:
    : W2 V0 L% y' ]( w' A4 w" P# |  |: {    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    / L& ~4 @6 U; {" J& n' R, t* w1 W2 `) [9 Z- S
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);/ Y. U& d* s& B4 o. x# k/ e: o. a
    ) @1 g1 a* W4 b5 M, }& S
        void Clear();% h) _3 g$ y7 ~  q& L* Z! O; a
        bool IsEmpty()$ A- {/ K" H) u0 i; B
        {4 t, u2 K1 y" \7 M2 t! I4 K
            return vexNum == 0;" @1 M" N6 Z" J( m5 L0 B
        }
    " [; \/ n+ ?& D0 X" A- ~$ O& j    int GetArcNum()const  \  m$ w2 l5 F. A% |( b
        {
    * I5 l- `3 O# l( ]; `        return arcNum;! E/ {- ]( i4 o  ^& g! U  n: F
        }3 h1 p! g/ j( C8 [
        int GetvexNum()const/ t) `# J) _( U1 L
        {
    ( n6 ^+ {& F+ l0 V) ^! [+ \        return vexNum;
    / m; G4 p" Q1 Q- M9 w    }
    * w! D5 U' a( m9 I& W! {3 K0 I
    , C1 h' z% A- l: w' h9 R+ d& g
    % G9 W5 ?8 v5 l6 u) F& ?    int FirstAdjVex(int v)const;7 I6 h1 ?7 X/ N4 A
        int NextAdjVex(int v1, int v2)const;
    ! M* L4 M6 X4 m% O; t/ h( C+ N' q. B    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    " M( P3 H# B! h% c0 A& ^    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;8 ^0 B; C2 b. }# A! I+ ]3 x
    " k! X9 H2 U. g8 v: q
        void InsertVex(const ElemType& d);
    % @5 N6 v* p, J, f- |# P! J2 j$ p# S    void InsertArc(int v1, int v2, WeightType w);
    7 D, {9 w! J5 d+ r
    , q3 I" ~' ~1 g7 y9 k4 l( r* e    void DeleteVex(const ElemType& d);
    ( Q+ H" y4 U8 J. M" C& E% [    void DeleteArc(int v1, int v2);/ T, Y3 C, q6 z* C# b

    ' n  ]3 r1 ~+ A4 A    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);! p9 a7 J, n  O4 e. \0 I
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);; n- @8 A& Q& Z% @/ G* ], b* i
    , k- J5 p1 M; n! @7 R
        ///深度优先遍历
    . \% l% B- w& k6 Y    void DFS1(const int v);0 r: ^+ V+ j8 L( T, X
        void DFS1Traverse();, o- j8 j8 Q2 c, j
        void DFS2();
    ( ]8 B* r+ l; i
    # v5 t3 ]; N1 V- c    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    + J$ P+ Y4 ?- W2 G8 l    void DFS3();; C1 Z+ s; X3 N; {# W  |4 ]

      K; b) h. R1 ]7 x2 w    void BFS();
      K% g' L0 o! p    void Show();9 H5 i! b# N5 Y( ^! c
    };
    ) ^, G- r: ?$ `' J) \# p, X$ y/ [8 J) y' D, Y
    2.函数的实现9 H- C+ c: B. _0 X3 N/ n% O2 Y
    研讨题,能够运行,但是代码不一定是最优的。3 k2 E3 y5 H6 {2 e+ D. s/ F
    9 v! g% T- g- {6 k1 E9 _- ^
    #include <stack>0 [/ g3 D/ l# q7 ~3 D. X$ [
    #include <queue>7 Y) F8 J4 ?, ^7 ?( J

    1 S3 u3 c. `6 {# stemplate <class ElemType,class WeightType>( {1 p0 w. j* S# f, P! l
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    - ^8 @; a. r  t0 C{
    ; r8 u6 c* Z) @5 [9 V5 I: Y7 p) x    if(vertexMaxNum < 0): L) x' @  U% c; P) E/ y1 q0 C/ k
            throw Error("允许的顶点最大数目不能为负!");
    / B3 F* n9 U3 T) V% A, p" Q+ E! R    if (vertexMaxNum < vertexNum); |* ?" n- P' k0 q  m8 A3 ^0 g
            throw Error("顶点数目不能大于允许的顶点最大数目!");
    # e8 Z6 h+ M0 J% R; w    vexNum = vertexNum;! v9 K! z  _6 m
        vexMaxNum = vertexMaxNum;
    , v  h) n; S9 V/ `( n    arcNum = 0;
    , t8 O- K1 {8 _! U2 J    infinity = infinit;- M- S* a4 _( A! [$ |2 s5 o9 v
        tag = new int[vexMaxNum];. Z6 m2 p5 x7 P) P9 x# \/ m; K6 v8 T
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];. e. K4 W5 g6 i' ~  J  J- a
        for (int v = 0; v < vexNum; v++)
    : C7 x' d1 l% ?+ J: {0 C# M- L    {
    + G* H8 i, x8 l        tag[v] = 0;
    . B1 x% q! T+ G( K        vexTable[v].data = es[v];
    9 K+ K8 Q4 Z9 L8 H0 U8 K        vexTable[v].firstarc = NULL;
    ( u1 `! J. r4 |% Z0 q- g: i    }
    / H6 _. _. {' b; l}8 {% p/ |6 e( v& L
    template <class ElemType,class WeightType>
      c1 T7 H5 f  I) HMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    / K* ^* i3 X0 B{
    0 ]/ G+ R% e# p3 }( X) R    if (vertexMaxNum < 0)6 p8 h/ {% U4 g! u9 G! _* f
            throw Error("允许的顶点最大数目不能为负!");9 P4 L% ^# `8 r9 A: ]9 r
        vexNum = 0;, C1 ?& e( z8 _! P% o6 g0 C
        vexMaxNum = vertexMaxNum;
    & k' l1 M  j% T  }0 R, C    arcNum = 0;
    ' S( e4 f) Z2 G    infinity = infinit;
    % ?" Z$ ~* {9 X3 e0 k+ H) ]    tag = new int[vexMaxNum];
    ( b8 H! C0 M- W4 D) H7 U4 F* E; U    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];! b* L* J' [9 ^# x
    }* ^: ]1 G1 ]( O$ V: Y) g6 N
    template<class ElemType, class WeightType>
    & m) A5 T3 y% g  J4 L9 ^+ gint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const: {- ]5 H$ ~7 d4 \" P6 D0 |- f! O
    {) P- }, W( Z2 P" G+ z
        if (v < 0 || v >= vexNum)
    9 ^  P$ r3 o( E' A        throw Error("v不合法!");
    6 I: [- B8 Y1 q8 \3 N5 e( M    if (vexTable[v].firstarc == NULL)* a9 V  H8 |3 J. z
            return -1;
    8 s4 n, M2 C5 v0 p% Z8 y- S    else
    ) C1 f2 K, q9 S$ F# e: I( c0 }$ l0 H        return vexTable[v].firstarc->adjVex1;& R% o( ~) @  r" ^
    }, {- \! G, ^6 e
    6 Z6 ?) E6 D2 D7 R  P( w" I
    template<class ElemType, class WeightType>0 l! a2 a0 S) p( O
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const, ~! o* a# O6 [/ j5 i
    {) q1 v# u, Q+ \* ]
        MultiAdjListNetworkArc<WeightType>* p;
    6 g( }9 D! x2 w9 A4 [! @    if (v1 < 0 || v1 >= vexNum)
    # S- G0 `: z3 m, A; F        throw Error("v1不合法!");
    - R& ]/ ^4 X' e5 j    if (v2 < 0 || v2 >= vexNum)
    % f  d  U5 a* M        throw Error("v2不合法!");! j  T9 d7 j) r
        if (v1 == v2)
    9 _* l0 M" X$ W% p# _        throw Error("v1不能等于v2!");$ ?# {( Z) w, q' {0 c
        p = vexTable[v1].firstarc;' n7 t" e: \9 ^
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)9 [4 J4 Y5 B1 }7 G8 W- R
            p = p->nextarc;& Q+ B: q3 R/ f' v4 ?
        if (p == NULL || p->nextarc == NULL)1 P3 I8 ^9 `# t% P! _$ i& G
            return -1;  //不存在下一个邻接点
    7 G* o" q. b' V6 [+ D' n7 W    else if(p->adjVex1==v2)% @% k  T/ T: X2 J0 R
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);" L" ]% z4 c( l+ l8 ?  ]5 N5 a" s; ]
        else8 H2 w6 h. W! m+ u% E9 O+ y
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);6 F- ~, E) a4 @( n- t) M
    }; |/ N/ m$ |$ t8 H5 M& ?- n5 A/ A
    template<class ElemType, class WeightType>
    ' Y* {7 U5 F5 e% a$ w& Cvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()
    , {5 I* s' `3 Q' g{! E2 X9 K3 ]7 q9 ^4 ~
        if (IsEmpty()) return;6 i% R' u! `4 k6 Z
        int n = vexNum;* Y) M0 s4 P0 @, O4 T  u
        for (int u = 0; u < n ; u++)& f# G" \' `; h
            DeleteVex(vexTable[0].data);
    + k9 k' A* S6 n9 ^    return;
    & t: r1 Z  t; y- G$ S! F}  x3 q5 X* H. f6 O5 d
    template<class ElemType, class WeightType>. S+ U. l" Z5 F7 M' Z5 i& M
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    * X( @9 Z4 A1 `+ A/ G{
    ; h7 W3 l6 l! L; [* h    Clear();; ?+ Y0 T. E7 n/ }5 V
    }2 C! j& P4 c- j) w, }! t( T
    template<class ElemType, class WeightType>
    & V9 M6 `; s% c1 z; s1 GMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    , v7 P) K7 F- k' g, q: g. i{7 b9 s  W3 Q) ^( z9 I* ^( I
        vexMaxNum = copy.vexMaxNum;' O  x5 A3 K, N
        vexNum = copy.vexNum;
    / g, h: V  b$ c. B2 a- ^# `    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    & }& A$ m7 A. J: p. p, u3 T  e    arcNum = 0;
    , u; I5 r' D: w* @    infinity = copy.infinity;
    ! ^4 O$ {) @9 \) _    tag = new int[vexMaxNum];0 t4 N0 ~, H0 l6 {4 Z* _

    - [- W7 v" B# T: T# t6 {6 P    for (int v = 0; v < vexNum; v++). A/ C, L/ k/ l0 p, w
        {! a8 S4 {  g% f* v9 B
            tag[v] = 0;
    4 {7 O' O7 {2 g( M; Y, \8 d        vexTable[v].data = copy.vexTable[v].data;- w/ Q' l* W7 C, H( c: T
            vexTable[v].firstarc = NULL;; h' F3 G5 }- O  O4 ^8 \% H% S6 L
        }
    8 [. `2 N3 R6 j# G; m" S: M    MultiAdjListNetworkArc<WeightType>* p;
    , _; `9 o  {( q; L  S! V! S/ }) }- Q6 E6 w, P6 m1 `  `% _
        for (int u = 0; u < vexNum; u++)
    0 ^* c) x$ q( y- d- Y    {
    % d  z) k$ n. i3 _' u2 D. i* G' }        p = copy.vexTable.firstarc;# ^% J# n* e" c6 ?4 P
            while (p != NULL)
    - K3 O  L# l( g& T1 I        {, X( e- O2 N, e2 ?& m
                InsertArc(p->adjVex1, p->adjVex2, p->weight);5 a& [; i. i: ]9 L: O
                p=NextArc(u,p);5 Y0 Y8 Z! P  U' @( |! _
            }
    4 i" C/ O- k- T: s% m7 Q" y  s" y1 Y    }
    ' l$ y: v3 m" e! h* w+ c' v}3 O3 T% j; I: \' V( F! K3 o
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&" C/ j+ D" ?+ D9 F4 ^" ~
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)& A1 M. }# L8 k3 p
    {
    8 N" a% P. h  k' ?! w    if (this == &copy) return *this;
      X5 ~9 h% {5 R  l    Clear();
    . s- y, {" t' {3 x# i% g    vexMaxNum = copy.vexMaxNum;
    7 X$ B; P% _2 k+ e/ O    vexNum = copy.vexNum;0 \! P3 b7 A& A# k: R
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    / H" o( ?. z6 ]$ n! i    arcNum = 0;. l$ h7 X8 o# L  D' O8 e- T
        infinity = copy.infinity;( T5 I# O) v  ^2 T# d' F3 _3 j
        tag = new int[vexMaxNum];
    ' d- V8 L- c! W: ^! ~- e% D/ v2 ^$ A4 E" D; k
        for (int v = 0; v < vexNum; v++)6 F/ `* j2 ~; [  y& z7 ~0 f. w; m3 a4 `
        {
    : n' S/ O3 `. X5 Q& q' a        tag[v] = 0;
    7 P5 N. v3 _2 R, Y2 j4 q9 O        vexTable[v].data = copy.vexTable[v].data;& d) `+ ~; x% c# B4 ]0 P# h
            vexTable[v].firstarc = NULL;
    - r1 Q3 w, V6 i) A. ]  r    }: r9 A5 F! \; p& U7 y+ v! C9 e
        MultiAdjListNetworkArc<WeightType>* p;* f% ~( z) v* @$ A8 w8 E7 g# s- g2 a

    9 H6 x* }1 ], S2 m( t; D6 i    for (int u = 0; u < vexNum; u++)* D$ _2 r1 b  @# Y1 O
        {
    4 f% N7 r% k3 P5 E6 Q3 _        p = copy.vexTable.firstarc;
    - l  O; q6 u0 r3 ~$ p        while (p != NULL)  [$ V- n+ |) w, h+ ?0 |
            {3 o9 F/ V! v- q: U" m7 E
                InsertArc(p->adjVex1, p->adjVex2, p->weight);/ I& s5 C+ V0 L  L3 o9 \
                p=NextArc(u,p);: v, W2 ]9 l% K" _
            }
    6 [  J* }/ b- j; d3 A- p    }
    ' @+ W- P5 i) y* }1 I+ r( w% R% @, z& I    return *this;/ ^3 e& {4 \* @+ f. k& R" m
    }& _# M; \  J: F. c% u( |7 v  K
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    - `6 Y  u" e1 u6 pMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const6 R, _3 ~* V1 R# p
    {- L, C- l2 ~/ F( w
        if(p==NULL) return NULL;9 s6 H5 J% i4 C" c7 @: v/ s+ ?  C
        if(p->adjVex1==v1)
    4 G9 r; D  _. J# e( d        return p->nextarc1;
    * }/ ^4 d1 F2 \, Z6 w    else
    ; y; M3 y1 B% z  K# m! ?        return p->nextarc2;
    7 Z. u9 @  A5 o. c4 R. V}" h, G1 J& k0 [* j
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    " q+ B. G4 h) Z6 F8 l* OMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
      t6 L7 o& c* V' N3 E1 Y7 p+ o2 e{
    0 j" y! a8 o5 M! _$ S1 N1 L  `    if(p==NULL)return NULL;  y' ?1 f& V! @% z+ B
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;, j+ X' v0 ^# o, B. a. Q2 w5 g
        if(q==p)) I6 t* K, z/ z) z( m# p
            return NULL;
    ' G, q: |7 r+ g  `    while(q)/ G0 a5 n0 e- n8 z
        {
    1 K' m, D& D! e) T' b        if(q->nextarc1==p ||q->nextarc2==p)
    $ J) N  Z1 c. v' R0 o6 N; R  T. s            break;
    $ L& X# x( O( F2 g8 q        q=NextArc(v1,q);2 r' Z. ?, Z% V& b% x
        }
    & p. l0 o* e; H; g" O    return q;
      y; `- A" O: F% K% j( @! W$ r& [9 r}
    % e4 b. J- Y5 U* r0 V( J6 }% ytemplate<class ElemType, class WeightType>
    / M2 x/ B( v! T* o. `$ n. Wvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    & j, j/ h. [8 ^9 ~{
    & W% S2 ]% [$ o    if (vexNum == vexMaxNum)+ o3 z) Z+ k5 U, J/ Z( k; U
            throw Error("图的顶点数不能超过允许的最大数!");" m9 p; k' P& T) k) [# W
        vexTable[vexNum].data = d;
    , K6 T& }8 a; _. D1 Z6 m    vexTable[vexNum].firstarc = NULL;  K2 S( R: l' @% N0 q+ y0 h: O2 M; M8 U1 E
        tag[vexNum] = 0;/ b* e/ E# \5 V( ^" V
        vexNum++;
    7 o; ]* H+ n# u9 B7 W, k( J; a}! z9 `1 u* ~9 A; R% f
    template<class ElemType, class WeightType>
    ' `) Z# V. l+ _8 Q# rvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)6 X" O& I; x1 C) e9 R
    {
    . }% _  K3 w1 }+ A' V1 c4 H    MultiAdjListNetworkArc<WeightType>* p,*q;
    0 Q4 O6 G' d" ^! X    if (v1 < 0 || v1 >= vexNum)2 a3 M% }$ r5 @* S- J/ U
            throw Error("v1不合法!");
    & Y* T; {5 W3 t3 M$ Q: n) V    if (v2 < 0 || v2 >= vexNum)
    & a$ R% J  t" E( {! \! c" y        throw Error("v2不合法!");
    ' ~" }3 G* _/ z2 l3 l0 M    if (v1 == v2)& A* E6 m2 Y0 _/ ~) m2 Y
            throw Error("v1不能等于v2!");
      q/ G2 ~4 S  W7 k9 G! s3 f    if (w == infinity)
    ) ]/ ?5 F! X7 t        throw Error("w不能为无穷大!");/ L- g' W* |1 m2 ^  G0 _! m' P/ l

    % }$ ^  L3 Z! T8 K8 P, m) p: _6 v1 \4 @3 m
        p = vexTable[v1].firstarc;2 {8 T+ o0 A- d5 ^: }  |
        while(p)
    # k) \- w) b! q    {
    " z6 F9 C% l4 t: ]2 j- _4 l        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中, H; A6 Z( l' n! ~% u; Y: L
            {6 g; L) G0 [4 Y' N% d
                if(p->weight!=w)
    ; J! D; f$ K; L5 ~1 o! ~; W, \                p->weight=w;
    3 H! ~! X6 i1 M4 r            return;
    2 {6 e' [' F: u+ a        }
    " K( ^/ h6 }# M  b! w/ c' x& ]' A  y# Z% F
            p=NextArc(v1,p);8 w6 T; B- x3 B( n
        }
    ; Y8 A3 ?' l4 C, P    p = vexTable[v1].firstarc;
    - h* n4 E$ ?% o, m) n, J7 [  O9 }    q = vexTable[v2].firstarc;
    ! ]# A- d8 J2 K9 H+ x8 j    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    ' D" |- Z) X! ~: [  X. g    vexTable[v2].firstarc =vexTable[v1].firstarc;
    5 x* _5 H, m: z' |5 |5 e& w* o$ y0 o    arcNum++;
    1 x: T/ W  H# L1 j) Z$ N0 B7 T3 C}
    4 P4 H/ M( n, x/ p# q
    : p8 u* f* ?& z+ ~: {# O( {template<class ElemType, class WeightType>
    ) ], C4 ~& G$ u- w* D, D; Dvoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)3 r6 ?. M5 x) x5 e4 |: X0 _
    {; _  O: k! I0 n0 h8 E

    ! Z* `) M3 H4 r' X  ^# K. ?    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    / J' p. [- j: @1 q$ M$ i  c    if (v1 < 0 || v1 >= vexNum)" D1 ^9 p1 w: \) v+ ?: W" p+ A
            throw Error("v1不合法!");) n9 F( z: [8 u% F8 O/ B
        if (v2 < 0 || v2 >= vexNum)
    / r+ i" ]% [; ]/ l0 S: p. S        throw Error("v2不合法!");
    ' H" _: i+ M* }4 r$ s* N5 m    if (v1 == v2)7 z& w- E  H, s2 T+ `3 N
            throw Error("v1不能等于v2!");
    $ ~$ b; [. Z7 m# N, B2 }! G# m
      `6 F! L5 {; K4 p    p = vexTable[v1].firstarc;  p4 X6 ]3 |& ?2 |& q4 j
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)1 g" @: \1 V# d% }+ V
        {
    / O4 p; K! T( X5 ]) b        q = p;4 P  T& K% X) d' |% Y6 e# q3 ?5 h9 E9 M
            p = NextArc(v1,p);5 Y9 i* W' u0 {
        }//找到要删除的边结点p及其前一结点q; A' S2 S/ _5 `+ T0 C- ]0 q% Q& _' s

    6 T* J# c- p  ?5 Z    if (p != NULL)//找到v1-v2的边
    4 m: O; c  F1 J3 y1 h3 W! [    {9 g5 z6 z8 @$ Q' P- [* N7 R% D
            r=LastArc(v2,p);+ W% F. a& O( g; q/ q7 G
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL! g' w, c$ M: n! }2 A2 v0 k
                if(p->adjVex2==v2)3 w. t0 N7 y8 s7 R
                    vexTable[v1].firstarc = p->nextarc1;5 h2 H) j6 w% p$ }6 a# u5 g5 H4 c4 i
                else vexTable[v1].firstarc=p->nextarc2;
    3 A- T) u, \* s; H        else//不是第一条边
    ' u$ V$ G, E  i& k        {9 A1 U( Q, F8 T9 ~, P6 u
                if(q->adjVex1==v1)
    7 d0 u+ a- `2 a. r- A! q. w                q->nextarc1 = NextArc(v1,p);
    ' D3 q+ v) G' }            else  l! j  ]0 A0 A* _
                    q->nextarc2=NextArc(v1,p);: F. s4 C9 O' y9 |
    8 M% ~' d5 R8 e* j7 G6 A
            }  N) E  ^0 s3 U& n/ w
            if(r==NULL)
    9 U, j& s4 @" L- c            if(p->adjVex2==v2)
    ! U  z  ~$ u) u+ ]- t* L7 \* V                vexTable[v2].firstarc = p->nextarc2;
    6 l" r* l: W9 @' c            else vexTable[v2].firstarc=p->nextarc1;8 N: }. K9 B" h( X
            else
    # ^: u- @: {. e& Q5 V5 i        {% `# w! i4 b, T" S) Y8 R: v$ Q
                if(r->adjVex2==v2)+ W/ P3 C8 V( L8 ?
                    r->nextarc2 = NextArc(v2,p);
    ! v8 ~+ E! Q" L& c: y3 G1 ^. H0 ^            else0 a3 Q2 z6 L/ k# P+ z+ l
                    r->nextarc1=NextArc(v2,p);
    % p) _* S; ?- M        }
    . i* E- g( J3 M5 O; T        delete p;
    9 ~' \% C% E! q  I* c        arcNum--;
      S' E$ V" y4 D. m    }
    : b* O' ~' _! D7 k( D0 S
    ' w* ?9 p- y6 T# L3 w7 {! I}
    6 m" q, }! G! jtemplate<class ElemType, class WeightType> void
    1 G. [9 P1 Y$ a! tMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    4 U* H- m, M* d0 N  w1 Q( e{& E3 T9 @9 \- A1 H* y
        int v;$ w3 O! ?; G" W0 t3 \  n
        MultiAdjListNetworkArc<WeightType>* p;) A$ B% q+ v8 P: o* U
        for (v = 0; v < vexNum; v++)//找到d对应顶点( ?( `9 U1 }4 j4 V7 @& T
            if (vexTable[v].data == d)
    - \( {  c. }" E( n            break;
    $ P. Y0 |1 m0 k: ]9 X; |$ H& X, e    if(v==vexNum); x4 R, H4 v5 ]; U4 J
            throw Error("图中不存在要删除的顶点!");5 {/ V$ _) _3 H+ Z2 E, Z) t: o1 c) l
    & T/ P4 e% O8 C' O
        for (int u = 0; u < vexNum; u++)//删除与d相连的边
    9 [3 z9 n# N9 Z! e' m( T& G5 Q        if (u != v)
    ( j8 i) n* E, J, T        {
    * F  l0 ^9 U! b- q            DeleteArc(u, v);! |- [8 ^. W8 K% m" p" ?
            }
    5 A# d8 S/ d0 D4 w; G$ i/ D    vexTable[v].firstarc=NULL;2 R/ ]6 P, W- R+ j' [
    1 [: P6 l+ x+ z
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置- `- x5 t( {: d' c6 E: k
        vexTable[v].data = vexTable[vexNum].data;- X* {7 l( n+ Q% A+ D
        vexTable[v].firstarc = vexTable[vexNum].firstarc;1 N4 L' j' f( Y1 D" l  t
        vexTable[vexNum].firstarc = NULL;
    " d7 g! I; m, R  H  Y9 k1 J- Z$ l    tag[v] = tag[vexNum];) k# y/ v0 S) m! O" q* v3 I! q
        //原来与最后一个顶点相连的边改为与v相连
    1 |) b, L. T, e% T    for (int u = 0; u < vexNum; u++)- m9 @# B- c! P+ _& i2 B" |
        {/ d' \. F6 N" y- t
            if (u != v)! D. |- x; S* R# x( p+ B
            {$ ~# k" D; [: ^3 x$ H6 J7 r( V
                p = vexTable.firstarc;$ u$ |3 s: i& C8 D  Q9 v
                while (p)
    4 H  \9 _$ }3 p1 Y; r- [            {
    $ {; _1 S  Y3 v7 A                if (p->adjVex1==vexNum)4 Q( W  j6 Z7 {0 `8 j, x+ x4 `3 y
                        p->adjVex1= v;" o' h5 e0 P9 v( C- C) e
                    else if(p->adjVex2==vexNum)
    + r, ^7 k; P% R; S3 h+ c                    p->adjVex2=v;. h- [- [: Y8 A3 K* d
                    p = NextArc(u,p);. [6 b$ ?# m& r% a- {5 O* w" g2 [
                }
    : C: Z) f# ^$ d        }
    5 V1 D5 N* \5 ^9 V( x    }6 |- P# p6 Z2 z$ A
    }
    % A9 ~) ]7 K) n///深度优先遍历& U7 T6 _9 C" C
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)  s/ j; N7 }3 Q/ V3 P
    {
    - g& {1 D# }4 z6 b    tag[v]=1;
    $ _1 w8 I; c/ d5 S: o6 d' H    cout<<setw(3)<<vexTable[v].data;
    : u% v  y' d# d( w- K. }+ ]. q    MultiAdjListNetworkArc<WeightType> *p;
    ) N& i( U3 X2 c) G+ X3 }. j% @, q7 d    p=vexTable[v].firstarc;+ t) n2 g, O3 L: \" I# M
        while(p)
    8 k0 n# _- J8 ?" r- m    {7 S. W" Q' |6 K( i% s. _% M( g& z7 Q5 J
            if(tag[p->adjVex1]==0)
    3 `" m( m  T4 Z% x            DFS1(p->adjVex1);
    " n3 N3 w& y+ t; S5 N$ m! X        else if(tag[p->adjVex2]==0)
    2 `" I' L0 f9 D8 t$ H7 J% h1 P            DFS1(p->adjVex2);* j5 F, a4 R/ e' ~
            p=NextArc(v,p);
    7 o2 D8 x, N3 w3 L# U* e$ k* t  W5 {    }( {/ u& m* I; f# K# O  S
    }
    1 t2 N7 O- w% jtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    % i$ L7 V# d0 X" J! S{
    + S5 Z+ z7 Y9 H    for(int i=0; i<vexNum; i++)
    7 l5 s; S7 m: u+ k' d        tag=0;
    # `: ?$ e- t8 p' d& r1 a    for(int v=0; v<vexNum; v++)! |* H* P+ ?0 ]8 T
        {4 Q3 L7 a  T5 N) x
            if(tag[v]==0)
    3 u) {! u9 u0 B9 C/ x/ ?            DFS1(v);9 H! s, ^% Q1 v& s8 j
        }
    8 z! z  _( k& }; V7 ~. L}5 k. a3 Y7 d* X. s" A1 h
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()  t$ s- d9 a5 V9 x
    {
      q% t8 u  m* x; ]4 w    stack<int> s;
    4 o, M) [1 G* x% p+ g1 T' M4 i    int tmp;
    : z; u+ E+ p1 S    MultiAdjListNetworkArc<WeightType> *p,*q;& z- T2 c! n3 k1 z( Z( I) ~  n
        for(int i=0; i<vexNum; i++)
    % @, {' @+ ?$ }. R: I" s7 c9 x        tag=0;
    : J& |" Q! C$ I/ p4 v4 Z    for(int i=0; i<vexNum; i++)
    + S3 B' ?+ P& M. |    {
    / j' @8 P; V8 M0 n5 V& k        tmp=i;
    ) z& K( k4 ^" }/ [        while(tag[tmp]==0||!s.empty())
    - Y6 A% D! r. _3 @# r# o        {
    # |( ?5 T7 z. t5 Y+ Z            p=vexTable[tmp].firstarc;1 F* h  b: F4 A( R( M
                while(tag[tmp]==0)- ^* E4 w/ U' r1 D# n' i
                {$ b% |% p% C/ R4 U
                    s.push(tmp);( t: }5 b. \6 D% H
                    cout<<setw(3)<<vexTable[tmp].data;
    : J3 f; g+ j5 |) t2 C# b                tag[tmp]=1;  j6 D- I' ]& x2 ]6 A2 B
                    p=vexTable[tmp].firstarc;
      M+ k1 @) r0 H3 D$ P6 J                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
      l* m1 M% X: }$ ^6 d) l                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    - h. O. m4 p( s$ ?6 d7 b! S) q$ C                //cout<<" 1st     tmp="<<tmp<<endl;* R7 n$ T9 W: r: x; A! k4 ]
                }
    ' d; X6 y) |5 p            if(!s.empty())% a1 v9 |$ S: N
                {4 q! ^; b- j8 W) V: b3 [1 G
                    tmp=s.top();
    5 F  h& m8 F, j7 J' ?                s.pop();
    4 V$ S4 v4 \3 C( e) Q                q=vexTable[tmp].firstarc;8 q' c8 Q' O% W: \  |
                    int t=tmp;  d2 Q# p! @; s* H" M, [8 Z
                    while(q&&tag[tmp]!=0)
    ) y3 U4 ]* ~+ @                {
    " v" h9 i+ p* J7 ~                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    + M# F" V" U2 ?                    //cout<<" 2nd     tmp="<<tmp<<endl;
    , Q5 I1 q2 `# X! S  ?9 a8 K, t                    q=NextArc(t,q);
    0 M$ ~( S/ M1 A* x0 s) b$ |' J                }
    ; i( t$ K% O6 D/ I) P" {( C) t                if(tag[tmp]==0), ^+ g% I/ l, D' l
                        s.push(t);' W, C% j% A8 b$ r6 W- n
                    ///1、对应上面连通分支只有1个点的情况
    7 e2 j  U1 Z( b) ?6 N+ j                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    : ?" |6 j5 b- P1 K                ///tmp要么等于找到的第一个未访问节点,
    ! S' {! d. X6 s5 \                ///要么等于与t相连最后一个点(已被访问过)
    & o! D: t0 Y8 q, R+ N5 f* R                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点' M& `7 B0 C; ~" d
                }
    ' b: n1 o6 q; k) _# T: p        }* d: ]+ x; G( S( Z, I4 `
        }
    ) `6 \+ `. `6 L4 ]/ H8 @# Y}) i. x$ R9 z% D$ c/ g% z
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-19 }. o+ X1 ]2 t4 @1 N5 j
    template<class ElemType, class WeightType> int+ w2 R% d9 K2 y& N
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)% A+ Z' Z1 P# K2 Z7 |' I  f
    {
    6 e( K% }7 J7 G0 ~6 M. Y  S- q" g    if(head==pre)+ b4 u/ e- n; c8 s4 F
            return -1;
    * M$ F7 i0 D, E* o" P8 F6 J1 c
    $ J# y% ^7 W3 C. E6 k    MultiAdjListNetworkArc<WeightType> *p;
    & W  A! I& w. T! ^9 p6 v    p=vexTable[head].firstarc;% n1 }/ P: D- \
        if(pre==-1&&p!=NULL). v( @1 }3 f4 `( _
            return p->adjVex1==head?p->adjVex2:p->adjVex1;1 j7 E5 ^+ b& ?% o5 O  D5 x0 P
        //pre!=-1&&p!=NULL3 J# Q% i4 b: Y. K0 I
        while(p!=NULL)& I$ Y2 l" v, y. s8 w  f
        {3 q* B' _& a5 w1 o5 r4 r
            if(p->adjVex1==head && p->adjVex2!=pre)
    & W. A9 [3 z) q! p. u* w9 r            p=p->nextarc1;
    ' q8 A& q- Z0 S: O; ]  d1 s* |        else if(p->adjVex2==head && p->adjVex1!=pre)
    7 C9 {7 @- r8 Z            p=p->nextarc2;* i  v8 e! t/ A6 v
            else if(p->adjVex1==head && p->adjVex2==pre)  [* V2 e. |1 l8 w+ R- q6 d* Z
            {
    3 p/ \6 G$ ~; K& u: i            p=p->nextarc1;
    , m2 `1 b; r8 l( d            break;
    , i8 q8 \5 V3 M& B. }# t) S5 ?        }# z) M: e2 I5 l  n# Y) e+ \
            else if(p->adjVex2==head && p->adjVex1==pre)
    - N' K( I, d& N0 v8 W% |: j: @        {
    " Q0 w+ P; W4 \7 Y            p=p->nextarc2;( |9 A6 L/ L1 C+ \, X% ~
                break;
    + b$ S: B; ?' W# Y/ ^0 A, @* b0 h        }
    9 k* v5 c( G$ p+ s" E: b: [3 v    }5 w* V+ k; A8 Y$ _9 V( }
        if(p!=NULL)- F+ m2 `# f: J* b
        {! Y7 T+ F2 q. J
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    ( Z- p, T9 a' }    }) z6 l1 \: g9 e8 J) M
        else. l+ i( P1 c& `+ \& ]0 b& D1 y
            return -1;8 @( Q# J1 ~8 i2 v/ _% [7 w1 }
    }
    ; \% L, d5 t, ]/ h  A
    ) o* A) X* ]1 W( d+ p0 o1 l1 x8 {: e
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()/ \8 F! w- {. e, K  n
    {
    0 s; ]$ j. }  G* c9 P% U    stack<int> s;
    . x* S+ D. \: X    int p,cur,pre;4 C: @3 r3 A0 y& ^5 ]4 ]5 }8 l
        //MultiAdjListNetworkArc<WeightType> *p,*q;2 F( i! ]( d  x5 w$ \5 M! ?
        for(int i=0; i<vexNum; i++) tag=0;//初始化9 e  g9 L6 J8 S6 C  T+ a" y

    ( A0 }+ E+ x2 s1 F$ e/ Q    for(int i=0; i<vexNum; i++)3 |6 ?0 ~5 d1 _2 ]( }8 z5 E
        {, O0 G5 Z7 z0 {* s2 {5 m0 K
            cur=i;pre=-1;
    - ~7 B% M" Q, ^3 D% h        while(tag[cur]==0||!s.empty())
    % u5 E, r; J9 W8 N        {
    + Y- i- N5 s& r- Z9 P1 p0 M% y            while(tag[cur]==0)
    9 e  ~$ X2 d. P; g  r            {
    + m6 E8 A  s" D7 ~# L4 v1 _' j                cout<<vexTable[cur].data<<"  ";
    ! V9 s5 |+ `- M9 m                s.push(cur);1 A$ f# b" F: `9 h- I
                    tag[cur]=1;
    - U! ~6 C; g2 _5 a5 k  v               //初次访问,标记入栈2 c& u. M" @! s5 s8 S5 l- ~

    , f: E5 Q8 ^& r               p=GetAdjVex(cur,pre);//p是cur的连通顶点
    . }! d# C& F" ?1 G               if(p==-1)
    . w. T! |- D' d. `+ ]- O! e               {
    9 d2 k4 F9 F" k* ^+ f3 H                   pre=cur;s.pop();
    - l" ]# k' g2 O/ t" \* Z                   break;
    ! k4 I4 C  F- [5 B               }
    / R3 ^; c, I# S$ U1 D% N1 M3 e% H               else
    1 k% X% n* J0 Y! `! }6 ~               {. o# e: U# O6 ~$ i
                       pre=cur;
    ! M1 P0 B0 y3 T6 d                   cur=p;& \3 g) A4 D8 A
                   }
    ' Y/ C. K+ B; \4 L8 n% ?! y
    * [. R! W5 z- X( Q$ C! Z. S+ X. @            }
    . K) h1 G% A- e6 }: e  o            while(!s.empty())
    # w  l, O" [8 O: {            {
    1 I4 ~6 K5 m: H. ?0 c                cur=s.top();
    ) [  f3 |, u! G5 C; o                p=GetAdjVex(cur,pre);
    1 n3 J/ @, s/ l) k- D9 g                if(tag[p]==0)# `5 J5 w% }- X2 s& _% L4 m
                    {
    $ X. j0 p& F6 w0 G: w: G7 C                    pre=cur;
    . \# _2 ^. X# Z                    cur=p;& x) n+ x1 v0 t) q( C9 J) I6 A
                        break;
    3 P0 Z5 ]  I% d) f- s  i. Q                }' Z* K; z8 q7 p% D
                    else
    7 n$ A% u7 R0 ]                {
    0 J5 i: V0 P, U7 K* u/ \2 L                    pre=s.top();
    ! T+ E8 o3 [  i" J; r                    s.pop();7 l  K7 Y% W0 N8 N/ \5 S# r3 [
                    }& n/ M4 l" X! Y, z7 i3 O  B" e
    3 V3 C+ q7 H/ c
                }1 q3 M8 h' P! A  e* R  x4 B
    0 h. p6 Z* s7 O* D( Z
            }
    * ]6 p1 r$ |' d# p    }
    # Q* N/ B7 O' k& l5 z8 b}% W: E" {" K( ^3 k. M! ^( \$ k
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    - r( |2 f6 C' I' s{
    7 E2 r4 {; P1 T# u. u6 `* z& [    for(int i=0; i<vexNum; i++)* v6 P  e: T# P& E! T
            tag=0;
    ( }. J# e5 d1 ]( C$ p    queue<int> q;
    % a* q. h0 I4 T7 C' p. e    int tmp,t;
    / |+ ~" f: R) D6 J+ e/ n    MultiAdjListNetworkArc<WeightType> *p;: w2 o+ x9 B- ~0 |* E! g
        for(int i=0; i<vexNum; i++): T- n% K6 i2 D0 |* u
        {
    0 j( h& M, o' ~- E& K2 @) ?        if(tag==0)
    & m2 E0 f, _2 e6 Z7 `        {
    0 Q8 K+ B% b% A' {0 ^5 \2 I) c            tag=1;8 Y! f  j. Y0 n8 S2 K$ i
                q.push(i);
    2 m7 r3 C: w, U$ f( j  S            cout<<setw(3)<<vexTable.data;
    : c1 Z+ B$ P2 N4 g% P        }
    ' {9 U: b- l" z4 E        while(!q.empty())% y) @$ }8 V7 B: v& d' k
            {- Q( D+ N6 b) |+ s, N0 r9 ?) n2 |
                tmp=q.front();
      h/ G2 G. Z0 e7 |            q.pop();/ t7 {/ c2 |" y- }. ]4 {  r2 u5 b
                p=vexTable[tmp].firstarc;7 S- D. X* @3 d
                while(p!=NULL)1 G, c8 I2 b' M, h
                {
    , h) ?' r. [8 B$ y) P3 D/ _- }                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);- x* v% y7 U3 n
                    if(tag[t]==0)
    * j- O7 ~6 ^- J0 ^5 U( ^# |- n                {
    2 a6 t: L5 X3 ?% W                    cout<<setw(3)<<vexTable[t].data;4 m3 A' r# ^% f; ?
                        tag[t]=1;# a! m$ r9 S. P! v* U% X* Y1 O
                        q.push(t);6 Z6 ~" s0 k  @' o  R& e0 x: f
                    }/ \- h, f5 {6 x0 ]9 S) B
                    p=NextArc(tmp,p);
    ' u/ {* Z* P6 S7 y! r+ m2 @& x            }
    1 w2 A: d- ^5 C7 `        }4 g3 ^# x: N$ z* Q; @  f5 c6 q0 ], F( v
        }& w4 j+ g" B0 O" w/ N8 C$ U& c
    }4 S9 o; S. H) ^8 W
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    ' x6 _" m/ @% f/ {{+ m/ \# j' D0 [, ~2 B2 y" U& ]! T8 d
        MultiAdjListNetworkArc<WeightType> *p;# Y2 Q. F; G0 w' p
        cout << "无向图有" << vexNum << "个点,分别为:";
    1 c. |; j' f0 m8 q: b, g    for (int i = 0; i < vexNum; i++)3 j0 T) k+ S8 ]2 }! s
            cout << vexTable.data << " ";
    . ^9 Q. k# {/ G1 {    cout << endl;8 K. M+ M/ ^7 H; t' W
        cout << "无向图有" << arcNum << "条边"<<endl;5 S# U9 H( @& v" L! F% C2 f6 g
        for (int i = 0; i < vexNum; i++)
    ( _; d0 D/ g( l9 C/ L    {
    $ ], X' N( S" N" C/ L: K% c6 S        cout<<"和" << vexTable.data << "有关的边:";
    ! D0 B) D; h! G7 b6 c) i, }; g- [        p = vexTable.firstarc;; F1 V5 O% i, ~
            while (p != NULL)7 E' @% n0 z. i% \
            {, I+ Q6 X* X- I; R1 {
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    : |$ }- ?$ d1 T% N& W& g            p=NextArc(i,p);
    9 M6 m' r* h6 `6 j, M; v/ ^9 Y4 b        }
    - ?3 N' u; P0 C: i        cout << endl;0 `( F6 e; j& x2 F- Y; o/ c5 }
        }
    . V0 z( M* I& d' H+ e  v8 e}6 Q$ C, v- j# B* y. ]9 Y) o8 ]
    - M' s- y- W* S# q* b6 v7 x* x3 g) F
    ' s" {: c4 V" z# f3 l9 D1 O
    邻接多重表与邻接表的对比
    & K( j! t9 I# o  \( P9 O  j) ^& e
    ) a4 V1 z" _" Y- y邻接表链接- v8 D5 [- E* Y0 K
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。& |1 t8 Q: M: K. k1 R( w
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    3 J) N5 O3 U' g" e为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。" |& {; R" o7 h. m/ F4 {9 _8 O
    ————————————————
    $ q0 i+ v; V1 e8 W3 x8 p6 Y1 ?版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ' n( D4 l, O' V" D* K原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    & s) [5 e+ s( x5 y& s4 i& D
    / T) b* l# O5 Y) n/ |' s( H4 a# ?* F' y6 P8 v

    7 N! z( z5 [$ I% E0 _: X0 A
    1 V9 [' {+ f2 f! b0 q, e& R————————————————
    2 k+ O! p& M& E7 n# W版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。9 L- y( l: F! Y8 e# q: F
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958. }9 {; k" V$ B" d  X8 T# A2 s& J

      _" P! A( b  E6 T8 Q5 R, ?! u  t" O; a. x
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-1-3 17:10 , Processed in 0.532458 second(s), 54 queries .

    回顶部