QQ登录

只需要一步,快速开始

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

    3 _2 M' |' x: x/ \" {) }. x图的存储结构——邻接多重表(多重邻接表)的实现
    . }1 [& R( k& o& Q* q5 k7.2 图的存储结构$ N5 ^) x: P( S# [

    8 \0 w5 c6 {6 ^7.2.3 邻接多重表(多重邻接表)Adjacency Multilist. r4 s+ O# {3 {+ `5 r
    邻接多重表的类定义
    7 W6 ~' |1 @# N邻接多重表的顶点结点类模板
    , l) U+ O; ^# O邻接多重表的边结点类模板; i! P$ P! T" j4 g% p! m
    邻接多重表的类模板1 o' ]9 T4 h+ k" h; ^& n2 I* t
    邻接多重表与邻接表的对比
    & r7 _6 V+ d# W' l9 ]  x7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    6 I+ i0 _0 D+ E, x# b" L) a' G- z8 \# y  B5 H( d2 k) _1 a5 e  }
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。! D2 e3 f: T! _: u" q% }
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。7 k, Q/ F9 H2 D( f+ r4 G% K- \

    0 z. N! S, T% u7 w* G% w! m邻接多重表的类定义( q5 R8 g2 {! b& G5 ~8 S
    1.png 0 ?$ Y- K7 J4 B: t1 \9 ^
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    , Q- |- _, z/ m2 ^6 F, f0 w3 n6 udata域存储有关顶点的信息;
    0 A$ B  l# J' }! s" Dfirstarc域是链接指针,指向第一条依附于该顶点的边。$ J3 z+ L7 p" n; G; d: O
    所有的顶点结点组成一个顺序表。


    * c& R4 v8 z- A6 v$ u
    6 u5 F: x4 z7 K; Ftemplate <class ElemType ,class WeightType>7 k5 ~" p! X. V6 F' G- r4 X5 F7 z
    class MultiAdjListNetworkVex
    8 [6 \$ b( E/ c0 I, T6 ]% J{4 x8 G8 }1 x" g: q
    public:( L2 Z$ P+ `/ z  \& @
            ElemType data;
    6 O% F4 V2 ]2 E) C0 y- A7 N+ `! n  O        MultiAdjListNetworkArc<WeightType> *firstarc;
    - R& T* S  c  x5 U2 f
    / [# \' o# w8 w5 X        MultiAdjListNetworkVex()
    5 ?) _. G9 ^* z4 y        {4 v) W+ O6 s- a4 Z  r
                    firstarc = NULL;$ i7 {% \2 }$ W5 `/ Q0 @9 }
            }
    ' {- t5 u" ]1 m& Y* E# u        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    " Y: L$ Z$ C5 {( ]  D+ B' |2 U/ K        {. }8 H6 b0 J' d/ L
                    data = val;
    5 O7 @9 @5 t8 l( ^5 V                firstarc = adj;
    % O4 Q7 c8 y8 R: q% p; q% [        }& P. c7 q' W* u% t$ w
    };
    % n7 L  O9 g9 w- I% F+ i8 j/ g
    5 X) y$ c+ d/ E( R; f, F3 _! A2 q邻接多重表的边结点类模板* D/ K; @% i/ w9 b) U7 O( K# h4 \
    & f5 ]. d# X  p7 n% P
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:& ~" w) ~0 }# P, ~, R" I
    tag是标记域,标记该边是否被处理或被搜索过;
    % i+ q, I+ `) L% D' J& u5 c1 G3 rweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    8 q2 L4 s! j! ]" m; |9 R0 j% ]nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    8 b2 ~, k$ W+ u6 [- j- znextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。* H1 ]7 h2 G  J  a0 ?9 j

      B) U! p/ x8 ]+ d' n) ?0 z: @+ r 2.png
    . }, H, z: M3 q$ Ftemplate <class WeightType>
    - q8 `1 O" w7 g* {' L- t* @$ wclass MultiAdjListNetworkArc
    $ I$ e3 X3 B6 p{
    1 q6 O8 Y3 T: p# X. ^8 _; [" n6 Vpublic:, U5 X7 O- x2 W0 U
        int mark;                                       //标记该边是否被搜索或处理过
    6 S1 `6 @% _0 g$ l% M' W8 U        WeightType weight;                              //边的权重! W! D+ E4 C9 n, P
            int adjVex1;                                    //边的一个顶点9 u' T' }0 w; j' d2 u5 Y* A
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    . d; D, q, E/ A/ I& A        int adjVex2;
    / G+ X6 l, _( V+ ^! B- r        MultiAdjListNetworkArc<WeightType>* nextarc2;
    * R7 @( E4 d1 S2 S4 x/ h( ?2 n5 ?; v5 V5 R4 m  j) ^8 a' ~, C
            MultiAdjListNetworkArc()
    . f6 b* h1 m& y! F5 }& [        {6 l* s# W" ^5 @6 B; S
                    adjVex1= -1;
    % p3 b; [# l, u# z* h% Q                adjVex2= -1;( h0 e7 L  b8 Q, m) y/ }  @
            }6 B- p" [' g1 b
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    : |, g7 X9 I- U+ m( k: |2 D        {, t$ ?% b; z: a: q# ?
                    adjVex1 = v1;       adjVex2 = v2;6 T5 i4 Y) h* W/ |
                    weight = w;
    ' `/ ^( D+ D' ]0 u  I. n                nextarc1 = next1;   nextarc2=next2;
    $ n9 j# e' x1 \2 z) s                mark = 0;           //0表示未被搜索,1表示被搜索过
    ' |+ e+ E9 _( ?/ M1 o        }
    # l9 A- W: b5 X2 }, A3 U" n+ k$ m) G# }* j
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>' D3 p" T) m( C5 y$ ^" B
    class MultiAdjListNetwork
    / Q' j- o4 u9 Q! [4 H9 ~{
    * ~$ P/ m5 p4 _protected:
    ( k8 `. ?1 G: A  e/ k4 _2 S9 f    int vexNum, vexMaxNum, arcNum;0 ?& ^+ g$ u. S
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;( J  |/ n8 H& c) b
        int* tag;* h% K. ]/ l3 m
        WeightType infinity;
    ; s& E& d$ ~" L* [) e
    " l2 U4 S% V% qpublic:+ T: E8 y7 L# [6 A$ |
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);! ?6 U7 v! p6 Y1 x& n
    1 f7 R! D- x9 q; a" e+ _
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);) a" T3 n% u" m0 _. f

    # @' ?& M' n1 U. P* C3 J. x6 E    void Clear();1 [; [. g8 n2 X3 W
        bool IsEmpty()" B, I9 a) O1 c1 g& d+ M8 U
        {
    & g3 }: q8 @0 _/ A5 E        return vexNum == 0;
    , }$ R! F# B& ]* S# ~$ O    }% }' x6 Q* P' Z) l& W, `% ~
        int GetArcNum()const
    * ?" ~- f* ~5 A0 V: l% `8 f, r    {& h. q4 Y  N  b8 A. Y
            return arcNum;5 d: r! l* b" i- `) s/ F2 C* S+ x
        }
    $ o/ \) v) ^0 J9 A2 r) j    int GetvexNum()const
    8 o, J* _8 Q/ _    {9 W% I3 x9 G( s# {$ {2 P+ i; c
            return vexNum;
    & ^. Y) s$ U& k% [) p    }
    1 O8 _6 a. A, v% E' a5 @! z8 c: h9 z0 q, R. C6 y
    2 S8 v5 Q3 x' d8 h* d5 z, N
        int FirstAdjVex(int v)const;
    0 k1 Z: A, A9 J4 E! p    int NextAdjVex(int v1, int v2)const;
    / i4 B' u% m9 Z. M3 z% y1 j9 Y    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;/ h9 W" m  W) m
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;. k3 k# G5 n+ z& b4 J

    6 P  c6 X9 v( K3 U& M    void InsertVex(const ElemType& d);
    9 h' v' O  o* o2 G9 B8 c    void InsertArc(int v1, int v2, WeightType w);- S( I* e" s. b
    # [4 L1 d1 d8 I8 `9 S& N7 [
        void DeleteVex(const ElemType& d);. ?* {' j! T9 \
        void DeleteArc(int v1, int v2);: f3 u  \- U) b: k) C3 {
    5 W$ V% p0 Q8 v$ J
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);) x+ X* w# f# y2 x# w3 y3 j: P# [6 f
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    ; l2 u4 j! x* A  T" O/ f9 u/ R$ d3 w6 M1 s) K
        ///深度优先遍历& k" e+ H8 ?" f+ I" `! _
        void DFS1(const int v);
    % Z$ T/ |4 m8 H$ m# m1 f) S    void DFS1Traverse();
    4 X1 D1 c7 ^" f0 Z( W; w$ a/ j6 U    void DFS2();
    . V6 J1 _* u& T' q9 g7 j1 j: p1 Z& L2 V0 p; H
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1, R; n8 H8 }  `" ~" y
        void DFS3();
    5 C( P1 n- }- V6 {. W6 ^) U4 {2 |
        void BFS();
    4 X8 [6 r# V- [! g. s6 O, G    void Show();- M4 F5 O: |" F/ \2 f' k4 E. ~
    };  w% j+ m. G3 F5 g

    & S5 T! x. A, x4 F2 y- J7 u2.函数的实现
    " e9 P, U  a. B6 I3 f$ X研讨题,能够运行,但是代码不一定是最优的。3 P( X' H2 Y1 L6 L0 n2 N) E
    : G5 J' |* n8 D/ _* `. j
    #include <stack>" }8 D1 e5 O& G
    #include <queue>1 {8 _9 I# R! E/ H* A

    & ]0 M, H- Z. Y+ [( Z$ |6 Z0 L; ftemplate <class ElemType,class WeightType>
    + u; N; U) K2 E$ n7 yMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    5 f$ G! C( S9 G  ~$ X5 @{" U! `! V( a0 B' [. N
        if(vertexMaxNum < 0)2 A( v8 t* H* L
            throw Error("允许的顶点最大数目不能为负!");: A/ ]  f2 z% n9 p. B! v& s4 i! G& E
        if (vertexMaxNum < vertexNum)* _3 f: d( Z5 r4 q0 p  R, q7 i
            throw Error("顶点数目不能大于允许的顶点最大数目!");# m8 P+ l; B) @! i9 D4 l: x
        vexNum = vertexNum;
    / [3 S# v9 @2 F' C* Z: z  D    vexMaxNum = vertexMaxNum;
    ; B5 ?8 x/ \- G7 [    arcNum = 0;: q! p' }% P) z/ T
        infinity = infinit;
    2 V& s( M4 {  G9 |, {; W# k: ~    tag = new int[vexMaxNum];; d: r/ R; ?$ I: u1 s& o6 G. m' V
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
      m1 k* j7 E* q* x    for (int v = 0; v < vexNum; v++)
    3 J% h$ C' @  G    {
    # R& i) ~# s, P* s2 q        tag[v] = 0;
    + X  I" X, W* m+ L' g7 I        vexTable[v].data = es[v];- r& v* |& }9 ~2 g/ \  {9 X/ p# H! P
            vexTable[v].firstarc = NULL;
    " ]' g; e/ [" h- V& D  Q. o    }. `7 z+ Z& ?' h) _- l' i
    }
    3 a4 N3 [+ p3 E7 f1 b6 }template <class ElemType,class WeightType>3 f. x, f" v' X+ S# n: W$ G; M4 n# _
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)/ D- j5 e' _* z' q
    {5 X7 g9 s2 [/ A
        if (vertexMaxNum < 0)' n6 ?& r; s- g/ Y
            throw Error("允许的顶点最大数目不能为负!");% m' b% \) L8 e' A
        vexNum = 0;- a4 U: ~: ^+ z5 p, E3 d3 }" {
        vexMaxNum = vertexMaxNum;
    1 g( ^0 A  z  ^; Q    arcNum = 0;
    2 e- c2 D2 ]; }: M& Y" c0 l    infinity = infinit;
    # S9 ~1 v9 b( |! \    tag = new int[vexMaxNum];& ~- I& N9 Y6 T
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];: M; m& \* }" n* n! I( S
    }% M. B/ v9 Y- o/ r  J( w
    template<class ElemType, class WeightType>9 k$ ?7 `0 I# V3 ]! G
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const5 G) d6 W* b/ W6 a3 i( G! z8 G
    {
    : {& o2 i0 N# _1 p" Z2 a1 h    if (v < 0 || v >= vexNum)
    ( |9 L1 e: s0 A  L        throw Error("v不合法!");" L, T! ^, C3 @% W, ]1 X3 h
        if (vexTable[v].firstarc == NULL)' _& y4 r/ Q2 O2 g0 d) v& `
            return -1;
    9 e; m& k' ^0 s    else
    5 P: h1 [5 N. l5 m5 A8 r2 z        return vexTable[v].firstarc->adjVex1;( b. V2 f" v* V$ E" @1 G
    }
    8 O, H7 x0 ?" E) ?  w' a4 m8 v
    template<class ElemType, class WeightType>
    - s5 P. u5 e. _% P5 q0 z5 Pint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    ; Y8 o& {6 L. I5 ]) M{. I! P2 K$ x- u2 }
        MultiAdjListNetworkArc<WeightType>* p;
    ) f9 ]- i% ]0 k( @+ p. M$ }    if (v1 < 0 || v1 >= vexNum)' A' H. p$ z( T5 ]7 j3 N0 F7 H
            throw Error("v1不合法!");
    9 v: q' B4 K4 `    if (v2 < 0 || v2 >= vexNum)2 |% I4 J3 p# C  N0 d
            throw Error("v2不合法!");
    * Z, ~% y' ]/ W" X$ G    if (v1 == v2)" J9 I" _& ?3 j$ R/ D  L
            throw Error("v1不能等于v2!");% c" d' V; X- e: K
        p = vexTable[v1].firstarc;
    " Q  K, R$ ^3 F3 u    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)2 s! Q3 n- b+ V& m1 Q4 E5 r
            p = p->nextarc;. w! n! W- t1 E; Y6 t6 P
        if (p == NULL || p->nextarc == NULL)
    . s! @6 Y$ I% A: q7 Y        return -1;  //不存在下一个邻接点* `$ I2 Q/ b! s* v9 g" n7 {
        else if(p->adjVex1==v2)
    + l* K5 P; D+ T7 }- ^" Q/ t  ~        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);5 v  K! r( a5 Z
        else
    7 I, m( A9 i. N' Y7 Q* _- t6 B        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    % z2 z) W+ h- b9 ]! I- s( P}8 Z2 h0 t" P; B5 N0 R) \( m9 B
    template<class ElemType, class WeightType>8 V) n( A2 a! h. {( ?
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()" U% {! C% N3 g( g- Z1 I
    {
    6 \: q9 c! N! {4 d! c    if (IsEmpty()) return;
      X: D, [6 [2 Q' _4 q    int n = vexNum;
    6 W7 c' N5 _- o' D    for (int u = 0; u < n ; u++)
    / h. c9 J$ t/ \. A        DeleteVex(vexTable[0].data);8 C0 M& C! i( ^4 s% v+ l3 z  x
        return;& n) j, P; ]1 E- k( O" r
    }, I9 d: |: O" u1 h0 k. w$ c
    template<class ElemType, class WeightType>
    3 ^3 b7 E" M7 eMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()* q7 ]' O* p/ v  r2 {6 P0 d
    {9 [+ O3 ]6 d6 l. }- Y# L
        Clear();
    1 u: _  c, H, H9 k: J}
      R; t6 b4 \% {( htemplate<class ElemType, class WeightType>! y' f1 J% ^6 d* K; M5 R! e
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)6 X+ |' F1 E+ d5 U% r& ~4 p- E) m
    {
    7 P! c/ x0 c9 e, y+ b( O    vexMaxNum = copy.vexMaxNum;8 I/ G0 R% O! M" d
        vexNum = copy.vexNum;/ S$ S9 I4 s. F. h& E' C) ?
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    " v* M3 [! e8 w+ M9 q  V    arcNum = 0;- q6 ?8 v) v4 p) f9 L
        infinity = copy.infinity;
      Q& f! r% d) Z5 D% `    tag = new int[vexMaxNum];
    : z+ \, v5 J4 c2 E- S( |, C4 G' k% C* R1 ~) S/ \! `8 ~+ V
        for (int v = 0; v < vexNum; v++)
    # S( q$ S' B$ C4 [    {" ?1 ]# u  J2 q/ u8 W1 w
            tag[v] = 0;' @. ?' R4 w* j2 d0 x# j9 ]
            vexTable[v].data = copy.vexTable[v].data;
    - o0 K( B- a& c        vexTable[v].firstarc = NULL;4 _: F/ [' o$ h" a
        }- m5 y' W+ F) ]% o
        MultiAdjListNetworkArc<WeightType>* p;
    + W$ D% l( y; R" z
    ! |, }! q8 v8 H! g" e    for (int u = 0; u < vexNum; u++)+ h$ ^, e- C) x# v5 C; I+ Y
        {# x2 _& M$ J& |2 t/ ~; u5 L1 a
            p = copy.vexTable.firstarc;( l% Y5 e2 E+ ^
            while (p != NULL). B! l' |; u* ?% {
            {
    ; W+ h2 l4 t+ y" a5 O            InsertArc(p->adjVex1, p->adjVex2, p->weight);3 ~6 n; B; f: T
                p=NextArc(u,p);
    4 E# g2 G/ D/ r# v6 h        }
    . W- J1 p' _# Z    }
    % X3 F5 ~7 ]! T% r}4 A7 y: L5 y0 a2 B/ n
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    / ], V! |7 y" W! Q$ h3 hMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)3 e& @* G) M  K/ n! D3 v
    {2 O* o( r8 o+ w: s
        if (this == &copy) return *this;7 c2 H$ ?% j4 n; a% w; J
        Clear();
    5 _& ^5 {- q4 U    vexMaxNum = copy.vexMaxNum;* S; C4 m+ B' W+ ^
        vexNum = copy.vexNum;8 m/ S, Z  b4 P  N
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    ) h2 @9 l' I) j. h( g* {    arcNum = 0;' w; M( `; R/ M. ^: {5 ^
        infinity = copy.infinity;; `2 g' @8 j' U) n& c
        tag = new int[vexMaxNum];
    4 E8 S  I. m, J; L7 B9 g% `: G
    ) ]7 U" k) O: x) h    for (int v = 0; v < vexNum; v++); |; l( e9 D1 |2 m: k( T6 C$ M8 |
        {
    , J5 y# g! ^/ G# Y  i+ N* I        tag[v] = 0;# _/ [# {5 B. }+ W! }+ z& R
            vexTable[v].data = copy.vexTable[v].data;7 S+ H# }; T% q0 ^: X) C0 }& X
            vexTable[v].firstarc = NULL;% u" m' L( _2 A
        }* j  r( N9 }9 y
        MultiAdjListNetworkArc<WeightType>* p;
    ( L1 p0 X1 m$ C7 G4 L2 ^/ x( v+ R( B- t8 ]% u
        for (int u = 0; u < vexNum; u++)# T* i0 }) b3 B% {$ b
        {+ X' `1 R( u- K! j* h
            p = copy.vexTable.firstarc;
    7 V; d' O+ I7 ~6 |7 E        while (p != NULL)6 G9 ~+ i2 x" Q1 }0 r
            {: M  i' X& w0 l& \
                InsertArc(p->adjVex1, p->adjVex2, p->weight);! b2 C) _% }6 N8 e
                p=NextArc(u,p);, R5 T2 z8 N4 t7 q7 }  N% Z
            }
    ) a$ z8 [- M  l5 }* @. b    }
    ' t' |+ |3 G& D' \0 d    return *this;
    3 \9 u- A. `: B* D6 o% ^9 U5 W. X}
    0 B% M) @$ Q  c5 n0 _- x, @template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*0 M+ m1 B) Q* W& X
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const! Q$ e1 E  x/ b7 c$ U1 Y; z. L
    {
    4 Y& J$ M/ c  s) U0 W1 Q  v    if(p==NULL) return NULL;7 f) J: a) O8 C; u6 Z/ T
        if(p->adjVex1==v1)
    0 n3 r4 U, x' z7 X        return p->nextarc1;
    4 a/ m$ M" P7 k: d; p: @7 p* b    else$ s) p# j+ [% P* I
            return p->nextarc2;2 z# A) e& |2 _1 i6 ^
    }
    . i* E+ Y- Z9 d  [template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>** K2 \# m8 V0 \
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const  V, v4 U* a4 y  T
    {6 w, S3 D4 }2 Q$ u: z* ]' f" a
        if(p==NULL)return NULL;9 e3 `8 p8 @( o% Z1 v
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;7 ^, W& C' ]9 \, Y. \+ v# B* k4 t
        if(q==p)
    - U/ C& U$ h1 d  f        return NULL;2 e% g; y6 {7 d+ _% h, U
        while(q)# p7 x& C7 ^1 l$ X( u
        {
    ! m5 v% J5 L& y' V3 M  @+ A        if(q->nextarc1==p ||q->nextarc2==p)1 O- U) S# \& e) z
                break;: S& h+ G3 T& R# j& O/ I) ]0 r, H; ^
            q=NextArc(v1,q);
    ; s6 K" m8 {. c4 J4 k    }- }" l  z% q7 v, Y: B
        return q;. x3 V- i# B4 c& f
    }* C0 |" |! M6 _; v4 o
    template<class ElemType, class WeightType>' @4 j# s6 c  j& x  V7 t( @9 z
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    # z% f) G+ r& Y' D  C{
    ' ~7 P1 c8 f3 ~  j" M    if (vexNum == vexMaxNum), `' ~! C! a4 @+ w+ G
            throw Error("图的顶点数不能超过允许的最大数!");1 u- a. E3 n8 w) T+ P* f2 d
        vexTable[vexNum].data = d;
    * W4 _4 D$ T& a* M    vexTable[vexNum].firstarc = NULL;4 [3 @7 b6 R9 K, W" T( u1 ?* S
        tag[vexNum] = 0;
    ; @+ J: L6 M  Y7 c    vexNum++;4 _+ ~+ D' F# a8 Z2 N  T; ^2 d6 ?! s
    }
    4 x5 @' y$ {& V$ Mtemplate<class ElemType, class WeightType>
    : W6 m/ {* `0 ]1 ^' P  @/ Vvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    7 o. Z6 T) e# G2 w. W4 x{
      F, E. i$ g; N9 q' o/ W0 G    MultiAdjListNetworkArc<WeightType>* p,*q;
    + c. T5 `5 z% O6 J$ J7 B6 b    if (v1 < 0 || v1 >= vexNum)
    9 q4 B, D2 P1 m7 ]: e7 o7 T4 X        throw Error("v1不合法!");
    5 I% t. U/ T: d: S    if (v2 < 0 || v2 >= vexNum)
    1 `+ N/ w/ u4 O) b" _        throw Error("v2不合法!");
    - L* q8 N$ o/ F" B/ y* r3 p% O0 P, G    if (v1 == v2)
    * c- V- H8 h3 D$ M1 `" s9 U        throw Error("v1不能等于v2!");2 t, W* g  _; ]2 H; h
        if (w == infinity)
    : b) i' d: Z* i- _. K1 t- n        throw Error("w不能为无穷大!");% o+ {: S, P0 {+ u0 L  d+ c
    7 Q* }4 |$ A) ?; O, G2 B
    , C+ P! ~: C0 P  t; b
        p = vexTable[v1].firstarc;) ^4 `! T: I5 r$ x5 `/ Z; H
        while(p)+ H  r+ b* k: t0 T
        {
    " V! r% d' B2 v2 J6 k; s        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中4 j, ]  k3 w8 }$ K
            {
    ! H  [5 N% @# U( c3 J, \* \; c            if(p->weight!=w)
    4 L+ s# ]5 I6 _6 Y                p->weight=w;. I1 g  Y; T& q/ `/ f6 M3 ]
                return;4 r  H( P- c6 E! H+ R
            }/ y$ S! ]$ w6 F# ?: s% D. P  f8 b; S0 i
    " W6 l4 d! j* |" I1 ]
            p=NextArc(v1,p);$ _' N8 A0 p7 F$ V/ ?' F) u
        }+ d7 t  b. y& `$ y
        p = vexTable[v1].firstarc;
    5 S9 i$ V3 Z5 S( ]) w$ U    q = vexTable[v2].firstarc;
    1 X# `$ j! q3 C  ]    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法9 P$ [- N: t' o4 a
        vexTable[v2].firstarc =vexTable[v1].firstarc;! V6 F& s: P0 h' Y  p/ X
        arcNum++;
    ' d" E% k4 W8 Z2 j}* z/ m+ {" ]/ o6 J/ j
    ' b; Q( Z. w" P7 o
    template<class ElemType, class WeightType>5 M/ _: I+ |/ Q* h; h' p! c
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)" ^8 M0 A9 e9 T) [  j+ b
    {# o* ]1 X, Q" c- q- `

    5 E% `9 R# o0 ]- {$ o    MultiAdjListNetworkArc<WeightType>* p, * q,*r;/ M% ?/ h9 t+ V  @0 Y
        if (v1 < 0 || v1 >= vexNum)
    3 u3 n9 L8 M8 d+ e7 k8 h* b        throw Error("v1不合法!");% @8 O- x' D8 q. K3 G
        if (v2 < 0 || v2 >= vexNum)
    ) Z0 f9 ~4 {6 L" _& @% S        throw Error("v2不合法!");7 c* h9 T, E3 D) Y8 t/ ?& I3 |
        if (v1 == v2)
    # {( m2 E( K4 G9 @; t# v        throw Error("v1不能等于v2!");) N% j& ~& m/ K

    ' r4 ^# s+ a8 F: h* Y    p = vexTable[v1].firstarc;8 [- Y5 z7 J  x
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)" c, u- G; d  z7 y. c3 ~0 ]
        {+ v$ Q( l' z- b9 u3 ~
            q = p;, A) w0 Q9 R" J7 k
            p = NextArc(v1,p);, B& _* B8 Z$ q. X& M0 b
        }//找到要删除的边结点p及其前一结点q5 l% Q, b( a$ C' a4 X. w' N
    1 a: Q6 O2 ^/ P2 u; K
        if (p != NULL)//找到v1-v2的边
    ( @( V) n. J9 Q* s  s, q( Z    {
    . t' F& \, a+ ?7 ?2 G        r=LastArc(v2,p);
    ( z7 y* w. l! ]0 r7 j+ r        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    3 H  ~1 P9 l! z' g            if(p->adjVex2==v2)
    ; T2 q0 j1 k1 F                vexTable[v1].firstarc = p->nextarc1;
    + Y3 k) n7 g2 a            else vexTable[v1].firstarc=p->nextarc2;) a  [) r* e2 a
            else//不是第一条边# `* c) R& A' t$ D7 q- ?
            {
    $ h2 m3 w2 x) z1 |/ U6 ^            if(q->adjVex1==v1)
    5 O) o8 G# r* {, K4 {* ?                q->nextarc1 = NextArc(v1,p);
    0 k* J* L+ z$ W# g, u" ^+ ^            else* a: g. s0 i3 y: }( z+ ~. g
                    q->nextarc2=NextArc(v1,p);
    5 o, P+ m# s9 l
    $ ~3 K3 }2 i! D* @, m: E. Y        }5 m, b  x" x4 |6 q
            if(r==NULL)& s( ^# V/ }9 J  C7 F( K: K
                if(p->adjVex2==v2)" C. U# L+ X5 j* S6 C: M; `
                    vexTable[v2].firstarc = p->nextarc2;; n3 T5 q! U3 O: ^5 @5 |' T
                else vexTable[v2].firstarc=p->nextarc1;
    ' w6 d6 @; `1 I- m- U4 K        else
    9 J$ m  _* B3 J, k        {4 S" P, @/ ]( b! d5 Q* n
                if(r->adjVex2==v2)* E- B! i: O3 |8 f4 I
                    r->nextarc2 = NextArc(v2,p);
    . m* G" X) X% V9 p' u2 A( w. G            else9 P* K8 a, y" v9 z
                    r->nextarc1=NextArc(v2,p);4 b$ M; q, q0 X3 o
            }
    & x$ y, w3 e6 F3 X        delete p;
    , m5 ?  P. {+ [' M$ n        arcNum--;
    # g: m$ t7 _( r! M5 ~    }
    % b6 }0 u; s' Z6 E; y
    : N: h( H7 o6 n& a2 |}
    / n6 B! I8 a8 r& `template<class ElemType, class WeightType> void) Z. S- v1 \* M. R/ c) F
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    2 K9 E! [5 ~5 c8 n2 d{
    " q7 U' G3 m1 w9 y    int v;( Z6 M/ A" [) I
        MultiAdjListNetworkArc<WeightType>* p;
    % [. ^8 S: S: `    for (v = 0; v < vexNum; v++)//找到d对应顶点
    , L8 V# Q1 O! B3 _) s0 c3 G" g        if (vexTable[v].data == d)
    " D1 T" [$ s8 G+ z            break;" \) x( z" N& }& l1 e0 z
        if(v==vexNum)6 t9 t9 [0 j: h8 L6 y$ H( C
            throw Error("图中不存在要删除的顶点!");
    4 R( ~- ?1 k( a1 [4 [
    ( B1 {7 f- V: S( z1 @1 ?, F" M    for (int u = 0; u < vexNum; u++)//删除与d相连的边3 |9 n, @  B: k& ~
            if (u != v)
    4 c' A8 t# L# C, \        {
    1 a& ^" x5 m8 b, G# _* Q            DeleteArc(u, v);
    " s7 n0 g8 ~; q        }
    ; M8 ^, P0 p, e- x    vexTable[v].firstarc=NULL;  _+ Q  C1 O& t/ ?# U; f4 V

    4 b" ]* d" Z+ W  ?, G    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置/ \8 `: ?) O8 i" T
        vexTable[v].data = vexTable[vexNum].data;# ?! R# r" p3 z
        vexTable[v].firstarc = vexTable[vexNum].firstarc;8 K" x! H' ]2 t$ D. ~( C: C" t
        vexTable[vexNum].firstarc = NULL;- P! f0 b  _7 p" v
        tag[v] = tag[vexNum];
    ' a5 B* U" M8 R8 _  t: N    //原来与最后一个顶点相连的边改为与v相连
    : {- ]& x1 S2 m" q    for (int u = 0; u < vexNum; u++)/ _- |; ?: z/ G
        {
    ! k  }+ R/ K3 X, L/ r7 p- z        if (u != v)
    , M6 j1 v$ S* ~* {        {
    , G: W4 x, k0 T' X- Z* ]            p = vexTable.firstarc;9 ]5 n3 z! d! k0 a* i. r/ x
                while (p)0 q+ ^5 q% k9 W" F0 x/ B
                {
    # h; i0 r- b1 a8 c                if (p->adjVex1==vexNum)
    , J1 b- |) K: y# V* _                    p->adjVex1= v;4 ~5 k2 W! i7 l: i
                    else if(p->adjVex2==vexNum)% Z) T4 A0 Q7 c
                        p->adjVex2=v;
    " D& P% ]$ b& `! d0 ^6 r# ?, L0 [* k                p = NextArc(u,p);5 _" m! L1 h: s( x1 C; Z
                }/ }5 U, |* y2 M: c
            }7 Z/ @  F8 j9 Y2 @. e; a: R
        }
    $ k% y  N+ b  H$ S  G& _9 i1 d% `}: q6 q$ h, v. x' G7 I  Z' W
    ///深度优先遍历8 i9 u. _9 N$ f! [: M: J4 S9 N
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    . Y& v& B; ~0 o! P8 }, O{1 ?# R6 a2 M( A
        tag[v]=1;
    % l2 t( B, Z# D9 Z( G0 G    cout<<setw(3)<<vexTable[v].data;8 C5 A+ n. G2 ?' x* Y
        MultiAdjListNetworkArc<WeightType> *p;
    9 d' Y, r$ ^+ p9 \! J1 }5 z, \# j    p=vexTable[v].firstarc;
    9 K. c# f$ y( e( J    while(p)
    - Q9 ]7 Z; Y8 o6 W& G4 y5 _& q    {
    + j) ]  `( |/ {5 ]& ^        if(tag[p->adjVex1]==0); G% Z. g- i+ A4 n# W' a% N1 U
                DFS1(p->adjVex1);6 q! q* S5 o% w: q
            else if(tag[p->adjVex2]==0)8 c4 {1 r$ c6 \2 x4 w: l! P; g
                DFS1(p->adjVex2);4 a/ i" O! v4 z  y- Z3 a
            p=NextArc(v,p);* n# j  B0 K: D; P8 r# C
        }
    ! j& C. n1 q$ O: R0 [}
    8 N! }: Q4 Y& p7 S" i3 T* Ktemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    5 _4 W. X6 S8 ^- x4 L{. N' W6 Q  U+ O! u1 k) l
        for(int i=0; i<vexNum; i++)
    - x/ o' n3 o8 S! L0 L! z& t5 [: L        tag=0;
    " S: k+ ~% F5 n5 ?    for(int v=0; v<vexNum; v++)- {- ?7 u6 p) s, _# H- p& P
        {
    * n& V. u  x! Z4 _2 v        if(tag[v]==0)
    - M- c' l! J% y- b            DFS1(v);8 T0 i. u: w0 X4 @! A8 n
        }3 W) e9 Y, z; |3 @9 ~. P5 M
    }
    : f3 n0 s% G6 ^- |# ctemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()/ S( c$ f/ [% `
    {1 m! h) S$ u! d# m
        stack<int> s;2 n9 m  m) B2 q; C& W6 b* K6 \
        int tmp;1 Q5 K- T& U8 y' F' R" \! m$ T
        MultiAdjListNetworkArc<WeightType> *p,*q;  C/ ]* i2 \7 q! n
        for(int i=0; i<vexNum; i++)  L4 B2 ~  f* E: z5 V2 ?
            tag=0;
    " E) c/ k: g4 r) G, D/ ^: a    for(int i=0; i<vexNum; i++)0 Y8 y/ \, m5 h8 s9 I" \
        {
    3 o8 X# h2 m% @" j: g1 i2 L        tmp=i;
    * \# ?# o( k) c        while(tag[tmp]==0||!s.empty())+ P* G% R9 h* n* G) q/ k- E
            {: |" y& S" X( c3 k' p
                p=vexTable[tmp].firstarc;
    ! j* M: O$ s& C, V4 V# H8 q            while(tag[tmp]==0)
    4 k" U* o0 j: H$ ?            {' q7 L7 M9 [: ^2 ?
                    s.push(tmp);& v" ^* @# |0 ?3 i
                    cout<<setw(3)<<vexTable[tmp].data;8 a0 ~, d/ l0 G8 G: S" L3 n
                    tag[tmp]=1;3 v6 u4 c! Y+ q; s. \
                    p=vexTable[tmp].firstarc;' ^; E! C$ p. H
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for$ Q/ o, J0 V/ L- p. V0 ]
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);0 T- p' y% A( t+ A
                    //cout<<" 1st     tmp="<<tmp<<endl;* j0 f# w0 f+ q# B
                }
    : f( M* p( Q( }( N, ~4 T            if(!s.empty())) `% J2 B; b6 g# P' N3 R4 x7 }8 `+ W
                {) W* Z% I9 o( `6 ?9 @, i5 E, B
                    tmp=s.top();
    + x5 v( l1 m, m" }' J, K                s.pop();' j6 B, X  K) X- `4 E$ `
                    q=vexTable[tmp].firstarc;, p8 d& U* _! X! \! R+ D
                    int t=tmp;' Y7 ~+ ~1 n7 E: P9 x' c8 c
                    while(q&&tag[tmp]!=0)
    ' H2 Q0 t7 n. z0 M, D; ]" E                {. U- ^0 O! `" Z( y4 s
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);& Q4 q' S0 G" P/ P9 N/ b
                        //cout<<" 2nd     tmp="<<tmp<<endl;
    5 y, a9 R8 ~. O$ A  i# w1 e$ K                    q=NextArc(t,q);' w5 X& ]( a! l' W/ V5 `
                    }% }$ @( [% }$ V0 V- ^- \/ z3 V
                    if(tag[tmp]==0)5 T/ O# O9 ~2 K; S7 P
                        s.push(t);& d( e4 P1 u; E* u' W
                    ///1、对应上面连通分支只有1个点的情况* G6 _# u; H0 O1 R- `
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    $ D9 c6 V$ g8 t, R                ///tmp要么等于找到的第一个未访问节点,
    4 E% x% h6 }# Q6 S4 `" _' Z( v+ y                ///要么等于与t相连最后一个点(已被访问过); U. q/ ^: ^; B
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    % C: {5 ~+ ?. s) k; v            }" `' j7 B6 s9 q0 @" {9 V
            }
    7 G; A9 Y# w- E) c    }/ D( L# {% @. B  L6 x* M
    }! @: `- t- T0 ?5 ?
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    . U* \& J" G- p( S9 Mtemplate<class ElemType, class WeightType> int2 m; n5 [- K  M# j6 K
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)- a! j1 b/ x) L5 s
    {& U) o8 \$ N6 \# V
        if(head==pre)( }& O) r' q6 Q8 ~# Z+ _
            return -1;
    + G& z5 ^  o& o' F, N$ y* t  m3 m; V4 x4 V6 k
        MultiAdjListNetworkArc<WeightType> *p;' |9 K9 G. s- {8 a; T
        p=vexTable[head].firstarc;/ @# z$ k1 H7 B  u* c# N  o1 c
        if(pre==-1&&p!=NULL)
    7 g! f: d0 \  A0 _' e        return p->adjVex1==head?p->adjVex2:p->adjVex1;( D# A6 ?# ]6 i" t* \8 x
        //pre!=-1&&p!=NULL  Q; n2 R' g  g) L) k+ o( }' m; B
        while(p!=NULL)) V9 W% z+ h+ Q: p) ^; N
        {( M( U' t6 J! ?
            if(p->adjVex1==head && p->adjVex2!=pre)
    4 a) B1 ~2 o8 n  G" F            p=p->nextarc1;
    1 s; N( t. D4 ~- V4 O. u* V$ l        else if(p->adjVex2==head && p->adjVex1!=pre)
    # f! c( g, `8 A+ X' ~9 i            p=p->nextarc2;
    + {7 }7 W+ E+ A' W0 R) {        else if(p->adjVex1==head && p->adjVex2==pre)) ~; c/ `! o/ J) a. c
            {$ p9 v" g4 x4 v3 M
                p=p->nextarc1;0 L" Z4 r* Z0 X, H: F6 w# r
                break;
    2 ]' c5 a  A/ W2 \8 A        }# v. ^" p0 g, A; y6 K% ]
            else if(p->adjVex2==head && p->adjVex1==pre)5 D8 E  H, k( Y# d. ?2 o3 H* _# v
            {, h$ t; O" N* h# o
                p=p->nextarc2;8 t, p2 v7 d& `% j. l1 U5 H
                break;/ G3 h% i* g; J; n- P( b$ l& B
            }: K1 F. b1 _6 K2 }. r9 _; X
        }
    * n' Y1 u4 D2 Z% S6 K    if(p!=NULL)
    ! y8 {2 l% U! V4 l1 t    {
    ( n( `! g6 t. G1 @/ {7 t+ w+ ]& w+ N        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    . I9 c& u  p& R  `5 e& c    }1 M+ I, k4 e/ S  `, G0 j: C8 `, ~
        else# ^! ~6 B& y9 ~2 U0 z2 x! o
            return -1;& d. \$ w1 P  Y8 B( `
    }5 d" V- N4 [5 I) R4 d8 Z; ?

    9 Z2 B6 n  W, g3 U; ]* l
    3 h6 {% x# S2 {# p* stemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()3 s, m! T3 q* }" U6 o3 j- }; J
    {
    & M7 O# e4 I% P4 p1 h, S    stack<int> s;
    5 x2 }- T& c* C4 ]8 B    int p,cur,pre;; [' M4 U; a6 W& B3 V! V* H3 o
        //MultiAdjListNetworkArc<WeightType> *p,*q;/ Z* E/ ]5 p' W& X. H
        for(int i=0; i<vexNum; i++) tag=0;//初始化
    ) ?5 ]: f9 x8 \2 e$ x. {" L8 f9 s7 O" j9 M- S- N0 Q" c
        for(int i=0; i<vexNum; i++); b  Y* J+ [3 N$ S. ?
        {
    " ^" M6 i$ e3 c: z3 y/ I        cur=i;pre=-1;) ~& f5 @* l& `7 y+ o1 A: {$ H
            while(tag[cur]==0||!s.empty())8 x+ g* V) @' f4 T* v
            {& s  m9 V) M+ J; t1 `2 j
                while(tag[cur]==0)8 O( Z) G' ~) I3 P  J
                {
    / t% g+ V+ q( f1 x3 c6 k0 W                cout<<vexTable[cur].data<<"  ";2 i; Y# Y% f" I7 D- r5 N
                    s.push(cur);
    # U* |: C- w; y; e6 a1 ^/ k- P6 {                tag[cur]=1;
    7 q* j; q$ |+ Z0 T! y/ u$ p               //初次访问,标记入栈; g! L/ b4 [/ F7 B. Z

    ; d  D8 [' M$ y- \               p=GetAdjVex(cur,pre);//p是cur的连通顶点8 ]. ]6 v# L, Q# Y' R
                   if(p==-1)
    $ i. w+ U/ ^  k: W5 z- W; \               {
    1 R& Y, p9 U( D6 R* \$ a                   pre=cur;s.pop();! e* I: n4 l1 C$ p
                       break;
    ; X1 P5 Y) S/ y6 D               }$ ~& M, X$ |0 g6 o* D+ ?& e4 B: l
                   else
      H( N# W  C) F  \               {
    2 N. ~7 s. J! b3 Y4 V+ B& d                   pre=cur;. o% P8 R  A, {: w
                       cur=p;" e2 U0 y/ Z: }$ o  Y; ^
                   }, l  K- _8 x2 q4 g  j5 |
    * O" o8 w8 S" ?8 @7 E  T
                }
    " Y' @; a# V" V' e2 f  a. i' F            while(!s.empty())% E! r+ v; e4 S9 x
                {3 w2 J1 m& ~; D- B
                    cur=s.top();
    7 t2 Z5 n) r6 n* U' B$ b& a/ c, w                p=GetAdjVex(cur,pre);
    " G( h2 t7 A; R& D3 x3 G, P8 y                if(tag[p]==0)
    - W7 D" F. j; C  @+ N                {2 }: H4 I9 ^4 d/ R! N
                        pre=cur;+ Q/ l- N- W8 X5 U, t
                        cur=p;
    4 i/ l! E2 m3 c6 `                    break;( w$ }6 a9 B1 H2 n9 R: f+ p
                    }
    ; U& G1 s4 {4 O: {3 Z" ^/ b7 h/ Q                else1 `- Q. Q- I0 K
                    {- t3 k& o7 N. z* H
                        pre=s.top();
    * I; \( z2 \2 f                    s.pop();7 T: O" q# X. \
                    }
    % W( W: J4 }- b. ?, W* G( n3 y6 F2 z6 ?  L& d  g
                }
    ! V& _+ U+ C& `5 E- Z8 D8 f: d3 [0 ~# z( I: ~: B- V- G
            }
    . h- E* v; ^3 [    }7 ?) T$ o" {3 N, Z8 {. ^. H% Y
    }3 w2 q+ a2 E7 @; p: Q, r' Y1 D
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    6 S. t3 H% F* k0 e{. ?' n8 Y9 L& V3 |3 m
        for(int i=0; i<vexNum; i++)# H% ~$ ^1 n' u" ^: Z. I
            tag=0;
    ! i& e: X, u& S# a# ]    queue<int> q;
    " {2 B7 ^- h! `# M$ c5 W9 k    int tmp,t;
    ) _. o. G; S& ~$ z4 K. B    MultiAdjListNetworkArc<WeightType> *p;
    & K9 u, X- Q- `; R6 T  V1 C    for(int i=0; i<vexNum; i++)
    * \) W$ Y+ N; p0 f- [# s    {2 Y; i3 [0 g, m% U
            if(tag==0)& K5 ^7 I; Z, Q" Y
            {! O- o- _# j8 I9 N6 f$ T, P
                tag=1;7 x2 m5 F& z, P* A- H' z# g
                q.push(i);0 p5 A( K0 B  J9 c* n. q! f
                cout<<setw(3)<<vexTable.data;' X! `0 i, I2 A, c1 q! Y
            }
    * e) r2 c! v1 u/ c6 p6 C0 {) `+ x0 s& h        while(!q.empty())
    8 y) m" R; B! }        {/ T1 \( G6 E7 v0 C
                tmp=q.front();
    - v" y. }& G" a& z, S  S5 a            q.pop();
    2 }$ t8 s+ _5 i/ I4 R            p=vexTable[tmp].firstarc;. y/ W; ^: F. Y9 w' Q
                while(p!=NULL): k9 m% k# e) o! Y. Q8 N
                {
    3 u' f! k* q4 t8 w                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);; C& m7 Z3 k4 j, d9 O5 M% a7 H# t
                    if(tag[t]==0)1 B4 K/ p3 T2 X; x7 M$ ~
                    {
    . [2 r' {0 s+ c/ x! ?                    cout<<setw(3)<<vexTable[t].data;1 m4 ~. g( @! e& L& y
                        tag[t]=1;! A* S6 M  A( t. j. I
                        q.push(t);
    , F$ d2 S5 a8 v, ~8 l6 b" l                }
    , C$ T$ \! M) ]* W8 n3 q7 l                p=NextArc(tmp,p);
    # Q9 g" T9 _  l            }
    & W5 H5 D& i' e7 U        }
    0 p# T7 @4 L! P5 ?    }0 f8 O9 j! S/ q; T3 _3 d
    }/ E, D; }3 g8 z. o
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()8 h/ E9 Q) O7 n: G
    {
    ) x3 c" C. p; A    MultiAdjListNetworkArc<WeightType> *p;
      i- {! b, X  ^& {, S1 M    cout << "无向图有" << vexNum << "个点,分别为:";
    & n7 c9 b  n; a  ~& ~* X3 K' j% b    for (int i = 0; i < vexNum; i++)
    - M5 \. d6 x7 o+ B% y" e4 j! I        cout << vexTable.data << " ";
    4 q( M) M3 c/ h, e, O( h    cout << endl;: F' L" i! [$ R, l% N
        cout << "无向图有" << arcNum << "条边"<<endl;" ]6 y  N( t1 J; m* Z
        for (int i = 0; i < vexNum; i++)
    ) s8 O' G9 O  H4 f( @8 o    {
      B" y6 c# }( N9 d% F        cout<<"和" << vexTable.data << "有关的边:";& ]% C( s+ ]6 ]: S# U, a% A) i
            p = vexTable.firstarc;
      d( z5 t! O* g0 b7 m$ L. D! n        while (p != NULL)* a. q) H, l, c# ?: u0 v
            {
    4 l- c( F6 B! d5 `4 V% ^& C2 D: m# e9 K            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";1 n( T6 Y4 \: @: C. L
                p=NextArc(i,p);
    ! H7 T6 v; B! ]  V7 s8 U% j: z        }
    4 x+ @% {# _% J% t7 r9 Q1 r        cout << endl;
    6 u  x3 }# Y. Q    }
    % Y( I- p$ c  o8 G}
    6 {! ]; C+ `' [; u/ x4 \
    ) d" R: h2 I0 K1 ^1 v
    9 p# `' O0 [) I: z! k1 w4 ^邻接多重表与邻接表的对比, F' x$ y6 a* K1 T- v* r* }
    , w% _( W+ t# o4 h& i; Z
    邻接表链接
    6 f$ s) [$ T! E0 [) U0 G在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。, Y: ^; l& d5 r+ m4 @- J. I
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。* s7 q! j/ Y1 l) y/ \
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。$ A4 T5 @; C4 Q) w# a9 x
    ————————————————3 N% W+ a& _9 ^* k5 i5 P
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    7 g- A, x8 N+ K2 E& z7 }原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    3 L/ ]1 O3 [  H% J: h2 w, u
    & p5 W, C. W9 k$ H" b1 l
    / `# o' L; G" A( O% M) h( w. S+ D& P  S

    / \6 l- X" q* N————————————————: |* b) g8 _8 X& S
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    3 E) D2 P' Z6 P, `* X) N2 @, M& H原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    8 e8 V/ G7 z; j3 i8 m# m  ?$ V* E  R" Z# e; |
    5 o4 p8 [4 ~% U( e: T. \  M
    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 08:17 , Processed in 0.456774 second(s), 54 queries .

    回顶部