QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1657|回复: 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
    : z9 C# j5 k# l
    图的存储结构——邻接多重表(多重邻接表)的实现$ ^' M5 V  f* s% N! o# h
    7.2 图的存储结构
    * o( f: ]( y* V) b$ x; n8 i
    7 C- O* n0 h) W7.2.3 邻接多重表(多重邻接表)Adjacency Multilist1 ]. \* c8 m1 z6 U1 d
    邻接多重表的类定义
    $ L7 p& t, {: L3 n; C, p9 F2 b8 [邻接多重表的顶点结点类模板
    ' C9 j5 |% q2 E" x. c邻接多重表的边结点类模板
    ; s. `* K4 y! D+ r( `  M9 c9 p  x' X邻接多重表的类模板
    2 K6 A2 l8 ~3 T# ~$ K$ C, W: F% K邻接多重表与邻接表的对比/ C" N& v" H$ {2 J  l) l9 X! B! x
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist4 `0 f( z# o. _- p
    9 A/ R3 F+ X9 {6 u8 e
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。" X5 [. U1 H1 `* L3 e
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    * s5 W6 X/ T8 P* u4 ~( S3 I+ D4 G7 o& p: b" u( Q9 c
    邻接多重表的类定义; Y$ u' T( a: Q  E* I
    1.png
    2 g" D6 t  [* i6 g/ I邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    % ~6 d$ h. `1 `. t+ b. A+ s3 rdata域存储有关顶点的信息;2 d+ D/ @9 y0 D, k6 I6 }, D% k" ~* R& r
    firstarc域是链接指针,指向第一条依附于该顶点的边。
    8 P) \  r% @/ a4 e3 H$ i, k所有的顶点结点组成一个顺序表。

    . L  {/ J% y8 F7 I+ S
    * O; w/ {0 p& T! b. f( }
    template <class ElemType ,class WeightType>  Z( c2 K* r  A" V6 \* t+ ^+ h9 n
    class MultiAdjListNetworkVex
    $ S5 c# y/ k. j7 t- d" ^3 }{
    6 x4 t6 y6 H8 d( J! d# j( J- jpublic:
    5 u4 R2 P9 f9 c! a        ElemType data;
    . Z, u0 u( |; y6 D5 `0 h        MultiAdjListNetworkArc<WeightType> *firstarc;
    7 n* d1 h0 H2 x5 ]
    + c/ j& z$ C$ V' t( o8 n; T% Z        MultiAdjListNetworkVex()! n" E" k- I! z% _1 \5 g/ Z2 f
            {
    , C, v) w# V6 a) v                firstarc = NULL;, ~! V/ t' f8 o3 x- ]8 x
            }/ R  m3 G  Q+ i& P! c
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)8 O' A0 x( Q( y% ^: m# F  W
            {
    : r. a/ Q) F" K+ {2 W4 @. W                data = val;
    5 h) N( h1 @! x7 B                firstarc = adj;
    : y* G# O1 e7 \1 E% p) l, W9 U8 w        }
    / B6 M2 H7 ?) o+ j};4 O2 f7 l8 [' j6 f& V& ?
    6 R4 y! S* q' b5 m% V0 I: p
    邻接多重表的边结点类模板" {' s: x+ s% S- J! T) A& k
    3 M1 B3 X; U1 M$ D) c6 v
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:' D1 [# X( A, o- E! Z2 b
    tag是标记域,标记该边是否被处理或被搜索过;
    + ^6 Z4 W: f* A) gweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;0 o; A6 Y/ k2 V
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;' Z; b+ Q) t' q. u8 s# i
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。5 Z, _  z% S. n# ~4 W* G9 ^; z- v
    5 i  o, u  c  B8 l
    2.png 8 {' ~$ r" e1 s2 F9 O/ _
    template <class WeightType>3 @+ r' T! t- g! K) J/ s5 K
    class MultiAdjListNetworkArc( ^: w% d8 k- _- d
    {4 p" r2 [1 G/ f5 q+ |
    public:
    , a4 K2 V/ f: d; s$ o; Q  a    int mark;                                       //标记该边是否被搜索或处理过
    7 E/ j/ K; i5 x5 O        WeightType weight;                              //边的权重- V+ I. ?1 K- M$ O6 ^; j0 \
            int adjVex1;                                    //边的一个顶点
    * x) v1 q& L6 D( B: K, P        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    ' D! l" y% o) ~, a8 F% d5 k; a        int adjVex2;
    ; Z0 @' ]. Z5 t4 r4 Y9 K% @$ T        MultiAdjListNetworkArc<WeightType>* nextarc2;3 |: j& p$ z" {, C. d. t

    * p$ {% m$ x7 G" |        MultiAdjListNetworkArc()
    # p! t, ~# ?3 K6 L        {  A4 K0 C/ E! l$ D, N5 M5 q( |4 }
                    adjVex1= -1;# I* P/ z( o9 _" F. i6 ?. O- ^
                    adjVex2= -1;5 O+ A6 z6 {. h3 @9 F: i
            }
    6 o" M' J; }* K/ A        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    6 U. n' `; t$ V" s& F& P        {
    - e$ A* g- a* Y  H9 Z( V                adjVex1 = v1;       adjVex2 = v2;
    ( I. F0 i* K; R; c6 ]  c: d( N                weight = w;
    & P# c- e* X5 ?% ?, x3 F9 e0 d                nextarc1 = next1;   nextarc2=next2;7 O# ?3 ^# f  t) B0 g2 h0 m' H
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    $ h; b2 U) g& I. g0 c9 |        }- q- j, I7 L4 @) e: M) E1 A

    $ y1 @6 E! g% f' Q' U3 P邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>: X2 W* }0 O& R& B9 h
    class MultiAdjListNetwork
    - b, ?! }8 p+ K/ I: K{' n' a0 c) Z7 ^7 s
    protected:
    ) I, h2 x8 T+ i6 B, t1 M    int vexNum, vexMaxNum, arcNum;! r% \# }5 j! v! w9 c5 e
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;/ K% z, v4 |. K
        int* tag;
    ' N$ G, }$ v: f  ]8 [" p- S    WeightType infinity;
    6 u, d9 z# A- Q) o9 X7 K& ~3 }1 E9 |5 [, Y4 d8 x) c
    public:
    # P" k( y# T, ?8 R" h3 K    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    + P4 p! h2 a6 ?; O% R: `6 }  Q6 a& ~
    7 w+ t& H/ }( ~+ k  N5 @    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    1 v  c3 {6 ^2 o( ]6 \) q  D8 k6 Q6 Y7 t  ~
        void Clear();0 ?4 Y$ [0 h- j; ], v) T" @
        bool IsEmpty(): e9 f  _! d4 E0 Y
        {' n0 Q( z4 F8 J; D
            return vexNum == 0;
    % K5 ]8 ]& j& e& L' N    }
    * g' r* w) r, w, T    int GetArcNum()const
    + V0 T& z& j8 u* i1 O    {* [! }% l" L) t( I3 @5 p
            return arcNum;
    & [# l) O! @0 q, g    }% T6 J+ j( [! {; K
        int GetvexNum()const
    . c7 y$ ?# U! |  B: v0 y    {
    6 i+ i3 p$ u1 y& P9 f        return vexNum;5 ?/ b& R; D( j) c2 O/ m
        }; T  K1 a9 Z* ?+ O
    4 t+ v9 j( u  c- n+ z
    ' W6 E, S/ ]1 {9 U( j
        int FirstAdjVex(int v)const;! C/ H' N% {1 u$ s
        int NextAdjVex(int v1, int v2)const;* v- g* ]1 H7 d4 K9 [0 U
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    " p# d$ B! _; J    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;. K$ h+ ]: b5 |* @& @1 l
    - W. Z7 R  D/ p/ t
        void InsertVex(const ElemType& d);& C# d$ e0 f8 Q3 b( l
        void InsertArc(int v1, int v2, WeightType w);5 W) B' J: Y3 Q& S
    ( c% V) w! H$ s' Y
        void DeleteVex(const ElemType& d);
    8 C) }) ?7 i4 S1 }    void DeleteArc(int v1, int v2);) C& p# q" j, q, P6 j
    % U$ L$ O. H! D) c
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);# \; n9 I( w0 l* a+ T! l
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    4 R/ w& p9 r0 y$ d$ f. J6 ^3 A" m4 P0 a
    4 \: M2 a& i5 {% D4 c5 l+ h! X    ///深度优先遍历7 g% d9 N, `3 j0 x% R! Q! u2 {
        void DFS1(const int v);
    ' V& I6 `0 P. ?+ G8 @* @+ C! A    void DFS1Traverse();
    & c9 q, \7 s' \7 S" _    void DFS2();
    " I6 J9 o# H- i. }1 c  n" R" p$ ?$ y: W1 E, K* R
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-12 U0 d* p" k0 l
        void DFS3();9 r5 j, a: @; c. \) u+ p
    / G) [* F  i! M8 A" Y& z- J  K) Q
        void BFS();
    9 }, {+ v/ e7 `& A    void Show();7 }8 |8 g  ]/ }1 Q' I$ t  ~& T$ O' P
    };" H! c  c- S+ v& i7 e" m8 S
    % C: v. D- s' Y# d
    2.函数的实现
    3 \$ A! R) Y) g. E) w! f研讨题,能够运行,但是代码不一定是最优的。
    ' P( [/ O, t% W
    - E4 s8 Q% {2 k1 S, y. d#include <stack>
    ( e6 F- R' h& l8 }#include <queue>
    + Q. U8 ?8 D' |8 p( j+ W9 W& Q( G% x$ }
    template <class ElemType,class WeightType>  Z) m; U1 q! o8 I4 e
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    ( J* g+ H$ c2 X* p7 W1 M{
    * I7 X& k; g) ?' C+ ]    if(vertexMaxNum < 0)5 w2 ^- m& b9 \9 |$ B
            throw Error("允许的顶点最大数目不能为负!");1 R" \  Y: k1 ?% o) l2 f1 r
        if (vertexMaxNum < vertexNum)
    ' N3 p1 @4 K' x9 T" n/ S) d        throw Error("顶点数目不能大于允许的顶点最大数目!");0 U$ g6 r+ z! `# @
        vexNum = vertexNum;
    1 J0 q0 {- @) S1 y' G1 R    vexMaxNum = vertexMaxNum;
    0 e3 s2 h# k  C/ w& R4 o    arcNum = 0;+ U3 y6 K! F" `- w) N
        infinity = infinit;
    4 K/ m- T2 q8 O& [    tag = new int[vexMaxNum];- I/ B: r( @7 v" M
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];7 a6 C! b# n2 y7 w" D3 Q: W
        for (int v = 0; v < vexNum; v++)* P9 c% V; \) u* p
        {
    ! H- _2 j1 L$ T/ r9 [  e        tag[v] = 0;
    / ~8 h% i$ o3 q0 y7 W9 X        vexTable[v].data = es[v];8 ^$ g$ u  ]/ H% o' Z; t
            vexTable[v].firstarc = NULL;4 O; n" P  s1 r2 {6 Y
        }
    7 K) i! v, Q# f  _: A5 h}
    " t6 F4 e  U0 ktemplate <class ElemType,class WeightType>
    ; s. ^$ h3 d% m$ @, j# zMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    2 U0 f8 ?+ r8 B{1 A! i' i# l$ w$ V- A4 C3 u9 }
        if (vertexMaxNum < 0)
    0 ~3 b# ~5 a' T        throw Error("允许的顶点最大数目不能为负!");9 x2 P1 I" {7 b4 W2 A
        vexNum = 0;
    5 |' z' f2 n( A% E4 p. e" d2 s" f    vexMaxNum = vertexMaxNum;
    # y$ K$ b5 s- P  r    arcNum = 0;
    ' E: L$ ?7 i! ?: T# s& e    infinity = infinit;/ h% r" f5 |3 C
        tag = new int[vexMaxNum];1 G3 t  D  ~3 b1 W( H
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    7 R8 b2 _2 \' @2 s}
    6 V% Q& t- |% p2 G  S; Ytemplate<class ElemType, class WeightType>6 V7 t0 H8 M' ~
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const2 m+ c9 t& {7 @8 Z- L
    {/ [+ z7 ]6 v0 Y
        if (v < 0 || v >= vexNum)
    5 N- H# b, A. C1 a6 k        throw Error("v不合法!");
    / r! e+ H( Z$ d+ I8 t    if (vexTable[v].firstarc == NULL)
    7 b! P1 _3 A. s  F9 p7 n        return -1;
    * ]3 |5 k; ~8 g7 N$ I4 M) v; J: t9 S    else2 V  M9 p2 v0 K, q4 E
            return vexTable[v].firstarc->adjVex1;* Y9 `) @* e) y2 _# B  W
    }& w0 Z8 d5 W  f8 Y2 D

    : b& Y( K7 v" [1 \template<class ElemType, class WeightType>
    9 ?- m1 Y+ {, r! P3 Wint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    # r$ @# W5 }* L{
    * V# M* T$ g8 Y6 G& X    MultiAdjListNetworkArc<WeightType>* p;: ~9 ^/ f7 {. B; u7 ^
        if (v1 < 0 || v1 >= vexNum)% @" J2 N, W4 l! @
            throw Error("v1不合法!");
    7 o0 Y& m1 D. [6 z    if (v2 < 0 || v2 >= vexNum)
    " l+ _9 k' }' F- {: V: Q0 p7 J0 _        throw Error("v2不合法!");
    3 U) v: F. G5 Q0 b! R+ F7 _+ B    if (v1 == v2)
    5 [6 {: g1 ~+ x+ O* F        throw Error("v1不能等于v2!");
    9 b& ~( S5 s1 L9 t/ t, K5 }    p = vexTable[v1].firstarc;
    9 B% g" {9 i0 Y    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)* e" N# J' R& p0 e0 w5 z2 w6 i
            p = p->nextarc;
      N  {. t8 H! d4 D6 k. g+ X    if (p == NULL || p->nextarc == NULL)" p' V& s# _  V' Q, t% m
            return -1;  //不存在下一个邻接点2 U7 C, V, }* j* c
        else if(p->adjVex1==v2)
    " A4 L4 z" G# j* M, Z4 _% C1 s7 ^        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);: h- T3 z. L6 J
        else# o, v8 E( K& Q5 z/ \) C
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);7 K* m! F2 u/ r
    }
    ! a9 G& q' a, h; F% ]2 e0 Ftemplate<class ElemType, class WeightType>
    , w" O2 j! |6 w4 Wvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()4 v( V9 U) K' K- ]- K0 R& E/ f
    {/ P9 e1 |  \( H& C- e
        if (IsEmpty()) return;# ]3 Y% C. Z- ^' c
        int n = vexNum;5 b9 i7 v" v: k2 z& K- |
        for (int u = 0; u < n ; u++)
    + u8 S% \* D5 y        DeleteVex(vexTable[0].data);  p8 a6 x+ D* p8 |! F; {4 q3 t
        return;
    4 e, V- f( ?6 @3 b, n$ b}8 H% v+ M* @. r' t1 z
    template<class ElemType, class WeightType>0 ^8 A6 ~9 i6 A6 {3 H6 L
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()1 `3 y# W8 `. ?- T
    {! L% \% V7 I3 p
        Clear();- w, G# m- Y! ^2 v3 t! h# [
    }
    9 C! |/ \# x9 X3 w- ~8 q7 S" vtemplate<class ElemType, class WeightType>
    % }, G9 W  F* Z$ {0 U) fMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy): g0 M0 D" O# [7 M8 o, G7 [
    {
    # p$ T& D4 Q4 x  o    vexMaxNum = copy.vexMaxNum;8 i. @6 G9 R+ l7 p7 \4 w
        vexNum = copy.vexNum;. y. {  [: |- n' `
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];+ I6 A" ^; N. l, G3 e$ B
        arcNum = 0;
    7 D5 z. J! t9 d4 P$ Q; [$ |0 U- t    infinity = copy.infinity;# ^3 m8 s5 a/ S( B7 W$ E/ a: E
        tag = new int[vexMaxNum];
    2 p* l% ~4 U% l) v. o3 E
    * [7 \  F8 T: }) x$ J! U1 S9 d# k8 w# d    for (int v = 0; v < vexNum; v++)5 N: [" d- |; H7 z
        {
    : N' r( H+ f) F6 s; b6 j, n+ Z* M        tag[v] = 0;7 t0 M) _; ~" Q4 I+ f+ z7 F
            vexTable[v].data = copy.vexTable[v].data;2 G# l6 ^5 O! e- j6 Q( ~
            vexTable[v].firstarc = NULL;8 r: o: s! k( q9 T: D6 ~! e9 z( S
        }$ {' h+ v9 K: k. f  U- |: S1 J
        MultiAdjListNetworkArc<WeightType>* p;
    ) k! U+ U' v( ]) o8 U% `4 }7 J* J. ~. l8 w  C  B/ l* n$ b" v% v! A
        for (int u = 0; u < vexNum; u++)
    ) |/ b3 v" v. F' m    {
    ! c+ Q2 y3 M, _0 c6 s4 F        p = copy.vexTable.firstarc;
    . I$ n: J' k6 z5 a' B        while (p != NULL)
    7 }- f. V0 N+ a# \2 Y/ ~8 B! ~        {4 z* K% ~* S, s1 f
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    ' S5 \, @% ?( c0 `" D# r$ k            p=NextArc(u,p);3 e: Q. C' r# O; {+ \& t) M
            }
    ! u. }1 B# f0 A4 z+ D    }
    " Q% x( h  o0 R6 L! g% @6 E- }9 Q}
    , B/ O% _" ~0 q# n, i- r+ O" qtemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&/ [* _9 u$ j0 e. B) k" P" r2 s* `( I
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)$ q9 j0 t& }7 q  R! D. Y* d" O( q
    {
    9 U4 P* H% \8 W* ?- z    if (this == &copy) return *this;
    , x& x) o2 e+ c; U2 p; V    Clear();; L/ z+ F9 `; x0 _2 {
        vexMaxNum = copy.vexMaxNum;1 x, G3 _& d; [3 ~8 C; n
        vexNum = copy.vexNum;2 B- G" F1 X0 @# L$ u6 y! O; j6 c
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    " ?' S& t9 [1 q$ B% E+ g* _) b/ H    arcNum = 0;
    * x- b* Y" r# x9 w# W( Z    infinity = copy.infinity;+ y! _3 _4 \1 j' K6 K
        tag = new int[vexMaxNum];
      x0 Q4 s" ^$ l# B1 S8 j! ~+ F& C- }2 c$ \4 @! _0 j7 A
        for (int v = 0; v < vexNum; v++)# H8 P6 T* s+ v" [' Y6 w, B8 S2 j# K* O
        {7 M6 c) M4 s6 [, u5 b
            tag[v] = 0;, v7 G2 V/ f9 s. z
            vexTable[v].data = copy.vexTable[v].data;5 E' n! {. ~. i8 r$ x/ O( y
            vexTable[v].firstarc = NULL;
    9 I5 [6 A4 g5 a2 V" y8 E. o    }
    % v6 }: U* k5 w: i5 \8 s    MultiAdjListNetworkArc<WeightType>* p;
    . S# B1 k* Q7 O8 A% X" }5 ~
    9 D/ z# |: ]: D    for (int u = 0; u < vexNum; u++)7 h0 O$ S7 M$ d
        {
    ' x5 c/ Z9 F3 N* x, z; M3 c& Z        p = copy.vexTable.firstarc;
    + m4 u1 i# ]: H/ N        while (p != NULL)+ a! c' z# ?' X( v$ `
            {  \) u) _! O1 l' K
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    1 B) m7 {  ^6 V% {: A5 \6 y1 d7 }5 I: A            p=NextArc(u,p);% m# b/ h/ a/ l9 l6 |1 J
            }
    # p7 Q" @; q$ ?) u  K8 }9 f    }" \7 v% I6 s/ G  b6 y& Z- k
        return *this;
    8 V6 g' d5 W' o# v$ D}3 u! D; n9 s  h4 h; G8 @6 o0 T7 i
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    + Q+ R$ n0 G+ yMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    " U' v6 [( F% Z/ f( D5 l{0 \7 J+ a9 q8 T
        if(p==NULL) return NULL;: W" R- K  f0 t! A5 Q
        if(p->adjVex1==v1)
    * D" `) K8 }- l$ ?( Q' _  f5 Q        return p->nextarc1;
    * F& I/ w1 N( P4 `/ m( h% r    else( k( `, G2 ~* }- X5 K4 x5 W  s
            return p->nextarc2;
    1 x- c+ s5 `8 E( [5 T! u}. w9 q) L9 U: l+ o) y
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*" |+ S' ~. b) o4 K
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const1 s" \8 n6 d0 a2 Z, c
    {
    1 X, y$ q2 c7 k- m    if(p==NULL)return NULL;2 q# C: F- Q4 R& b
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;2 q! ~6 j' g: w/ }+ ~% U8 |
        if(q==p)
    " I" K1 W- m7 Q% c( D" @4 N# e        return NULL;- S. {, [7 |) D: x
        while(q)( G: b* D" o) O0 t6 j! f5 x
        {. n. K9 p9 H2 |5 M8 n
            if(q->nextarc1==p ||q->nextarc2==p)
    ' h, i* w6 _6 r) B2 t            break;4 ?5 K$ S2 H% Q1 i9 |/ B+ I
            q=NextArc(v1,q);
    % H9 O- l; K( q& T- V9 F    }
    % e+ p! k" D7 O/ j( G    return q;7 F  X# [' s9 A3 R: H: N
    }9 F7 Q% G  W$ F/ I# F! d3 }( w, I8 C: U
    template<class ElemType, class WeightType>7 s% _2 n+ {  ~% V/ }, @
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)3 b( L; E: s5 e
    {
    ) k7 n& m# B$ j$ u+ Z3 w1 m    if (vexNum == vexMaxNum)/ q; Q' S* |* h5 v/ t
            throw Error("图的顶点数不能超过允许的最大数!");
    2 B$ {( C; ~% _8 P% M! h    vexTable[vexNum].data = d;
    & b7 S: ~9 h" m9 o5 C0 ^    vexTable[vexNum].firstarc = NULL;/ m2 |  S. F% Q0 U+ s: s
        tag[vexNum] = 0;8 Z1 S/ s2 u# M+ S+ x' t$ |' y
        vexNum++;6 B2 U* }+ r1 \6 S% L% O" n- E1 @  j
    }
    ( c  \3 D  }) m1 |" z/ Z( [template<class ElemType, class WeightType>6 @) j6 o7 q$ N! o6 D+ `
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    ' h2 E  J4 R% u. g3 j0 k{
    9 g# I! Z* O" U- E7 _. C    MultiAdjListNetworkArc<WeightType>* p,*q;6 W7 a" x; n5 O9 G3 {
        if (v1 < 0 || v1 >= vexNum)  L7 {& G" m, f9 N) a
            throw Error("v1不合法!");0 f7 M1 N$ j7 f
        if (v2 < 0 || v2 >= vexNum)
    # `) g2 t  W+ z; g  o9 {        throw Error("v2不合法!");, o1 }: n' a3 _
        if (v1 == v2)7 N9 y2 O8 L% I  u+ F
            throw Error("v1不能等于v2!");' `$ t/ T/ I2 ~0 w" ]# v( L
        if (w == infinity)
    , R6 ]9 K$ G9 K7 C5 \! [        throw Error("w不能为无穷大!");; `, w: _2 w8 F
    ( A9 E. o# j) f9 P8 z
    / e% T+ L- Q& g* T) _
        p = vexTable[v1].firstarc;, z* C( U( E$ @2 ?' b1 V
        while(p)
      x. Z" J9 o) W7 B5 j- q5 ]    {1 e# c! `6 H* K# E' k# _2 Z8 `
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中; m) x7 Y& p) R& F9 P
            {
    ' u$ e2 x7 i% z& n            if(p->weight!=w)
      ~: z3 a9 e# |( H# A                p->weight=w;& F( y4 l) v9 F! f0 d) h- Z
                return;- y9 k4 _% E4 K* q
            }9 ^9 ]( r- x% \
    3 b& N  S" D( H
            p=NextArc(v1,p);$ b; ]5 m+ ]$ H) F
        }
    $ V% c: M4 ?" b( R6 o. i# V    p = vexTable[v1].firstarc;
    , ~% S1 e' @5 T+ A5 w3 u    q = vexTable[v2].firstarc;
    % i( E! \3 P/ j5 ~. ]! N' b    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法/ @/ `4 ]* C5 n, c1 o
        vexTable[v2].firstarc =vexTable[v1].firstarc;4 B- x3 T% ^' l  T+ d' n
        arcNum++;! G9 I1 C0 m) z1 C0 h% E
    }
    1 Q0 R7 \3 t4 t" J9 g* p! W7 j7 I0 L, D) r
    template<class ElemType, class WeightType>
    # k& Q3 H! q* e+ mvoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    + |. M! H) V; w) v{* l+ \- O' K8 e! m
    % T) [, p% A( \" t) p6 Q- i5 X8 a
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;3 [9 y% u& y; t) B% i
        if (v1 < 0 || v1 >= vexNum)1 j! _* o& d+ X6 ]9 d; O4 N
            throw Error("v1不合法!");
    $ @% L: A& {# [5 f6 D5 V  X: f- x    if (v2 < 0 || v2 >= vexNum)
    1 P8 u3 W5 p7 _5 d+ H: ^' h$ R        throw Error("v2不合法!");
    0 A- y$ D9 K7 }9 d    if (v1 == v2)' W* Y' K0 Z; L
            throw Error("v1不能等于v2!");
    ! P9 v1 N# Z# c! v8 P/ L4 c6 D
    9 ]1 _8 {0 w8 M& l8 Z    p = vexTable[v1].firstarc;* X1 _! F% T: Y1 Z& R2 r4 Z
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    , _+ z$ c5 {5 _/ G3 j    {  n) r1 ~1 H# T" J
            q = p;
    & R% T* h- C7 e1 H* n. a; M. p        p = NextArc(v1,p);
    ; e* v/ W5 g; ?$ ^& ?    }//找到要删除的边结点p及其前一结点q
    % ^* M+ H1 f: ~8 V$ C2 I  t
    % B5 S( `) S# N$ ]% V) k8 `    if (p != NULL)//找到v1-v2的边" X5 g: O  O. g2 _3 V5 C  J- y. g7 O
        {
    : Y7 P, |- ?% M* }' G) T        r=LastArc(v2,p);& `* w: m! U" e: E3 \7 ~5 O# w2 \
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL1 `1 v3 D5 X+ I* M
                if(p->adjVex2==v2)8 O3 p9 d8 @0 h6 D% n" C1 r
                    vexTable[v1].firstarc = p->nextarc1;3 c2 {$ Z, G: H/ O( B( [' P0 t
                else vexTable[v1].firstarc=p->nextarc2;
    ( p1 E9 o' W1 ^5 `        else//不是第一条边
    9 f/ z  l/ `0 ]        {4 T0 w5 C8 w- E" {3 l- ?' Z
                if(q->adjVex1==v1)! V0 W3 m% V$ [. z: M
                    q->nextarc1 = NextArc(v1,p);* g( d9 v. B3 `5 J& L
                else) A; q( G* q! \3 G
                    q->nextarc2=NextArc(v1,p);+ p; T' B* Y0 T, ~( [

    ! t, h& q( o( v9 X        }
    0 |* _- d/ o* |0 z* u        if(r==NULL)' F# c# N7 m5 J3 ~$ ^
                if(p->adjVex2==v2)& y0 n4 `0 f. v( _# E3 d
                    vexTable[v2].firstarc = p->nextarc2;
    : ^) ]1 E7 X6 Q  k0 J2 a8 y. l            else vexTable[v2].firstarc=p->nextarc1;
    ' E8 {3 X$ [. A" @/ K, R. J+ R        else  r' P7 T' Y0 ^
            {& i4 z5 w! m( g
                if(r->adjVex2==v2)
    : Y$ |+ R$ c( j' G                r->nextarc2 = NextArc(v2,p);
    ; \' t3 z0 C0 i6 T$ U8 N            else& Z/ ~; R( S: Z( c9 g7 a/ b
                    r->nextarc1=NextArc(v2,p);$ R+ |7 _1 S- y
            }
    * ?! }4 }5 W1 y5 h# k; A        delete p;
    - l8 o6 u7 A$ }0 g' p$ C$ [        arcNum--;
    3 M* O4 q' ]5 H6 R0 E- r: v- H8 m    }
    0 S# ]5 [  B9 V2 d( [$ f
    0 P  F7 D% d! Q8 H) ?$ a' r}+ B  D5 k' k9 s! i3 x& N
    template<class ElemType, class WeightType> void
    4 M+ I% q! F( P5 y1 M+ ^& HMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    $ U7 T! l! ^2 i$ c{
    4 c. @, G* a, M' P  B    int v;
    * ~* F2 E4 I* ^- t4 H' o& E    MultiAdjListNetworkArc<WeightType>* p;
    / w  l- U# t: G    for (v = 0; v < vexNum; v++)//找到d对应顶点* X( p& q' a, W" X
            if (vexTable[v].data == d)  Z/ @0 w; b0 J' s' {- G
                break;* f) Y8 S- T" a$ W7 e! Y5 F. \+ r9 i
        if(v==vexNum)
    : D" j5 ], n0 J        throw Error("图中不存在要删除的顶点!");
    2 D0 v! n) d# p( E4 O0 o1 d5 O$ ~, F; I1 V9 j3 n! e7 T
        for (int u = 0; u < vexNum; u++)//删除与d相连的边' D' c, c/ w" U& c2 w; K% }. ?
            if (u != v)
    ) Q" n' U, I5 P        {9 `' {/ ]2 W7 v. f: [0 q
                DeleteArc(u, v);
    + P) _( x2 f  h        }0 u  p( V, |- {
        vexTable[v].firstarc=NULL;7 w) A" e# n0 a. P! m9 o1 t. G
    9 s& U) O( u: K
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    ) k( O0 L: z2 w' B  ?2 A9 \    vexTable[v].data = vexTable[vexNum].data;& }. Y: `; E9 |7 m& D
        vexTable[v].firstarc = vexTable[vexNum].firstarc;
    3 e0 q8 v) r5 ?    vexTable[vexNum].firstarc = NULL;
    ; I0 N8 J2 Q- ~    tag[v] = tag[vexNum];% l8 G( m6 W* n0 J
        //原来与最后一个顶点相连的边改为与v相连5 |" F: E8 q9 ^: T, W* t) s8 R/ S
        for (int u = 0; u < vexNum; u++), E1 y% @- C) C/ B3 X6 q, m
        {/ ?7 @" d, d  ]0 b; n
            if (u != v)
    # Z  D' S( e6 t% H$ i" ?/ h; K        {
    - O' \' P  B" G            p = vexTable.firstarc;* ^' S' r( j5 i
                while (p)
    ; r+ ^& z" p! g' D            {% b6 ^" l: {# U) j  Q
                    if (p->adjVex1==vexNum)( W6 x" [+ o8 P4 u+ s( y
                        p->adjVex1= v;6 W3 `  q+ e& r: d9 q5 V7 e) s
                    else if(p->adjVex2==vexNum)
    : Z$ o. X1 g. T                    p->adjVex2=v;
    0 l, e: @+ S; w  N1 m                p = NextArc(u,p);7 X) E1 t9 J4 N
                }3 G6 D$ @' [& N4 ]8 O) q
            }
    ' C6 T; i2 w6 }) Z: i: o    }
    * n5 g9 |4 S. M0 B% ?% u( z& ?}1 z, L2 i- W( T" k" O& [2 b3 Y
    ///深度优先遍历
    + x# m: k: _7 @& }& J2 {$ L. {template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    0 _( e  _5 x  v! w* r5 U{+ M% v/ L6 {2 H& `6 V# a
        tag[v]=1;
    , D& p; x) j9 u2 x1 u% r    cout<<setw(3)<<vexTable[v].data;5 u7 C: e, t& O1 n
        MultiAdjListNetworkArc<WeightType> *p;
    + A) X( `% I- G6 H+ o" d8 ~    p=vexTable[v].firstarc;5 f; g' B; z( }  i0 h0 k& p
        while(p)' x1 j: S+ a* P. A' \- s$ D
        {% `' h7 @4 M3 m/ X. _
            if(tag[p->adjVex1]==0)
    - ~. |7 P1 ^3 n6 A            DFS1(p->adjVex1);* Z3 i! d! ^$ L) M5 g8 E5 ]
            else if(tag[p->adjVex2]==0)( n" G  `. u% {
                DFS1(p->adjVex2);
    & r+ d( B" l1 }, G0 \3 O3 _        p=NextArc(v,p);
    ! {' x5 W, v- m# N    }" ?* n- H0 g+ R5 S9 n( p
    }. o4 U& K. b: E' ]5 Q* c2 c% C
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()6 @7 L! ~! D+ O9 a! d7 B0 r: Z
    {
    : N2 c- h% d! g, W    for(int i=0; i<vexNum; i++)
    # \4 g2 U! G- {1 H        tag=0;. T$ w$ Y- {$ ?, B  N: J
        for(int v=0; v<vexNum; v++), C  \/ J1 A+ z% W- z$ P
        {
    % u& W! m& S4 E        if(tag[v]==0)
    1 d: P+ `! K3 C7 Q            DFS1(v);3 @( [7 |+ u3 h" c
        }1 g- M, c, l* N5 S
    }8 z& N: \; a. w& j
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()5 u( q( |! E7 w# `
    {
    ; N) b: x& m6 k3 i  G    stack<int> s;
    8 q, C$ j) w1 H" h% m    int tmp;/ Z. F- E4 z0 n+ x6 P
        MultiAdjListNetworkArc<WeightType> *p,*q;
    4 v( V$ [( W; p7 c7 B    for(int i=0; i<vexNum; i++)
    , ?; N2 O4 X8 ?- }2 x8 s% P9 A        tag=0;
    ; l$ g; z# O5 S8 |% \    for(int i=0; i<vexNum; i++)
    9 S- I2 U% P; p2 p7 ~8 L% |0 D. H    {
    0 ^! y- e7 S; b1 Q        tmp=i;
    # X: K9 Z/ X( ~. t; y  ?        while(tag[tmp]==0||!s.empty())
    0 C3 L/ `% Z* j/ x' ^7 k2 Y        {
    " T* r+ x* r9 f            p=vexTable[tmp].firstarc;
    2 ^3 T. ~  B  c, R- F0 y5 p: @            while(tag[tmp]==0)% `! m/ p; ^4 I+ q' ?9 q6 J6 Z
                {
    0 b( Q) R9 z: l. I% N/ U* N  r                s.push(tmp);
    & Q5 n" G6 X& y5 M7 M                cout<<setw(3)<<vexTable[tmp].data;
    + n+ O/ o! N" C                tag[tmp]=1;
    0 O; U+ ?) P( g                p=vexTable[tmp].firstarc;8 o# t) C! D$ K7 w% z
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for$ W( b& A; a) Q* f" v, [
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    , c: e1 _" i' g* h$ V& s0 J/ L                //cout<<" 1st     tmp="<<tmp<<endl;
    / A% p: s% A. ~& t3 |            }2 [: T$ ]( D. S
                if(!s.empty())9 [) T' L, K" A  ~" x
                {& Y4 M6 K2 p$ g1 `: f
                    tmp=s.top();
    & b% Z0 j$ [. \4 j. H9 C( Q                s.pop();
    3 `5 b$ Q$ y, f                q=vexTable[tmp].firstarc;
    $ Z1 a0 a/ F; ~! [1 K; d                int t=tmp;4 Y' m& v% J  b0 [
                    while(q&&tag[tmp]!=0). N6 n9 g5 n- h) z" W% H/ I
                    {  c% q8 w% |9 }& j0 k
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    + x3 H+ f0 X& g                    //cout<<" 2nd     tmp="<<tmp<<endl;
    ' T* M" e% G8 j$ v  n5 s                    q=NextArc(t,q);, x& ?+ Z8 ]2 C
                    }
    . u* x9 A+ m* W                if(tag[tmp]==0)
    ; P' H) ~) ?: W) I2 E9 d9 P( r( f                    s.push(t);% {/ Q1 y) T: d
                    ///1、对应上面连通分支只有1个点的情况  e+ h' N3 a: ]) f; P. r% x
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈5 X- k3 D8 ]. g- g* D: v8 [
                    ///tmp要么等于找到的第一个未访问节点,( {% _5 e" x  ]: M8 |: t
                    ///要么等于与t相连最后一个点(已被访问过)7 D8 ^; _/ }% F4 K0 E
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点* k# Y: f& h+ r+ K7 S6 C8 h
                }. T- B9 c# O6 y) ~& ~, q% H
            }& @( M/ i' K$ }" J: e; A5 n4 }
        }
    % u3 V, d0 }8 H! q2 ~3 k' r2 U0 {6 R}0 t2 _% Z* D0 c) y
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1% d+ M  T3 `- _" g4 ]! }6 s
    template<class ElemType, class WeightType> int8 m7 o( _! s7 Q7 r9 |: c
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    2 G  {. I. ]& v  y{
    * [& h7 y7 b% z    if(head==pre)
    & F  f5 n+ y3 t7 p        return -1;3 P* _& b! [! c7 K! ?9 |, v

    . c0 o& C( J' M# f* X; z' `& i    MultiAdjListNetworkArc<WeightType> *p;
    ; W/ A. t+ M3 y. ^# U2 H    p=vexTable[head].firstarc;! q9 w+ k( x# }3 t& [
        if(pre==-1&&p!=NULL)
    ( b/ `) O( q/ ?: k/ u; X2 [; ]  K5 r        return p->adjVex1==head?p->adjVex2:p->adjVex1;5 E" T# u5 y4 r! v  V7 s: c& ^" i
        //pre!=-1&&p!=NULL
    # u! s/ }8 Q5 G2 s/ Y2 G2 @    while(p!=NULL)
    " Z( ]# M! \5 n* r. a    {
    + ?7 |3 K; i1 P1 S        if(p->adjVex1==head && p->adjVex2!=pre)2 L: j, B( f* J
                p=p->nextarc1;9 p$ S! Z8 h, y- M0 m* a/ k* s
            else if(p->adjVex2==head && p->adjVex1!=pre)
    6 I. m  k8 l$ W1 k) Z0 E& G            p=p->nextarc2;
    5 ?" L& ]4 [" V9 F+ b5 w        else if(p->adjVex1==head && p->adjVex2==pre), @, G  p' `6 D" n% w
            {# t+ H: S: U1 R) S- F
                p=p->nextarc1;
    * u& C8 w4 w6 \# d. a            break;
    5 C" X5 [1 }( g        }
    2 ]/ y" f- t- d. d- u  ?+ f        else if(p->adjVex2==head && p->adjVex1==pre)' H) a- k7 ?1 ]" |9 ?9 ]# j
            {
    * ?9 }, ]+ D: U* ]+ ~            p=p->nextarc2;
    / ~$ q* j( j3 S6 I8 i- j& w4 a            break;$ U+ L4 r3 Y2 }* n
            }) O0 [6 O; `7 m* t6 m# t2 [
        }# c2 T( P+ F: }  A- J
        if(p!=NULL)& P1 i, v0 h. S2 d
        {0 w% ^0 H' `6 m9 X6 Y& m" M
            return p->adjVex1==head?p->adjVex2:p->adjVex1;1 N3 D6 u5 x( C7 j2 ^# e
        }* }+ H9 v8 V; `' @1 V9 t1 t/ }
        else$ T& Z2 D7 _. }
            return -1;2 A/ h: _* D- `
    }9 l; U* K4 _$ U" L

      p+ A! C2 ~3 c" d0 A: Z$ S5 t) q9 c0 `: L
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    - f% q- H$ _2 r. g+ h5 j. B" s& G{
      H* H" P4 ^8 O    stack<int> s;
    ( e, e+ C* y% Z    int p,cur,pre;
    * f1 z" P7 f7 a& ~  H: P% U5 U    //MultiAdjListNetworkArc<WeightType> *p,*q;
    # Z# F7 W5 x  w. h5 P1 j2 M    for(int i=0; i<vexNum; i++) tag=0;//初始化( s1 S" P& H/ B8 _- v9 T2 _
    7 K$ J* b9 L8 f  [/ m3 [, K7 o
        for(int i=0; i<vexNum; i++)" v% S1 h0 Y6 |! z  S
        {
    + f9 [  D7 [( F        cur=i;pre=-1;
    % ]7 k2 ~% i% o- @  z# O/ ^        while(tag[cur]==0||!s.empty()), t5 r( u! Y3 s, Z
            {- P1 K2 A+ n' d( P0 G
                while(tag[cur]==0)
    9 f6 K' E, s: Y  o& D            {5 C* b1 m/ E6 J. W! N2 @
                    cout<<vexTable[cur].data<<"  ";
    ) }+ b. S) U: e! B                s.push(cur);
      f, z" K% A5 h+ [( k5 b8 [                tag[cur]=1;
    ( f" K7 `3 K, m" E4 C  q5 e               //初次访问,标记入栈
    2 z$ n3 X: k# b. C6 ^! d$ o, w9 a) q6 y3 _3 a
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点' @8 M/ ?4 [0 i/ p! y- X: v
                   if(p==-1)
    7 h* i+ K% _# V" n1 P( d) \6 Y; c" c               {* V: o+ _5 n8 r0 b' v% k$ ^) h: E
                       pre=cur;s.pop();7 D5 i4 s0 Q5 d5 C
                       break;/ E- @, q. h5 B1 x) X& T
                   }# j3 w( I$ t' n# W- w' T
                   else
    5 v8 K6 U5 ~% s% F4 t; a# a4 K               {# Y7 v$ A1 j, N! K
                       pre=cur;
    5 D5 a1 }* I" M" r0 d9 L+ I                   cur=p;
    - L7 @  i: i3 D+ Y( q) I               }
    - j* e3 [5 \1 K$ C/ M2 A, J4 w( T6 e( e2 T
                }
    ( y7 c. {$ _+ \- ?; T: _2 b0 R            while(!s.empty())6 v' J! Q3 F; R3 ]
                {
    4 z0 Z; s# ]5 F" _                cur=s.top();
    2 o+ U4 w' ]/ {. h$ Q/ \+ C                p=GetAdjVex(cur,pre);% m4 X# w  I. D' I4 P7 h
                    if(tag[p]==0)
    & T9 m0 C/ U. S% g- o                {
    & }8 r: C" E8 h, x4 D                    pre=cur;
    + b# V' H3 d1 R5 s! i/ u                    cur=p;
    5 I" c6 g8 V3 d+ {                    break;8 p/ v* p5 Z# c9 @6 X" T" F
                    }, x; ^) ~6 G! |* R& x9 r1 E/ N
                    else$ f7 o# j8 s: A# _, |
                    {0 |) O! B2 A$ I: G
                        pre=s.top();
    2 N4 G( b* J  \                    s.pop();
    / ?+ v( i2 p; g8 j                }+ H0 Q1 y1 R/ T

    # m2 T1 N; B# _            }
    + T; J* B" o" R4 R; g% g7 e& a  D9 F. K0 q  A5 d0 l
            }
    ' ?- z( M$ ^8 g" |" i& j/ d    }( a+ f8 m0 C% ]$ A' X
    }: m* C% V; U+ T- ]3 C( _+ ^3 v* \( A& @
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()/ X- K/ b  E- e, J0 T4 v; R
    {. Z) Q2 u1 G. D# }
        for(int i=0; i<vexNum; i++)0 w- x! d; B6 [
            tag=0;. Z/ J. Z8 B0 v/ A9 @9 v# ]
        queue<int> q;
    7 j# f5 |$ Q! R( T( F* r    int tmp,t;
    ; |: @5 x% f+ O4 T1 O+ D( P7 s    MultiAdjListNetworkArc<WeightType> *p;5 O4 n5 K6 x% j+ H& r
        for(int i=0; i<vexNum; i++)0 L, |/ y4 c: Q0 b3 l
        {: x! i4 s4 k' t0 K- E3 t5 C
            if(tag==0)
    1 e+ y- @$ T3 E! W: U; X7 B( t  s6 P        {+ g( z" i! Q' d* I4 @6 d
                tag=1;8 j0 f: r0 O" v/ v9 B# A
                q.push(i);
    5 j# ], ?# ?" j! n! e            cout<<setw(3)<<vexTable.data;8 M  T/ ?: ^6 z3 o6 R" h6 L, I
            }7 \4 x# i3 j( ?, E
            while(!q.empty())* \! p, d/ v+ N) V4 C* @2 M$ w/ `
            {
    ! D1 h; `7 V" _/ y; P            tmp=q.front();
    # B3 V- ~. u( x/ l( x; p2 {            q.pop();9 `" ~6 D% b( _/ f8 Y8 x
                p=vexTable[tmp].firstarc;
    ( K" {  F# w% Z! i, E" U" F            while(p!=NULL)5 S* \/ A1 L, v2 G
                {
    - t& ]8 A/ m& O- d$ W                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);& U8 A$ e( k5 U6 R9 [4 q+ {
                    if(tag[t]==0)0 P% D4 e# d, w. F
                    {
    # y+ d! \! y+ {9 y( C: U$ Q                    cout<<setw(3)<<vexTable[t].data;
    5 E, I" s0 p5 u0 K- ?                    tag[t]=1;8 L+ T( O: ~- ~3 c3 X( {
                        q.push(t);
    ; H& C6 c* g5 I5 J. n8 ^                }
    ' G' F+ d; I6 [( d0 Z                p=NextArc(tmp,p);$ a6 b" P# N8 x9 c
                }
      g/ x* v, q/ \, k6 ]+ Q4 b        }
      p* K2 d7 p; m6 Y4 Q/ ~' E" e    }
    9 R( p6 p0 M0 C: K8 R8 }$ |}$ ^% y: y7 B$ U3 _$ _3 D
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    & y5 c9 n, H" k1 z4 ?/ b{! i7 ~2 S6 N2 }, [6 y8 t+ W
        MultiAdjListNetworkArc<WeightType> *p;
      x- a' S  W5 \6 S- N( K9 y. y    cout << "无向图有" << vexNum << "个点,分别为:";0 X4 Z  h% O  r% N
        for (int i = 0; i < vexNum; i++)
      r8 C3 _2 |5 F; K% \2 z        cout << vexTable.data << " ";
    9 Y: a2 ]2 ]* q! i( m; E    cout << endl;+ F% h3 \" ]! a3 G
        cout << "无向图有" << arcNum << "条边"<<endl;
    1 k/ `* u+ v2 W3 O  M2 `% n    for (int i = 0; i < vexNum; i++)8 v7 h6 T+ E2 u) O, G7 K
        {
    : d+ n+ ]- Y0 p! w7 T        cout<<"和" << vexTable.data << "有关的边:";
    # p5 G6 p7 y7 m' L# `        p = vexTable.firstarc;4 _. Q$ Q- V/ v7 Z+ ]5 |6 P$ t
            while (p != NULL): c; g' L! M6 d# S
            {# [7 x5 ^$ \9 B7 x- \# |# L1 W! B
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    " b5 Q! N8 J! v0 q) M! R            p=NextArc(i,p);
    5 e  F7 C1 s" T( _2 J+ @        }
    1 h& B6 p  T# a4 a        cout << endl;8 P( m$ o  r, e- ~/ ~- u' C( e& H
        }
      O% r2 b& E8 M7 s7 F7 _}/ F7 X, u9 y6 N

    / }: X# U( Z" ?; Y7 E. [4 s6 l' T6 r2 P: i
    邻接多重表与邻接表的对比
    . {; l. y1 A1 f7 ^+ D' H4 L/ N! Z& @+ U
    邻接表链接
    6 E4 x, B7 I/ m+ H' x7 R在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    7 E+ J7 A7 w! X% [在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    # _% y7 j3 \" l% C. M7 H/ s为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    6 @% f2 C1 N; G2 [) c7 J————————————————
    0 ^. j; C- y# E$ Z7 I/ r; ^7 C版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    * D3 f/ C: j' B( R原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958' b5 i1 i/ D: j  N3 }

    & K$ q1 W4 J/ [5 Z- E! X6 y4 g+ Z+ c8 e! ]9 c6 S1 O, h

    " C  l1 i, C- |: O  f
    ! i1 w- Z7 u( j" s2 ^5 ?————————————————
    ) A: j9 t5 v" ?/ F* N9 Y7 A6 v% y版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    2 B# C. k2 r% B9 p7 x" _9 y原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    & P8 I9 c/ g, G& u5 K" T# O* W! q7 u

    % x1 B+ N. X9 i/ }6 o0 S
    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-9-10 07:33 , Processed in 0.394047 second(s), 54 queries .

    回顶部