QQ登录

只需要一步,快速开始

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

    " G% p) q, E2 j/ b3 z图的存储结构——邻接多重表(多重邻接表)的实现2 `  E; W2 @& F# @/ N
    7.2 图的存储结构2 P- N4 v: W% B. H$ _8 ]6 F# @5 ]

    ! I! a2 T6 A" c( V& h) q7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    , r/ X$ H, ^9 H2 }0 A0 s7 Q邻接多重表的类定义4 j8 v' n$ ]. T' ]0 P, W
    邻接多重表的顶点结点类模板- f, T) v1 Q8 {) A3 ?
    邻接多重表的边结点类模板
      z5 |. W6 t3 V3 ?邻接多重表的类模板# \; W; U" J9 T6 @& t5 m
    邻接多重表与邻接表的对比
    ! |* ]: \+ C& x6 c$ k  S7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    - j+ {# [2 V. C
    $ O% }5 H, z- D* T( i4 R3 r) ?( ~在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。+ ^6 v$ W; z1 I# F7 X
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。* [  w/ x8 k3 {2 z5 J

    , Z0 i; }7 W4 q5 A  g- W  Z8 i% e( p邻接多重表的类定义
    8 O' V5 ]# x$ l4 e" w& R; K 1.png ; E' m% S3 X  A% E2 `
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:: w- o4 L, N* k0 i. V# y5 O
    data域存储有关顶点的信息;$ p3 v; x3 |  u7 x% i* `
    firstarc域是链接指针,指向第一条依附于该顶点的边。
    / F, \  J* D- L9 n3 y所有的顶点结点组成一个顺序表。


    : J% V: \$ H8 [$ ~7 _! E0 z
    . g3 C% G/ _: D+ H  o# G5 |7 T; L9 Ztemplate <class ElemType ,class WeightType>
    # [+ K  H5 t4 W1 oclass MultiAdjListNetworkVex
    ) f1 Z! ]: T. j4 l# j( Z: T{
    3 E, Z& c3 C( V( }public:1 w% j6 g' G4 ]" L9 p+ ^
            ElemType data;
    % t7 W; p+ ]( G3 w  ~        MultiAdjListNetworkArc<WeightType> *firstarc;9 b) v( R. K9 w( a) w
    9 ~  B% Y) t, b9 u+ F
            MultiAdjListNetworkVex()
    / \5 u& Q; H7 S. a, i/ A        {
    ' I  k) k1 V2 ^1 N7 p9 u                firstarc = NULL;4 C3 R2 ^/ |7 n, p6 T
            }
      v+ }& Z6 H& R/ l3 ^        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)( {6 H0 L' l5 k& x! v$ N
            {! x, Q# _0 X$ S  o' r
                    data = val;9 R4 H! H5 s7 N5 P3 n- _
                    firstarc = adj;' }4 Y) I: k+ u/ n
            }
    4 v) r: c2 C8 V8 @" |. V9 g4 L};5 L2 u/ U. P: X8 z

    * ~% K8 v8 c- W# B+ b邻接多重表的边结点类模板
    , U7 h8 [) E* g( z$ e  L7 k; N2 r2 w5 l8 e
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    8 k+ P& B: l. l* utag是标记域,标记该边是否被处理或被搜索过;9 W: b) V7 q" h" ]# a3 j& O& m/ \
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    ; O. t! K9 s" z7 Y* Qnextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;. V, d+ B  ~( i! [3 k: k& x7 k
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    & y5 p5 P- g) ^$ J; f2 a3 b3 _
    1 H: c$ h1 f& l6 Q( ^% D 2.png
    4 R4 P/ Q/ h$ |: {template <class WeightType>. B; L9 V# B: K& {9 _" e/ Q2 L
    class MultiAdjListNetworkArc$ O* c% R; W) c
    {
    ; x1 a4 L" _+ ]2 M* Ppublic:% @0 S2 w' q9 ^, i* Q7 `; @6 r
        int mark;                                       //标记该边是否被搜索或处理过
    ( ^; I4 q  K3 N: }$ t        WeightType weight;                              //边的权重7 o/ r( G. S" x/ s" ^- C: i
            int adjVex1;                                    //边的一个顶点
    " A. x; n( r' d        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    5 m5 A. u( U; l; y7 e( C( V        int adjVex2;
    # W) `; q1 m; |8 I% H9 T        MultiAdjListNetworkArc<WeightType>* nextarc2;
    5 x7 i, m4 |1 A0 @' U9 u. S( E& l+ A1 d
            MultiAdjListNetworkArc()
    . G0 P+ \5 E6 [6 v+ Y3 j+ S        {( I  |5 H& S) Q! @* h
                    adjVex1= -1;  X5 ]) E+ B0 u/ d, r6 l. a
                    adjVex2= -1;
    6 V; W# e; G( O# g; ^. \8 {        }
    - F% f, w* N7 d6 V4 ?' T        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)- y8 U6 |- e) B4 d
            {- }, n! u0 T- @  g" }) a
                    adjVex1 = v1;       adjVex2 = v2;) _( f* m, k. X2 i0 V/ m. t
                    weight = w;
    4 V" [, y' T" D- p  j5 f( ^/ p                nextarc1 = next1;   nextarc2=next2;
    - k6 V. {7 @/ T0 ~4 h7 z0 V+ s                mark = 0;           //0表示未被搜索,1表示被搜索过
    & i' K' y; M7 r# o7 C        }( ^! S* T$ i  L$ z, w5 g
    0 \% D7 P0 K5 _# B/ _- D( a, q
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    . R8 b2 x: R+ ]8 c# g9 Jclass MultiAdjListNetwork
    " I" N; G$ F; n: z6 ?$ p- l{" N( W! k% d  ^# ~2 c4 S
    protected:" k. |4 o( T2 f5 C/ |6 Q2 E
        int vexNum, vexMaxNum, arcNum;  q' ^* _' C3 o- u8 \' v
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;5 {4 H) z- s) ]9 r) @
        int* tag;
    7 l0 |4 {' t" j    WeightType infinity;- ?+ W3 A( a7 [9 {* @! Y

    6 Q+ \7 w% M5 Y' tpublic:& {- q: b: ]9 c" ?/ s: A: x
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);/ o4 }9 V/ O, W' Y0 M- d) m
    8 d5 [  ^2 O5 u! h. f
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    : C, b' I2 K# v8 m
    ; w5 c) b. ^1 s: N+ r' z    void Clear();* r( {) G& ^1 d- h9 D" t; Q
        bool IsEmpty()$ s9 T; O! j, x' {! @  C
        {
    ! B8 @6 u. R" [: p5 i& |        return vexNum == 0;
    6 U6 Q1 O' N, K* F0 M    }
    ) h( r4 F" A/ B- K0 [. b    int GetArcNum()const5 c  X1 E; f* j9 W
        {2 U. Q0 P! L: J/ N+ q. `
            return arcNum;! c( w) D5 B$ c% D8 r
        }7 v6 C0 u" Q( Q% B; }
        int GetvexNum()const
    * g8 ?: d' Q: Q" j& Y    {
    8 `4 N% C3 O/ f& U1 S        return vexNum;5 _. z* B  N; G3 k$ F3 ]
        }4 D8 w. I# J$ P! s1 L
    # E! E- S* g, y- ]/ ^0 X& @
    + l2 m& e) ?3 D2 |
        int FirstAdjVex(int v)const;
    8 W4 z. l/ I0 N    int NextAdjVex(int v1, int v2)const;* B4 r' {, O6 D
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;& d& J. p% `7 z' f& r/ ?2 r
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    $ s- ^* D9 K8 f2 T5 }
    ' H0 D; \/ x7 ~' A7 S    void InsertVex(const ElemType& d);
    0 P% A$ l* K1 P/ Y" V    void InsertArc(int v1, int v2, WeightType w);- f3 ^' l. B9 t; `- L4 j

    ! t2 L% o$ m5 ^    void DeleteVex(const ElemType& d);
    % x1 T8 Q7 c+ h6 S# J    void DeleteArc(int v1, int v2);: B, m, Q5 f1 U2 B! G
    " k' u9 e5 L* m; ]( t
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    ! T, p- {6 A" E4 Q" L0 H; s2 G0 N    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);: H2 w9 D, w) e' x

    * }2 A+ U( g; t$ x5 C    ///深度优先遍历/ _, ~0 {/ K9 s& v0 ?( i7 P; _+ e
        void DFS1(const int v);
    / t, g7 V1 l: u, V" N' ?9 b" N    void DFS1Traverse();
    * u& i! v  K% \) [    void DFS2();) ^/ E* a9 J' t" T1 G8 p
    ( H2 p! v3 V5 A* B
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-15 o$ z6 r$ a) N) o7 ~1 S
        void DFS3();9 s9 C! G& V' G( Y

    " B+ `( N( C" `1 _( w* m7 S7 V" a" i    void BFS();* k+ c# u2 p+ }! P& {3 v# g% p1 Q
        void Show();
    ' r" @* E6 B: G, R6 r) g};  [' Q! S  e7 b; j
    ) r' k- K7 O8 |: L# ~. x3 K/ ~
    2.函数的实现
    & Z- P+ S+ F# p) k研讨题,能够运行,但是代码不一定是最优的。* F  S5 y" [6 y% {
    ' t5 b, {/ y! S, J
    #include <stack>
    * \+ n4 J) m1 @4 ]" c3 U& M4 Q; a#include <queue>
    * A+ E6 U8 W1 g: v" O. v8 A7 u! K' h+ I% {9 x& I$ w9 P6 W, T1 x
    template <class ElemType,class WeightType>
    8 q3 U0 J5 Z3 k& D" sMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
      }3 Q1 M2 G0 H  v* b! w{" y. k( @1 w0 q" o' i; g
        if(vertexMaxNum < 0)4 Z0 a9 }8 N; G" i
            throw Error("允许的顶点最大数目不能为负!");
    - s7 s' C0 n# M7 [/ F9 e( _    if (vertexMaxNum < vertexNum)
    " I+ q% O4 q/ F" Z9 i. L        throw Error("顶点数目不能大于允许的顶点最大数目!");( S; J% j* D  g6 ^) r& y) A
        vexNum = vertexNum;
      M! c7 `2 Y* t6 o9 g/ i% w    vexMaxNum = vertexMaxNum;
    1 V' _" ^4 o$ Z" K. g    arcNum = 0;
    8 s2 f  l  h0 k  s: F    infinity = infinit;
    % S# R7 j) K! Y3 l- i' J9 k    tag = new int[vexMaxNum];
    . A5 w" S% u: F$ E: o    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    ( i. L- W$ C( g  \7 A- K    for (int v = 0; v < vexNum; v++)
    * S0 i( M* i9 O, p' ]    {
    9 q& Z% l" U9 W& J0 R0 h' g: H# i        tag[v] = 0;- p/ T* h) Y, y( V
            vexTable[v].data = es[v];
    $ m8 z- G3 {6 H/ m5 a5 ]9 |3 p        vexTable[v].firstarc = NULL;: T$ F! Y  D+ H# ]
        }
      o) ?2 f; t) i) Q; A. _2 u, C; L8 R}
    ; @$ U1 O+ v3 Gtemplate <class ElemType,class WeightType>
    * p) i2 x2 |% k6 X2 I# L5 iMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    7 Y# K6 E8 ?* d. i3 H( |( f  s{
    6 j1 _( w7 q6 U2 d' c$ e    if (vertexMaxNum < 0)
    : @' I: n; P! N; D: Y4 e        throw Error("允许的顶点最大数目不能为负!");  Q6 [8 v$ d# @: ]: j$ u3 y
        vexNum = 0;
    3 K0 I7 V$ q; K  p: E+ _9 w. x    vexMaxNum = vertexMaxNum;7 E( X7 j+ F5 _6 W/ G3 i
        arcNum = 0;; k9 g; P& S% M" t& J2 S
        infinity = infinit;0 L8 o0 O. X* X9 B$ s
        tag = new int[vexMaxNum];' m" D" t$ p" @: }) A8 i
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    ! a7 ~9 H. T- f- C. D}
    ) r) s6 _! U$ Atemplate<class ElemType, class WeightType>9 }, o0 Y& P  B7 c' A
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const2 y3 t/ R& B# b' c0 o3 z6 n, v7 I9 P+ f
    {
    $ ^" c! |4 c/ e" a" L  ~$ b    if (v < 0 || v >= vexNum)
    ! h) d: H  G: d- F3 E5 a5 ~* V        throw Error("v不合法!");
    # M/ d! u( n9 _! Z1 [) o" s    if (vexTable[v].firstarc == NULL)7 c* v) L/ |; v( ~3 d5 _8 O, e
            return -1;
    * j4 K, y+ k- T0 J3 S* n1 X/ t* Q' y/ M- x    else
    ' `6 w1 v& ~3 \        return vexTable[v].firstarc->adjVex1;
    3 Q0 Q" x! v, L2 {+ Y( T}  p( F# C) W4 m

    - r7 k0 k. g; ]9 c) ntemplate<class ElemType, class WeightType>: }1 q" m. y+ j! B$ q
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    , m% j7 F( i8 C{
    4 L5 v# j. J3 ?# H7 |' u& J    MultiAdjListNetworkArc<WeightType>* p;- F% d7 Z& t( V3 r# i
        if (v1 < 0 || v1 >= vexNum)% P6 m2 r: e' d# l" s: j
            throw Error("v1不合法!");
    1 e+ ~( L0 Y& S- L# i9 `4 r% {" {! Z    if (v2 < 0 || v2 >= vexNum)
    4 D. y# z2 T7 i        throw Error("v2不合法!");
    + M% O* g4 @9 [2 t    if (v1 == v2)
    * f% b6 T3 C6 a/ q1 Z2 }2 V+ G        throw Error("v1不能等于v2!");
    / G7 ^1 T' R! e3 I) o6 x. l& |    p = vexTable[v1].firstarc;1 B" _! C8 F/ q' `( n
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    ! {. O$ Z0 z+ d, T( k$ t+ O2 U        p = p->nextarc;
    # |! I( Y5 H& f" a* w    if (p == NULL || p->nextarc == NULL)- W( c0 w0 p" V& v% Y' Q9 G1 g
            return -1;  //不存在下一个邻接点
    % \6 B$ W! D& Y' L7 I7 o2 V    else if(p->adjVex1==v2)0 [9 }" Y8 _7 q
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);8 o4 ?# ~$ ~! i8 F
        else, x9 O9 M8 D: t( z# h) Y- b3 ?
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    $ }3 J) Z" }# T; J}. k. f" s0 w8 F# `6 f6 }* e$ R$ A
    template<class ElemType, class WeightType>6 @' N) m1 K8 A
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()
    7 W; G1 p; I3 G4 z/ Q{
    ( _6 J' F+ e* V2 {4 I# F$ ~( q    if (IsEmpty()) return;9 [- _7 O9 b* b+ Q" ?0 V" g
        int n = vexNum;
    : k0 }( J: v: M6 _7 f- ]    for (int u = 0; u < n ; u++)( |6 j' n; m1 S7 T. ^
            DeleteVex(vexTable[0].data);' E& @- ~5 K# E, v% c& L
        return;0 |) o( j' Q8 a8 `& C8 k4 f% g
    }5 z( i$ k: o8 o: R6 e' W3 p4 C
    template<class ElemType, class WeightType>' N) `4 ^8 f% ~5 ]2 [  n
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    * d- ]+ B. [) S* j: ^{1 g+ x8 M7 x$ I. p$ p
        Clear();
    # d0 L! o. _0 x& ~0 O. l}
    7 i+ {& J$ c7 M( atemplate<class ElemType, class WeightType>
    / s! d4 X6 E, J: e3 ?7 r" }7 NMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    & I) C7 `( `" |" z" W# X{* [% V: f- m" j, m7 y& p; g
        vexMaxNum = copy.vexMaxNum;( _/ O, ]- M9 b5 q0 f( N
        vexNum = copy.vexNum;
    1 ]1 {1 s- E# S0 U& q% }0 g5 c    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];2 J; a. T. ~8 ^5 c+ \' a
        arcNum = 0;
    / Q2 I% f% Z: {2 f$ c    infinity = copy.infinity;
    ' ~! x# e" [- X    tag = new int[vexMaxNum];6 X: s; U8 _: ~, D( J" i

    7 X2 w  {* f1 P0 {1 g6 K    for (int v = 0; v < vexNum; v++)4 ]8 \' A+ Y& [/ S& a
        {+ L. j, d8 i' y7 }/ ^6 H" z2 D
            tag[v] = 0;- u5 I. ^  A) Z9 d6 t0 c* s
            vexTable[v].data = copy.vexTable[v].data;3 ^4 H; T$ J8 e& o5 F; g
            vexTable[v].firstarc = NULL;
    ; G  F4 _  D/ ?0 I  u5 ?* J; ]4 [    }% J% G( k" p9 d  s, E# c
        MultiAdjListNetworkArc<WeightType>* p;
    : Z2 M% `4 S5 B0 b2 R2 A9 x9 I2 a4 x% S' f3 y2 q' z% l
        for (int u = 0; u < vexNum; u++)/ q2 `. \" |& z4 h- ?/ S8 \" Y$ |2 ?
        {
    * [' V: u+ F8 X& `7 g; D6 R        p = copy.vexTable.firstarc;
    1 n; K3 q% b9 K8 J: F; D! E        while (p != NULL)2 B2 _7 [% ]7 b# t( P$ L6 S
            {
    $ A! [) Q+ v& v5 E+ z! {3 }            InsertArc(p->adjVex1, p->adjVex2, p->weight);7 g, G7 C) w" D. t& y4 ]# z$ r
                p=NextArc(u,p);
    # s; C5 }5 u) b4 g' N        }
      Z# b0 g) f) r: ]* ^    }
      x: @5 Z; i7 C! p) l}
    * ^2 W. B. P1 R: b2 utemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    7 }1 ^# f; ~/ L! ?MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)2 W( ~6 ]" s8 @! l' ?' G
    {
    ( ^& o8 x# q6 M! y: w4 T    if (this == &copy) return *this;
    " B" Z: V* Z: s( X9 x    Clear();
    6 U, N. l2 K2 M! d+ B0 Z, I    vexMaxNum = copy.vexMaxNum;
    - E8 ?" V: H* A' _) W8 U    vexNum = copy.vexNum;! M8 l: `/ _& |$ G" u7 {+ |, J
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];1 D7 @$ ?* [$ {( M4 o1 y
        arcNum = 0;
    $ a) J7 M; X3 q) I3 m    infinity = copy.infinity;/ w! N, E1 [4 f0 t
        tag = new int[vexMaxNum];
    3 @( Q* i- i6 `* j4 z
    ( a% l# o, w, E    for (int v = 0; v < vexNum; v++)6 N* ?9 \' C8 n2 K1 k9 ]6 g
        {! ]  m- v' m: f: o' Z
            tag[v] = 0;8 m! v; b# a1 Q; L5 |# U3 I
            vexTable[v].data = copy.vexTable[v].data;
    9 ~: |4 b0 K7 P# P$ i        vexTable[v].firstarc = NULL;
    8 x" i1 E6 E; J5 C! g  w    }
    - R' l/ v1 Y3 `0 W, z  d3 K% v- k    MultiAdjListNetworkArc<WeightType>* p;' f: b, N: n: n

    / |3 v: G  o0 ]* J+ Q3 M/ z    for (int u = 0; u < vexNum; u++)
    : J0 D. b1 i' P7 h7 v/ C    {
    + D4 l) M/ Q6 A" ]. l' w        p = copy.vexTable.firstarc;
    - z: S! S4 Q. b+ u. k        while (p != NULL)1 Y' ^6 A3 c" I' q0 @' o% O0 l
            {
    ' R: T1 k$ I0 q( I            InsertArc(p->adjVex1, p->adjVex2, p->weight);9 U3 K! \. S9 O. B; f% w& ], N
                p=NextArc(u,p);
    $ Y) P9 L' L* c        }+ Q& A  o6 }. N7 V; S* j& S8 |3 h
        }7 m( I, L' v0 O2 u# _
        return *this;
    $ x2 I, W4 H- |}
    + t# j$ `0 P  htemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*& k) Q+ C5 C" R' H  [2 ?/ F/ H
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    $ j1 _! i8 m+ Z+ t$ G{' M) ]; l2 f8 q1 `3 _* L( z( `
        if(p==NULL) return NULL;9 E+ P! F* m$ P  n- _7 [+ W  M0 i
        if(p->adjVex1==v1)
    7 q3 j( l8 O1 R        return p->nextarc1;3 {# G) O0 o# v0 n% s
        else1 {5 R6 ]  w( F- _$ U/ Q* D
            return p->nextarc2;3 n3 o1 x6 @8 d2 X4 `' V) [
    }
    2 J. F2 n* b$ k. e  `% xtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*" ]2 k; ]8 h+ |( \, J9 {6 L) i  d
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    4 T6 B) h. O# D{% K  v. x. W# K6 h# o
        if(p==NULL)return NULL;
    7 M6 ^2 P: Z1 A9 {& P; f    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;; X1 Z( @: ?( O( w- ~
        if(q==p)
    ' ?# P0 i5 z3 z3 X& j% a4 ~        return NULL;% M$ D6 R1 ]' |$ C# p) J
        while(q)" w4 t, R' ]) b# @) B! G/ a
        {* h. V* ~& o# S3 s' X0 s
            if(q->nextarc1==p ||q->nextarc2==p)
    ; i& d3 c$ _4 t  R' x& Z9 ?            break;- F; X$ O" k7 T" J, N4 E1 T) V7 M1 Y. d
            q=NextArc(v1,q);
    $ b) g3 C& d9 _- b2 A    }
    4 S& Z8 U/ i5 V% w5 K# u    return q;: D* t& j; S: E# X
    }6 e( K0 \% P* x+ i
    template<class ElemType, class WeightType>
    ' s9 v+ l8 J* Dvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    % Z8 P/ v1 u9 N0 C{
    * m; `6 J% v  U2 [    if (vexNum == vexMaxNum)
      N' G; b5 d; f! [+ q        throw Error("图的顶点数不能超过允许的最大数!");
    $ |; B+ v" P# _    vexTable[vexNum].data = d;
    7 [! ^" }. R# {9 Q$ s  ^: R7 h- ~    vexTable[vexNum].firstarc = NULL;
    4 @( h6 I! r* J. E    tag[vexNum] = 0;
    8 t% ]1 P* d5 n& A9 F    vexNum++;
      X5 q% b1 @8 [0 N6 R}! ]0 c; i  @& O! T, ?5 ?: r
    template<class ElemType, class WeightType>
    : y6 o8 q, e9 x4 |& m! tvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)8 j* {) c/ f% K/ p) Y& c
    {7 S/ z" w$ H1 T/ t2 v( s7 |% a
        MultiAdjListNetworkArc<WeightType>* p,*q;+ V* D4 Y5 J5 W+ Z/ y
        if (v1 < 0 || v1 >= vexNum). o: \" Q1 p; N2 E) t  E% ?
            throw Error("v1不合法!");4 `6 s1 [5 H6 I$ D
        if (v2 < 0 || v2 >= vexNum)+ x1 H2 y. ?- C
            throw Error("v2不合法!");
    0 `7 P) [' u: b" l0 J    if (v1 == v2)
    0 f6 P0 e9 U* f: v2 i        throw Error("v1不能等于v2!");
    / e, b$ [1 x0 a" P$ n# d; |1 m8 K. F    if (w == infinity)5 K; `/ \3 D$ M9 N( n. G0 R
            throw Error("w不能为无穷大!");
    $ b6 U) y9 T( b; n6 E6 J7 W% u; }! e: e% O7 h# L, \
    , v  j9 s7 ]  ~( v1 _  m
        p = vexTable[v1].firstarc;
    . ~# x$ {) a# U    while(p)1 {4 O8 E$ `& ]- ?- Y; c
        {
    1 }! H* o1 k. S! a9 {, O        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中2 g, E7 @' k1 j) a( Y6 b
            {
    2 X; ~3 N; Q4 k: I            if(p->weight!=w)) \0 ~2 U7 J1 }. j, c: Z. ?
                    p->weight=w;- p2 I1 j0 M# y
                return;5 f" o5 ?5 P2 L* Z& B
            }
    6 q( Q. W4 H: y6 G0 S0 C2 R/ q( f' Y; d. g* ~; N
            p=NextArc(v1,p);
    * P6 F0 e4 T. O- m2 M    }* _; @: E. Y6 Z  y3 h7 d: @7 J6 v
        p = vexTable[v1].firstarc;& p* Z  o; k( u7 B
        q = vexTable[v2].firstarc;" m# P4 Y4 o3 D7 u0 {! ~* y7 g
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    , ~- B/ b6 [) g8 r    vexTable[v2].firstarc =vexTable[v1].firstarc;; e, i9 ?% F- n* G" |' t
        arcNum++;0 e6 [9 ?; [7 T& A% ^6 V
    }
    ; N. y2 n7 M' ]% e5 _# E5 A4 z. ^% Q& s- R3 v
    template<class ElemType, class WeightType>
    8 m/ @2 q7 S4 ^; q* Fvoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)2 W( ]0 N9 J5 Q/ w
    {8 D. B3 l, k/ B7 m

    # q2 |* M2 s5 b    MultiAdjListNetworkArc<WeightType>* p, * q,*r;- e3 ^4 \) T5 ^2 j
        if (v1 < 0 || v1 >= vexNum)1 _9 K9 ]+ q& i$ _* X) E
            throw Error("v1不合法!");0 b. a& |- f) K0 w& q" X, c
        if (v2 < 0 || v2 >= vexNum)
    : o8 O) ]  a/ r7 m1 O) c! ^# g        throw Error("v2不合法!");# p# ]" U$ K8 `: \( x6 `( Z
        if (v1 == v2)
    ' R! U: s  p* j  r9 f        throw Error("v1不能等于v2!");3 f& e) x$ D' F3 }- Z

    " J% A2 j( [% ]+ X  b    p = vexTable[v1].firstarc;
    8 {5 }$ |7 s/ O) d, I    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)$ U: X7 E! r% k' K# ~1 `- r
        {
    9 I7 d0 }' X" v$ h# a  s        q = p;
    5 E, |5 [$ Z( |        p = NextArc(v1,p);
    + V4 L2 v: Q1 k- [2 x4 h    }//找到要删除的边结点p及其前一结点q$ E3 _" o5 r% P1 q, m8 U
    / ^- H( I' R1 _' A! @: R' i
        if (p != NULL)//找到v1-v2的边$ A* t1 D( R0 S# {% d6 H* [
        {2 e: P0 r. `7 t* e6 m# `
            r=LastArc(v2,p);' B4 M9 r% Q7 ~
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    * N* }8 V; A. z% [            if(p->adjVex2==v2); U" _( h# t& ^3 U, G: h7 t+ d( s
                    vexTable[v1].firstarc = p->nextarc1;
    " J6 E- H  n; H            else vexTable[v1].firstarc=p->nextarc2;, F+ a7 t( `4 J' q- O3 b: B9 V
            else//不是第一条边! ]  u* N; E2 s: u* q4 z7 c( O
            {# S3 |, P. ~7 w. Y) f7 s
                if(q->adjVex1==v1)$ D- s. R. e& k
                    q->nextarc1 = NextArc(v1,p);" ]/ J  }6 i5 c& d
                else5 \" C" f# |. a) t
                    q->nextarc2=NextArc(v1,p);
    2 ]0 O/ o' r: e3 H" C3 O& s3 `6 X# ~% o
            }- C$ M8 [* g2 h* m
            if(r==NULL)
    9 r8 |) T- F: P/ \8 Z1 O' b            if(p->adjVex2==v2)' T5 W  l8 V2 X6 G8 K+ w( ^
                    vexTable[v2].firstarc = p->nextarc2;
    $ i& \$ H" [, ^  e+ i1 F. O; g            else vexTable[v2].firstarc=p->nextarc1;+ D3 l2 `# ^, _/ T( M
            else7 B5 l( `/ {# }6 X. K+ n
            {) w2 F- u% u! t! i- x* _* M& E
                if(r->adjVex2==v2)0 W0 f9 C% L/ @- M3 Q
                    r->nextarc2 = NextArc(v2,p);2 B& o% o  T: ?3 ^
                else8 ^& [& Y* r& B9 m9 E
                    r->nextarc1=NextArc(v2,p);
    ' Q) V- o( u3 z; [$ K        }
    9 p- |1 l* Q: O% b# H+ v        delete p;) T. x, `* d; X
            arcNum--;. z8 X; z- G( h+ ^
        }& G0 k2 d" {$ y' g
    , u1 J  D' a/ e
    }3 m3 c# r; K4 j+ q+ E
    template<class ElemType, class WeightType> void
    ) h. Z7 d( o/ t/ S: @MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    ) T; A" c0 u% I' |" Y2 Q7 D- ~{
    + R1 O2 B: G! E- U2 [+ e- e+ ^    int v;. V! p+ \% Y) E2 U8 v% k
        MultiAdjListNetworkArc<WeightType>* p;- f3 v' |1 `( z( c! I4 c( [6 ^
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    % i& |" j9 z: h1 h        if (vexTable[v].data == d)
    # n) W: c4 L7 `6 J7 n. x            break;1 r! e4 q6 ?: m6 E' [. j
        if(v==vexNum)& N2 z9 h2 G" {2 f4 l
            throw Error("图中不存在要删除的顶点!");
    ' f; g3 F% t/ b. s7 M- f
    & Z+ ?, _9 y+ L/ u7 m, A    for (int u = 0; u < vexNum; u++)//删除与d相连的边4 E9 P: C' x5 E3 F% j5 y+ [- @
            if (u != v)4 I) J( Z, Q$ j, }7 L
            {9 r1 L3 }' c% N+ U2 h. I
                DeleteArc(u, v);) E* x' m  t! O# Y9 k9 F9 S  V
            }
    - ?2 ]9 ?6 c7 l    vexTable[v].firstarc=NULL;* H& V/ T8 F& g, u

    " ]5 H; ?  s/ E, D8 k    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    0 [4 T) P$ h$ o3 Y    vexTable[v].data = vexTable[vexNum].data;) \6 _- _2 d+ l
        vexTable[v].firstarc = vexTable[vexNum].firstarc;* o+ X4 ]/ U) s, h; ?0 k6 i: }
        vexTable[vexNum].firstarc = NULL;
    $ M" G# [; v  H5 Q    tag[v] = tag[vexNum];
    1 n7 F/ \+ z  X5 r" I. l# F3 u3 I    //原来与最后一个顶点相连的边改为与v相连
    / A% u* k7 g- d+ H    for (int u = 0; u < vexNum; u++), Q: M( O7 {$ i* k9 Y3 d
        {
    & Y: R6 z0 A" Z: g3 l3 ?        if (u != v)
    . ]) S5 Y  r4 Z6 o. `        {
    ! ]/ b4 S! ?1 w5 R! c6 R            p = vexTable.firstarc;
    2 a$ ~# F+ r/ x  F            while (p)! K6 W( V, C( s* o" K
                {( @% d& I1 q+ @( i" s
                    if (p->adjVex1==vexNum)2 t: H- D3 n' c8 D5 J
                        p->adjVex1= v;* I) `* g7 s' v  a# x
                    else if(p->adjVex2==vexNum)
    . D, W" r8 o, |8 u                    p->adjVex2=v;
    - P+ d. W. ^* h% C5 M                p = NextArc(u,p);  L" |9 W; J- e
                }
    " A; [* J9 b$ D# Z1 R* c' f" n        }
    1 u* ?! E9 v: n% V3 P    }: J1 X) U, W: ]( W+ B8 [
    }
    * }/ t3 B! K$ O2 x8 g///深度优先遍历/ ^: \. B% ?8 E$ ~, T4 g6 V
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)8 D/ B8 J" K# F3 E
    {
    2 _  Q+ U% N: U. m% b0 G. R) }    tag[v]=1;
    " ?  r- s+ s; F& a    cout<<setw(3)<<vexTable[v].data;# |9 G; ?% l/ q( f/ o. r8 \
        MultiAdjListNetworkArc<WeightType> *p;
    ! _5 P* k- v9 D8 ^# Y: d5 x6 U    p=vexTable[v].firstarc;
    " l: I, c2 p6 O. c* u* o3 ]9 @    while(p)
    3 G# q. O! \1 B' x3 K    {
    8 ?; |/ K- [5 L* Y% K# U7 |        if(tag[p->adjVex1]==0)
    - L" z# `- X' H( i# [; P' F            DFS1(p->adjVex1);
    8 d" ~2 L2 S) `( ~$ g' l        else if(tag[p->adjVex2]==0)1 ]; ^& d/ ~6 L/ n
                DFS1(p->adjVex2);  T" Y: w) [  k8 s2 z: S+ z9 @% S! R
            p=NextArc(v,p);) V! U' D' y+ U% x* [. t  V2 w
        }1 K2 Y; x* x: `4 N  k! v
    }
    1 U+ N( N% m& ?6 E$ b6 Atemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()/ X" ]0 a* d5 C! x( S
    {2 m2 b9 I, z8 p. H% C+ o
        for(int i=0; i<vexNum; i++); ~; Y+ H& [6 B# o* r
            tag=0;7 b, }  T1 o9 h/ ?& Z+ D
        for(int v=0; v<vexNum; v++), M' _2 p9 P* m2 J9 A* @, _
        {
    + }! R- c7 Z1 ?+ L# N' k8 V        if(tag[v]==0)
    ' l' y  y3 c/ p- d/ f& y            DFS1(v);3 P7 q2 Z' n. _2 y8 m% L0 L
        }
    * x1 A. h0 M# y}
    3 M# _# F- {9 V) l. Mtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()8 i5 G5 A3 P* ^1 p+ v
    {' E, b- t. R( ]" V1 ?4 l# e$ T4 ^
        stack<int> s;
    ' w8 y& d8 J4 O# v( D    int tmp;
    ( O4 L( ~- F3 c/ \. M( x' i    MultiAdjListNetworkArc<WeightType> *p,*q;
    * L9 J( r) \7 Z. `    for(int i=0; i<vexNum; i++)$ g; S+ I2 h. c+ Y/ V% m4 m, o
            tag=0;9 s- p; g0 X! m" y" W
        for(int i=0; i<vexNum; i++)
    8 Z# ^% r! \2 X# j' A9 K    {
    1 I! o9 V% e; @7 t5 r, A        tmp=i;
    ) |1 C9 B3 _. s        while(tag[tmp]==0||!s.empty())+ e; e& h8 ~% z$ l4 W
            {
    ! B0 A1 j+ E. B0 U* k2 S, y9 O            p=vexTable[tmp].firstarc;0 w3 n1 a. R0 Q% K2 t5 u
                while(tag[tmp]==0)
    ( H. W8 o  C, u; \3 X6 V$ ^            {& g  N7 w3 N( \/ O# Y6 w& T- h
                    s.push(tmp);" H; |8 z5 o* ^. Z6 ], ~
                    cout<<setw(3)<<vexTable[tmp].data;9 t, k/ }/ j' ~; ]5 M
                    tag[tmp]=1;$ m* l$ q2 F5 M8 `* L" A( |+ E
                    p=vexTable[tmp].firstarc;
    - c  v: W% t7 R* S* [  n                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    2 L9 g( d  y) Q6 f; [) d8 T                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    " f' O) Y* b/ q3 C6 y$ X; @( s! u* F                //cout<<" 1st     tmp="<<tmp<<endl;
    4 @4 `) X5 P4 B, h- p7 K7 _" c7 e            }) Q) g9 Z2 z: d) B( t! i
                if(!s.empty())
    * N' b: D/ p6 `- K! Y4 E            {4 F2 T! R& A0 Z2 b5 t
                    tmp=s.top();
    . k2 `9 i3 i) g, P                s.pop();2 b! ?. X# i% ?' \8 v
                    q=vexTable[tmp].firstarc;5 z9 z' w" x6 S6 V+ x# F  Z2 x* r
                    int t=tmp;* T- a' J- u* E6 e$ ]: U7 I( o
                    while(q&&tag[tmp]!=0)6 L: D5 I. }7 P
                    {# \; D) {4 }  T+ y; u; Q
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    7 T' t* k' j' O/ i. g) M3 I# u5 S                    //cout<<" 2nd     tmp="<<tmp<<endl;
    & {# N( k) t) D. a+ u/ B! N+ z                    q=NextArc(t,q);' |# Y5 V! V7 Y; n; i' s# [* [* |
                    }
    . K* T: W+ f0 i) }( @: b                if(tag[tmp]==0)& a) s: [9 y% W4 o1 h8 o
                        s.push(t);# O7 h' `  R% Y0 u; w( l8 }* z
                    ///1、对应上面连通分支只有1个点的情况
    " S8 b. p- Q/ L2 V5 n& Y                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    + p5 ?: ]! Y7 S5 q2 N                ///tmp要么等于找到的第一个未访问节点,% m& e; F# z# l5 K& l" h; {% P
                    ///要么等于与t相连最后一个点(已被访问过)
    3 H- r# l  s, ^3 n, Y                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    ; H7 J" g& I! {            }
    " b8 y% r& D- f" V4 Q        }
    0 i0 x5 L6 Q9 ?1 M' H; }    }. [( d* R4 O& G& b3 A
    }, T6 ]" x) L" E& c+ |) C$ b
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-13 E( c( k) a8 I) z$ \# x& {
    template<class ElemType, class WeightType> int6 G0 W0 V. d3 ]; ^  {
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    9 b+ ~; Q& c( Y& o3 o' W{. @) r% y$ n! |7 ?
        if(head==pre)
    ( u, Q& @( t  Z3 d        return -1;1 z; U" c9 H8 S4 B- A2 S
    : B# M) k/ |. [
        MultiAdjListNetworkArc<WeightType> *p;
    9 j: H" j9 F7 V3 G7 z0 W* |& R9 K$ W    p=vexTable[head].firstarc;
    % c6 A, @! v. _6 ?    if(pre==-1&&p!=NULL)' g! j; S- |! e6 n7 ]. D
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    ! X  `; |' i, ?9 W6 M3 R, L    //pre!=-1&&p!=NULL
    6 G$ W- ~% x% E2 W    while(p!=NULL)
    5 q4 B+ i# |- o# y2 i- l$ ?    {& C, g0 }1 v  {6 y6 Q
            if(p->adjVex1==head && p->adjVex2!=pre)
    8 b- g8 M( y+ C" q3 B, Q) i            p=p->nextarc1;
    ! d. T& p& j2 y  C6 L9 b+ y        else if(p->adjVex2==head && p->adjVex1!=pre)# |9 N: [$ S4 R6 J% g) t& L) I8 N
                p=p->nextarc2;7 R1 F3 z! \* r; Y& `7 W$ ~
            else if(p->adjVex1==head && p->adjVex2==pre)
    # ]6 L# \4 F7 c1 b/ I& t2 Y# I/ W        {
    5 j( q2 i$ |$ ^% [. b            p=p->nextarc1;
    ' H1 t( D  f/ B% q1 f0 g  U            break;& N" p4 ~# K% v6 _7 P
            }
    / W: ?( M+ A) y& m# x4 k/ l  _        else if(p->adjVex2==head && p->adjVex1==pre)1 ?6 I- j! j- ~+ z9 b
            {% X8 x9 Q: q" a' w2 S
                p=p->nextarc2;8 a/ I7 K2 _, ?0 H7 _
                break;
    6 L# F  B1 m! r        }& s0 ~; O! [, g/ O: }3 `
        }: L6 M- V) r9 g& g3 j" t
        if(p!=NULL)' x  |8 I2 M/ H/ F- P" B) l6 E% x
        {+ m& S# ~3 E  q& a4 _* C: U
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    $ Q  k& |! m( n    }
    ) t; @# t5 e1 {3 h    else
    % ]1 C3 _8 k0 h! S        return -1;, Z/ n8 `$ E3 O6 W% [! A3 Z  ]6 v7 f
    }
    ; h& o4 q+ N( Q* a# I
    . a3 G0 X5 Y" M) ]6 h  w: y/ ]3 j( E
    $ V( L! o9 |6 l% vtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()( ~3 s7 e+ r& b$ n2 B
    {6 q+ m' i; E; a0 m4 k! j  u
        stack<int> s;* X- F% K' J) }! p/ f$ J
        int p,cur,pre;# ]5 p( |- ^/ ^. r$ n- O' g4 `
        //MultiAdjListNetworkArc<WeightType> *p,*q;8 i; F: H' g# V' g$ X
        for(int i=0; i<vexNum; i++) tag=0;//初始化( k; G  ^& x+ U( `# z7 b& A* b& v, v
    7 ^9 `. p4 F2 N# Z
        for(int i=0; i<vexNum; i++). y; b! P- ~9 @) Z
        {
    6 m# k  s; q2 I3 _7 }$ R        cur=i;pre=-1;
    & o7 O7 |- ]( F' I! x' ^- x        while(tag[cur]==0||!s.empty())* R# d  n/ E/ r9 k$ e$ ^% w
            {
    9 Q5 \- s( j4 y' r1 m3 n$ |            while(tag[cur]==0)# p# ], o' s, m" L0 ?8 Z. u
                {4 P* N  e. E  O
                    cout<<vexTable[cur].data<<"  ";
    ; q9 F! L0 z9 O: K( j4 \                s.push(cur);
    1 o" Y, f4 m# s4 A7 D                tag[cur]=1;5 u7 ~5 p5 D9 |* |* O9 q
                   //初次访问,标记入栈
    ) L- ~# j$ V" D- `: B8 ?
    % p: U, v& A1 c; [9 K; ~) ^               p=GetAdjVex(cur,pre);//p是cur的连通顶点
    % i+ `! W0 ]% I/ ~" z$ b) ^               if(p==-1). f" b3 u( |, V
                   {5 l- h8 P* }1 x9 V5 B5 b$ b
                       pre=cur;s.pop();7 @# d; [2 x8 n7 a3 B. |" q
                       break;0 l1 K, r5 D* C2 L
                   }
    ( ~6 f0 t4 ?' H/ m. S# r$ D               else0 G9 @  D% X3 I8 X  Z& p
                   {
    4 B" u3 I3 ~) q8 s; f9 A                   pre=cur;
    + w0 c7 X% s$ F                   cur=p;
    / m1 o' {' T2 K, }! ~1 @; y               }. W9 Y5 p+ m9 }# i- C
    7 {4 C) ^6 J& R5 C! {, u# f
                }5 x$ w  L! i( D, p
                while(!s.empty())( C0 X7 o; M" m" i! S
                {/ W( _3 P8 M/ @- u7 U- t. o
                    cur=s.top();+ X& ?& @/ S7 l, D9 C9 f
                    p=GetAdjVex(cur,pre);
    , ~0 B4 r3 n! ?; p                if(tag[p]==0)6 Y7 w0 ]7 c$ V1 }# L
                    {. j$ M( m5 T* u$ i' T% j; Y; G
                        pre=cur;: R, c3 q$ d6 T' d. H
                        cur=p;
    . R8 L, C9 V, q/ p                    break;) A/ D! D4 ~+ o, l! m2 b' S
                    }
    " V! Z/ @+ _& h. M. ]. o% I                else2 k/ y6 V* e) k. H& j! L4 S' K
                    {1 ^# J3 r; g+ E8 r0 ]
                        pre=s.top();. _1 `6 v/ Z: h6 M
                        s.pop();
    / j, j0 I9 r' x4 p+ v8 ]' D# c                }
    * g) l: B) ]0 a8 m* {- D1 k' ~0 R1 k/ Q0 G1 `1 _, n
                }, q. \4 E6 q  n
    1 v. p8 |# h4 Y* o2 `
            }
    / c2 a" [& w* o8 n- k9 e( f    }( w2 a6 j/ h4 R, u
    }
    & N# L# F0 F- K  ]5 _" e$ c' [template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()+ q3 Y% o- r( L- z
    {
    ( B1 u/ K6 g$ @" ?1 N5 `6 ]" r; p    for(int i=0; i<vexNum; i++)
    / u$ [: {- t5 c  [        tag=0;
    + a8 f9 F+ ?# t% ~) d4 b% `5 s) _    queue<int> q;
    % P5 a8 ^  J$ |- ^+ X9 k% {    int tmp,t;+ X" W- x4 F0 U# ]* k/ A
        MultiAdjListNetworkArc<WeightType> *p;
    + Q9 m( h# h+ `' K; S. I    for(int i=0; i<vexNum; i++)" U: A0 E/ X6 s( U  n+ O
        {, C& X$ [  J' G
            if(tag==0)- m' `5 g, P# n$ k! A
            {
    / I# b& {- l9 N! z3 l% B            tag=1;
    8 B: I0 @, e, W            q.push(i);
    ; [+ c1 r0 I* `6 e            cout<<setw(3)<<vexTable.data;
    ' ?" ]; S+ P) k9 M& w        }% C3 u' [8 a9 I. n* H
            while(!q.empty())( H: F1 k& y6 Q3 d9 N
            {3 w2 m$ ^! @- P9 @) k2 U+ _. m
                tmp=q.front();6 H% p, }5 y# |% u3 B1 j4 f  A
                q.pop();
    " s. x, X5 o, s0 C3 c            p=vexTable[tmp].firstarc;
    $ q: C0 ]5 T6 E# S) V; v( Y            while(p!=NULL)
    3 R2 J  v* Y! u% g5 X0 m            {
    " M5 }  |" u' p5 T) N                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);* a8 B2 ^9 e$ M" H. G) B6 t) q
                    if(tag[t]==0)* G9 e; T' J1 T0 Z
                    {
    # d" z6 l; p  z. y                    cout<<setw(3)<<vexTable[t].data;+ o7 L- b! H3 Q  W
                        tag[t]=1;
    & ~3 P* R- u8 E3 M4 f7 K1 n5 y                    q.push(t);
    0 N0 G5 g& ]% D- L                }. g; c& f+ V5 ]: l4 N! |
                    p=NextArc(tmp,p);3 g- Z% c" F, }
                }
    6 r& {4 l. `9 Q; T        }! V( X! `2 N7 g/ X0 X. x1 P6 {
        }
    ; {: i  W" D2 ]; ]}
    ; r4 l1 \5 _, O0 ~- N' v, Ntemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    # ~6 o: {2 u. [% V' Z9 @" L{
    - h3 h: c. }8 O! z    MultiAdjListNetworkArc<WeightType> *p;
    ) U8 D% s% r$ Y    cout << "无向图有" << vexNum << "个点,分别为:";
    ! _7 Y0 a8 t6 [8 N2 o    for (int i = 0; i < vexNum; i++)1 X: S! s" e* {2 W0 }) O* _
            cout << vexTable.data << " ";% \" |, x) R$ w* j6 J
        cout << endl;3 e# ]5 p1 l. I+ w
        cout << "无向图有" << arcNum << "条边"<<endl;
    ; ^0 y! R& v* T6 A: m    for (int i = 0; i < vexNum; i++)
    + {& S4 ^$ B( c; r% H3 ]* M+ h    {! F- Z; G0 e+ |
            cout<<"和" << vexTable.data << "有关的边:";( k+ Y  K- G% p& }
            p = vexTable.firstarc;
    3 Q0 G4 i, u* f) f7 l        while (p != NULL)2 S. A3 e; ]8 D; b
            {$ t% Z) V, a9 E# e/ |9 k0 N
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";/ D5 w1 _6 p& B& K& a& M/ j
                p=NextArc(i,p);
    3 h* c+ _  }2 J& D+ k  c        }
    3 P0 T% [' A2 J# s* W        cout << endl;
    6 \* R4 C! H: q, i+ Q    }( Q; R4 u8 U$ `7 q
    }  y& o5 k- Q% U7 i0 i8 ?

    8 b% g) |9 l! v+ r$ p
    ' g' E3 y3 K. i. h- s0 F5 U. L; Z邻接多重表与邻接表的对比1 W7 K* Y6 n% C& ~+ Y

    0 V, p% r! q! n! w$ Y/ U邻接表链接
    2 C- K- ]" w8 f5 K, @2 L, H$ E在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    : w0 b/ q& p5 E3 g! o9 n在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。, c7 g9 u1 M2 D* e* r; C
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    $ e( A% E2 F, \- ?# |0 ?————————————————2 x, I# o9 f; J" I  F: Q
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    4 y! l; Q5 h& y$ A' s原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958+ ?9 F  ^2 L* E7 b5 M* G

    1 {  G1 s2 U1 ~. u; V. d1 h/ s3 o9 I' i8 B: u4 C% V3 w$ x
    0 I7 r" Z7 O( ~, t2 M: [
    : b3 |8 i% N" ?8 p
    ————————————————
    ) v+ M% ~* s# s* _/ s6 `  Z$ y1 F版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。$ b8 l+ W5 `6 w$ `
    原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669589 D& m, \( a( ]+ J9 P" S# d& X2 P& ^
    ' n! k9 q* a( V
    4 B+ Z% P) w& ]1 ]
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2025-8-1 15:31 , Processed in 0.826010 second(s), 54 queries .

    回顶部