QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1596|回复: 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
    . [  k; [+ \- K
    图的存储结构——邻接多重表(多重邻接表)的实现0 b2 d! }$ ~$ D; X+ c- o1 _- b
    7.2 图的存储结构
    ) R0 k/ ?7 w& m0 M3 N8 T1 X
    + x$ [5 Y1 a& j" l7.2.3 邻接多重表(多重邻接表)Adjacency Multilist# e2 }  V2 \: l7 p# u9 |  r
    邻接多重表的类定义
    # F0 x5 {+ t. N+ F, D  z# @9 R邻接多重表的顶点结点类模板) n( d# ]6 l' S1 K1 ^6 D
    邻接多重表的边结点类模板/ m1 E# h, l6 f6 {
    邻接多重表的类模板
    ) I, X- c: r. I8 h5 ]& D# J( K邻接多重表与邻接表的对比7 @0 e) r: ]& I0 _' O
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    9 Y- T7 L! ], e8 Z5 k& t* L2 {4 C* s  g8 X: o2 t- a: }8 j4 ~
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    0 j( f4 v' n* z# z' f* @% S在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。9 \) U0 G1 ^) d' w- O6 r

    5 }/ A0 _: T2 v' C! G. B邻接多重表的类定义
    1 X# Z! l8 G, a: H3 t; x$ H 1.png 9 i0 I+ U# B8 i) E# _( G) d. ^6 U
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    : f. c+ t0 i: W" T" Xdata域存储有关顶点的信息;8 }1 l  O0 D# ?/ C1 p. c# b& t
    firstarc域是链接指针,指向第一条依附于该顶点的边。
    + G+ k/ h7 s/ G8 `' K0 |: R, Z6 N1 D/ _6 B所有的顶点结点组成一个顺序表。

    $ Q" l6 |) K5 X2 \3 N

    1 K5 U9 F# p, V0 P( M0 ^/ Htemplate <class ElemType ,class WeightType>
    # \: s) R) F9 t( U3 L' Pclass MultiAdjListNetworkVex/ Z8 ~* |% B2 \* m( h# H) _2 g
    {
    3 f- g& f0 V, K4 D3 Z- e! A/ Jpublic:
    9 i( ~# e7 y6 f        ElemType data;$ H" I$ F; `, `! M. v
            MultiAdjListNetworkArc<WeightType> *firstarc;
    5 [! [" J, u1 Q) ^3 U7 {4 d3 I( j
            MultiAdjListNetworkVex()
    & _9 o! H; k9 Z5 ]* \( T/ o        {
    + @% K8 N- Q+ T$ B1 b& ^                firstarc = NULL;9 }% y3 r0 w  a
            }
    % B0 N! R, P5 y5 V% e) y        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    3 U2 p) B, R! @! ?8 h' d' v" N        {* B* [6 G  ?$ W" I  c. [
                    data = val;+ w. ]. K6 Y7 v# g5 L, {; g! n; M
                    firstarc = adj;
    2 h# ^, ]( o: ?4 X' y8 N. C        }
      D/ f) N& q6 U- r};
    # t9 W* {% \7 M: c  I8 r' C/ ^: j) |
    邻接多重表的边结点类模板
    ( s4 t% p1 h2 R8 p8 S% S7 g8 g0 c8 Z" b; I0 r
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
      j8 y/ r! `, i* w6 ktag是标记域,标记该边是否被处理或被搜索过;
    9 U7 p2 k% d% M8 w/ t1 h9 E0 h, ]weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;; i- x& X1 c: d6 @2 }6 F5 H: C
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;- {5 R+ ~9 u/ q( x
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    " d% n5 U. G& `  Z4 S! x$ ^% d5 N) I$ r8 u& Z' d
    2.png - k3 o* }( r7 \! e" Z
    template <class WeightType>
    - Y- p1 D& u& ]8 l' j' Rclass MultiAdjListNetworkArc; y! C9 N0 `+ I9 O$ E) b
    {
    ! v( X$ J* r4 a/ rpublic:5 X* I0 V3 l& g9 o8 I) q/ u
        int mark;                                       //标记该边是否被搜索或处理过
    : T$ ^% I4 @: q        WeightType weight;                              //边的权重
    ( S9 s7 j8 {+ Y$ ]+ g        int adjVex1;                                    //边的一个顶点0 j, ~5 o, Y) O1 S( U0 p, O3 y2 F
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    4 ~7 g& i7 g: E0 v; H2 Q) l        int adjVex2;2 d: w5 N# `$ Z1 l  y" U$ q
            MultiAdjListNetworkArc<WeightType>* nextarc2;0 u4 E8 H* ^! q9 b0 K7 o$ k

    9 ^* z% Q! O# U% E* ~        MultiAdjListNetworkArc()
    1 O/ y* C9 y; ]6 T' ]) v        {! p! O9 H& p- G+ L) ]6 t' @; F
                    adjVex1= -1;
    ) _/ ]/ @' S0 J3 P                adjVex2= -1;
    & z: G! m9 }' W+ O: J& e8 U, _. g        }; c1 \. h' N5 u* j4 Q6 _
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    , f& d! A( b5 A& ]8 ]& @% |8 M        {  s5 V1 }3 E3 M! @+ {2 f5 A
                    adjVex1 = v1;       adjVex2 = v2;- i* H4 l3 B5 R, ^) |
                    weight = w;
    5 _" w! K& e. z( K4 O4 L2 Q                nextarc1 = next1;   nextarc2=next2;8 S6 Q. I4 r& D1 @
                    mark = 0;           //0表示未被搜索,1表示被搜索过- X* f( {3 p+ C
            }
    0 c  C( E9 g# Z% A; z( o  c$ Q% ^( j' C6 {6 @8 l) m
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>1 ?/ g! n0 ~9 f! @" s* w0 D
    class MultiAdjListNetwork/ u% m6 W8 d& u2 b" ?* Q7 Z
    {
    , q, ?1 k8 J/ Z- V9 _; A: nprotected:
    1 q* C0 k6 M: k. p. O    int vexNum, vexMaxNum, arcNum;# z* Z' J9 b1 H1 |
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    " |# q1 ^- ]) d; _( v# z    int* tag;1 P8 d; j# {9 M4 m( G8 M
        WeightType infinity;( D+ V8 L- M6 g; B; b

    1 D' Q4 k$ c& G" Q" rpublic:: q  O% B  d: ]4 _
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);4 V; f' {, [# X, m. T+ u2 S
    7 ?$ ]- O1 @: \2 Z. U, v/ \
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    / O8 {$ f9 y8 W( m/ g
    ; s2 o% ~5 r0 I7 N7 c    void Clear();
    , R2 @, H8 R/ b- k    bool IsEmpty()( u- v3 m) M' z0 o: G( g) y
        {
    ! i" i) [- H$ p/ @% X% m        return vexNum == 0;
    / l0 |  J3 e# @, _* `+ _    }
    $ M1 \$ O! L; N$ a    int GetArcNum()const
    , N$ P1 E2 m+ n: ]    {; V+ p" t/ L' n5 N. B: l
            return arcNum;7 M6 V! {; ?3 z7 ~  g2 {
        }
    : U6 ?; I) D1 }: \9 O- J    int GetvexNum()const8 ~; ~, s  _/ E# p+ z
        {
    $ G* ^9 I  i& k! E! {# [        return vexNum;3 B; H4 c: r8 \: F( ?; x% y
        }
    6 W1 l# i, t4 z5 J, b4 y/ v; a- H+ ]/ W5 T
    ; w& c- |) Z( t% a8 ^& y
        int FirstAdjVex(int v)const;
    6 Q* U6 V5 o: p( g    int NextAdjVex(int v1, int v2)const;: S: ^2 z  _, l
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;: P" w( Y* v/ ~# s3 ]
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;; W6 {4 Q3 H3 a3 L6 v) ^( N

    + N: B) D2 j5 H( v3 D) b7 v    void InsertVex(const ElemType& d);4 P, u( L% v) [$ k. x; j- g4 |* ?
        void InsertArc(int v1, int v2, WeightType w);6 K) F& i' M; ^3 q2 ~* p9 S2 f/ j

    : h! b$ w( i$ H  N: Q    void DeleteVex(const ElemType& d);
    % s9 r' C9 W* J# m5 c2 ?' @    void DeleteArc(int v1, int v2);0 U$ C8 Q& G1 q0 i: q, p" d
    , U- B4 `: j- Q& M  }5 ~
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);/ L8 z! u' ~+ w1 C0 _& b
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    " v, d, o) b4 y" K* |% T5 i8 [; x9 d
    ( R+ s4 J2 F1 P, }0 ^4 E5 E    ///深度优先遍历$ a* ?+ q& U" O6 ?' X
        void DFS1(const int v);
    & w  ^$ J. d# I/ s( }7 P    void DFS1Traverse();
    + q; P" j7 t2 `/ T    void DFS2();7 p4 _; Z0 c# D
    " T) [, P) o3 e" p% J. l
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    * {3 m4 u6 U9 H8 M7 f# |, u5 o    void DFS3();( J1 Z5 n" J. z/ L' ?
    3 N8 U& A, f2 y2 q- U# F( T
        void BFS();3 d8 z! o, y1 L- x  t! a: y' T
        void Show();' Q# h/ K( l7 j  [9 m0 M" o
    };2 k, w; \! S8 P6 y7 Q2 E
    . E# }5 D! p! j
    2.函数的实现
    ; @: W( T! x2 P+ A: k" n研讨题,能够运行,但是代码不一定是最优的。
      q" P+ x- N  p; F! E: d' f8 m
    # o4 [& W1 \2 z- |% ~$ h' I#include <stack>
    9 W: F0 v  @8 ?6 T. [9 A9 v#include <queue>, N# p$ y; @' O6 v+ U3 I" Q2 U
    # n% C6 K  a2 S5 m+ N$ j5 b/ H
    template <class ElemType,class WeightType>
    * ?# N( m- w+ c! G6 f2 o8 s% s% bMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit); K; D9 O+ `8 ]$ [! q
    {) M! |; y( d+ P9 a
        if(vertexMaxNum < 0)
    1 K% i; a) z: [7 H% b$ O$ l        throw Error("允许的顶点最大数目不能为负!");
    ; e( X$ p) r/ f# ^/ e    if (vertexMaxNum < vertexNum)
    * C, x  d& X, [$ l' x$ X4 D: v        throw Error("顶点数目不能大于允许的顶点最大数目!");
    0 U& q  d& X3 M9 D1 G    vexNum = vertexNum;
    . T. w& b& d. x9 X. ^    vexMaxNum = vertexMaxNum;
    4 @# n6 o( s8 a4 k: _- u* [* D6 K    arcNum = 0;; W0 u1 Y& y5 {- {' b: {& R
        infinity = infinit;
    , T/ w6 ~. ^. h& v' \4 L6 N    tag = new int[vexMaxNum];+ I( L: q: O3 R& b6 v
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    % F  r) T( Z& I" j1 N4 F9 d    for (int v = 0; v < vexNum; v++)
    2 _+ x" ~" E5 M( H( b    {
    ; J7 E! O) q7 M        tag[v] = 0;; U, u( X6 Y- O, [  Y0 V
            vexTable[v].data = es[v];
    2 ~3 s$ j+ e& T$ U/ e        vexTable[v].firstarc = NULL;
    ; o9 ?9 P+ j7 u4 j6 d4 C+ g    }
    3 Z$ b8 N- z# D0 H" q; S}
    $ C$ s2 P; ]/ J: dtemplate <class ElemType,class WeightType>
    ) W( {. D- z+ [7 o/ c. wMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)- V1 s0 Y; b! |) C# r; R  }
    {
    5 j' R. c/ B* z    if (vertexMaxNum < 0)
    ) [' H# I! N5 Y! z& H+ I        throw Error("允许的顶点最大数目不能为负!");
    8 a6 P2 R+ h- I  [. `3 a8 a    vexNum = 0;
    - _( I/ g& q* x    vexMaxNum = vertexMaxNum;9 M! f4 m6 m) Z1 N& e+ ^* [
        arcNum = 0;! A5 s+ W# r* k8 S( i4 F1 U
        infinity = infinit;
    # @! S2 u$ S0 ~) g: I* B3 J    tag = new int[vexMaxNum];
    # f& x$ @9 L7 s    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    2 b# b7 N! t  ?# @. L# `; \$ M2 o}
    , D  M& r& q/ h% x7 L2 a5 Atemplate<class ElemType, class WeightType>7 I! d7 g2 [  H7 l* b. e
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    1 p% j# \( r5 B( n1 Z; R$ y* d{
    8 L$ \- Z: q8 R    if (v < 0 || v >= vexNum)
    1 R8 ]' }+ X. r7 {4 p. t" o. ~        throw Error("v不合法!");
    ( Y' q+ T7 A% P- g    if (vexTable[v].firstarc == NULL); M: ?7 r; O: c& ^* V( u' }  Z
            return -1;
    - g5 L* i& S$ M  e- D! k) |# C' \    else
    ! S8 x; }2 }& F: C$ S        return vexTable[v].firstarc->adjVex1;
    " n& W, U+ k# J2 i" d5 S}
    9 X5 r: o$ L3 X* X
    / S' v# a! h& p7 Wtemplate<class ElemType, class WeightType>. ?5 @* W6 g5 j; N8 Q2 {( N3 p
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    - w: P; k6 l$ ~7 H2 q{! C; T, ^' R; k  ?5 {3 e
        MultiAdjListNetworkArc<WeightType>* p;1 \7 `& V( i' }+ F8 p$ y$ V3 X
        if (v1 < 0 || v1 >= vexNum)+ v/ l1 [- d( V5 o$ Y& A4 ~  `
            throw Error("v1不合法!");" q- y, s- T; R
        if (v2 < 0 || v2 >= vexNum)" q6 l" X: s( ?* P$ n2 B/ r$ o$ P
            throw Error("v2不合法!");
    . v  k. F& f9 X: ]# q9 f. k! O    if (v1 == v2)8 @) p0 C( v2 ~9 T' ?- J  K1 g
            throw Error("v1不能等于v2!");7 |3 {) r) c/ z' r& q# i
        p = vexTable[v1].firstarc;
    + Y' R9 `4 N. h    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    ; P0 {4 v' w2 |        p = p->nextarc;
    0 K% U( a. l; |0 L9 V    if (p == NULL || p->nextarc == NULL)
    7 A8 I# K& q+ ^9 W        return -1;  //不存在下一个邻接点8 b* x- X! d2 d' n& ]
        else if(p->adjVex1==v2)2 M% R" _' a+ |+ L% h
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);# k% s. y* t7 e) G2 |
        else
    0 @" Y; X3 K/ C1 W9 F/ u        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    ( g- Y! E  u* u1 s) m4 ?: B1 Y# t}6 y; }8 U6 Q$ F
    template<class ElemType, class WeightType>3 @) u4 |( U( d' Y$ d
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()8 Z. o9 A, j' L$ Y8 a* W3 W
    {
    , h5 L( ~8 b: ~# j! N3 k    if (IsEmpty()) return;
    0 t' z5 E, c0 |9 s+ t. x: E    int n = vexNum;3 t7 G6 N# Y5 D# j
        for (int u = 0; u < n ; u++)
    - s& d* ]& i2 A        DeleteVex(vexTable[0].data);9 ^$ u% `" m' u
        return;
    1 @6 @: q8 P" }& g& b. @! a}
    2 w, A  t1 C+ v9 j1 [9 U, ltemplate<class ElemType, class WeightType>
    * M0 G6 y. d3 R0 y  q8 Z5 [4 `6 oMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    + d. F" B7 L' h. v! l* L{, \) k2 _& }( P. j6 G: W
        Clear();
    & B+ _: x8 y" \5 z: P! O$ }}# s  X! ]6 J& J0 Q6 G/ Q) z
    template<class ElemType, class WeightType>, z# X9 }5 b/ ~
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    : O! u9 e( ?' W( ^( ]. W( B{! r7 u4 G1 T: ?0 V" C! t
        vexMaxNum = copy.vexMaxNum;; ?/ b, g" D  B* n+ E- Y' B5 y  j
        vexNum = copy.vexNum;
    5 |' |1 q: j9 z2 W. c5 o! I    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];  G! n) d8 h! Z5 T
        arcNum = 0;
    / {& h0 L- n( e- ^, I& Z    infinity = copy.infinity;: b: |& q9 m! e5 {7 P  B
        tag = new int[vexMaxNum];5 O* D  G, r/ W; \

    3 [  I$ b' F* |6 M* |& r    for (int v = 0; v < vexNum; v++)
    / G) ?( S7 f6 p3 z0 E( t    {
    . c/ [" m+ Q3 _        tag[v] = 0;" ~% h$ s/ w( \
            vexTable[v].data = copy.vexTable[v].data;
    * Y, l* S/ h% S; u  F+ g        vexTable[v].firstarc = NULL;  u) A: R! d+ A7 l
        }
    + }( ?0 b* X  F1 G3 u1 [    MultiAdjListNetworkArc<WeightType>* p;
    9 _' ]2 u- |* L% l# C( y0 \5 ]3 {6 B  z9 t2 W  w! f
        for (int u = 0; u < vexNum; u++)
    ( I" b' p) l: ^    {
    7 A( J, D3 l6 ?# L, v' y6 O( h        p = copy.vexTable.firstarc;" m3 I* o" P. [
            while (p != NULL)* |2 g8 N0 H/ A3 P" s/ G
            {
    1 M; H7 D0 P# Z. v9 q            InsertArc(p->adjVex1, p->adjVex2, p->weight);5 \/ _4 z2 s/ B8 J3 }
                p=NextArc(u,p);
    2 Y4 B/ X7 B5 M        }
    ) _& K( @  X" q5 H9 S2 }# X! n2 V& N" G    }
    2 o" ^) g* ?7 P$ n; w8 g8 \}
    2 T  ^! D, p" Utemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&0 E+ b# b7 y3 n% U
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    ; m) X* m9 s+ Z{" z, \* y7 S  X' a/ g/ P
        if (this == &copy) return *this;3 p6 L, U- Z, a7 u
        Clear();$ L$ H) W# N1 O( S6 @3 r( u2 v
        vexMaxNum = copy.vexMaxNum;0 ~4 D- G% x; e' `6 P+ W5 z
        vexNum = copy.vexNum;$ B; W  K& o- |7 v8 ^
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];  f7 e& K. G. O% d. e
        arcNum = 0;
    ( h2 b( W) W" A# ~9 o    infinity = copy.infinity;
    4 T! R$ n1 m5 |% `2 w3 w    tag = new int[vexMaxNum];
    ; s! |- u! z4 V& }% K( K' @
    ' v& B7 ~* t- ]8 u+ w. b' s/ U: Y    for (int v = 0; v < vexNum; v++)
    $ S4 X: W# F8 |    {
    0 K" g( _6 `+ \0 c# j: B5 a        tag[v] = 0;
      f, |; E/ p( y, m  W2 V% L3 Y6 ~        vexTable[v].data = copy.vexTable[v].data;2 j& r$ n- J! a# a9 P! C
            vexTable[v].firstarc = NULL;4 r- C% N3 N  Y
        }
    . a# _( s1 z. E+ K8 C0 j    MultiAdjListNetworkArc<WeightType>* p;4 K% \2 l4 e) ~

    * a: F! t! ^& \4 G) _5 W, A    for (int u = 0; u < vexNum; u++)+ c/ k: V6 U  o3 v
        {
    $ g$ I5 n: Y0 }/ K* C        p = copy.vexTable.firstarc;
    6 `3 }' r3 S7 r0 X1 i5 n6 r! R# D        while (p != NULL)
    1 |; x0 {5 [9 W3 z3 N; t4 |5 V        {8 r* b" N- M7 H2 s: K# M( B
                InsertArc(p->adjVex1, p->adjVex2, p->weight);" s; L& I$ o' j. e  C
                p=NextArc(u,p);
    ! ~& O& {$ Z) w( C4 S* }. z        }
    $ Z: G* M; G; M/ h. v, O8 Q$ E    }  m" l. Y" [# u
        return *this;. v! I, A! H  y
    }8 E+ @3 I3 Q% c3 N* i
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>** c8 t% C" Q- T; }8 x; q
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    & }2 H$ p. W& H: K* ?# M: a{
    1 T# d- p5 O% V4 }8 [: c    if(p==NULL) return NULL;
    ! z, p7 |: u% x* H. ^9 E9 Q5 ^    if(p->adjVex1==v1)
    - f$ K5 H  g( X8 x! I' S        return p->nextarc1;' e0 S0 a! m& I4 ]$ t, R+ v
        else
    1 R5 ?( f) D9 q        return p->nextarc2;9 ~. E6 K5 V7 z1 V& `8 r
    }  I  V0 o* ?4 K
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*$ Z# m$ _$ b% B; g' P+ q. L. f
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const( Z4 ]" \& ]7 p% s  ?
    {0 R' f- T  C$ I3 A& W! S1 f7 k* z
        if(p==NULL)return NULL;
    2 a( ?/ d6 V7 @* @& z. ]8 A    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;# ^8 s0 `; p2 F7 F2 O2 A; g
        if(q==p)
    2 ?  w: c: q0 }" s, Z! D        return NULL;2 V- I; T4 y% k0 e. A
        while(q)
    ; z+ `& z& P4 s8 b( O- \7 L    {) L. D$ g+ s( M5 ?" N
            if(q->nextarc1==p ||q->nextarc2==p)
    + A+ t! K9 A1 [7 V6 O, R5 S$ X            break;# `( C" h1 W. m. M, O% E" b0 l& V* q
            q=NextArc(v1,q);
    : W* L$ R- D/ R5 h  s& m) r) B6 H    }# k: j5 X% r5 w9 t
        return q;) `0 `! u8 E. a2 S# w7 w8 I  v" j
    }
    6 P5 ]6 [$ A9 ]" y# N- K& j8 Rtemplate<class ElemType, class WeightType>
    ; s+ l7 b2 e8 _% g$ S1 |void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    4 D+ V! F0 t% r: B0 H! S6 s{
    3 d7 k2 O  H; }    if (vexNum == vexMaxNum)3 a2 _$ M& q" z7 h
            throw Error("图的顶点数不能超过允许的最大数!");
    / l& V  Y2 \0 H) \% O# N    vexTable[vexNum].data = d;
    3 r' e9 {& W- [! w% {! K: V: v+ w    vexTable[vexNum].firstarc = NULL;" I& Y  l( D; L+ ?
        tag[vexNum] = 0;1 G3 U( @2 _+ `. G
        vexNum++;
    ) Q2 W! Y" k9 Q& U; p* n}' a1 x5 Z! o& M# Y; b+ U1 J
    template<class ElemType, class WeightType>; c- R0 ?) U' g% X1 p% _1 |/ h
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)6 z) F- Z# Z  L
    {
    / }# Z0 A- u$ }. Y: t    MultiAdjListNetworkArc<WeightType>* p,*q;
    & t. H. o3 E7 {7 e2 p- V/ M; t    if (v1 < 0 || v1 >= vexNum)* E6 @$ ?- M# w0 S
            throw Error("v1不合法!");8 H! V, B. n& s+ a0 ~. n8 ^
        if (v2 < 0 || v2 >= vexNum)
    1 \. l; t) t# Q" r( A9 f; q- B4 k        throw Error("v2不合法!");: x' o, z9 ~/ t) w9 J
        if (v1 == v2)
    # F' W" y1 e; X0 h& b: H4 S        throw Error("v1不能等于v2!");4 q& |! r3 H) H# I
        if (w == infinity)
    1 ?/ Z  ]4 ?" t( v; o7 q5 L        throw Error("w不能为无穷大!");6 e3 [$ R. i& T/ j

    6 _! ?+ }# N5 B0 E. D
    % F- c% E+ F9 y, L    p = vexTable[v1].firstarc;" q" q; C9 y( m+ N3 T) e+ V
        while(p)
    ; i" y) m3 H; E+ [- R    {# \8 a5 n" j2 a/ n" _
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    & }9 q# B/ }7 U. r" l4 m) e8 e        {  o( J9 F3 @% P- r+ i$ t9 w# L( z
                if(p->weight!=w)
    4 t* J# i1 X% I' W$ n0 i7 y                p->weight=w;
    0 p' w8 F) \# E# @: @) D- ]4 W            return;. h+ x- @* J" r# B" a5 F" x3 ~6 [3 p
            }
    + V4 V: d9 K6 L5 ]% M' n# b, B8 P! z- a4 `
            p=NextArc(v1,p);- W4 O, b1 m$ v3 v2 E9 C
        }8 g. y: o5 o3 H
        p = vexTable[v1].firstarc;+ j0 r; Y( [( g# {( x
        q = vexTable[v2].firstarc;0 Y4 M  g3 W/ ^, u% ]
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    % |; E. A/ l: g6 v1 J    vexTable[v2].firstarc =vexTable[v1].firstarc;
    # X* i$ j2 v5 j4 O+ \    arcNum++;3 Q; U8 s: M" p9 e+ D2 ~$ @
    }* I8 P2 J$ ~6 x* W
    6 F$ Z$ D2 E  k; S8 ~
    template<class ElemType, class WeightType>8 ?& I8 g9 c% L, H! ]
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    $ _% j0 C# c: t+ y) {# b* y* j& ~{
    ( y( b' w% a0 {* n0 q. l( P* w. f5 e% S/ T* l* ~$ ~% j% ]6 o
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;! |7 L0 O7 u6 U: N/ ?
        if (v1 < 0 || v1 >= vexNum)+ ~* u$ T1 |9 R9 r5 y% H2 \
            throw Error("v1不合法!");1 w% Q) t4 ], W5 N9 S  _( X
        if (v2 < 0 || v2 >= vexNum)
    8 E3 L; M" R/ \) S2 m( l        throw Error("v2不合法!");
    # h) A' n& S$ w4 k3 r    if (v1 == v2)
    * Y! B  w* W7 h2 ~) J- `( G* B) ^        throw Error("v1不能等于v2!");% Q2 F! m1 y# q( l9 ]8 x
    " [' H8 v- j4 h5 j: F' W( y+ v& Y
        p = vexTable[v1].firstarc;
    : F# |+ a" m" [5 p, q    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2), n" I  [& k5 X; j. o' w+ C! ^
        {
    1 y+ k% y9 R, O  T# q9 T        q = p;
    0 }( H, R4 P- T/ g        p = NextArc(v1,p);
      Y6 T+ \- `/ N+ T6 \! r    }//找到要删除的边结点p及其前一结点q
    / B7 c, H" O4 e9 g! g) j7 Z2 d) J# \' d4 q8 q: b  h5 S
        if (p != NULL)//找到v1-v2的边0 W$ \% y% v6 |1 I% |$ \' K( ?6 a+ H
        {0 D6 V5 v6 D: [4 X9 h8 s" U, v0 S
            r=LastArc(v2,p);
    3 s. n0 v5 l8 k2 v; G        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    4 `* g3 p) w, {( X  k5 z& E4 v; |4 P6 E            if(p->adjVex2==v2)5 F2 v2 r, S' k8 c5 l
                    vexTable[v1].firstarc = p->nextarc1;
    7 @, d/ m* A* M& \2 w( M7 m* V            else vexTable[v1].firstarc=p->nextarc2;
    " ^& V- N) F0 r        else//不是第一条边2 f) m; z; i4 g
            {
    ' w. f* X" i4 {7 E            if(q->adjVex1==v1)
    5 w5 F1 r! N' t& L" h; u: t                q->nextarc1 = NextArc(v1,p);
    6 r$ \6 d7 S$ w            else9 @* G6 ]) L% j7 y( ]0 x6 {
                    q->nextarc2=NextArc(v1,p);
    3 [9 S) Y7 D3 X1 e$ X9 ?
    2 E8 w" l9 |4 ^$ E; q) O        }; B( i7 l# p2 q' O# S7 \. O6 U
            if(r==NULL)
    4 J1 m" _& z+ ]) \1 c5 z- @            if(p->adjVex2==v2)2 B" N  J8 k' r. q
                    vexTable[v2].firstarc = p->nextarc2;
    # N9 d6 C  u. U$ M% j* U. e            else vexTable[v2].firstarc=p->nextarc1;4 _$ o# P: |, u- L1 ^7 z5 B
            else& q2 c9 y) |& v& B, L
            {" @( w) S8 G! k" f) W5 N
                if(r->adjVex2==v2)2 O/ n: [  A/ e7 K+ l
                    r->nextarc2 = NextArc(v2,p);
    % }" {3 S8 F. x' Q! ?            else7 ~, c3 X8 q( N2 Y
                    r->nextarc1=NextArc(v2,p);
    0 c) L+ R/ r6 p4 M/ m9 f- J6 y        }
    : C1 ^; h, ?0 Y' A9 ~0 ~& k& D7 \% @        delete p;6 x5 h5 z8 a8 P1 ^1 Z
            arcNum--;
    " l* J, a: E) }1 q, q9 z    }4 D5 q- o/ ^1 M3 r& O

    ' E- K7 E5 k' A1 P9 O}; Z# F. H: K  }9 h1 K8 q
    template<class ElemType, class WeightType> void) M" `% h* @0 c+ h* t0 [
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)5 A1 m% p9 h. e. ?' ^/ ~. H
    {
    & r# H( o  e2 K2 T0 ?    int v;1 z% T: ^5 g$ @
        MultiAdjListNetworkArc<WeightType>* p;
    8 h/ E& e; B2 s' C    for (v = 0; v < vexNum; v++)//找到d对应顶点
    7 E* _* z  t' M& n% Y/ d4 I# k        if (vexTable[v].data == d)$ p* i. Y( N0 p) A" g) F5 ~
                break;
    . x: @  G% L9 A0 M* U5 V/ y7 H    if(v==vexNum). |9 q% C; H5 n5 e  m/ k
            throw Error("图中不存在要删除的顶点!");, g- L1 r7 r4 y: X) z( L

    # J  T- K9 J  a/ X    for (int u = 0; u < vexNum; u++)//删除与d相连的边
    ' c2 w/ e4 n( t% U0 F: U: d4 ~        if (u != v)
    ) n  }- }9 d' R& G+ W        {
    4 }- p) b) ]3 E% `/ u+ P5 [            DeleteArc(u, v);
    % V$ y' ]' }% t$ {& j, ]) d4 Q/ q; I# E- Y        }; S, W8 A' U$ \  ~
        vexTable[v].firstarc=NULL;
    ! P+ g8 k8 C% ]7 ^
    4 ^: k; _4 N) r7 }9 R/ A    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    0 ^6 K4 G8 `7 x6 S2 n5 ?% o    vexTable[v].data = vexTable[vexNum].data;# S. b2 `/ U- y7 f- {- }
        vexTable[v].firstarc = vexTable[vexNum].firstarc;  R# U# x1 H' z
        vexTable[vexNum].firstarc = NULL;  T# q% J1 m* [' f; ^( a( |
        tag[v] = tag[vexNum];& \0 J+ B3 b% M$ a
        //原来与最后一个顶点相连的边改为与v相连
    + U" d- X, F! E9 E" w1 r  n# ]  d+ q    for (int u = 0; u < vexNum; u++)4 T! K# c- l2 g4 H# X5 m& P  z" T
        {
      @  \) b8 l- |, }" h* ?( l3 L        if (u != v)
    # h, M' B0 _0 ]& f7 \; }# ]        {0 \' O2 ~+ Z( N2 S: b# Z) L
                p = vexTable.firstarc;
    $ h: G% M: F! \  g0 A% v            while (p)1 w  b  a3 S: a6 R/ U- [, N
                {) |$ M& R  n, Z6 `$ @" `. w/ Y
                    if (p->adjVex1==vexNum)
    - l. {) R  a( i! t                    p->adjVex1= v;
    , P1 g; ^( f* H* i! p5 s" ?4 u                else if(p->adjVex2==vexNum)$ {5 A0 K2 Z! |& `8 O5 e% l
                        p->adjVex2=v;
    + ~" k9 Z; a1 U                p = NextArc(u,p);! N, I( g' P8 y  J
                }/ r: g6 W. q) p# D. b
            }
    1 i+ u9 S; A- W9 N( n    }
    0 ~2 f) z+ s' {0 d1 h}
    ( V2 d# n5 S4 \2 Q6 e8 j///深度优先遍历8 h) `% X. e- r3 {
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    % _5 [; j) w) ~7 l* N: s" a; X{6 \- |/ f3 _% q9 g5 O
        tag[v]=1;& B& [" L$ N( K4 j  t4 x
        cout<<setw(3)<<vexTable[v].data;' w0 _% e7 w* F1 J  c# r$ s
        MultiAdjListNetworkArc<WeightType> *p;
      Y# B" U2 J. ?* a    p=vexTable[v].firstarc;8 X$ ~; {! v$ z$ n& ~
        while(p)& C$ |" `8 H! u1 K) O
        {" g+ Z& z4 V7 x
            if(tag[p->adjVex1]==0)$ B# s6 r- }5 \) k1 ~2 ]; o! h- \
                DFS1(p->adjVex1);( {) ^5 h2 _  M7 s2 u$ ~0 Q8 c
            else if(tag[p->adjVex2]==0)  g* r! a0 [( [9 _0 ~2 f
                DFS1(p->adjVex2);
    # _( w$ I$ D: k* ^* g$ H" \        p=NextArc(v,p);* E3 v7 m  v0 A" F7 u, O
        }
    . q! e$ b9 o3 M( j' F5 B0 `}
    2 L' I. s0 [+ k8 F& {8 X/ btemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    * v  B9 C- `* p/ Q( H0 R1 U{, J) f5 {/ A( a' g! {8 z9 ^2 t
        for(int i=0; i<vexNum; i++)
      d2 z( d, M5 D) j        tag=0;
    3 x. m: ?$ E+ _. I' \    for(int v=0; v<vexNum; v++): i* D9 |* n0 O+ ^
        {5 W0 L* Y9 b1 F0 |# F
            if(tag[v]==0); x8 Y# y  V! g( L
                DFS1(v);3 Q: |* M! @9 B- r! t; {
        }
    6 x1 N" g1 C% [5 b  n4 o}
    2 w1 \& n4 t) T8 ]7 [# i+ {1 [template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()6 q. ]0 ?# R4 T; ~' }4 E% t
    {: z, u6 X: A3 r
        stack<int> s;
    + g8 G6 J0 _; ?; G% Y    int tmp;+ P8 q! |3 G  D. V, v4 z% i
        MultiAdjListNetworkArc<WeightType> *p,*q;- V6 T& k" s) w( ?" o
        for(int i=0; i<vexNum; i++)
    3 d; z# A3 v+ l        tag=0;
    ( f+ ~" {3 r. X2 l( w! X' d    for(int i=0; i<vexNum; i++)
    , I8 g# |0 w" Q: n& [$ ^    {- N$ O8 L6 f% N" b
            tmp=i;. i0 u% k3 \5 G
            while(tag[tmp]==0||!s.empty())
    ' x2 x0 G: `& c2 u, Q1 q7 V        {
      c9 B- x+ b. i  w" v+ X8 L            p=vexTable[tmp].firstarc;4 d0 k$ @9 a3 c# M  Z
                while(tag[tmp]==0)5 F% q1 B5 D/ N0 O6 g, S0 x
                {2 W; Z; k. U0 h7 w3 ]3 h
                    s.push(tmp);4 Q- ]. z+ x; I4 k
                    cout<<setw(3)<<vexTable[tmp].data;; p  A9 W) v9 \6 e+ {/ I0 [
                    tag[tmp]=1;
    1 a: @) a9 r. g' S9 B$ @                p=vexTable[tmp].firstarc;$ Y  @, t! K7 T6 V" F: g3 O+ o
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    9 T% p  |! j- z+ W/ z                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    $ z# g% [2 I' A( Q. [                //cout<<" 1st     tmp="<<tmp<<endl;
    0 |* [2 a- a3 J/ `' R! w            }
    / O: I3 z) |4 e4 C* w5 ?3 ?, T4 u            if(!s.empty())4 q7 M' u  i6 M% T3 p
                {! t) K5 F, ?* x4 ]
                    tmp=s.top();
    1 h4 E/ E6 h; @' I                s.pop();
    : u9 w# Q$ Z1 H7 z7 Y3 i9 D, N                q=vexTable[tmp].firstarc;6 U9 L- k: V; T$ Y  ?4 P
                    int t=tmp;7 x$ ~. ~! H2 F5 T( v
                    while(q&&tag[tmp]!=0)2 c5 {* f7 ~( \/ R$ o
                    {
    & \# U5 E; m# L) z- G# |                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);* j9 r" ?' |4 L$ ]# c2 i# x/ {
                        //cout<<" 2nd     tmp="<<tmp<<endl;
    ) B% @8 S& m$ i4 W                    q=NextArc(t,q);
    / O1 K- h# D# X- ~                }
    $ r$ O( f% q7 C; }. w& r" W                if(tag[tmp]==0)6 Z8 Y! Y# e3 N0 r5 x6 D5 c+ Y; _
                        s.push(t);) ~2 y8 d. Z# I9 R# D" b# r
                    ///1、对应上面连通分支只有1个点的情况
    2 j* c5 o6 N$ s9 }: a: \                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    " J/ r8 a0 Z/ U; A- {/ ]. p                ///tmp要么等于找到的第一个未访问节点,
    ; G2 S* B' ?/ U2 K  @                ///要么等于与t相连最后一个点(已被访问过)$ q7 T5 D; ?" L# o, q" a8 [
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    0 V% j5 e7 k4 U: Z/ W& m; j            }# F3 m3 n( q+ _
            }
    8 {( z- v, f/ E2 I5 {3 o& G" {. v    }! E+ E2 [" D: H, l/ X- T# z" d2 o* M
    }( q% W( l( S6 S  Q  }+ v
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    * K% e& f) P0 u2 ^4 ltemplate<class ElemType, class WeightType> int6 A% R3 C" i& B$ B$ b+ K7 z; }
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)# `4 t; ?9 {( ?5 J. Q1 Y' W% ^
    {0 u$ k$ U: y- S* [% e
        if(head==pre)' ^, y9 w1 A& D1 W; v
            return -1;
    / x9 q) u) c/ P0 e5 z8 q' |+ G2 b6 b4 \# ]
        MultiAdjListNetworkArc<WeightType> *p;
    7 z& H! X; [9 J' D! m( N/ [    p=vexTable[head].firstarc;) r( {1 f! ~( j8 o- _
        if(pre==-1&&p!=NULL)
    ! T5 q9 \* M$ c) c6 N; r8 u6 B$ p        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    ; H8 v1 m7 u1 ~) r- ?    //pre!=-1&&p!=NULL
    * k2 w- N, M3 B' O4 z+ C1 P    while(p!=NULL)6 x, b5 V- f0 ~) ~( M
        {! f; \3 i. Z5 d4 |  c5 W
            if(p->adjVex1==head && p->adjVex2!=pre)
    * F% q0 H  n' s) ?            p=p->nextarc1;' W! i; q7 _& i. |+ [# E
            else if(p->adjVex2==head && p->adjVex1!=pre), l; x) @' V2 N3 r0 A2 l
                p=p->nextarc2;3 ~1 g. K$ n: j8 @  n* I8 P  j
            else if(p->adjVex1==head && p->adjVex2==pre)
    ( R) _4 N& o: U* ~" @        {
    2 K, ?8 T3 V/ A3 V( M            p=p->nextarc1;" ~( d. J* j! }, l# }. b( b
                break;( }6 d3 U6 ]) [4 W% {0 ?
            }
    / |$ w- @. B4 M' }' j        else if(p->adjVex2==head && p->adjVex1==pre)
    8 I  d6 d1 R. O: {# ~        {
    5 E1 a$ o2 e7 G- t; @            p=p->nextarc2;
    & k2 {  ]/ C% b2 g. [) X& Q            break;5 \9 t* |6 L( f" ^& n! j/ H
            }& C4 F% N) R1 R% h- P. Y7 B
        }& o5 k5 N( p; N0 X* V% a" U
        if(p!=NULL)  g+ S9 X$ U$ w3 ]5 ?. F/ X4 O
        {
    " t% O6 z" [8 v$ Y, j2 a7 Q! J        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    / w+ N. F( M7 t    }: c5 b  b% ^2 }8 _* k# m1 m3 i* r! O3 ?
        else
    9 F& G) _3 A- y( Y. A- I% q        return -1;
    ; ]8 _  y) h( t7 A( ^}, X. q4 j6 b4 _/ }
    7 Q1 m* M# t9 ]: z

    4 K* O  ]8 b6 G& w# J, U2 Htemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    - `( \8 d0 i1 W4 m{
    $ \7 W2 l; O! B8 h& ]8 P! Y7 [; e' w    stack<int> s;  M- m/ T7 Q) u4 v# ^9 x: W  [* R( k
        int p,cur,pre;
    ; g+ c2 F& Q5 Q2 g7 Z6 y' M7 T& W    //MultiAdjListNetworkArc<WeightType> *p,*q;
    * e2 X; x2 [5 a' }    for(int i=0; i<vexNum; i++) tag=0;//初始化% m, I! Z7 l1 k" R- b# C; e- ~; y
      g- V6 F: E. x2 ^* D! C
        for(int i=0; i<vexNum; i++)
    6 W+ i4 t3 E7 @5 E* h- A    {' y5 ]1 N7 P- T% k3 u6 N0 I' s
            cur=i;pre=-1;7 O4 ^$ h# Q0 D
            while(tag[cur]==0||!s.empty())7 L- z" `& _: v  X
            {7 A0 S) h9 ?; u9 F/ G, H
                while(tag[cur]==0)
    4 \% a" W  ]; D0 C' @            {
      X/ b/ L* N8 O% S0 g: f+ o                cout<<vexTable[cur].data<<"  ";
    1 v1 l3 h4 O  H; ]8 E                s.push(cur);
    4 |7 G( ~2 d, y                tag[cur]=1;
    ) |2 `/ z5 G3 V3 `* \# B' g) Y- S               //初次访问,标记入栈% K. x8 ]) [0 [5 E4 W" B- u& G
    - ^2 ~$ W9 b3 Z, \1 T$ C% q, f
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点
    6 _! h2 @2 a6 K2 w+ k! C" k. b- U0 T               if(p==-1)4 Z7 m" O, W8 H6 |" ]2 j6 N
                   {9 Y1 f- d* R+ a& ^5 V
                       pre=cur;s.pop();
    8 v- `. v) T6 E$ f+ y% M1 P  _' z                   break;. ]5 ~3 v9 E2 }3 I1 `+ }
                   }6 `. f* `, X# Z
                   else
    " p2 Y9 U, E3 \; W$ e( N; o' R  e               {
    3 `! H- X" R' s4 `- `                   pre=cur;, P' G3 Z2 e2 M, H7 n% b3 G, B7 {. ?6 r
                       cur=p;
    2 p6 M  s1 v: V( t& X* Y               }0 P# R: C2 R) ^) t+ @: y

    / j) M2 P$ b7 L7 P8 {2 w% l            }
    , @. `, c1 v, I" L! }1 [            while(!s.empty())
    ' Q( I: P) Y! I- ^! n            {6 H# ?7 [, D9 Y! o' f0 R
                    cur=s.top();% b1 n5 n+ F# u: ?: C* _( v# Z
                    p=GetAdjVex(cur,pre);
    1 G# y9 B2 `4 j7 U7 K                if(tag[p]==0)
    ! O0 p; z9 c! d/ G: b: V                {
    / F. Y8 b2 w' |! s% R                    pre=cur;
    5 s# h; R- U* V2 O/ ?; w6 R; [                    cur=p;( p, c0 @+ ]  U/ h/ ]. @5 i
                        break;
    & ~. j: a: _1 F$ I( E                }
    ' @* I* @! X5 o+ D3 z' u                else
    6 X. t( z# H0 H$ W                {
    ( o3 J- T3 a. T0 a+ D                    pre=s.top();* u9 s; ]* l9 [* Y# @: P) z
                        s.pop();) Q  Q- p! g: `' J. _/ u
                    }; ]6 U6 }' h  @/ L# \1 F; S1 G
    5 X+ R  U2 L' h% w4 j9 H( O6 }& h
                }' y) {4 t8 f: u+ |4 Y, j
    1 O* n/ ~) N  r  K
            }/ O, q6 d$ M+ u( E& G
        }  T% S/ B2 w, ]# N6 q8 I" \
    }
    9 U3 P* o) o8 C9 ktemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()+ X1 x' @) f1 n, J
    {) [: r% }+ z- E5 o: u
        for(int i=0; i<vexNum; i++)* G. h& Y7 K2 z
            tag=0;
      Q4 F2 u7 M$ ]1 |- |  Y    queue<int> q;
    9 t* g/ k: l/ j6 G/ H    int tmp,t;& s, }% ]5 f9 `& ^: z. ]/ U8 b
        MultiAdjListNetworkArc<WeightType> *p;2 ~1 O/ V4 {3 l" T- @  P
        for(int i=0; i<vexNum; i++)7 c+ k' U" e% Y, T; O7 s8 J  E! `
        {* ?3 A7 s1 Q3 _' z% x, f
            if(tag==0)6 n3 N3 L1 D, L6 k' f4 ~
            {2 G8 Z0 [0 ]0 N( {
                tag=1;; O( d7 |+ i: k. @( ?) K
                q.push(i);
    1 g8 ~& z/ n! s% h3 e            cout<<setw(3)<<vexTable.data;
    5 y) y" O* ]( r+ ~        }
    6 t% J  ~. R. y        while(!q.empty())% n2 c" p* p' R2 ^. u& o7 G
            {
    7 |3 k! \8 {& C( u            tmp=q.front();
    ( X" r8 k* z4 s            q.pop();# l2 V8 u8 g( O. l/ n9 f5 m- e
                p=vexTable[tmp].firstarc;7 l7 D4 V  T2 [! [; r( `  x& `4 F
                while(p!=NULL)
    - X! ?4 e) x0 ^- x' d            {6 p; n# [9 W' Y0 [: N( U
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    8 Y0 y  ?  E$ Q6 D% b0 s                if(tag[t]==0)4 b9 P% G; v1 p) [
                    {. J5 r% U# i7 N
                        cout<<setw(3)<<vexTable[t].data;% T( c/ c; S. S% }, G+ r* ?( M
                        tag[t]=1;
    8 W! S, P: `$ U  Z                    q.push(t);
    2 E8 v& v1 C1 J* h5 i6 P7 R                }
    7 b- u5 S2 H$ d2 F( _& f                p=NextArc(tmp,p);
    : L( x% s0 i, W/ _4 R4 j            }
    9 T& A2 i  x' _2 a0 l0 Z! m        }. ~5 t! G, _# Q7 C  Q7 i8 W
        }
    6 G+ A) S0 h, O# i0 p; {  ]}
    , D0 i* ^& S; l" S; mtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()0 l7 a: M7 O3 l1 V4 w: p4 U# ^
    {: d; i5 ?# Y) [( N1 `) i
        MultiAdjListNetworkArc<WeightType> *p;- [9 P+ Z2 F* Z
        cout << "无向图有" << vexNum << "个点,分别为:";
    - Z3 @: r6 c! E2 M    for (int i = 0; i < vexNum; i++)7 p0 F/ O! G" b% t' _) a1 }
            cout << vexTable.data << " ";
    ; R/ D- @8 ?( V; s; S/ j) y    cout << endl;
    ( y7 j- q+ R6 q/ U( b% B# x    cout << "无向图有" << arcNum << "条边"<<endl;
    & \5 z' b) }+ b, C: p# o    for (int i = 0; i < vexNum; i++)
    0 a9 J6 A7 X6 P; D1 ]; z' B; N    {$ [) X! C% f& `7 Y7 R
            cout<<"和" << vexTable.data << "有关的边:";7 j) V, y) ^6 Q
            p = vexTable.firstarc;9 V; T1 G  u, v
            while (p != NULL)
    5 f& g5 }4 `" y* ~# `+ U2 j+ H* s        {
    2 u9 T# p  t9 W  P$ c            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    ( T2 z/ C6 D' B; k5 y0 E            p=NextArc(i,p);
    * j* k. ?7 @/ @* h- H, f        }0 g: t( T- A, \: I- k  j
            cout << endl;
    ! O3 n; s* m$ @; {4 }# e    }! [5 Z8 ~; e# q/ [' S' F
    }
    + O; k- }/ k* {; w  k
    + f* o9 Z$ Q( r7 B: V
    2 z% z% d! ?' X- e( W- j7 L- l0 q邻接多重表与邻接表的对比
    + M: D. H6 K0 E/ Y8 R7 o5 G  I' Y# v  F4 @8 o% h4 n
    邻接表链接( o" ^5 v1 k9 F. A3 m/ U
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    / u0 w3 ~* ^- _5 M( r在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。1 R* N% [$ J4 s& W
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。2 B' F  Q  C" `; G5 o, w
    ————————————————7 C3 U) b9 w" n. I
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。) d, ^9 z+ e) j6 r0 _
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958. G# a# R! p. q, I2 ]$ P

    / p4 z3 [9 e4 H4 b: t6 O# }, K* f6 B7 J+ C8 H. B- m

    % `$ U9 I- K) L) K( y5 W" V0 J: u0 Z+ n1 a0 i# K$ A
    ————————————————1 @0 {5 l$ R* m" K0 |8 e" o& b
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    6 P- W) K2 @4 F- ~$ M3 T原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    + z! \5 v( x  @% l) ^" S! ]& D+ {9 Q  [2 x& Y( [# X) w0 v7 Y
    1 V; A( \) x' j  z1 e
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-1-16 07:24 , Processed in 0.329656 second(s), 54 queries .

    回顶部