QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1639|回复: 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
    9 r& w! ~4 y' m8 C/ g9 G9 O
    图的存储结构——邻接多重表(多重邻接表)的实现
    . Z6 W, @0 {- I- o( V9 f6 i7.2 图的存储结构
    8 ^* y* Y. q( \# B6 Y8 H, Y( ~/ `; @# E: \3 O& Z
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    , w, y/ Z" w; J# d邻接多重表的类定义
    ; Q4 ?; |( X+ U) S" g/ b7 ?邻接多重表的顶点结点类模板' F8 o$ G) Y1 k( Q$ y' b6 m
    邻接多重表的边结点类模板& A) A9 W- ]% D$ I& n
    邻接多重表的类模板# U4 n) l" D1 j# X9 b
    邻接多重表与邻接表的对比( A* z% p8 z! b+ Y
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist- B1 g! Z. ]/ v* m

    1 v" ~" O8 T% O6 b- a: O在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。/ b7 c4 A: b1 u; c5 t& X9 Q/ f
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。" {# c9 t% \: v, G2 ]
    6 {! [# q4 b1 K) v2 [) H
    邻接多重表的类定义' `/ X! I3 q! q/ f- M+ B  ]* A8 f) s$ \
    1.png
    - C4 v# U. U: h) s1 d邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:* Q+ C  |+ g% Q& y
    data域存储有关顶点的信息;% b# i1 S- ~# \: M
    firstarc域是链接指针,指向第一条依附于该顶点的边。9 y' G  v' ^  W6 U$ y
    所有的顶点结点组成一个顺序表。

    " `& B) Y0 B. F

    0 I/ ]( Q0 S' m/ `( b1 X5 z) ytemplate <class ElemType ,class WeightType>+ e4 @2 m4 H; P" ]
    class MultiAdjListNetworkVex
    ! `# W7 b5 b  S2 I5 I* s( t{% }: b0 N4 W; Z" ?: Y
    public:
    ) s: c7 _  Z) ?+ N8 h6 @0 h+ U        ElemType data;( ~6 h* i2 O- Y2 W- a" T
            MultiAdjListNetworkArc<WeightType> *firstarc;5 U1 U2 U6 a6 {& F' c8 z3 ]
    + o4 D0 s  n4 |4 f
            MultiAdjListNetworkVex()1 ^& W" Y9 v& J. y- I) C$ Q
            {- H' b: j# ^( y1 O' T! M
                    firstarc = NULL;# _( X- [" H) w( _7 y# }3 `" |/ h
            }
    ! t6 `( ]; J+ {. r+ f6 D- @; R, R1 C        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    & I/ g+ v% X% }% C' O8 Z        {
    " F8 M: ~. e% q0 q- @8 M1 ?                data = val;
    ) k6 Z  E  \2 m* V                firstarc = adj;* K2 W" ], x! O; W' X' G2 B
            }
    9 I4 D/ |" f' x- R};7 H" k% H3 H  y( s7 K6 w* L

    ( D8 f% [4 V, W* {6 S, e邻接多重表的边结点类模板
    ; A* m/ W4 a$ ]6 M3 B, ^( Z8 z$ @& X& o7 S8 Y! q5 e! `, c) h) f
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:% ?) A5 N9 [+ I1 {/ @
    tag是标记域,标记该边是否被处理或被搜索过;
    7 w0 [) ]. c9 k" L) y9 Oweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;$ R+ @5 s4 F# D/ i
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;0 H+ b1 R& o) l+ V* g
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。( ~# J  i. Q. k& y! _5 f* |

    ! n$ h0 Z# U7 f+ v9 q% I6 [ 2.png
    ( g! n% e5 i3 \  u8 Z9 Ftemplate <class WeightType>
    ; t8 C" f( b9 Gclass MultiAdjListNetworkArc
    ( \7 |8 H6 m5 ?# T/ s+ j{) K( u9 \5 l2 f! {* \! d. P( {$ {
    public:
    9 L2 J0 ]( a* d0 J# o* `    int mark;                                       //标记该边是否被搜索或处理过& J; a; V" [, R1 z, J
            WeightType weight;                              //边的权重5 X; P2 N9 b: z% W) H
            int adjVex1;                                    //边的一个顶点! J! l5 D. }! G" H
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    - _% g; {2 x/ p        int adjVex2;3 T5 d! ]$ f  o5 t/ N2 p6 Q* x  w
            MultiAdjListNetworkArc<WeightType>* nextarc2;
    0 t1 M6 W" W2 S( n: Y
    8 \7 `7 A7 P1 \# }9 f. |        MultiAdjListNetworkArc()
    - \. c1 [8 w' c! J        {3 f, h. e6 y  }( n9 @9 p, T5 T, j
                    adjVex1= -1;
    4 \2 J% C) ?) |                adjVex2= -1;
      ~. Q% \9 o; f* c        }
    3 z6 I* U( ~, u4 y& V; ^% S        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    ; [- [" B" `. t0 h- x4 T        {- g( l7 _7 U& B( ?
                    adjVex1 = v1;       adjVex2 = v2;
    ( t9 w: T& \6 b: `                weight = w;; z6 T/ Z5 m4 g7 l  c" g
                    nextarc1 = next1;   nextarc2=next2;
    0 T( |3 g2 A: ?. H8 x2 M! D  S                mark = 0;           //0表示未被搜索,1表示被搜索过
    " o7 y! ?: r( Y1 Y  [8 m        }8 ^* ^/ W% b/ T- {

    : |) C& Z' N8 `+ e, i8 V邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>* T9 }7 |; t' R/ a* i
    class MultiAdjListNetwork
    : k. L3 }+ F9 d4 O! d{' p. K! j) @2 {
    protected:4 m/ w8 s3 ~4 m! x) f
        int vexNum, vexMaxNum, arcNum;
    * l" M8 g& u& _' B6 Q$ t    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    ; r, ~; [' g" j, ]    int* tag;
    # R% J" W% s  {9 E    WeightType infinity;
    7 }9 _  C6 `" w0 _/ k0 @2 A; D1 r& V: H9 ?0 p% U% a6 a5 x6 F4 b
    public:
    , A: i4 O& Q; ]: |    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    + M0 @1 p9 \- x; a* U/ m
    . r5 p$ a  p0 o& k8 l    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    2 j) C% b/ G0 b
    ( r1 K3 c9 F. C: P' F+ ~    void Clear();
    ( W; \8 t9 C+ C    bool IsEmpty()
    ' W4 M, e7 h5 @) }0 }  j    {
    $ v9 g/ t0 T$ j+ \8 V- x        return vexNum == 0;
    $ B0 E2 r$ [7 c. `    }
    ( f% V/ l9 c! Y1 |6 J    int GetArcNum()const
    1 C" |+ X8 f7 B0 t" M; g    {
    * H+ @6 F5 t. O6 E( D9 x" q; K        return arcNum;5 u/ k+ u) J, }" z- T. R6 T
        }
    $ l; d2 f0 @% N5 v- x, y    int GetvexNum()const
    & d) q) M+ Q# Z( ?8 {    {
    . O& u! S2 B) ], t6 L9 ?        return vexNum;
    ; r2 h0 E( \1 s8 X( j    }9 L, y4 S0 Z) q- {* q7 d. M

    ' U1 u  Y5 j5 H( E" W" r9 q" |, @; E/ J8 B: Y# l, y8 i/ u
        int FirstAdjVex(int v)const;
    5 I* c" E1 [* J5 b8 h5 |    int NextAdjVex(int v1, int v2)const;0 y9 s0 k% q0 E/ }
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    * ~  k. L) `% ^. N! O) u/ W0 B    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;( y1 F' [$ m" c$ w+ L3 T8 s1 l, I
    . X3 y0 c/ d% I2 J; u5 Z% k
        void InsertVex(const ElemType& d);! y9 Q3 J1 g9 ?2 C% g
        void InsertArc(int v1, int v2, WeightType w);
    * v' h& w- L$ C0 v7 ~8 x4 O8 N  ~
        void DeleteVex(const ElemType& d);
    : E) T: Q; y$ H% h& ^. w8 ^    void DeleteArc(int v1, int v2);! o" G' Q# G* W
    0 c7 C7 Q6 d' s* x$ K. _
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);& m* |- i* o4 A$ g. R7 w
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    7 y( j) m1 p3 V3 v) ~3 e4 Y4 U$ G9 ~2 ]+ T
        ///深度优先遍历1 i4 e1 V" W% G6 x! y2 B9 C" Z
        void DFS1(const int v);
    * Y5 u/ v6 Z3 b! K0 Y    void DFS1Traverse();8 Y  t0 f! L. \/ o
        void DFS2();
    # ~2 e7 Y; E. n5 u  R
    $ J9 I! E; R) M9 p1 m# g( g    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    " R2 j% q0 g, G' |; V- E; m    void DFS3();
    " ?. a) k- K5 }) h$ y& W7 d" a: V* X, M/ J  G  d
        void BFS();* X! B/ {8 p0 a. @
        void Show();
    ; L5 ?% J/ V1 @& j: t9 i. B};
    ) Y3 M# G1 `2 i) v  ]" i9 E1 ]* m. x- h1 R! ]0 Y# W, a% @! p; a
    2.函数的实现+ G3 i+ p# C/ ^8 |" _
    研讨题,能够运行,但是代码不一定是最优的。
    ' S9 M, u7 b* e8 }* i1 E" U7 y2 r6 {0 k3 r8 V, |' u; ^: w8 O" V
    #include <stack>4 h9 v6 Z! T* Z' h: T! S
    #include <queue>6 _8 B1 N9 ?" K7 Y/ c- d! z

    + |7 k8 j( S0 S) b0 d9 h1 U  _template <class ElemType,class WeightType>
    . k/ Y5 y9 h: ^% {  P" \7 \MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)5 C$ B7 H* J1 @1 @4 m+ c4 E: I
    {4 c: s( p6 H! b+ [: d- Q' k
        if(vertexMaxNum < 0)
    9 P$ U0 X; Q  V3 z        throw Error("允许的顶点最大数目不能为负!");2 J2 ?# O( l  d
        if (vertexMaxNum < vertexNum)( V" A6 V: a8 {& h
            throw Error("顶点数目不能大于允许的顶点最大数目!");8 \- X( @% }. ]" q6 F( w6 {6 c
        vexNum = vertexNum;
    0 D" V( U$ u4 U- Q9 [3 H    vexMaxNum = vertexMaxNum;
    & t7 @& r& N: y2 q: u    arcNum = 0;' P  x2 w9 X4 k; b4 {- t
        infinity = infinit;+ i0 _# p/ Q8 R8 ~4 U$ |
        tag = new int[vexMaxNum];
    * e% {) `; |2 S2 I4 ^& z5 i    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    8 c0 o* }: z, A  i' [    for (int v = 0; v < vexNum; v++)# I, b# }# ]' l7 B6 n, U) P
        {
    ' D( y% x7 i  |! V7 H* H; S4 S        tag[v] = 0;
    ! ?( V2 ?9 K, e: x1 z        vexTable[v].data = es[v];2 u3 W, y0 {- }7 y$ c! W5 D6 o
            vexTable[v].firstarc = NULL;. W/ b* o7 t+ A, w, a
        }! I. g! w, v; K7 W. W, y7 r: K
    }; }- a2 L- \: l; H, l7 S# K# d! v% X, d
    template <class ElemType,class WeightType>
    5 |3 m3 k% m: }; zMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)4 X* M% i4 I1 l0 |$ s* Q
    {
    3 p" I" K* m# ?0 }- S5 L    if (vertexMaxNum < 0)7 ~! x1 ]4 T# ^+ y1 G& c) s
            throw Error("允许的顶点最大数目不能为负!");! z, R( o' i# K0 E1 c  m3 w6 N
        vexNum = 0;3 Y: |! O+ {1 |+ Q
        vexMaxNum = vertexMaxNum;2 m8 c" o* m0 b9 L& n+ v- G
        arcNum = 0;
    * m/ }* U4 `  g2 C# t  {    infinity = infinit;8 w% Z2 r+ a: R* u6 i4 I$ ^5 \
        tag = new int[vexMaxNum];7 i8 f9 a# @  K4 l' D
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];, _0 k2 M  c, x8 ~
    }& e7 w( i& l* J4 T
    template<class ElemType, class WeightType>* i# u# a" a' C' m
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const  b  y1 M7 i1 p  R) T2 |; O& F
    {
    : k3 o, z. f* C& b1 {! W& {    if (v < 0 || v >= vexNum)
    ! ^" G2 T" W) q9 f* Q8 B9 \        throw Error("v不合法!");
    9 F4 R" h2 t& ^% N" D    if (vexTable[v].firstarc == NULL)9 U3 E$ h/ P$ v$ X
            return -1;
    " _- O! m3 u2 j    else
    ' R8 }0 j1 X" k* P# u6 C7 Y        return vexTable[v].firstarc->adjVex1;# L$ |* y0 M+ K
    }" R0 v$ U! |, C& o* C

    ' A4 B+ Y. n! l! e1 w+ ?template<class ElemType, class WeightType>7 @+ ?& x, T9 p3 w" Z9 h
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const* M- B7 v. d' M- d
    {* _$ E3 c8 `# i8 r+ D
        MultiAdjListNetworkArc<WeightType>* p;5 m' c( K; m0 T0 t( J
        if (v1 < 0 || v1 >= vexNum). A3 k1 t: s1 H" |, l' [  @% h/ o
            throw Error("v1不合法!");
    * T& j1 D* Y  r( e8 u3 O% |- S    if (v2 < 0 || v2 >= vexNum)
    5 E9 ~9 I2 u5 Y        throw Error("v2不合法!");1 f% i0 t2 K# b- o7 n* \/ a) F
        if (v1 == v2)
    9 d, N9 B" i. t$ y; l3 P; ^: v% y        throw Error("v1不能等于v2!");8 R9 i4 J6 Q8 ]& g
        p = vexTable[v1].firstarc;) B8 e) v: t1 ], ?" h
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)( f$ V& ?9 T$ a+ c
            p = p->nextarc;1 Z2 o0 J& R, p1 v
        if (p == NULL || p->nextarc == NULL)2 A0 L) R& L$ t! [1 f  {4 ^
            return -1;  //不存在下一个邻接点9 y8 ^. M  @1 E, T6 X
        else if(p->adjVex1==v2)
    8 D! m; T4 p5 o: |        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);( S1 `3 l0 N, F, i& f: q5 a8 h
        else" U- n# D% @; d6 l- k  Q
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    , Q/ f& d  x( e. `' h' i0 C}* f7 c  M, }  Z; t& V: C& |% Q
    template<class ElemType, class WeightType>$ I6 p* ?. V, `* m
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()% D, e% p4 k: {  H. Z6 n
    {& a( {# Z- s6 U( k. d( ^
        if (IsEmpty()) return;
    9 E- q8 k( V6 p( M    int n = vexNum;: \# `/ Y/ f2 d- u0 N& z
        for (int u = 0; u < n ; u++)) V5 E$ Z7 V" }1 [! S, e
            DeleteVex(vexTable[0].data);
    3 h% k! Z# V8 E/ G6 q    return;* h7 S' \' G- X) t
    }  H; B8 ^! K0 o' r
    template<class ElemType, class WeightType>
    $ s4 z/ ^* p& j5 R1 F9 Z; N1 uMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()3 B0 n9 T/ }! K& c
    {9 ^7 d1 E- s. j* J2 {9 Z
        Clear();
    ! l9 z, K  R8 m4 N}
    1 |* v# l* @! e6 jtemplate<class ElemType, class WeightType># A6 z0 a4 j' S- P% i5 T  w+ o
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    9 B& _9 |0 h6 Z0 x; X1 n{0 V, e8 c" a  U& U
        vexMaxNum = copy.vexMaxNum;: J! o7 V8 ~# c/ O& L. p: j, S7 H! i
        vexNum = copy.vexNum;" m% a7 W! D4 i- _2 F/ c- t
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    # U# f) [' a1 O/ u3 a    arcNum = 0;
    : n+ x5 k! e* F7 s    infinity = copy.infinity;" q. s4 @! K( ?# u0 T6 E
        tag = new int[vexMaxNum];
    . A) c  R# T2 f9 `9 g7 z  r; Y" ]9 T5 C
        for (int v = 0; v < vexNum; v++)
    0 A' C: `6 ]  v' \6 d& Z9 ^( m    {
    7 a* L. N9 M/ z        tag[v] = 0;
    $ F; R& I: I" D5 e$ L  ~: z1 [        vexTable[v].data = copy.vexTable[v].data;
    ( r0 c" g" h' k2 s3 W; Z; W        vexTable[v].firstarc = NULL;9 Y/ \& @+ Y# G, {5 z2 V+ ~$ Q9 S/ A0 M3 V
        }4 V9 N  V9 B- x1 v3 N
        MultiAdjListNetworkArc<WeightType>* p;
    ! V# t9 f; U6 n" y8 U" a/ Z+ e6 p6 Y- G1 a8 a. h
        for (int u = 0; u < vexNum; u++)8 G' L: z7 i3 p7 L0 S
        {; q5 Q% F- i& j& O3 [
            p = copy.vexTable.firstarc;
    ; F! x2 R3 Y3 k( z: M        while (p != NULL)0 `. l" K7 j( o5 N, n" K9 a+ w( P* w
            {* p$ I" b. ]+ W. h
                InsertArc(p->adjVex1, p->adjVex2, p->weight);9 H2 n  r2 ~, l! L5 O3 B
                p=NextArc(u,p);
    * G; E# ~) v/ {) @. Y        }
    # Q+ T+ G+ ]8 W; V- r4 h/ Y    }- K# r5 C/ G4 `# r& @
    }- {  t) G: d2 I- ?5 d
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&6 z0 L' ]2 B1 Z% o8 ^+ X
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    ; ?' e1 K9 i( L{
    * @0 U& m0 y. P. E7 \! `' p/ R    if (this == &copy) return *this;
    - V* h' j; p; u) g0 E    Clear();
    ' G' ~' g( {/ \. o4 n    vexMaxNum = copy.vexMaxNum;
    - S  s& h. U) f1 j; {" t/ y    vexNum = copy.vexNum;+ z' ~  Y9 V3 F! V( ~
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];. `5 h& j. H/ X4 t# v, ~
        arcNum = 0;
    7 P- Y% f! w6 O: o2 |) l" B    infinity = copy.infinity;; o: L1 N4 u3 {9 G1 l1 k# }- G" B0 {
        tag = new int[vexMaxNum];
    & g, ^  J7 }. O" j$ d; d5 w+ l1 e" e) ~4 N, W  v* b6 [$ `
        for (int v = 0; v < vexNum; v++)
    , r) w  D1 v0 t5 I5 W    {7 g4 D7 P. Q  T0 ~  N6 d0 z% x
            tag[v] = 0;
    # e2 e/ T# e0 V7 E, R5 j% e        vexTable[v].data = copy.vexTable[v].data;
    7 Y/ ^  H1 q' n; _9 ~" O8 [; \        vexTable[v].firstarc = NULL;
    . X- u# a) N% F- Y. S    }
    $ O* B9 k* M4 @1 n9 @* y) X    MultiAdjListNetworkArc<WeightType>* p;' i) ^: d1 I* I$ o
    : O# M5 s! i% \. x
        for (int u = 0; u < vexNum; u++)
    * [/ H' j# i( _1 H7 r: l    {2 z9 ~+ J% S) Y/ H
            p = copy.vexTable.firstarc;: H: r7 }: @* R0 e' C
            while (p != NULL)
    ( _. s$ F% ?! a! k4 `  U        {
    ! O+ Q7 I, V; L+ {* w8 i& c            InsertArc(p->adjVex1, p->adjVex2, p->weight);3 T0 F& A  _: I. g8 G
                p=NextArc(u,p);
    9 Z7 }8 ?* _9 f# w        }
    ! P/ K- a3 }6 x* p$ l    }
    9 x0 K3 @8 i" H) b5 k    return *this;3 v6 K8 P) l& b1 \2 c: @, I
    }
    ( R0 [- r" A# x" i* b5 }- ztemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    0 U2 B. M3 L1 y1 \- U8 R$ UMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const- L( X% {4 p# y
    {
    / z$ G% I! X% u8 W7 A    if(p==NULL) return NULL;
    4 w5 {1 T4 a* v; k  `8 N% b    if(p->adjVex1==v1)+ w; W6 v1 n5 \! r( c
            return p->nextarc1;
    6 K* t8 y6 x( h3 j) |1 k4 V6 b! O& i0 a    else) c8 h* s  P4 Y* d# [, s
            return p->nextarc2;7 V1 w- {: v- t( d
    }1 w8 G+ |6 G' d9 h9 [- r
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*- x% f% E; b5 R9 n1 B. e# l
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    3 M  p' ~# L$ y6 |{
    0 l/ j+ J7 Y9 b$ m( X    if(p==NULL)return NULL;1 L, w$ m; W! `7 k2 C
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    4 W$ `% S4 G& I* @/ u    if(q==p)3 n7 l" C7 |# H
            return NULL;% ]+ H2 n! e. {$ R3 X( `
        while(q); a2 ?5 O6 M; B
        {& Z% `0 [& H* g/ ]- b" A% s
            if(q->nextarc1==p ||q->nextarc2==p)
    & m4 z" I. [& J; c  q            break;
      S* h# a3 v1 G+ n$ t' ?        q=NextArc(v1,q);' r' m2 o2 F1 C9 d& _% D3 B1 `0 y' F
        }
    9 N( T+ s4 y& A! T    return q;
    # H2 Y, O; E% a9 g  Y( g}: d+ U1 ]+ G( Z' w0 c- ]+ J
    template<class ElemType, class WeightType>
    5 k) R2 b" D) U( Q# ?4 V: `" C! Evoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    - L) r- J% G' Z1 W{7 @/ C: c5 m/ g" W- C" F5 U0 F$ u; G+ X
        if (vexNum == vexMaxNum)' e" G4 j  l9 q+ r( @# I/ E1 [
            throw Error("图的顶点数不能超过允许的最大数!");) m" @0 T' d7 B8 j. b$ v* M6 T
        vexTable[vexNum].data = d;7 d  C' w. t/ S+ @) O
        vexTable[vexNum].firstarc = NULL;
    7 W& r3 p$ o) j+ d, O* Y. o6 a    tag[vexNum] = 0;3 \# K# B: r1 E$ H2 r
        vexNum++;" J% e& @2 @! b' l
    }: G9 f6 O  w5 C5 p
    template<class ElemType, class WeightType>
    ; k9 [- |- a6 ~! svoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    # E* f% y. C4 f6 r9 `, C" N{- _- }% U' ^1 J% J, n
        MultiAdjListNetworkArc<WeightType>* p,*q;
    ; `& Z% \+ c3 V$ K    if (v1 < 0 || v1 >= vexNum)
    - c% R: Z5 L: t* F: u, c1 x2 ~        throw Error("v1不合法!");% t9 K) F) \7 f& B; A7 E
        if (v2 < 0 || v2 >= vexNum)
    5 I$ p  }) q5 I! k9 x! C6 D        throw Error("v2不合法!");
    - J$ H( C  M1 y0 m( |- H5 s% U    if (v1 == v2). _# Q: w/ u  f  ^& \7 f5 e
            throw Error("v1不能等于v2!");
    ' \) w, F5 @+ w5 w% M* w( f    if (w == infinity)) }1 ?- [1 d1 f$ n* @
            throw Error("w不能为无穷大!");
    " f$ _& U) H# r( [% b- n7 i# y
    - m! V' c8 @' m
    . ?. Z' H, A0 Y/ o    p = vexTable[v1].firstarc;" a7 N0 p" K* Q9 a8 }
        while(p), b% j/ f  y/ Z# b! e- n2 i
        {
    * i: b& I; l2 g6 I4 H$ D1 h) m8 W9 m        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    7 h# u7 i. y5 v- ~: l/ x        {( w0 Y4 Q8 d! j6 D3 O2 L+ ~# w9 j: S( C
                if(p->weight!=w)
    ; l! p1 z( l  T. h: l+ r* b& D                p->weight=w;( x& u2 ~) Q9 T  f1 y" U
                return;% ?& a! b, E; h3 ^5 D7 j/ d
            }
    2 h2 H/ t0 t: V
    . Y" p/ l/ B% B7 H        p=NextArc(v1,p);
    * ^5 _5 e# f; ~4 m4 V    }
    ( ~0 ?+ c" c+ ^& N! Y4 [; m" w* h    p = vexTable[v1].firstarc;( ^* @3 m; B. u/ D4 e" Q
        q = vexTable[v2].firstarc;, B4 t8 B$ o  h+ U+ h1 a
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法# x5 Q: N; P: R: ?- U( R' [" n
        vexTable[v2].firstarc =vexTable[v1].firstarc;# w0 U9 z% H0 O; B! ]
        arcNum++;
    ; B8 q) {2 N' R  V8 n  n}# h1 b. x) q4 W: @8 G8 M- g) t

    ; X1 O; ~( S2 D* Y0 |template<class ElemType, class WeightType>
    0 o( H1 ?, t' @* A! nvoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)5 v  S4 `. U* M4 K3 x& ~
    {
    0 a; _7 g# p  }' |7 H
    + }8 y1 i6 e* f) M% K( G' ?- e    MultiAdjListNetworkArc<WeightType>* p, * q,*r;; c/ O* d, i" [' B/ b; u$ j8 m- S6 I
        if (v1 < 0 || v1 >= vexNum): ~3 j0 Q5 N0 ^# ?
            throw Error("v1不合法!");
    # x* _: T2 B- T( ]% {: R/ C7 {    if (v2 < 0 || v2 >= vexNum)
    6 |, S6 F  c: H/ p/ h, ~        throw Error("v2不合法!");  a# E! {& `3 \; z& j5 a- i: E
        if (v1 == v2)' r; U$ b0 q& e. G' T$ V; c; |$ r
            throw Error("v1不能等于v2!");! M+ B" t! m" e" \- g% j
    , q: z5 D  ^( Y, s$ h
        p = vexTable[v1].firstarc;
    " x" z3 m# w2 q    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    0 x2 Q3 ^4 C$ {! @    {! _; L$ T. [2 u' B& C  y: \! g
            q = p;7 D2 e- `: n7 v3 j/ e; c
            p = NextArc(v1,p);4 R) k0 a0 f- D$ t: [. j
        }//找到要删除的边结点p及其前一结点q& [( j0 n! @4 V& n$ o1 P2 X  ^* K& `

    . T7 h* a; r7 n1 c, e( D1 w    if (p != NULL)//找到v1-v2的边
    4 J+ b0 v+ ^3 r7 N6 H  W    {4 i# {' [# }1 n8 w7 x: N
            r=LastArc(v2,p);2 j" M! E( r2 R5 F4 H' _( R
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    ( N. V0 W+ k% s6 O0 a            if(p->adjVex2==v2)
    ) v- o6 \. W; x! @1 T4 A4 W                vexTable[v1].firstarc = p->nextarc1;
    3 d# J3 f" U* F. I            else vexTable[v1].firstarc=p->nextarc2;# n6 k0 D% u5 \, P- i% u
            else//不是第一条边  P  r) f- f' r$ ]1 G. |+ i  @+ _
            {
    " i' |/ i( Q/ U( f' J1 L! V3 \! s- [            if(q->adjVex1==v1)
    $ X0 ]" c0 P1 m                q->nextarc1 = NextArc(v1,p);
    ! ?! t. E; d, C, S            else2 R8 Q4 F7 s) B0 u6 X4 O
                    q->nextarc2=NextArc(v1,p);2 Q* o7 U9 k1 k" I, P, ]

    4 e/ B. C( W) M# Q: h        }
    - L! Y3 R' {! A" D) M+ ]+ m        if(r==NULL)* |7 i3 a6 I, R* [3 s% Z
                if(p->adjVex2==v2)
    % S/ K! M. ^) K9 Q1 x9 L                vexTable[v2].firstarc = p->nextarc2;
    ) e7 ]0 j5 X3 e7 q            else vexTable[v2].firstarc=p->nextarc1;
    ! j0 t# \; ?7 C; M1 a' U0 z        else4 L4 \1 Q: I( x3 q% n9 J4 w
            {3 j7 O* ~8 q+ }% R8 C( t: `* h$ l7 h
                if(r->adjVex2==v2), r2 t' ^8 Q6 a0 Z* G
                    r->nextarc2 = NextArc(v2,p);
    # p$ W& E$ h; Z/ g. C+ d! [            else8 y' L$ Q- _3 Q: K, b( a* n
                    r->nextarc1=NextArc(v2,p);
    6 g( }. `% r1 _* o  n( X# k        }1 E9 T0 {5 k0 j: g
            delete p;' O1 f- S. ^6 d
            arcNum--;. S' d6 t5 O" ~1 j$ J: T; E  X
        }; M& p9 G" J: J6 s6 X: L
    : W, ~- I* Y1 k- I
    }
    ' A! _9 m1 l: x" w; ~: }template<class ElemType, class WeightType> void
    ) ?$ E" f5 v8 `  U& e* ^. B5 \4 NMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)( q; Q% t4 l# f- v. H! q
    {
    9 }7 E( k) B! X# O) }5 |    int v;
      Q2 g5 S! M4 O6 q) d/ X) x    MultiAdjListNetworkArc<WeightType>* p;+ k) \1 C, {# R& J. U" v
        for (v = 0; v < vexNum; v++)//找到d对应顶点4 J2 Z1 q! ]5 ]3 @6 ~& G' W, \
            if (vexTable[v].data == d)+ P: W7 O/ M% J; t* L0 L
                break;$ r3 a+ u3 J. B
        if(v==vexNum)
    1 R* f/ G# G7 }$ [        throw Error("图中不存在要删除的顶点!");
    6 z3 t" G5 Y* Q7 U: K6 Q, v: K- n) T: s1 l" P
        for (int u = 0; u < vexNum; u++)//删除与d相连的边7 `2 F: u7 P4 }8 I# L! i
            if (u != v)
    , `9 G; }/ ]$ x        {9 @, ~* j& I$ E( z& I3 f
                DeleteArc(u, v);6 T0 U! \4 A* ~0 i6 U8 u0 w
            }
    * d* ?* `& _& s, p9 A1 G% {# P3 o! `    vexTable[v].firstarc=NULL;  g8 d: O  K, f5 E6 {0 f7 `

    ) Z* ?8 X. V& K! T& Y    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置7 q5 R* {5 o: b0 w+ ]1 S' ?) X& i
        vexTable[v].data = vexTable[vexNum].data;
    + n7 I# l: q8 Y' W/ j4 Y2 i    vexTable[v].firstarc = vexTable[vexNum].firstarc;
    % d) @+ J% v+ I, U4 k7 f    vexTable[vexNum].firstarc = NULL;
    / m0 d2 Y2 I1 G4 U4 C! l" W    tag[v] = tag[vexNum];4 x) U( a, F" B7 d7 N
        //原来与最后一个顶点相连的边改为与v相连
    : \8 {0 d" M2 I) S3 Z    for (int u = 0; u < vexNum; u++)
    . m+ i+ A" A' Y% }; Q- s    {
    6 x7 P" s' P+ X& E- P        if (u != v)$ K/ Y9 A) O+ o" x
            {
    & M9 ?9 D$ d; U: U" }: p0 }            p = vexTable.firstarc;9 E9 Q5 U& C( _5 N1 o
                while (p): {5 A! k' N: ?! E. O, H
                {* e0 N- I' U( @7 e7 }/ R
                    if (p->adjVex1==vexNum)
    " X2 P& t: _% R; j( o                    p->adjVex1= v;
    + P" e; @5 w5 Y3 L$ o6 Q7 U2 s, |7 x                else if(p->adjVex2==vexNum)
    9 |, e+ S; S" ]4 _- l7 x                    p->adjVex2=v;
    6 t5 Z1 Q0 g8 O3 p# B: |) U) ]- _4 O                p = NextArc(u,p);
    4 m  H% y7 b( Q/ Q            }/ g0 Q& d( G; C, O, n6 r
            }
    5 [, L! k( v$ g7 V    }
    4 H$ u( ?  F. [5 V}! f- L( i- G. m9 j1 h+ `( ~
    ///深度优先遍历
    . b: y. l( D$ m+ J' B: Rtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)' [# \. q1 S7 ^& C2 R5 l
    {" j* |$ Y; T, q, c
        tag[v]=1;4 x4 h. b' f, ~: n9 D
        cout<<setw(3)<<vexTable[v].data;% U$ |% H+ b9 G$ G' G" |; l. x
        MultiAdjListNetworkArc<WeightType> *p;2 @- E. K+ I" E: f0 p# ]+ O
        p=vexTable[v].firstarc;
    3 f5 l; S6 [6 ?+ p    while(p)" V6 q( L; S, d0 Z+ n8 Z, v! o. y
        {
    $ e* ~% B+ K9 w        if(tag[p->adjVex1]==0)
    " X, D9 P- ]. Y3 Y9 s' k            DFS1(p->adjVex1);% x: @; k2 |2 `' M" P6 z7 v
            else if(tag[p->adjVex2]==0)  N: |# D2 R2 w8 @7 U
                DFS1(p->adjVex2);4 C8 [6 p+ u5 u' L5 d" p4 Z, ?& W: Q
            p=NextArc(v,p);. \1 T4 G% ^9 ^; \  Q0 `% O5 t: w* ?
        }
      x7 ]2 r# z2 B6 g! @7 I}
    ( G; I+ T8 {( z0 q( Q" ]1 Otemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    9 Z, @1 [# D1 N' o! o9 w* i{
    7 A" I0 O' D9 K4 J8 g# f    for(int i=0; i<vexNum; i++)
      Q; B8 M; I  }. m! m. y- m        tag=0;! t8 ?! ]) n0 `# G
        for(int v=0; v<vexNum; v++)
    3 q2 V. L# z  K    {
    8 M7 A) Z6 i, k& q' F" }3 |        if(tag[v]==0)9 \5 M7 C3 h; p
                DFS1(v);5 k$ k+ ?, ^3 n' J
        }! x7 m  w4 J& K# A" `- X3 J# g
    }' _) B" m" \/ c# Y- A: z$ Z
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    1 D9 L) ]& ?( G/ ]  X! A0 [{. [/ p8 T0 c8 z* v, e3 T$ s
        stack<int> s;& P  E, i, {; s- G  {- b6 k; D  {
        int tmp;0 Q( S. [3 e, O+ Z
        MultiAdjListNetworkArc<WeightType> *p,*q;
    : A' u2 U. L1 {+ Z" k, c! C, F5 h    for(int i=0; i<vexNum; i++)
    ! R. N- r) l! {& ^" J( q        tag=0;3 l3 y) k9 f4 W( e+ [$ v
        for(int i=0; i<vexNum; i++)6 A5 ^  Q+ ]% K+ Q5 C+ v  C
        {
    $ L/ B7 R& ^. v. N        tmp=i;  f; R- C0 V) Y: }% r
            while(tag[tmp]==0||!s.empty())
      W& x* q7 I* L  ?        {
    - ?; i6 \* _' k$ r, c1 u            p=vexTable[tmp].firstarc;' \- z. |- U6 C# U6 y5 Y
                while(tag[tmp]==0)( t/ f- v$ T) z) D: i3 ~/ h& n
                {. i- N# l, f' t
                    s.push(tmp);
    0 r6 A/ Q- ^6 W) T! M2 k                cout<<setw(3)<<vexTable[tmp].data;7 |# Z) i+ L/ h
                    tag[tmp]=1;+ X' R1 G& H( N3 |1 w
                    p=vexTable[tmp].firstarc;
    ' b% x% a  D( I. N9 ?7 ^                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for! y$ k* e2 y+ s) R5 y
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);+ D8 w3 S7 C2 E9 Y( ?. k0 e
                    //cout<<" 1st     tmp="<<tmp<<endl;
    1 `; i! F, z2 Z1 Z6 ]0 B            }- ~/ d6 J. x; F' y$ l
                if(!s.empty()); y; K! S5 u) R& ^+ k) W4 X5 A
                {' b$ z8 G* b2 u, P  L& B1 M( |
                    tmp=s.top();* ]& E3 C, h: H" W, S
                    s.pop();
    , x: _0 Y7 }% G, V                q=vexTable[tmp].firstarc;
    - d' G7 S3 ~+ H8 c                int t=tmp;/ V! U% Z' x1 S; f: J6 @% f
                    while(q&&tag[tmp]!=0)  R- x( E1 z% |! I" d9 @1 _
                    {
      X) p; o  N# z% u+ v                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);3 U, n- Z  s- _1 J- p# b
                        //cout<<" 2nd     tmp="<<tmp<<endl;6 C# a4 \" Q$ m8 [6 z
                        q=NextArc(t,q);, N) N/ d1 Z$ U% X- c& W
                    }
    # A. N" L; s* i- K                if(tag[tmp]==0)
    6 j$ i' H/ w. S4 \7 f; [3 l7 v; }                    s.push(t);
    & N7 }% U2 j' ^7 K' Y) k                ///1、对应上面连通分支只有1个点的情况  B7 K" T+ [" o: l# D! V: X$ G/ e; E( k
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    7 U, M6 {  X6 c, }3 j2 J9 g) N' J                ///tmp要么等于找到的第一个未访问节点,
      W2 g6 [# R3 H                ///要么等于与t相连最后一个点(已被访问过)3 r2 i+ t3 Z: m# J
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    " h5 F7 D" H% ?  w' s# h# H0 Y            }
    1 x1 u3 Y# t, v, x        }
    $ {- ~5 g. ?/ a7 \: t9 @% S    }
    3 _# H& y" B1 C* I7 }* M}1 A0 y; T1 y$ I# H  P8 q1 \1 n
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    + ]3 k& m: G  E. y% q8 ~1 `; Ctemplate<class ElemType, class WeightType> int& \7 L9 }$ L% K; t# u
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    8 X8 V6 \% H" u/ n9 I{
    ( W5 N  U$ u* Z2 x- f' n  B8 F    if(head==pre)
    0 F& B8 T+ ^# [# V( o1 J' M/ w% c        return -1;7 B3 K: f1 D" \# n; G2 i
    6 G# x8 \, J$ O4 p
        MultiAdjListNetworkArc<WeightType> *p;
    " J* V* K- C/ n" w, M& o' _    p=vexTable[head].firstarc;
    " q& {0 t' s2 U; Y) B% B3 ?* y    if(pre==-1&&p!=NULL)
    / L" g; O( i8 m  a, [2 f$ x        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    # a, @, v) l) u0 I& g    //pre!=-1&&p!=NULL
    9 Q1 O' R) {7 N" X5 ^    while(p!=NULL)
    * N+ h5 o5 r$ o" V3 p/ D" ]    {6 h3 b. T1 ]  \' i1 l7 B) v# i
            if(p->adjVex1==head && p->adjVex2!=pre)" E0 Z) l& \: p7 ~* D( t! i
                p=p->nextarc1;
    6 q/ d+ m  l; m* Z        else if(p->adjVex2==head && p->adjVex1!=pre)+ W: s  O( E6 k. b2 c' H
                p=p->nextarc2;
    8 ~2 H! S7 z& z8 f, k/ C4 f) C- i/ d        else if(p->adjVex1==head && p->adjVex2==pre)6 F+ S7 [& o8 L  X& X6 c8 t
            {. Z! F: f% o0 w2 v1 x. w6 u- ~
                p=p->nextarc1;
    , D9 t2 u. |' H* r/ ?            break;
    + T; N1 C: A: K) n3 Q  F        }
    ; h) z2 R; A9 `, l& D/ v! A# H6 @        else if(p->adjVex2==head && p->adjVex1==pre)
    9 s) \/ K' ?, y# J; A8 Q9 V        {
    / _) o0 d2 i4 Q/ z            p=p->nextarc2;
    % ~5 z& A9 z: x' |! o- n            break;+ c; q( {0 z& P% @3 K  X
            }' g& B% r0 ?# N+ K
        }# G- l# H  C  t
        if(p!=NULL). v" X. J* ]. b* K
        {# n0 b$ O! _6 K) ~
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    1 c' ^& |6 Q) o    }
    + }6 n3 S  U) @  }* u7 q    else
    " O* v5 c" T( h3 g        return -1;9 j" m) j& R; j% K$ }# s
    }
    + U$ D& J2 q4 S0 n; l5 X. s, Z0 Q! r2 {: R, c2 V. s" q8 x% R. A2 h

    % X- F5 e& I( s5 x( `1 B3 Otemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3(); P. V+ F' o- R- c7 u' w
    {1 _; A0 G' w9 x+ @0 i; r
        stack<int> s;/ ~6 B* q- ?5 s1 N! H' m, D7 n
        int p,cur,pre;
    5 Q* }) D8 v4 ]- t    //MultiAdjListNetworkArc<WeightType> *p,*q;* L2 m" N2 N* i% M, J. n
        for(int i=0; i<vexNum; i++) tag=0;//初始化4 w7 b. P2 ~; O# |# Z
    & t7 |- u( `3 Z' F7 [8 @, m* ~! c% a
        for(int i=0; i<vexNum; i++)2 r+ v7 @# v' j
        {
    5 u3 @# G4 \! q8 v8 ^        cur=i;pre=-1;
    0 ?4 U7 r- e7 o! s" r# b' L        while(tag[cur]==0||!s.empty())% |' C  t3 I* g( Z+ @- X  y, d3 L2 `
            {) F1 Y6 R+ h0 g' j( w- T4 Z
                while(tag[cur]==0). j1 [. P; p9 T. \& B2 e# E
                {
    # V. Q; T; j2 a/ a                cout<<vexTable[cur].data<<"  ";7 Z: U% w" i7 X) _9 R
                    s.push(cur);
    8 r% c& j7 I' j1 [3 g9 q8 Z                tag[cur]=1;
    5 M1 K) L; v! \1 A1 n: X               //初次访问,标记入栈
    - E8 J9 L5 d2 L; K+ r
    1 q: R/ E1 W* f               p=GetAdjVex(cur,pre);//p是cur的连通顶点- a2 M* B3 b. K8 F" x/ f
                   if(p==-1). x# h" U& G3 n# ?* H( P& D
                   {
    - a9 x6 {. q' Z. r6 c; s, F                   pre=cur;s.pop();
    % D* P; S) _4 H2 r                   break;' q) P/ a) o/ c7 e; b
                   }
    : Q1 k( m% n# z- |" M' ^9 b               else: a9 d/ K7 h8 A3 E! n4 B& `
                   {
    + T: B6 p1 P8 D$ P, B                   pre=cur;. G1 h3 K4 _: o
                       cur=p;" L+ \5 ?. k; R
                   }4 j+ k6 X. Y: h' x% k

    & p2 v; @3 ]* F' ]2 f" V5 `            }# b1 L. h1 b* i- r/ }
                while(!s.empty())7 E. X- \: |' Y4 n; D
                {
    ( ~0 T. D$ Q+ i% T& l1 b. P  b$ b                cur=s.top();" C7 v! J$ c* {9 m, K
                    p=GetAdjVex(cur,pre);6 R, d* T8 \1 q; _
                    if(tag[p]==0)3 ^. I9 y$ d; s
                    {/ M5 G* L( a1 F$ F4 n. D7 m
                        pre=cur;
    $ z0 ?+ {! G  [                    cur=p;
    ; h5 ]' _2 D" B, a; L% [# i+ _                    break;) {2 ?+ s' P9 Y  _% s
                    }
    : Z7 U# D9 Y, x+ L& R                else3 k: `" B' O/ F  w2 |2 ]' D# w9 X
                    {* ?! o# k# v0 ?# K' C# E
                        pre=s.top();
    ) p& f# x% G8 K1 w) p% R                    s.pop();
    ) t2 @2 U5 @5 n; d( J' t4 H$ r, X                }
    * ?& n% |' t5 w2 i+ P8 o3 U( f9 V4 A2 B$ V+ ]( J
                }9 p. d5 _$ N' N9 S9 v2 p- D+ Q9 M

    1 \3 x* h8 _5 f3 S        }4 C7 e, T* s4 L/ F6 _7 z
        }
    : Q" j1 d, L% u6 w- c' H}
    / Z0 x$ M( D" e* ?: g6 k' ^template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()) B2 r  Q6 \; P- y& s8 r4 D
    {$ |0 h) _; O: \1 V/ ^  v. i0 x
        for(int i=0; i<vexNum; i++)
    6 U+ H. P1 a: R! r- @9 @+ C2 G        tag=0;2 D+ [% J0 `0 r  `' S- a
        queue<int> q;
    1 z- f! g8 `+ _4 O  T    int tmp,t;
    9 S7 P9 w( U4 T+ V" h& g    MultiAdjListNetworkArc<WeightType> *p;) T- s+ ?, d  P* A  R2 ]
        for(int i=0; i<vexNum; i++)9 x4 F! e3 d/ \6 I1 a( V
        {+ n, u# V( S/ L! ]0 e& o* ~4 O/ N
            if(tag==0)6 W) x) L) s6 [5 T2 s6 ^; v: u7 n
            {
    . g5 g2 K& t! q' W            tag=1;9 y! @  w2 y/ G4 @' w0 a
                q.push(i);
    , t! F! G  E" }            cout<<setw(3)<<vexTable.data;
    . }1 p8 a# C: M' P2 ]- v7 D        }  D  N- F3 F3 O9 t+ ~8 r* ^3 H. ?
            while(!q.empty())' x- ?( F; T, u: }* C! h
            {
    - e# i6 J7 R: s3 ^            tmp=q.front();
    7 m# ~; Y4 ~& r7 s. {9 q; `7 G            q.pop();
    9 Z4 u; s- x$ ?            p=vexTable[tmp].firstarc;
    ) E! v; A. v2 T+ N            while(p!=NULL)) Q) F$ ~6 |" ~+ D, P
                {
    . D" {) C/ ]  X2 L                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    0 b6 L& w3 |/ b6 `% j) F7 w8 n                if(tag[t]==0)# {. W7 u  T. C. Q; v
                    {0 \, N/ ~; {. r: d6 T. I
                        cout<<setw(3)<<vexTable[t].data;/ f5 W. K2 E9 L- Z0 B0 e! G! i# d
                        tag[t]=1;
    ' o  \1 P; {% E5 I                    q.push(t);  r+ M9 X- D  \$ D! ]
                    }
    ' p- F% h3 ]9 U+ ?* H' ?/ k                p=NextArc(tmp,p);
    2 C, S4 x: _0 ]& Z/ ^% N7 ]            }' G) E! i2 c/ T! V& L( Z  F
            }) V- |2 {, J! Z1 z1 D
        }
    ! V' X$ }/ G# P5 H: P! U}$ g1 D/ e: V$ M; z$ R' e2 z
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()6 p& B. l2 N9 q0 K* m" L) E
    {
    , O* u4 a, g3 ~7 R9 g4 k    MultiAdjListNetworkArc<WeightType> *p;
    . ]0 p: r- a  `3 R" l4 z    cout << "无向图有" << vexNum << "个点,分别为:";
    " w% @- y3 L" |4 X; }( P' M- u    for (int i = 0; i < vexNum; i++)
      C  n3 _0 r+ n        cout << vexTable.data << " ";
    - ?# C) y9 _4 ?: I/ g; P    cout << endl;3 j  R5 Q! O% q' `* k. R
        cout << "无向图有" << arcNum << "条边"<<endl;0 k. [9 v* L. I  R" V/ r& ~/ q
        for (int i = 0; i < vexNum; i++)
    # w8 }/ @8 }3 ^& n( f    {
    # e6 K/ m2 q' _) O3 j        cout<<"和" << vexTable.data << "有关的边:";+ b0 y- a% J# M2 T  c& b+ e+ m" ?
            p = vexTable.firstarc;6 \! p/ N+ `/ J( Y+ K( L
            while (p != NULL)3 @2 V# Z0 u: Q. Z- S8 H5 o
            {
      j4 P2 g! M& T9 y$ h7 Y* u+ t0 A            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";- L# T+ D9 C+ N3 c
                p=NextArc(i,p);! U/ M+ d  D" C/ J: i6 T$ i6 {
            }+ z* G% r6 K6 d# S0 m
            cout << endl;  u+ }2 P0 r/ G% q3 l
        }
    3 h3 x- X5 v, [- M}
    ( J( m5 `& P" g( ?# v. c" M
      Y3 a- i+ K2 A; ]* b& v. ?- h. e& C3 {6 i9 ?( K4 d
    邻接多重表与邻接表的对比8 G+ R4 t8 Z* i6 N2 K0 j' Q" Y
    % x6 M3 ^3 F" `* r$ }9 V
    邻接表链接
    , T3 {$ d* P( z% v* L# c& @/ ]  f在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    & r( G# x0 B* q& M, G在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    ( M) s/ g* \% s  o  W$ }为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    & v4 ]9 l4 X" H; ~————————————————9 ]! s% h, x. H6 Y
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ' z( R# k) i2 o6 N# h原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669582 u8 L6 q/ z+ ?, ]2 R: _

    - R. B* N" ]3 O3 P4 n9 n4 }! X: v5 y& B5 I: q

    % S1 e. d- c  b; N& u. G: s# P6 v  U( m  J3 H
    ————————————————
    8 C3 g) {3 v8 B# Q4 D0 R) ]版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。8 K6 ]4 }" u. `9 \
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958& [5 ?; ^0 b- M5 k, V" l- m

    : q: L) |" T- l. U, M6 l2 N) m! T5 n% P8 N0 _
    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-7-25 06:20 , Processed in 0.563574 second(s), 54 queries .

    回顶部