QQ登录

只需要一步,快速开始

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

    , a" c. T1 y9 y) M) n5 i图的存储结构——邻接多重表(多重邻接表)的实现
    1 q- q, c$ R4 ?# J) N7.2 图的存储结构
    & F( }1 t4 a. s9 J0 t4 [8 T3 i2 U9 L% V! s  ~( @( m
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    3 g# ?/ g. p8 f邻接多重表的类定义1 L5 D$ S$ f; q* C8 v! ?# m( {
    邻接多重表的顶点结点类模板2 b' \, X  x! Y$ D3 t
    邻接多重表的边结点类模板
    % v, d0 P3 ~+ I' n" T: _邻接多重表的类模板, }/ O6 a, K; Q; E4 y
    邻接多重表与邻接表的对比0 j1 z1 A& H& Q6 g' w
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist" w3 k4 @# ^4 z

    8 c( a- O" _) S+ C在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
      f0 z% Y. M& p在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    ; q7 N7 W0 {1 k  B. D7 R# J
    ( _+ Y( u  _* V$ [$ e) u邻接多重表的类定义! f- |4 h9 d  M6 L
    1.png 5 A5 {/ ?- n! j
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:- p* r0 G) R# {" Q/ G
    data域存储有关顶点的信息;8 f4 H  Z7 F7 o, F! ?
    firstarc域是链接指针,指向第一条依附于该顶点的边。
    ) h' S! L' D, u3 E所有的顶点结点组成一个顺序表。

    1 Z* L/ r, I; z) K, v9 R

    2 i! A- ]7 ]; T: @/ n$ o: Htemplate <class ElemType ,class WeightType>! G6 r/ o0 V8 C& ~
    class MultiAdjListNetworkVex' w6 `, {' g, x& s1 ^0 W# i. m
    {  w) R- U* y/ |
    public:" U$ j( o4 g7 y- W
            ElemType data;
    & X( \% l; t* Q% P; V        MultiAdjListNetworkArc<WeightType> *firstarc;4 c6 j+ A! `0 i
    / B9 q2 g. o. B9 ]3 S2 f
            MultiAdjListNetworkVex()3 j/ k5 o# [; W' P, `: Y
            {, w) @! k" W0 T* s9 l! z
                    firstarc = NULL;
    # u7 `, w" h2 c$ U        }
    . T/ e  }8 N" [3 p. P( |        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    , A/ Z, \$ H; Z9 f6 `* l  v; k        {8 k" f. d: `* ~. w# p8 Z
                    data = val;
    ) `4 t% U  Z( _& ~                firstarc = adj;: J  A! r- F3 p+ |
            }
    / @0 _! b% e& i- K" H* ~3 D/ M};! z& j. _: _; T( x" ~! n
    . C6 I/ u6 d9 t$ {$ t/ y# F
    邻接多重表的边结点类模板
    ! o; }0 m9 h; j- ~) u  }) Y6 W; ~, {8 Z  u8 h) J" u* v
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    7 s: U6 N! g0 G) T: h* a: utag是标记域,标记该边是否被处理或被搜索过;
    % s: h0 {/ P$ k$ bweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
      v% h8 g, Q2 O! w! O2 snextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    2 `0 Q# n% j. d4 }9 Enextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。* d; \& G1 f. `+ T! W

    4 I& b2 y  m& T- D  B- \$ G' O2 u9 ?% B 2.png 7 P" x2 N( L1 }1 i+ B5 C# }
    template <class WeightType>3 }* H$ S: W8 b9 m5 C) |
    class MultiAdjListNetworkArc! \  o# y7 j! o4 `* |1 M2 Y1 D/ _
    {
    ; ]$ S8 z" ^, c$ j4 X+ |/ tpublic:; I1 `8 V$ Q6 A( E. U
        int mark;                                       //标记该边是否被搜索或处理过8 E2 ?1 R' F% u( {
            WeightType weight;                              //边的权重
    2 P& [9 b2 }3 ?& D; F  l: F) v        int adjVex1;                                    //边的一个顶点
    4 u% q5 v2 x+ r        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-14 m6 r' I1 T1 Z8 ~' M
            int adjVex2;
    2 y8 q6 E7 x( V, W* u6 n+ e        MultiAdjListNetworkArc<WeightType>* nextarc2;
    ) \; N4 U) U# J3 J6 W. y& n
    " O) J0 ~) q5 y9 B' P        MultiAdjListNetworkArc()
    ( w2 f1 m5 c0 l$ P% y        {% O0 [8 N% r% q. ^
                    adjVex1= -1;
    & Q/ P. S1 [, }* o' _! {                adjVex2= -1;8 ~# G  Q% [' x( u6 R4 z
            }
    4 m& F4 d6 Y" a4 @        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    % s2 Y) g. [4 o        {
    + Q1 i/ `% w# g5 P! F3 ~4 E- P                adjVex1 = v1;       adjVex2 = v2;
    & V- U& c6 P! P, u" |. N. D, J                weight = w;3 B9 K7 x1 G  Y' Z/ A
                    nextarc1 = next1;   nextarc2=next2;% H$ f/ y, Y! o
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    , T- a9 w. q" ?        }# b. q0 q% v1 D3 [" S* C0 l+ D

    5 o/ x: V- P% G. l- Z4 \& @+ p邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    . v' {  b+ Q4 I8 O; x3 B2 |* e' x7 Aclass MultiAdjListNetwork
      N$ I" }+ Y  g: r- `{! f2 x- m6 p6 @- d
    protected:" K  ?3 p+ N4 O% x
        int vexNum, vexMaxNum, arcNum;% H8 P2 d1 V2 R9 w+ V6 a) j0 z- e
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    & \, g4 a  e* j$ s7 a$ }) T  d    int* tag;9 o3 O7 G; q+ b/ {* ]
        WeightType infinity;" y) u! G2 N% j) o. d
    5 }5 s8 [. e  r! V, }' m5 _/ s
    public:" p8 J# @; L7 E
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);$ R5 l! S0 c( [" S
    ) p2 w& _" j5 X; E# N: w
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);, y7 a8 y  z6 q' d

    . ?' f, j) ?7 n( I; w+ c    void Clear();8 n5 O2 F; L; x, W) ~
        bool IsEmpty()! y: Q/ M# t0 }# F
        {
    9 j1 Z! B/ p- B& `3 `        return vexNum == 0;
    , Y: V* b# R8 l* E    }6 j2 }( g. c) E
        int GetArcNum()const
    & [" d$ O7 _1 R' G9 X2 b    {
    ) e0 S+ r7 s( p) e  X( e8 S        return arcNum;7 ]1 X5 l2 }2 K% v. v( R
        }: l; I, a; o6 y$ m$ U% D% y* ]
        int GetvexNum()const1 W; n/ Y* P* }) G' O% O6 n
        {
    - q: s+ y1 B' ?3 `        return vexNum;
    " I6 Z" J& d7 {    }  a" _5 F; E5 H+ P8 ]6 u# m
    ; k) s4 I  Q3 v3 f4 `# A  [
    " d& i) z  X* _* Q# \# b. n
        int FirstAdjVex(int v)const;
    $ p+ q; e( j6 m7 ?    int NextAdjVex(int v1, int v2)const;
    + @/ R$ |9 H6 g% w" J3 e    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    / z- [; b2 Y* l5 D' b3 T* q    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    . l: @2 Q: Q) I, L. [( n6 v9 Z
    7 G) m4 V: t" u6 J    void InsertVex(const ElemType& d);
    ) l% o% e- g1 V    void InsertArc(int v1, int v2, WeightType w);
    . S! x. e5 }: j8 `9 R9 `' H( W! T! f& n' W5 k8 A2 W
        void DeleteVex(const ElemType& d);
      p# S/ A+ M: d    void DeleteArc(int v1, int v2);$ k  Z/ y& s) U7 u# i/ r

    , t+ Y# w) n! j% I2 l4 u+ ^- E- {    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    3 t1 C; A' Q8 T, R- }    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    $ `4 z. k& B: o8 Q
      a8 a8 ?$ z# r" z" K! Z    ///深度优先遍历
    7 W( r) B3 B3 F+ M    void DFS1(const int v);
    ' ?& s, i- x/ ?0 |5 V/ m    void DFS1Traverse();
    0 z3 c& h/ P: J; Q6 l    void DFS2();
    # D. x5 L$ [, T1 ~
    : p' D. Y1 x# t  [) Z8 \7 S    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1  T5 ^1 O! c/ Z! k8 h2 @& `
        void DFS3();
    1 ]' m) y# n3 Z' u) q! z
    - U1 J: z% t. d8 j& c    void BFS();2 p4 L! m6 v- C$ R% {1 u% B
        void Show();' f3 J) c0 `) V
    };
    3 q; b- Z  r; B6 n1 Z+ s0 I/ H, \0 q. J# B: }; k
    2.函数的实现
    - {/ r2 X7 O& p8 [$ ~6 z研讨题,能够运行,但是代码不一定是最优的。  o8 k% k! t. d9 w2 w; i% s
    4 R) R9 o$ a& L) j- J% ~, f! K
    #include <stack>
    0 Q  T% X  c; ~; O#include <queue>
    # S. f8 x8 {1 w! R- L8 {5 P) i; b& A0 |$ {: U1 h( I/ P
    template <class ElemType,class WeightType>0 g* `1 I! w% r- T* L' `
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    ) c2 s  q3 }6 N, z& C{' {( ^, Z8 G, z" y* [8 i( T0 k
        if(vertexMaxNum < 0)
    - D) s0 O4 m3 k; E        throw Error("允许的顶点最大数目不能为负!");7 d; `* J9 B; Z7 |- _$ v" T( u
        if (vertexMaxNum < vertexNum)) q' h# x; ?( \8 n* `
            throw Error("顶点数目不能大于允许的顶点最大数目!");
    . b. a( c6 D0 W$ V  d5 G* U5 ^    vexNum = vertexNum;6 F' `" ^* ?2 A8 \+ @/ l- t
        vexMaxNum = vertexMaxNum;
    8 D- m9 E. O7 ?" T    arcNum = 0;7 d, f9 V; o' D* d2 d8 m$ ~
        infinity = infinit;3 V4 O9 B* j6 E9 e% a  q
        tag = new int[vexMaxNum];. Z4 J9 M# k% \0 u$ Z, A
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    $ r2 Q- }' Z& H% K7 r7 j8 E* W    for (int v = 0; v < vexNum; v++)% D5 Z9 L( P# k* y1 `) A; `% l) C
        {: c5 h/ n2 c8 |1 b. Z
            tag[v] = 0;) V. y9 p8 e, H  k5 t7 I7 V
            vexTable[v].data = es[v];
    6 X% s6 _$ q4 ]$ m8 c        vexTable[v].firstarc = NULL;
    3 [4 v5 q+ H( r% R    }4 h- `# ~' K9 J7 W% D: Z5 Y
    }4 T* j2 H' O7 f! M
    template <class ElemType,class WeightType>
    $ R0 J1 a% P# c) P! wMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    . B. W; \, |) w3 O) Y1 s{5 V8 Q$ I/ i) V$ i2 P
        if (vertexMaxNum < 0)
    & m0 N) r+ L4 J% l! U7 M        throw Error("允许的顶点最大数目不能为负!");
    " y4 v3 n/ e8 H7 b; l% ~9 f; z    vexNum = 0;
    ' k( u" b! g5 H# w    vexMaxNum = vertexMaxNum;
    9 g) [. P8 L* l! u* ]    arcNum = 0;7 b, G; t6 {3 {3 P7 X5 W+ ?3 F
        infinity = infinit;3 o8 F0 }( O: D; ]5 }$ f
        tag = new int[vexMaxNum];& G9 E9 P. q- R( i" f0 O9 v$ ~/ L* \$ f
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];: u. `2 u  |& N+ k9 a8 |
    }5 p+ K/ F0 ^- i* ]: y$ t
    template<class ElemType, class WeightType>9 F9 e* q# g& T$ [" A' C1 J7 [
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    ( L( }7 j& @& D( u{1 M5 f* B7 b* q) t
        if (v < 0 || v >= vexNum)( ~. b, ?4 z- x- J' w
            throw Error("v不合法!");8 _  O6 `8 H- d7 X
        if (vexTable[v].firstarc == NULL)
    7 |( I! F# j) N0 w1 d0 Y        return -1;$ d& S: O$ m3 A
        else
    . P+ s# L4 b. s. ]        return vexTable[v].firstarc->adjVex1;
    7 \) P% U/ a- K" I% Q}
    + _& O' }  P8 ?& h$ c! c2 `5 @9 c# |
    template<class ElemType, class WeightType>
      h5 M  l  M% W: v$ Wint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const( w0 }+ }3 a/ X; g  W4 N
    {, E" D% _. H2 k9 ^, c! i+ R
        MultiAdjListNetworkArc<WeightType>* p;! t+ F6 ~+ C( A! ^; [
        if (v1 < 0 || v1 >= vexNum)
    ' }' ?3 S  D1 p! T        throw Error("v1不合法!");. T) _  l* ?' t% U
        if (v2 < 0 || v2 >= vexNum), x) J& O+ j+ u2 B
            throw Error("v2不合法!");
    0 e) n( l( l7 J) A6 e    if (v1 == v2)
    , a0 B' X+ ]$ ?0 e        throw Error("v1不能等于v2!");8 j- K) F% V) `- [! a. ^* P3 S
        p = vexTable[v1].firstarc;, J+ l) H  Z8 K0 r
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)5 S) ?9 _9 G, \8 g
            p = p->nextarc;
    ( l# j7 Z) [1 z: O' }% ^9 C    if (p == NULL || p->nextarc == NULL)
    8 q) ~! ~* `. ~6 {5 M        return -1;  //不存在下一个邻接点
    5 f8 ~  y  u$ e) k0 t+ F    else if(p->adjVex1==v2)
    9 u- m9 k- S% W' a$ g        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    9 v' O# x$ O1 L    else
      u  j: ]* h5 ?- C+ y" z) d) K        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);; e4 q# l) ^& c3 G# X
    }
    1 M1 k7 l( k7 t1 r8 gtemplate<class ElemType, class WeightType>
    2 |/ K  Z; t' r  E! fvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()
    2 @2 G3 m+ R' A2 l* N8 a. l{
    ; N) H( F0 W; T1 z2 T! }" `4 T    if (IsEmpty()) return;
    : s9 q0 w- m) ]2 O    int n = vexNum;
    - B. p& ~; T- F/ B    for (int u = 0; u < n ; u++)
    . q4 [( [5 y9 ?: b# V( |' Z        DeleteVex(vexTable[0].data);
    1 I/ H0 ^  E5 q# s9 F    return;% A" C( t) n: y$ i
    }3 a* v' f) V6 g
    template<class ElemType, class WeightType>: F. y2 c* V' |* R& r* n5 t
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()8 w) }) M; y; \. p
    {4 V2 y, n* j9 ], I( G( k
        Clear();8 s1 \( C! X+ Q8 d6 A# a1 }
    }. V" N3 G# ]* c' L$ }
    template<class ElemType, class WeightType>" L5 q- e* M! t4 S9 a6 K
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    ( }0 G, O. Z- h- @{8 [: ?( V% X' o8 M% Y: E
        vexMaxNum = copy.vexMaxNum;
    , [5 F* @! ^7 ?% [$ F. F  l    vexNum = copy.vexNum;
    0 T6 r% o+ H5 q$ H    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    # e+ r, o1 P. \$ Q    arcNum = 0;8 X8 k+ l. ?+ E
        infinity = copy.infinity;' q; V; x' H4 N$ j
        tag = new int[vexMaxNum];
    ' C' Q5 Y! z7 {; u& w
    / j/ C( V" f7 t    for (int v = 0; v < vexNum; v++)
    , f$ J: r' P; R4 ]    {
    4 w1 N; |6 f: c. |        tag[v] = 0;
    2 \0 M1 i! n6 ]( V        vexTable[v].data = copy.vexTable[v].data;* u* f: b1 }+ h( f
            vexTable[v].firstarc = NULL;
    5 [4 I" J# ~3 ]; V4 V    }
    # i% {1 `' {- r; X3 s) R    MultiAdjListNetworkArc<WeightType>* p;+ O  A' e4 z, r. u3 t! X8 o
    6 X( X% ~4 k+ I" X5 X& U4 m: a
        for (int u = 0; u < vexNum; u++)
    + s0 \2 o# S5 U: E; h4 g    {7 K1 E9 I1 ^9 y% q
            p = copy.vexTable.firstarc;
    ' F' q1 f) u4 P        while (p != NULL)" E+ K/ G+ Q5 c8 z9 b
            {
    ! F& J  R5 V; c5 O) q5 c            InsertArc(p->adjVex1, p->adjVex2, p->weight);# D" J" C0 ?% ?. H4 T% p
                p=NextArc(u,p);
    ! z0 K! w7 M' D        }; M9 I" K8 g8 X; S: q* q" C
        }) `; x3 i# |# v) o3 A8 o2 l8 B
    }
    ' `2 |( D: X2 y5 `& Gtemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&6 c7 T& v% ]" L1 u4 ]3 h; U
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)* K: N: q$ Q1 S' ?, C! b/ S
    {
    ' K1 v6 o1 D! d, }    if (this == &copy) return *this;8 z6 y/ _2 |9 A+ w/ N6 `
        Clear();" X' t, Q* s4 Q9 v
        vexMaxNum = copy.vexMaxNum;
    ( c& o7 r# N( D$ k# d    vexNum = copy.vexNum;2 y4 o$ ~3 ^) \, n
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    ) p, s; O, t+ @) ~" x    arcNum = 0;
    % V$ R% H' T1 d( Z4 r    infinity = copy.infinity;  J7 u3 l6 t2 y1 Q2 T  c
        tag = new int[vexMaxNum];
    + u1 q, r' `1 j8 c0 \: A( ^9 y' I8 V1 e8 s
        for (int v = 0; v < vexNum; v++)
    + c: W# i" ~, _0 c( z    {
    5 s1 \1 T( h: \' F4 ?  i  W        tag[v] = 0;
    % z" Q2 `+ _3 W. Y        vexTable[v].data = copy.vexTable[v].data;0 Y2 p% v7 S4 c
            vexTable[v].firstarc = NULL;+ S  x# G) O4 n( G6 t" l. @
        }* s) e+ G7 e( L, y( W
        MultiAdjListNetworkArc<WeightType>* p;: W( ?# e- K: W! z3 A
    # M) u) r$ U+ Y5 A/ J( ~: |) l
        for (int u = 0; u < vexNum; u++)
      n4 U9 {# Y0 `5 @* }3 B! ?    {
    5 N/ h- M* @! r2 _8 e( L  c        p = copy.vexTable.firstarc;
    + o/ R& j( h8 y, r- H8 k        while (p != NULL): L7 ?9 v; b* z$ O7 D! F
            {$ J9 n  s9 S$ S" O, O% v
                InsertArc(p->adjVex1, p->adjVex2, p->weight);" Y4 t* I* q* J  |
                p=NextArc(u,p);
    , b" p( h& K- t: G9 v! q: I        }
    ; I+ y" t3 n" c; u' E7 z    }
    . M* m4 w" T3 P4 \* K/ [    return *this;
    5 b( G4 @" W% N% Z5 o% c( F}
    * U: R" @* C* y1 h* u! k# Ltemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    2 x# M. [3 [# v& k8 I9 }MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const9 z5 ?! t) |# ~5 S  g
    {
    5 h: F% \* y0 g' g" }' U* \( w& i    if(p==NULL) return NULL;0 m3 c4 m  Z# W, h1 X# z/ u4 ?
        if(p->adjVex1==v1)" M, G' f" m. [5 U! K% e7 v
            return p->nextarc1;
    - R. [% m9 ^" R8 U/ Q8 I    else: I& B$ K6 K$ k- q
            return p->nextarc2;& Q# y8 {, R" j/ q& h" Z# M  M4 H
    }8 h" U: |  [+ c0 E# W
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    " W% V' p% P- Y. ]MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const% J9 B6 f; V3 |8 A* E. {1 M
    {, O8 X" [7 I# }' m
        if(p==NULL)return NULL;. h9 m% P: l" g0 V' x' n/ q, W
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    / W  L; M# ]4 D, N3 d/ V7 v  x, l    if(q==p). a  E+ q' F5 E$ u. O. {
            return NULL;9 c* ]* K7 @" |/ H) `4 J2 G. t7 l
        while(q)
    , M; J! c" |- k( F    {
    ( n4 @0 f+ x3 t; s7 F        if(q->nextarc1==p ||q->nextarc2==p)
    / s2 _( ~) Y$ q: Y$ w9 [            break;) ~& s) v7 z7 k! \- e8 f
            q=NextArc(v1,q);6 O6 A, c& f$ Q" z
        }  j3 b8 p. o" w* _. b" }1 |1 j/ |8 b2 q- s
        return q;
    ; F7 L& Z5 V1 O* P" {* o}
    / d0 z" \6 n$ r3 f" }' K2 `template<class ElemType, class WeightType>
    7 C3 e5 R7 ~" P7 y( Mvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    - j5 K' C, u9 f6 O, w{! |1 l! {& ?0 _
        if (vexNum == vexMaxNum)! q: k& Q8 s. b0 x5 A
            throw Error("图的顶点数不能超过允许的最大数!");5 B7 `/ C$ A, E7 m9 j, n
        vexTable[vexNum].data = d;9 H+ Q; c, B: `( R
        vexTable[vexNum].firstarc = NULL;1 U5 L8 h6 V/ V# E( f  y0 D
        tag[vexNum] = 0;* L9 D0 M% {( U" p; [
        vexNum++;
    0 |; \5 U3 \1 v- P}5 _' ^) g2 V* R9 ]6 }5 X# D
    template<class ElemType, class WeightType>8 R( W2 U: X" u* j# F- P3 C
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)" z1 [7 s9 I6 X/ s0 V4 W
    {! Y1 I. s8 y  Y5 q( z* q. l+ C( B
        MultiAdjListNetworkArc<WeightType>* p,*q;2 O8 z5 Y' `* o# A; T( h
        if (v1 < 0 || v1 >= vexNum)
    9 @; T, H7 {0 |7 Y+ N; B        throw Error("v1不合法!");8 ?1 h" c! P0 I) R2 J+ ]8 q
        if (v2 < 0 || v2 >= vexNum)
    / x9 s- v- _' @  I3 A/ i1 n  W        throw Error("v2不合法!");; h( G- o4 N4 f, D- z
        if (v1 == v2)* v  S9 R" d! }- B9 ]6 {
            throw Error("v1不能等于v2!");0 i5 v( f; J9 H' V4 G: M
        if (w == infinity)" X4 e/ n3 t5 Q; G. c
            throw Error("w不能为无穷大!");
    - t  |9 I: p# j% e, v1 y% A7 B4 b9 b" j+ r8 n

    " o: w6 ^% f1 X& n5 ~    p = vexTable[v1].firstarc;( f3 n5 k( P. l. F1 O1 S
        while(p); `& b9 T9 a: p" n3 g
        {
    ' k: K# Z) u) v  @1 W        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    ) y3 T' l, ?6 y0 D& }3 c! g$ |        {  y0 }8 c& T9 F8 R
                if(p->weight!=w)
    8 D8 z$ S! v% n% E. o                p->weight=w;
    9 |) D4 M: L" A4 {8 Q7 f7 ?            return;" ^5 ], t1 T' @/ o: E" f1 D4 a* ~
            }; y2 e% y& U9 ~7 t

    . n4 W$ z% z3 O+ ^: U7 C+ S/ o) O        p=NextArc(v1,p);  A0 G3 O4 y8 T6 u2 s
        }
    ( Z( [# |2 v* O# i2 C/ c    p = vexTable[v1].firstarc;
    ( ~) a# ^. P* o6 X/ M    q = vexTable[v2].firstarc;
    8 k+ V0 T2 B6 t5 k9 v4 ^    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    & O1 z1 S. m! `) }( z6 q. M    vexTable[v2].firstarc =vexTable[v1].firstarc;
    ! q! C" P9 a! x; I! j3 M    arcNum++;
    * n" b, w( L' @  h2 D}
    2 n& ]. e2 e- B( O# }5 O7 k( e: X0 K6 M6 t* T+ Q. F; t! X
    template<class ElemType, class WeightType>+ P5 U' X7 r% R6 y% }& v& i
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)8 k$ C/ N3 A5 X% Y+ s  I+ y
    {
    ' L+ J% |( T$ J2 K4 T, `' E) h, V/ J- D+ ]) A. M" z
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;0 C) O2 h* x& m" q/ |
        if (v1 < 0 || v1 >= vexNum)# o. }! c( ?: N  P( w& i" R
            throw Error("v1不合法!");3 t0 ~+ ~: Z; K6 [# t: W
        if (v2 < 0 || v2 >= vexNum)
    ( ~7 |8 [; P9 W! Y- g6 W) y. B6 h        throw Error("v2不合法!");0 L2 V' r# B3 P' e
        if (v1 == v2)
    # C/ p& w8 E- v8 H: {# P, ]' j        throw Error("v1不能等于v2!");7 w8 o& f' J5 K& e& u% P4 I

    3 }. T) W# ^5 N    p = vexTable[v1].firstarc;0 r! D1 ~) r/ l
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)  G, [  m8 [( a2 U) s
        {
    . H" [* S# z2 m3 V% b        q = p;
    - G* x7 T  Y5 \8 ]9 e4 j6 C) Z7 @' S4 |        p = NextArc(v1,p);
    6 y- t. l# c2 T  K    }//找到要删除的边结点p及其前一结点q# n8 X  v$ T; X

      |) p1 l: ~. c, ~& n, L    if (p != NULL)//找到v1-v2的边
    6 z4 v2 h- G8 ~" ?0 F% {    {: N! f: Q$ Z0 L2 f4 S
            r=LastArc(v2,p);
    ' |/ m2 y' G" H        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL: ]; l7 I: c7 C3 ^* b
                if(p->adjVex2==v2)
    # u( J$ M4 t5 _7 X                vexTable[v1].firstarc = p->nextarc1;
    / h+ a5 F7 d, E  S1 f            else vexTable[v1].firstarc=p->nextarc2;9 o! \4 m$ x3 s& u- w+ b/ |) |
            else//不是第一条边
    5 R; h" V( D' H1 y3 u. {0 N        {! l6 {2 o7 i' f1 n' W: l) E- B
                if(q->adjVex1==v1)
    , e  r# c4 @* [! m0 q( P                q->nextarc1 = NextArc(v1,p);  C9 ^1 r$ u* A. p' T& V/ n1 J
                else' n' e& ^% m# v9 `
                    q->nextarc2=NextArc(v1,p);0 O- W3 Y+ j8 I& p/ z9 {+ J& O: G

    ! U" V8 k; K6 {5 F+ z; X) X        }/ ]7 \( e8 c9 c" O* a% M
            if(r==NULL)
    ; d) b' D+ }  X5 U5 V            if(p->adjVex2==v2)
    # w: ^. d. x9 K2 a2 `                vexTable[v2].firstarc = p->nextarc2;
    0 F2 J) S. d1 @. H6 H7 J            else vexTable[v2].firstarc=p->nextarc1;0 B5 R( t  |6 }7 I1 v; `
            else" L- `& l( L4 c/ C8 @
            {
    " Y0 i9 a: [7 x/ ]            if(r->adjVex2==v2)+ h2 {% [  w+ S- y
                    r->nextarc2 = NextArc(v2,p);
    - \% d5 J4 M4 g4 O) f            else
    4 D. T& j) R5 B- P+ [0 j" Q                r->nextarc1=NextArc(v2,p);
    3 V$ C& J3 Y. V2 |/ w* {        }
    " ]+ h5 b- a+ m7 j* k& W        delete p;
    ) c$ _1 X( K6 ~/ l. S" m' i2 e        arcNum--;- G7 w+ _  \3 ]& l
        }
    3 M! F$ [# R* }9 n0 l; m$ R/ b% G  j$ K3 ~4 B
    }; ~# H" h0 j2 l0 D; k( D- D% x
    template<class ElemType, class WeightType> void  V' z. K1 T9 ]
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)! z7 m* q/ E; l8 [( i$ O
    {
    5 \% g" a& H( k0 P2 Q6 O- B4 x: O2 r    int v;( [2 H, `: z& k% L7 ?
        MultiAdjListNetworkArc<WeightType>* p;
    7 L% H0 Z6 S& R! h! |% g1 O    for (v = 0; v < vexNum; v++)//找到d对应顶点4 Y: q# Y+ ?( |! f2 g: A9 f
            if (vexTable[v].data == d)
      H9 ^, l* f+ j9 `# R            break;# r, A2 \, s: L
        if(v==vexNum)
    # y; v3 o% v) O' K  w        throw Error("图中不存在要删除的顶点!");
    5 v9 ?' _' z2 s( m- ?5 L$ x$ a2 S5 h9 u- k) U6 c9 X
        for (int u = 0; u < vexNum; u++)//删除与d相连的边( K% |" R6 C0 J, s3 s
            if (u != v)
    * s  K) v  U, T6 d        {
    * Q; A  j1 j3 N            DeleteArc(u, v);$ m0 J' a6 G, b6 L: a
            }& h$ a' W5 J  D7 P- z
        vexTable[v].firstarc=NULL;
    / r, O% C" E8 ]; `4 b' J, k) U% }2 u6 g. R! O/ h9 c/ |+ A5 D
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置/ G* q. R8 h9 _, b, {/ M
        vexTable[v].data = vexTable[vexNum].data;
    & G. c+ W' S& R' H, d" o    vexTable[v].firstarc = vexTable[vexNum].firstarc;
    - M& r5 o/ c" T" N3 P- a- H, V    vexTable[vexNum].firstarc = NULL;0 `: x/ u! ]: B4 j' C; A9 u1 x0 n
        tag[v] = tag[vexNum];* k7 Q) M) q; B1 n( Z9 g
        //原来与最后一个顶点相连的边改为与v相连
    " r% u, g1 V' s1 a: m    for (int u = 0; u < vexNum; u++)
    4 ~9 z( ?: k- L+ Y! V$ G    {" R! V% T2 ^6 ?: _- L$ j
            if (u != v)  F9 w# O+ j7 k: x, W
            {
    ' ^  ~$ l# O% {7 |8 ]            p = vexTable.firstarc;
    : K3 \( o. S: C0 j5 X' E, f            while (p)
    " E8 E$ l# x# F8 h            {1 j) q. k6 @3 R  q" y
                    if (p->adjVex1==vexNum)
    ! H. Z+ H! s" ?3 S* b) T                    p->adjVex1= v;
    % W& k! A$ x9 n# y: Z                else if(p->adjVex2==vexNum)  ]" m  x2 T$ P9 c2 f; i
                        p->adjVex2=v;
    ' h$ D/ I0 ~: b8 p! g% a                p = NextArc(u,p);0 b6 I* O/ S; b& }
                }1 u' z% s5 H6 q9 w# S; X1 g
            }% v. c5 a* C0 X4 c0 ^$ T) `( ^
        }9 y# b! ~6 x$ r  Q6 a/ C
    }
    " H' }2 a  I7 J% w1 D( D///深度优先遍历1 p8 _- ~9 }. x) B# ?
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    / {6 n3 _+ T4 d; v& t{  P0 H" q/ q5 R# S  E
        tag[v]=1;" {6 T; ?2 e8 a# l: G: h- x" F
        cout<<setw(3)<<vexTable[v].data;
    ) Q  A1 U0 W5 ^, \    MultiAdjListNetworkArc<WeightType> *p;1 N/ P4 {( e: E& R
        p=vexTable[v].firstarc;
    ( T  T  ]" k  t3 c1 l" h7 I( B* Z; z    while(p)0 r/ S2 v6 E; \& s: c1 G. t
        {
    ' s& H% S- {% O& s4 I; e, A5 W        if(tag[p->adjVex1]==0)
    ; f) y) l( ^/ T5 Y            DFS1(p->adjVex1);
    8 ^  j+ B" s  W$ p, v& x        else if(tag[p->adjVex2]==0)- j) S& X$ o6 Q5 s  V% R) g, p2 r6 o" ~. k
                DFS1(p->adjVex2);
    , \9 c, X# ~- d3 t        p=NextArc(v,p);
    # R1 y( v& \: K# D$ E$ `2 t    }: V: V# N) z6 K% [
    }
    . G5 W" ~$ d4 a/ ctemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    - _. |2 r( Q1 h7 m: Z" t{
    & M) o7 {0 o" |" S, a    for(int i=0; i<vexNum; i++)
    ' r! Q2 g% {2 {. }% C        tag=0;
    3 j  ]8 t$ O$ Q% F' t! D/ K3 q    for(int v=0; v<vexNum; v++)
    " ?  W8 l2 k" J  _! s1 N    {
    " s% c: T4 `' C5 e/ i+ f& j        if(tag[v]==0)
    & ~- O7 m  R5 _            DFS1(v);  q; b  F) O% N- B" g3 c
        }
    7 H5 j- ~6 q( c6 w) Y4 d}: Y, A: }+ m# \% P7 O% H4 N
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()  m8 e  ~3 T1 y) l: ?
    {+ }; {! K' h/ @* t: e
        stack<int> s;; ]2 @3 L) f3 h5 N
        int tmp;
    ) i# X) C$ b& K% G, M5 x5 u8 v    MultiAdjListNetworkArc<WeightType> *p,*q;
    " {$ Z0 O( d0 G% b6 r    for(int i=0; i<vexNum; i++)6 Y+ S- G2 C5 k
            tag=0;; k2 ^6 E+ V3 z* z( i" P
        for(int i=0; i<vexNum; i++)) s3 i0 l; Q/ X& ^1 Z
        {; e2 k$ Y+ j" W- D
            tmp=i;) T* `. Z8 [7 n0 @" Y( R0 |
            while(tag[tmp]==0||!s.empty())4 `& i) V/ B: Y5 `* Y9 |
            {
    " t5 x/ b, Z4 [7 G5 {7 h            p=vexTable[tmp].firstarc;
    3 V8 z: ^/ G+ K- k% `; \0 n2 s6 C            while(tag[tmp]==0)+ A0 U$ n6 K5 y0 f# l3 z1 n
                {9 b; x* |9 @1 ^) G: i
                    s.push(tmp);
    * D  X1 v" u4 |5 e0 f! q                cout<<setw(3)<<vexTable[tmp].data;: _7 o) ^5 X9 l% ~
                    tag[tmp]=1;
    ; V* B" e' T0 A                p=vexTable[tmp].firstarc;4 Q: b7 u* q7 E" Z+ }& G3 l1 h
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    9 z' t3 z5 R* z9 |- p                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);; d1 w3 U' @( Y; O4 y4 V
                    //cout<<" 1st     tmp="<<tmp<<endl;7 p( `, x& u  S; g" N7 _
                }
    . t# \9 @& a9 U            if(!s.empty())
    / A$ ^- t- N5 ^! N            {
    " Q3 B6 V- ~' A0 q/ \( }+ N                tmp=s.top();
    + ^' ?1 A/ I$ O  T* `9 n                s.pop();
    7 ~4 |- N, H8 \7 Y; ~2 }$ [- {                q=vexTable[tmp].firstarc;
    1 z" ]. E5 G' k% P8 F1 W+ W                int t=tmp;
    + H1 s5 g/ u* H. _                while(q&&tag[tmp]!=0)! {4 O# y' X5 g- _
                    {
    - I( S6 m3 s0 a' F1 T  A9 W& o7 U                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);' ^0 y/ S% s' v
                        //cout<<" 2nd     tmp="<<tmp<<endl;
    * n9 o0 r4 u; w% w                    q=NextArc(t,q);, A1 i! c2 h5 b) p4 U0 ~
                    }
    : ^4 R/ S3 u3 ?$ v7 C0 e$ ]                if(tag[tmp]==0)& Y9 f& @% d# t+ @
                        s.push(t);( ?$ }7 U6 w. ?9 M# s
                    ///1、对应上面连通分支只有1个点的情况% u$ y' M& }& f5 \
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈% G0 a! }# _. W: Y. O/ g( u
                    ///tmp要么等于找到的第一个未访问节点,
    $ j# ~$ ~3 Y/ w' J: {' @5 q                ///要么等于与t相连最后一个点(已被访问过)
    8 o; k+ k! U2 _3 ?" K' D; V                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点+ X9 e: L8 U6 i& ?' M1 q
                }0 a- J% M- {. Q+ g
            }7 C, _3 t+ z  ~
        }
    + f1 J; R6 a+ W# f. E& g}) r: t! ~& U1 B5 r
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-14 }4 e7 y% l- P3 h2 c. B/ ^: R
    template<class ElemType, class WeightType> int, \6 @$ f' a; I, S2 o
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre), Y4 ]4 V1 \5 Y. @! T" y
    {1 U3 E; U; i, Q5 F
        if(head==pre)
    - x. x4 F1 @# c; E% i1 S        return -1;
    + {' N' g7 E+ `9 l
    ! d" j5 U, c; ]    MultiAdjListNetworkArc<WeightType> *p;& s& a) ?0 |, T+ O% |" M
        p=vexTable[head].firstarc;3 N( v: p. U/ Y( t7 b+ i
        if(pre==-1&&p!=NULL)
    ! b, [% {# o2 {! L0 `        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    ' J, P( u# P5 `4 L1 Z9 ~    //pre!=-1&&p!=NULL4 ^" X& ?) ^8 m1 s" F
        while(p!=NULL)6 e% C% q) s+ k! s
        {
    8 i! o; p2 r: }: ]( z" y. ?        if(p->adjVex1==head && p->adjVex2!=pre)
    : p4 V) O! J5 b# Y) r1 y+ n8 R            p=p->nextarc1;
    " w/ r: x9 C1 D, n# |        else if(p->adjVex2==head && p->adjVex1!=pre)
    * g0 I* p# |/ T6 b7 C            p=p->nextarc2;
    ) X  U, `9 |0 ^1 {1 r* z        else if(p->adjVex1==head && p->adjVex2==pre)" p/ A6 B' g; B& h5 N
            {4 }9 L( c! r) @9 \9 L2 _4 h$ ~( Z
                p=p->nextarc1;
    & }0 n6 D, S9 k& H/ P            break;
    ) V  c8 t) M( d        }4 \2 U9 h& v; C! V' F, H6 q' i1 M
            else if(p->adjVex2==head && p->adjVex1==pre)2 b! v$ N' k$ _  ?
            {
    ! p6 h$ O2 |9 `& c! c* r: t            p=p->nextarc2;
    : i2 i* P3 f+ l            break;
    9 s9 _* i: B9 |+ }/ n- v% F        }
    ' E' F) H) B5 e2 ]7 I3 @  z$ W    }( O3 T- u: O/ _7 ^  q, j1 e6 S; `
        if(p!=NULL)+ Y" L5 x0 f& `7 q# B% O4 s; K" h$ W
        {8 ^2 `$ M% Y& u1 r
            return p->adjVex1==head?p->adjVex2:p->adjVex1;4 Y5 K. S; \* b+ o# ]& }; [
        }1 m4 n; n0 q7 ~8 W2 R/ X6 x3 U  L
        else
    & j% `6 ^' ~) ~7 G7 ^        return -1;
    * e/ @% a9 ]; f0 q# k: E}& x# l9 z. x" \7 b: [" I
    ) N, L- T- p3 M" u' V

    ) T3 ^# B  i" O% o  |6 u4 Stemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()! a, G  j, w( _, d
    {
    & P7 O4 u& A9 c+ q% g( O    stack<int> s;
    + K7 C" l* u; W, C    int p,cur,pre;: l8 D% B+ Z8 j: _
        //MultiAdjListNetworkArc<WeightType> *p,*q;
      _% m- q4 C7 x- E    for(int i=0; i<vexNum; i++) tag=0;//初始化3 i. d8 v7 y/ P$ Z+ ]2 S

    & a1 A. X& P. a4 C9 |  B) q: n    for(int i=0; i<vexNum; i++)( S5 k; @% V5 p1 ]
        {
    - g4 W* n1 _( o' J        cur=i;pre=-1;
    9 @4 v, D! {% x6 h9 U        while(tag[cur]==0||!s.empty())* Y! i% q2 n) N% K2 {9 X; d) H% e
            {
    ' ^& C) e8 \) A            while(tag[cur]==0)
    * {# j4 {. s9 E) c4 K6 Z! B" @            {
    & r' E7 C' K) h6 P& g  V                cout<<vexTable[cur].data<<"  ";0 y0 d4 s2 b2 ?" N3 D+ f3 K# F
                    s.push(cur);% n  J1 N) ]; k: @6 u
                    tag[cur]=1;& G; |/ ]' z8 X
                   //初次访问,标记入栈8 q+ d( E7 [2 s8 O/ K0 `; ], T

    9 O" ?* ~' X$ |# i' Q" @               p=GetAdjVex(cur,pre);//p是cur的连通顶点6 ^( j$ E# j  k/ Y  Q: P7 m
                   if(p==-1). N9 b& u" L1 }) u9 G4 C
                   {
    , o0 m& S* U  f5 H                   pre=cur;s.pop();/ j# a* [. E, M" f- v9 M9 R) z; {
                       break;
    ' j0 ?# l3 ~5 I               }* g# s0 a& z* g( R* n% s$ y
                   else
    8 I- O. g( _2 t7 T: f               {+ G0 r* c6 x7 x. ^' Z9 Q. l
                       pre=cur;
    3 d# x: f2 B( O& T" N  ~' u                   cur=p;
    # t: i: L# o7 u- ?6 l               }; V- y5 m0 [8 c) I( p$ b, G5 Z: y

    7 C% A9 M3 F  ~6 q8 w* }            }
    ( n7 @' b- S- J$ o. ^            while(!s.empty()), P; l9 l7 X8 d5 ~8 B& g# V9 u
                {
    2 [  c" L5 x6 h* k- i                cur=s.top();
    0 d8 f& F: O" N. G% F2 Q! h6 k7 P                p=GetAdjVex(cur,pre);
    ' O% h1 q* C( I, i" E. k( U                if(tag[p]==0); G2 X( c# K. ]) {+ k* V
                    {
    2 R$ s: N2 G- C) `' H  C8 s                    pre=cur;: q! ?6 |2 @" h* y1 f/ C
                        cur=p;
    9 g  \# |% d6 H( e) r$ R* y                    break;
    , z- G  E; ~$ O) s                }
    ( g2 H8 ]0 ~; E  n  ]                else3 ~) _# p0 u9 k0 W: C4 g$ P
                    {8 G7 {" B; f" _3 c( R) t* ?" m9 L
                        pre=s.top();  L4 A( i. U& I4 L
                        s.pop();
    $ b: n8 L, [9 {# D$ P- e                }
    8 n5 O) D! B# j' o) U: O/ ?* Z1 U* g6 l; e5 ]2 h; c' {, g1 a
                }5 ?" F  M+ D* `8 T) }. f( A: ^
    0 P8 N' i0 E7 n& b
            }
    ( L( j% X* g% }/ c3 x; ^    }* W, |- W8 ~/ k) B! y# m
    }5 ?1 `0 _8 Z4 e4 h3 P8 \6 P
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()1 E6 H; ~, y/ e: G( [
    {" n* T/ r& H7 {6 `' W
        for(int i=0; i<vexNum; i++)
    1 F' R/ Z  E% c        tag=0;
    3 S, @+ O, z' y! c: s    queue<int> q;
    ; z$ _! V0 Q. [1 m2 X! u; q, ]. b! ]    int tmp,t;
    , n8 E) h/ \7 \# U    MultiAdjListNetworkArc<WeightType> *p;5 ~# @* {! p1 z; E
        for(int i=0; i<vexNum; i++)3 x! C( s1 s1 v. P7 m9 I
        {
    4 Z! L4 ?9 T4 G. d        if(tag==0)# U: h. \% h+ ?7 \. @) J
            {
    ; r# S% G& \: X& V. v0 N            tag=1;
    2 ?! _( y7 z7 [. Z0 d# Z2 f; z# _            q.push(i);
    " Q: N* [, Z8 a8 K            cout<<setw(3)<<vexTable.data;% b- X0 N3 @) x3 B0 ^
            }
    " v7 T) \6 p/ ]8 A1 T/ X# h        while(!q.empty())+ L$ B. K( P+ |9 A3 b( f
            {
    ' A: p: U* j$ z            tmp=q.front();# z& m. Y/ x. e6 O
                q.pop();
    & L  l: ^+ k9 s9 }            p=vexTable[tmp].firstarc;
    9 o3 }2 w9 b3 n0 s. B. }            while(p!=NULL)
    9 Y0 K5 ?- F2 l, S( g5 R# ?            {
    4 |/ a  p, Y" b) l                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);) O- f" E1 I* m. Z4 V9 ?! e; E
                    if(tag[t]==0)3 H: e$ v* W6 e
                    {
    : B) ?1 ^/ ~1 L0 D6 ?                    cout<<setw(3)<<vexTable[t].data;0 j  u& j5 X: U
                        tag[t]=1;+ h3 Y# Z, @" q0 f
                        q.push(t);
    . H4 t0 J- D, R1 q0 U                }! B: O. V7 y1 Y- H
                    p=NextArc(tmp,p);
    : y  x7 L( ~6 B" s( l            }& S4 L. e7 x: Y8 F. \. P! b: G
            }
    , t$ S! p7 s7 _4 G8 j    }
    8 J$ o, @& j9 F7 o* g}# v4 S) \& `6 m( [) J: N2 v# W
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()  J5 O2 Z- ?- w" ], F8 y/ H
    {, x1 I+ g0 M% N2 s8 Q1 ^* {
        MultiAdjListNetworkArc<WeightType> *p;
    # K4 F( I) @# R( ~& ]" _4 V    cout << "无向图有" << vexNum << "个点,分别为:";& q2 Q4 C* J: y3 r/ N
        for (int i = 0; i < vexNum; i++)
    ; v, [7 a& P$ n& e$ |) q1 W6 U        cout << vexTable.data << " ";
    ( I% O6 k- f9 ?& |7 g    cout << endl;! I, A! Q, M7 {
        cout << "无向图有" << arcNum << "条边"<<endl;0 x$ {( l& S4 |1 H) S6 [. c/ Y- H
        for (int i = 0; i < vexNum; i++)
    " C& C* Y; I. I/ V' o& w' T. @    {
    4 G3 Q" R! L) Z( |. R$ z; O        cout<<"和" << vexTable.data << "有关的边:";+ |0 i6 K* C* b( ?
            p = vexTable.firstarc;
    $ N2 A- p% k5 N, y/ f        while (p != NULL)
    " b& v2 C" N2 b- o% `        {
    - l# ]# C* B+ b2 \& V            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
      X+ v7 t8 L' i3 L" X7 X: `2 k2 l            p=NextArc(i,p);$ f# B! m5 j# {6 Z7 j  O
            }% [% P3 p0 U$ R. u+ t
            cout << endl;# u, m" M2 D# u6 O, P% D
        }
    5 Y5 W1 ?3 s3 p0 |0 ~. {1 b+ q; V}8 V$ P) }. @+ E( D/ j
    $ B/ L8 o; p5 X. U8 x8 ^& B, Z" |
    / J1 I8 b! O* T0 d4 l  X) s/ {
    邻接多重表与邻接表的对比8 x* u5 j( v: h) u

    0 c. m8 n( h! A3 \' H$ u邻接表链接
    ; |: y9 k8 H' _3 d' N+ w; U在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    3 p; Q  c8 _7 [1 q  m在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。+ }- B8 w. y2 b0 d( m
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    " P( L! ?/ o, r4 K( U$ Y" R" |" ]$ i+ N————————————————
    % c/ R$ w6 O1 y/ b9 K版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    6 j7 F  b7 J+ y) f8 H原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    , X0 t+ `8 f3 N5 T. H
      S. n  I+ H' H( c* ~/ j
    + c9 F' w# A& r$ j4 m& m
    2 a1 g+ [$ K5 j
    7 o8 X% i' p, }+ A+ B/ o- v: Q————————————————! z+ Q; p" ?% ]9 a2 q4 J
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。& {/ s6 w6 v. L  P& @( `  M) K- U- {6 }
    原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669583 z6 f* G8 W* d, {
      o  F7 O  g# b" }8 M

      n+ c3 I( Z3 H$ X& P. i
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2025-12-13 10:42 , Processed in 3.019927 second(s), 54 queries .

    回顶部