QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1582|回复: 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
    % I3 ~5 _' g+ \- |0 T% ~
    图的存储结构——邻接多重表(多重邻接表)的实现6 H- M; |# y4 U/ K  c
    7.2 图的存储结构) R7 y; \& n& d
    2 ~- E5 d# j: y+ @3 E  W7 [
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist" ?" E8 M8 ^! R' c
    邻接多重表的类定义- y3 m$ y* Y1 Z
    邻接多重表的顶点结点类模板0 D5 D2 @: m7 S( Q+ A7 m
    邻接多重表的边结点类模板
    8 q2 X9 F' I) E邻接多重表的类模板
    ( U8 b/ z, S- A邻接多重表与邻接表的对比3 b  t6 _0 M7 ?9 T" h$ Y7 P
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    ( K  A0 e% `+ O! @" }" [7 ~( W% c5 x! f* l
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。6 j' t9 f- `6 O: E. A
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。  o# [, g! D6 S
    0 p3 |! t, ^) Z% g9 Z
    邻接多重表的类定义1 `/ ]) y, Q* ]
    1.png ! Y: Z% g; q/ M7 `/ D
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    # D( [7 G) o7 H: N0 x8 g, adata域存储有关顶点的信息;  K  W" ]9 T& Q% Q) R9 l) F
    firstarc域是链接指针,指向第一条依附于该顶点的边。
    0 \: l+ y4 P, X7 v! U! R  s; c" Z2 J所有的顶点结点组成一个顺序表。


      W, @2 J1 U6 {, A& B) G0 o
    3 i- {3 |' X; r5 q+ {+ jtemplate <class ElemType ,class WeightType>
    ( C) a* ~2 ]- K$ n- S0 a, \class MultiAdjListNetworkVex6 i" z: ^' Z0 o1 [3 [2 v6 |& J
    {- }9 N7 ~8 Q3 C: E, m* F
    public:
    ' z  [6 D) x  \' }; b$ [        ElemType data;
    , `* s( s5 c/ h1 |4 m        MultiAdjListNetworkArc<WeightType> *firstarc;
    * P- P7 |# d8 w/ `4 s
    ) s$ Z+ V/ J; A% ~6 e        MultiAdjListNetworkVex()
    % s" e  N9 p) {  X        {
    8 ]$ a6 C3 b5 `* d8 q$ n% W* |                firstarc = NULL;
    " w* q2 p: P4 y2 K        }7 g! ?! |+ V: p5 E+ a/ k% ]2 P0 f+ S) r  u
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL). }' o/ f9 `& N8 {  q  L: g; d
            {
    ( l8 C" Q. Y7 }                data = val;
    % o7 e! R1 y$ {8 X                firstarc = adj;
    7 b. c4 G# E2 |$ }, u        }
    8 ^- {3 I3 x* m9 o$ i};$ k& k2 S: U% o. G. @7 M

    # B7 v% w3 B/ g; u邻接多重表的边结点类模板
      F' I% O0 B5 f' n5 r& S
    1 \5 F$ v1 v1 E+ q在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    ) q+ N: [! i  q/ `tag是标记域,标记该边是否被处理或被搜索过;, r$ q* q& p1 _, v- U
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    0 `# z. y  L& Y$ `nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    5 {+ H5 e+ R/ ?. H& vnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。" h7 `; g+ q5 T8 z
    6 C/ L5 I/ p+ q& y
    2.png
    5 z! f- I3 J5 ?/ E# P0 ^) Ftemplate <class WeightType>" W/ D4 `) R3 M! N
    class MultiAdjListNetworkArc
    / ~4 z4 }1 O( U- x{
    3 Q- X+ ?7 _$ L( `+ xpublic:
    $ V' k2 y  ~+ A7 p    int mark;                                       //标记该边是否被搜索或处理过9 r5 L. o0 {; q$ |2 L
            WeightType weight;                              //边的权重9 x( ]$ ~! d( d( Y& \7 v) B/ u
            int adjVex1;                                    //边的一个顶点
    ) z( l9 S  q- u        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    ( d6 |" T! \$ h        int adjVex2;
    % k, I# k$ x* V% ?        MultiAdjListNetworkArc<WeightType>* nextarc2;
    ' D7 k/ s" w3 P; q2 p5 r% Y
    ' x( h3 e2 o0 \' w) b* x4 k        MultiAdjListNetworkArc()
    * f, N/ w$ g' C1 p6 m5 V' f        {' Z7 }8 W: X, r* ]6 T# v
                    adjVex1= -1;5 y# Z) `% i9 p2 u+ |
                    adjVex2= -1;
    2 b  F* u* o0 u! S  B        }$ ?) u) N- ?. ?
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    9 N5 W% H, K" C5 i        {; P1 j4 A  Z. I) b: ^, z& P4 M! x
                    adjVex1 = v1;       adjVex2 = v2;" O9 B' Q- b' ?; H7 a& A/ k- S
                    weight = w;
    * ~7 v0 r- _3 x" ^                nextarc1 = next1;   nextarc2=next2;8 R5 c7 ?  t2 F; ~* {# w
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    " R- W2 j; P6 s  c: q6 h        }
    " }1 u! L& G5 m: t6 _, [
    * F  `5 t5 Y( Y邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>8 g$ ~/ T& G* Y2 S4 O2 m) T
    class MultiAdjListNetwork
    + a8 V3 I* w: U- F' u$ p5 }/ p7 `{
    " {, d0 c8 K. Uprotected:
    3 C6 I; w  v* {, d  L" b) x; H    int vexNum, vexMaxNum, arcNum;- _2 N' j; @( Y
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    ! K( q) Q3 C" L    int* tag;
    , M3 ~4 Z. [1 i. ]7 \    WeightType infinity;
    * y( p( P  m) }. ^% b7 U. _! p, {/ ]0 b+ K% q
    public:! K' I) ?9 `; O, r' R# C. x5 a+ q% N
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    , C( r0 h* Z; J8 H: ^3 r' x( |6 w# j, v
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    ! T7 h2 M+ d$ ?- o# Z# V" U* o7 {2 H+ I: ]! h6 K! r- U
        void Clear();( P) J& K  L( r% M, D! r- f( b6 r
        bool IsEmpty()$ B  n. C8 c( t2 a
        {8 Y3 D2 a. U, J% [/ S- n
            return vexNum == 0;4 O: Q0 d, n% W& h1 I5 v3 X/ f
        }
    5 n9 ~: f1 a( a# x6 F+ }4 |; k    int GetArcNum()const
    5 F3 a9 n6 t3 b) t( b4 b    {
    9 w  u8 _" B1 R/ n+ K        return arcNum;
    0 |* u% H5 ?. |7 x0 m    }& T+ C3 x- J/ K" Q3 ?8 [
        int GetvexNum()const
    + u, C& B( m" M: w& z/ J    {9 @+ U4 P3 w) N& z6 U, e5 J* S2 l
            return vexNum;
    : G- s' Y9 r8 R- G) [    }7 h- z6 C; K4 n8 T% r% ?

    0 L8 |  L* ]) G! t. o# u3 b: |% @9 `
        int FirstAdjVex(int v)const;
    7 c0 [& [& _/ A9 Q' p0 B    int NextAdjVex(int v1, int v2)const;
    0 p9 c" V9 y: u0 y! q    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;6 [& `, B* G  d+ K9 ]' O- X
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;+ [+ ?. R' n  `6 x* P8 k0 `

    9 f9 r( r8 ^5 `0 M( r  e$ G    void InsertVex(const ElemType& d);
    5 y) `7 c% ~! @1 O* w  S* X2 w    void InsertArc(int v1, int v2, WeightType w);
    ! g8 J& N  Z; u4 E4 r) M' Z1 h$ w# X6 ?- O
        void DeleteVex(const ElemType& d);
    1 ~- W* f) ?( `  S+ ?    void DeleteArc(int v1, int v2);2 I" y3 d: C( s, S

    / ~. T! N* K. m2 ?2 D+ K/ g( t0 g    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);5 L- {$ b+ a* _& _' [+ |! m
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);- P# t8 s6 U% z, y3 V" M6 B
    + z4 r( f6 r. Q9 r1 L. M# ^2 R5 t
        ///深度优先遍历0 L* \* `- s* g
        void DFS1(const int v);1 {) \8 E9 D8 |' j9 f
        void DFS1Traverse();, j/ d# Z6 N, [; L* {8 Z: t( a& P# v
        void DFS2();
    7 n. T  Q9 a: f
    , D: c3 _2 ], X2 P6 c    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-15 g& \" p! k  O6 q
        void DFS3();
      n6 m: d* u/ A* Y/ i8 S( [. Q9 t, L9 r  K! p
        void BFS();& `4 i& i# K4 j- x/ O
        void Show();
    % ?' k0 i. b. ?, n/ ~};
    3 b8 e- r1 |" j" c# E9 j( K# i
    % l5 q2 c* o- V- u% {) ~2.函数的实现+ ^0 `6 r8 G3 k5 L6 X
    研讨题,能够运行,但是代码不一定是最优的。- `6 A5 ]% p2 u

    / D7 F) `1 U6 m+ J#include <stack>% ]6 b4 Y4 O0 T0 t2 w4 |$ X! m1 x
    #include <queue>
    * ]8 r" [5 F. M+ J: P
    % ^# P" A$ u# X) h* c- [- c. d& gtemplate <class ElemType,class WeightType>0 z: I; Y& Z4 }8 O8 Q; O: w
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)( {8 R  ~! j. i; @1 W; ~* O
    {7 h1 [1 c1 u/ J5 a8 v
        if(vertexMaxNum < 0)
    " [: n# k! v( q% t9 Y3 W0 v        throw Error("允许的顶点最大数目不能为负!");
    " N! O+ {$ a4 W" P    if (vertexMaxNum < vertexNum)4 u& {; |! c/ ~3 y' l
            throw Error("顶点数目不能大于允许的顶点最大数目!");
    3 B) {' s" _! J1 x    vexNum = vertexNum;
    7 G; ?4 M. p2 f+ k    vexMaxNum = vertexMaxNum;
    2 J+ G  k6 f- t* ^    arcNum = 0;  J9 n1 U/ r  g  X/ N0 W$ n) g4 n
        infinity = infinit;3 U- `3 e  `/ f' Y* [, R0 O5 k- b
        tag = new int[vexMaxNum];
    9 Q9 z- k: |9 s" V! l& C7 `* L" `    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];1 y6 M  u1 r9 o  A9 m  ?) b* ?
        for (int v = 0; v < vexNum; v++)
    ' \) R# U* f% ^7 P# P    {
    / K& Z  ]; S% H: G; V: P, U5 D        tag[v] = 0;
    6 z7 y( I. K, |$ z        vexTable[v].data = es[v];7 n' F" E) a" P' C& w% A8 w
            vexTable[v].firstarc = NULL;# a3 s$ }  S  d
        }
    " n5 ~# [$ ]" d}% `+ _1 t6 v2 V4 @
    template <class ElemType,class WeightType>' A4 w  @4 U+ p* A* U4 b$ [/ p" q8 \
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)7 L3 I% P$ S# b7 H" U8 m0 R7 {! O
    {0 n' Q6 _+ i9 F. |
        if (vertexMaxNum < 0)6 \& F/ C6 {8 ^6 I' J8 k
            throw Error("允许的顶点最大数目不能为负!");) n4 @: i! \( S
        vexNum = 0;
    . Y3 T0 V9 k  Q" d8 n  Y/ m    vexMaxNum = vertexMaxNum;, T% Z" W; V# W+ U: p" ^7 @: i  ^. d
        arcNum = 0;7 D" T  N) H. o- V, O
        infinity = infinit;9 B+ E% P. |2 P; N' {
        tag = new int[vexMaxNum];
    % D2 D% H( p  ^    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];4 n; m8 B, B7 ]5 P  W- n1 u+ g5 d
    }
    ) I8 H: q3 L4 r' J5 Y  Ctemplate<class ElemType, class WeightType>
    4 O; ~# o+ h5 ]" uint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const2 M( ?6 N4 L" l7 X: r9 |
    {
    1 S6 M( e8 \! T) d8 C3 M    if (v < 0 || v >= vexNum)  U5 w: d$ ]( Z, K. U- r4 A
            throw Error("v不合法!");' X/ E2 Y( q9 m7 a" \
        if (vexTable[v].firstarc == NULL)
    1 W7 I0 {+ m" ~  ]+ n+ d5 R        return -1;# k$ h2 R. q0 p( g3 j8 ^* r/ A
        else
    # R2 w1 |: L2 w% C( b/ m- Z        return vexTable[v].firstarc->adjVex1;
    * z! d% L1 {3 Y2 K7 y1 _/ x, J}
    # s( n# Q2 p8 J3 M: c" J( K# @. X! ~! ?6 h
    template<class ElemType, class WeightType>
    9 \2 l* Z+ ~% q5 J; D7 g" vint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const; k) X; g( T5 h. ?# R( P: K; v
    {8 S4 t" g" n$ M6 B
        MultiAdjListNetworkArc<WeightType>* p;$ V' a9 q  g5 ?/ {2 v
        if (v1 < 0 || v1 >= vexNum)
    . [7 L( d9 X( X! }        throw Error("v1不合法!");2 Z+ C; m0 Z. Y; H) [2 q7 Y" H3 j
        if (v2 < 0 || v2 >= vexNum); R: G& k! m' ?$ I' ]# a" T! C
            throw Error("v2不合法!");
    ) l# y) c; l$ V, k; @- o    if (v1 == v2)5 P+ l0 G8 X2 w% @/ _( b: t) T
            throw Error("v1不能等于v2!");. @% ^: |: W/ K8 Y
        p = vexTable[v1].firstarc;
    9 q3 y1 W$ _! @; a: D    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)1 o& W2 D: K7 Z
            p = p->nextarc;
    3 [0 U8 j7 }  R8 b    if (p == NULL || p->nextarc == NULL)
    ! X* i5 u3 d. w( ^. [9 ]0 W        return -1;  //不存在下一个邻接点
    5 z2 y, U: d! ]. F    else if(p->adjVex1==v2)
    - s1 S$ T9 t% V8 G8 x: g        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    * |  I* r2 ]& {6 |" a5 |/ ?3 l. i    else
      f, Y& D% z# t& h; R0 e2 k- F        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);. x: w4 I6 n( j6 W/ r: N
    }3 ]- {; q8 V- I" m5 p
    template<class ElemType, class WeightType>
    5 W% r, `3 ~# Fvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()8 o6 J2 n( w7 n5 o+ T/ G
    {7 a8 A0 @1 C$ K( N- g
        if (IsEmpty()) return;
    7 {$ y) r. G0 [, |  q( z    int n = vexNum;2 y& B' _) d, K2 z3 ?9 v) ?: U
        for (int u = 0; u < n ; u++)
    7 l. J" x. n7 {) K, m        DeleteVex(vexTable[0].data);6 i* l1 E1 a3 w
        return;
    , f. F: L; J- g; `, ^2 k}' `# c; l& P+ v& i; |
    template<class ElemType, class WeightType>9 b+ i' _% ^. _  y
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()4 w. n  K# T. g
    {
    3 D/ A2 y- X' H2 Q: i" A4 s    Clear();7 k6 d: O: [: A# ]+ u( G
    }! Q* d* }8 d; g$ p, x
    template<class ElemType, class WeightType>) n: @7 G- Y) z- R5 k% t
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    ( _2 n8 J5 `$ U5 F, g) w( z{, [5 x2 N$ @& O) j1 b
        vexMaxNum = copy.vexMaxNum;: D1 q: `3 R$ m* O9 F
        vexNum = copy.vexNum;
    " k! B1 C8 D3 {    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    , X* `& Y- y! s5 s8 l    arcNum = 0;2 |1 B9 B0 v# ^1 {  `
        infinity = copy.infinity;
    2 J: N: j9 f8 C$ x2 K    tag = new int[vexMaxNum];$ n# B: Y* N2 k3 |, n) o

    ! o7 J- [4 k& X3 m- P7 p% c. v0 e    for (int v = 0; v < vexNum; v++)
    / n, z* \0 O* g/ Q    {( b4 c+ k* d4 c0 E/ e
            tag[v] = 0;' R9 t+ i& h" K( _( H
            vexTable[v].data = copy.vexTable[v].data;
    # C0 T1 V2 P& V        vexTable[v].firstarc = NULL;. F; e+ _* a. A. A; b* F; F7 d+ f
        }3 A/ f. s+ q2 O* M" w% j
        MultiAdjListNetworkArc<WeightType>* p;
    ) R' H  k+ v  ?, C/ N* Y  |; D1 w; ~: {% A- M9 e4 \2 X
        for (int u = 0; u < vexNum; u++)
    2 L" N( A; ^7 b' p9 A  w, F    {9 E' ]' r3 s$ S% u, n, z
            p = copy.vexTable.firstarc;
    & ?1 p3 h6 R/ q# k. V+ H        while (p != NULL)& d$ ^% ~2 J8 }- W+ c. {; K  O
            {
    % {: A2 S/ n' y5 Z6 T1 U2 K4 E            InsertArc(p->adjVex1, p->adjVex2, p->weight);5 I) ?1 r0 r& E* G
                p=NextArc(u,p);
    ; g) V+ x7 `' y4 R+ W9 G        }
    ( W: W  F  m) J, D    }- L8 \5 s- P6 L0 D; O
    }" E# ^6 J0 ~5 u; r2 R, S9 p
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&+ o* R( i4 {0 @- h; }# k
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    ! f% d# l8 b& H% E5 {{+ X& g. b+ N8 L7 f1 A0 i0 k/ T
        if (this == &copy) return *this;  M# k$ y2 W. `
        Clear();
    7 r# R4 o5 v7 S, t    vexMaxNum = copy.vexMaxNum;
    7 Z( T, {) @- W9 l% ^0 u    vexNum = copy.vexNum;$ _: p% S8 P& W+ U
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    6 |+ B3 F' U# A+ R) w4 }! j    arcNum = 0;
    6 Y* y3 ?* {9 a( B; J$ ]    infinity = copy.infinity;" Y% X8 i! S/ x0 I4 [1 T3 [
        tag = new int[vexMaxNum];5 n$ `6 h5 m( i7 L. g6 A+ I

    ' G$ {+ h. S6 g- G; _; n    for (int v = 0; v < vexNum; v++)
    6 L: B" V7 K0 b- {, {, s( S( A6 S    {
    * V9 F: o: [6 h4 x7 H, R4 m# B        tag[v] = 0;
    % |& a! E$ x9 c8 `- P        vexTable[v].data = copy.vexTable[v].data;3 a& ^& F. S- \# k0 V+ [- k
            vexTable[v].firstarc = NULL;
    $ x; }7 ~; x$ C- f  i+ u2 ?    }: y, t$ I; g% n9 l7 ?$ }' ]
        MultiAdjListNetworkArc<WeightType>* p;% k* P/ m+ ^4 g9 Q+ t! ^% O) U
    , }; i6 C* c- F8 W5 Q; u; ]
        for (int u = 0; u < vexNum; u++)' F( g0 M; o. l
        {* T( c$ ~7 S# @' ^! X% M+ W3 `
            p = copy.vexTable.firstarc;1 V6 `7 x, e$ ]# @; o  Y5 g
            while (p != NULL)
    , S1 Y, Q6 K: x' M        {9 E& w+ l$ |  a! c" H* j9 z
                InsertArc(p->adjVex1, p->adjVex2, p->weight);0 t& q+ s: l, a# u1 }
                p=NextArc(u,p);( \- U2 V' r# d* }* M
            }
    7 g7 a, J! K$ n6 R    }
    ' t; i- ^* W  e- b" E" B- P    return *this;
    : O! J. }7 X) T}
    5 L* m; @# Y( Z3 {7 K, X0 c2 U% z" \template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    , X  W, r% B4 X6 U8 |MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    2 I4 J! I, V& V2 E5 f{, ]: r6 `( U3 [  |
        if(p==NULL) return NULL;
    ) n2 v4 y- R( B1 _3 S    if(p->adjVex1==v1)
    & R& i$ J/ ], N/ M        return p->nextarc1;# E7 R0 t+ _/ l2 k! W! }
        else6 x2 M' t8 e+ c" I2 q/ e" Z
            return p->nextarc2;$ }9 A& P  b2 }+ Y( N7 {
    }; X# T9 d) r$ p2 O, x# {$ m
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*% u# G( j5 G' I( A* y; P- Z
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const; }% U, p& j6 m' l. i* m" \$ [) u" S
    {
    - d  A8 z1 a' F1 H    if(p==NULL)return NULL;
    & G3 q. P: Y9 H9 Q- h) a- J: Z    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;) y  J" p5 p* y& f, A* _- ^
        if(q==p)% d$ d; F  h3 D" e7 \! n6 C
            return NULL;
    , g9 @" W8 |9 M* P    while(q)
    & C# H8 e8 l/ Y: K2 G" t! y    {# g& J" v4 ?4 ]! E! g. S
            if(q->nextarc1==p ||q->nextarc2==p)
    9 w; M, w. b" U0 G& _8 ^: P1 \: Y            break;
      w( H# @% f; H8 A        q=NextArc(v1,q);; C+ p! o" ~- T( t$ @
        }
    . n$ s9 [3 |- O. ?) K6 e/ g    return q;4 e1 O0 f6 Z- I: G, f
    }
    - |9 X6 J" d) o0 [template<class ElemType, class WeightType>
    + z3 e* v9 k! N& X6 Fvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    % h4 y/ ^5 K4 X2 a; C  W{
    . G" L' W* q7 v2 ^    if (vexNum == vexMaxNum)/ Z8 E$ G7 v# G" y! `( X$ q
            throw Error("图的顶点数不能超过允许的最大数!");
    - x3 _: [: g2 ?. Z) N8 {! b: J  w9 B    vexTable[vexNum].data = d;
    ; d3 b# U/ J- Y9 D1 k3 Y. M    vexTable[vexNum].firstarc = NULL;
    , o! @/ ~' P+ \$ x+ u3 g    tag[vexNum] = 0;0 F! ?- F* H# s" r. d
        vexNum++;* r' ^7 f5 O3 C- N% @. _
    }# n) m# X# O' T% s' e% e" a7 Y
    template<class ElemType, class WeightType>
    3 ~; \; ^2 k! n% J# R0 Wvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)( r! K) Q+ f  Y: R5 I7 x6 K
    {' M. N) ?7 p7 W
        MultiAdjListNetworkArc<WeightType>* p,*q;
    3 Z9 S/ {) a' a' J& |    if (v1 < 0 || v1 >= vexNum)
    ; N' k- ?9 n) o8 {* o. u        throw Error("v1不合法!");
    ' r, _' ~, L- L1 ]1 J    if (v2 < 0 || v2 >= vexNum)
    & u5 I* t1 ]( D! }) }6 k1 f        throw Error("v2不合法!");2 d' Z/ y! P, m# M" p4 J
        if (v1 == v2)
    - k9 h7 b" E6 `( Y$ w        throw Error("v1不能等于v2!");% Z: b8 r) N1 N, g
        if (w == infinity)4 y3 m1 p' j" l2 G
            throw Error("w不能为无穷大!");
    : b" p7 ^7 J; V. G! ^# Q
    2 g% x3 H5 J( X! Y
    : Y# h3 }3 J& \! S    p = vexTable[v1].firstarc;
    % Z  B$ {1 s  L1 H8 o    while(p)% }2 L& X: }( |" u) e! Z2 A
        {% [. S; A' V0 |7 {7 b- `$ y  p3 A2 H
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    $ j! g; I4 N" t        {( W+ @' F& p$ r  `0 V8 h& }- t
                if(p->weight!=w)
    0 a) a# {+ p2 S+ M4 q$ ~                p->weight=w;& E0 D5 F( {  m5 j
                return;
    * @6 G; S+ V8 b        }5 i; Z2 H& O  k; |( p
    $ z2 L" B" W' ]9 X  ^# U9 r- o
            p=NextArc(v1,p);* ^' G/ S; w! x3 p( \
        }
    / n( T/ h: G$ Y! N    p = vexTable[v1].firstarc;
    7 j; |6 E$ w9 c- r2 m/ n4 |# I    q = vexTable[v2].firstarc;
    ) T. ~1 q! d, c" _# ]+ g    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法/ |9 h1 L+ _" @8 \' q7 o
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    # t% Z9 M' v4 v* P- p* w    arcNum++;
    ; h5 Y( a  n0 |$ {: I7 i1 P& a2 g}' Q! w2 i6 C6 P
    4 R  g6 |+ P5 i6 t) p' A9 ^
    template<class ElemType, class WeightType>
      q( D" o4 v1 ivoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)6 h% Q6 t9 P6 ]
    {  ~, Y# u, W8 o- f4 D
    4 Z+ i+ u" c* d1 u  }2 H
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    8 l5 l! [4 c4 l: L  v: W    if (v1 < 0 || v1 >= vexNum)! [; B3 K. u; [# A* M: M( m/ W0 m
            throw Error("v1不合法!");
    + @+ Q9 J, a! U    if (v2 < 0 || v2 >= vexNum)+ ^& a+ ?4 V1 z' k" t- l
            throw Error("v2不合法!");
    6 I9 W1 A3 a$ U% J/ s* P" j, F0 T5 `    if (v1 == v2)
    7 f# r6 G$ O- Q        throw Error("v1不能等于v2!");  ^4 `: A7 X& x7 y* Z# e; Z0 B5 p) x
    6 T( r0 }. T0 Q' {) s; B
        p = vexTable[v1].firstarc;1 Y$ R' ?" Z3 D1 o
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)$ m* t  @$ w, i6 C! B' V; E
        {* z0 ^" [7 z& \: ?/ d$ F( U
            q = p;2 }3 _& F( e) A2 r" J! g/ B
            p = NextArc(v1,p);
    ; w  W' [% c5 Z# Y  \( s# Q    }//找到要删除的边结点p及其前一结点q
    * e9 i  R; R! _9 ~9 f& C2 c/ S" d
    ' `, X! E( [/ `7 n* j    if (p != NULL)//找到v1-v2的边
    - Q' {7 @5 M7 s* @3 O3 ~% a    {8 k& E; z/ [2 Y# t) y
            r=LastArc(v2,p);
    / M4 c8 u' B: o/ w        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL" }/ j; L) `* h' z$ S
                if(p->adjVex2==v2)  F4 @4 b  }0 k1 Q$ q& p- P
                    vexTable[v1].firstarc = p->nextarc1;
    % B( Q$ m& v  ~            else vexTable[v1].firstarc=p->nextarc2;! y# ]  q2 W8 [3 a
            else//不是第一条边
    . ]2 \: X7 R: ?2 h) I        {6 Q: O" \. F2 k6 c: Z
                if(q->adjVex1==v1)" O( y) @  g3 b. M
                    q->nextarc1 = NextArc(v1,p);1 Y' E7 c4 w+ A$ s% }8 s
                else
    ' _8 L$ f- x4 \5 `6 A                q->nextarc2=NextArc(v1,p);; a1 [1 _) y3 C7 Y2 J' w# }

    . S) I% U* _" V* q6 X2 J        }
    / W* T; g8 i% A9 @4 S6 W6 F& ]9 R        if(r==NULL)
    $ v) e' f6 R* m  S/ I8 g9 M            if(p->adjVex2==v2)5 q: x# @9 J- t
                    vexTable[v2].firstarc = p->nextarc2;1 u7 w" a$ _6 @! Q- I/ z3 _
                else vexTable[v2].firstarc=p->nextarc1;: b- V) [7 o' O! C; a
            else( |6 J' q5 y0 m& h" |" t+ @6 n# _4 z
            {# K6 x' h- V/ P( T$ r
                if(r->adjVex2==v2)( h1 ~- O( c6 `8 m7 w# H' z. f
                    r->nextarc2 = NextArc(v2,p);9 @/ Z- ^4 m7 V% Z4 R7 v$ g" L8 K
                else- x" \) ~+ [+ M/ t1 K
                    r->nextarc1=NextArc(v2,p);
    6 c, |) @) E2 v1 q$ j1 G        }
    1 d$ Z! b2 _9 P& y8 U4 d7 [) f        delete p;
    % e3 {7 ]+ i/ ?: R        arcNum--;
    1 P0 m; j. u- J) u% c8 M8 `5 t    }5 d  k2 ^7 ~6 H7 I

    5 M7 N& c+ v3 \. Z  L6 g( t7 \5 `}
    + @0 s' F/ f" ?& atemplate<class ElemType, class WeightType> void0 Y1 H/ u$ m) o+ L' n7 [
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d); b! ^; j4 i$ P4 A
    {) N8 W* d5 ?: E. h6 P) E
        int v;
    3 M- ^7 D5 i: q  ^* `. G    MultiAdjListNetworkArc<WeightType>* p;
    $ T1 _- E8 T, j4 ~# C; v" k" e    for (v = 0; v < vexNum; v++)//找到d对应顶点
    * D" \" f* D1 d! e% H        if (vexTable[v].data == d)8 C' m$ o) H2 i5 y* a. |
                break;+ L8 y0 P/ X, B: _# S6 Q+ K
        if(v==vexNum)
    $ n3 u& h% s0 X& s; u" g& l        throw Error("图中不存在要删除的顶点!");; G( V1 X& Q, j. h- S

    & |" w4 I/ a2 X$ r8 C& Y( B7 p    for (int u = 0; u < vexNum; u++)//删除与d相连的边9 D- K2 w3 `$ ~' o
            if (u != v)8 |1 O* ?- B7 P+ ?; E1 A
            {
    , O+ b( p6 b' e$ B& b( k: w( [8 z  o            DeleteArc(u, v);% D7 ?, Z( }6 R+ X$ g
            }' ^* ~3 G$ L+ F1 S. y+ q
        vexTable[v].firstarc=NULL;
    9 ^3 D' B( O2 [2 i, H, s% v* z4 K& e1 j& s( {
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置7 _$ M" c" p% W" G& R8 p7 G
        vexTable[v].data = vexTable[vexNum].data;
    4 _6 H+ c" X8 ~( j- [    vexTable[v].firstarc = vexTable[vexNum].firstarc;: L) V) c' h' e4 L# `
        vexTable[vexNum].firstarc = NULL;0 S7 @& G: X* `/ F$ {6 R; V- T+ p0 Q
        tag[v] = tag[vexNum];1 ?$ F+ B* m5 \2 E4 K& p
        //原来与最后一个顶点相连的边改为与v相连0 K! D1 k/ Q* P; \0 X
        for (int u = 0; u < vexNum; u++)
    % O3 {1 g4 x; s7 [* R. Z9 U4 j) t    {% \4 ^) C( Q$ b% X" o! e
            if (u != v)
    " S0 e5 N: Q* u3 c. m4 y3 K5 p        {: y8 I4 S& q  n7 x4 X4 K
                p = vexTable.firstarc;
    & q) |3 K! s1 I% Q. H3 x            while (p), b8 {. H: R1 s7 ^! R
                {6 U: Q" ^; i, ~7 T% o
                    if (p->adjVex1==vexNum)! G/ F8 ]: N4 i7 f
                        p->adjVex1= v;) i  }( F) x* e( D, v/ B0 _
                    else if(p->adjVex2==vexNum)( O% F$ G+ ^1 ]# u
                        p->adjVex2=v;; e* f& }3 U5 ^% E6 M* r6 E
                    p = NextArc(u,p);. L% w: m& |( o0 p  N" m% B
                }; i7 H- f; d: r( p
            }
    6 y4 p4 E2 [+ u6 K3 ?9 Q* k  I    }
    ) e: i' [2 N* c% I7 `* Z  D4 i}
    & ]) _- k0 w8 {; |///深度优先遍历$ L: o( G+ D% J6 v3 J& w
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    ! m# y( u4 r* G8 O& {{
    + n3 @$ y7 R! e1 u+ v+ s- c5 ~    tag[v]=1;
    0 C& y2 h* Q! S# {2 a    cout<<setw(3)<<vexTable[v].data;' d4 K% \, Y+ h3 j1 V: i
        MultiAdjListNetworkArc<WeightType> *p;0 G2 k1 H7 O5 r$ M5 H' N/ B, t
        p=vexTable[v].firstarc;
    5 c6 p3 K# ^$ T% m! Z    while(p)% I: n1 i% j' N4 _! O6 ~- ^
        {/ [, U$ r. D/ i' l
            if(tag[p->adjVex1]==0)" U' W9 D( z. P
                DFS1(p->adjVex1);
    # u* N  o- K- i' R        else if(tag[p->adjVex2]==0)7 B4 I8 q$ e4 w- [4 E8 z
                DFS1(p->adjVex2);" H" }& X, I, \* D) _
            p=NextArc(v,p);
    ! U4 V* ~) n7 V    }, l" e* P: w7 x* C, C6 E
    }6 w+ L& D' K5 ]4 W' ^6 o* |
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    ' ^% H2 M* J5 e! |; S/ `7 m{7 T3 ?" p* p; d+ e9 G
        for(int i=0; i<vexNum; i++)2 d$ S. l5 s- U3 h2 D8 ?
            tag=0;' K! K2 q( f+ G2 O, x; X* R
        for(int v=0; v<vexNum; v++)2 {7 _/ b  A. `* \. F
        {
    ' n9 F. H0 }' E" K$ X        if(tag[v]==0)
    1 X: ^; C/ `, [1 Y            DFS1(v);
    : y) E  }5 _* E2 l9 ^) ^    }
    5 d$ V; t1 `8 F7 S4 c8 w}
    5 {( r  V* f" x" L8 Ptemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()$ U- j/ c0 L7 n8 N$ {
    {
    % L+ |9 R# ?# V( l* Q' s' t    stack<int> s;
    . f6 j* \# T5 U, t    int tmp;
    . Y: H3 l# N% C+ ^7 b' e3 |/ N    MultiAdjListNetworkArc<WeightType> *p,*q;
    ) n# m9 K( Y" y% o7 L" S) s    for(int i=0; i<vexNum; i++), O2 v. v$ v/ e4 K% N6 ^
            tag=0;0 e  t( ?. H2 N5 o# Y7 m$ T( t+ D
        for(int i=0; i<vexNum; i++)% c. N8 K" i0 g4 z" g/ p
        {
    . G3 Z3 a5 q5 n, m& r        tmp=i;, `3 n( `8 q4 s/ D$ c5 }7 p9 e
            while(tag[tmp]==0||!s.empty())& C5 T4 v/ ~2 N" H) v( p
            {
    ' _% w6 ?2 C& M+ P9 `  N1 g            p=vexTable[tmp].firstarc;. C5 ^8 G( O5 p. f
                while(tag[tmp]==0)
    ' r6 [4 u. d3 c* l& [4 c# l( A            {* t7 c0 W* T+ B4 g2 I
                    s.push(tmp);
    8 w, u: k* V1 F) p' {7 f) p7 b0 O                cout<<setw(3)<<vexTable[tmp].data;8 r( }7 u( _2 T, p# v( T( W
                    tag[tmp]=1;& z  J8 X1 c( G: g6 ^2 o/ L: ?% Q
                    p=vexTable[tmp].firstarc;& j. |" ]- O; Z
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    : _: H: S4 N3 W: A# x# M                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);' _" I. O3 \, \0 o/ {! K; M. j
                    //cout<<" 1st     tmp="<<tmp<<endl;
    9 W+ Q& B% @! a1 {            }/ a+ S6 X  S; S9 z' q8 h
                if(!s.empty())
    % f2 K  r4 N5 o1 ]            {0 t4 j4 \4 ]5 T9 \* _3 D
                    tmp=s.top();2 B/ i/ A& \6 O. a. p) J  N- O
                    s.pop();
    ' N; U( D3 _* b) d6 h3 b                q=vexTable[tmp].firstarc;
    6 d: D8 z- }) G, ^! ]                int t=tmp;
    1 h: L+ n# S. k* s7 b                while(q&&tag[tmp]!=0)* y! V! w0 H7 E$ a+ i2 \
                    {2 q2 }& I& q  @2 u0 S
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    # J% A" t0 U, X9 Z$ R9 B                    //cout<<" 2nd     tmp="<<tmp<<endl;
    ( ?- f$ l8 r' ~6 C$ n+ B( L                    q=NextArc(t,q);
    3 z/ m! l1 f' T5 \+ X: i                }
    ) E1 b" B( l9 Y                if(tag[tmp]==0)7 I, S, T/ D: q- |% f7 X4 H
                        s.push(t);
    * |' @  z8 v1 s9 W* Z7 r. `                ///1、对应上面连通分支只有1个点的情况  \9 k- i. E) n5 k( R$ o: ~
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈9 J& u6 c0 T9 G$ @0 w: Q6 u% ~* ^
                    ///tmp要么等于找到的第一个未访问节点,# B8 Q% ^; `4 {7 x) p) z/ B
                    ///要么等于与t相连最后一个点(已被访问过)
    4 i4 L$ ?$ s. l1 E                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点/ N/ d  [, B# A  U
                }
      U1 m7 j7 t4 c, V  a        }
    4 {* X- N& `" k; S+ n4 k" ]  @    }
    0 ~1 ^( n0 `% ]8 h$ `8 R}
    ( t! s3 m4 ^. J6 q. X* Y9 }% X0 b//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    . D, g: K! r4 U# \7 L' |" X8 ]template<class ElemType, class WeightType> int$ X' [$ A& l. ~/ }; |% W0 S
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)9 {! t/ w, R3 \! t5 B
    {9 I+ H2 h! ^+ C- T( S, X# m
        if(head==pre)+ V* p# x# w6 s- a
            return -1;
    : g9 L- H' @% a# M4 k9 u! n
    # g+ Z+ w0 f* `1 y    MultiAdjListNetworkArc<WeightType> *p;
    ( }4 I# n2 v' p3 N! P( [4 b; S3 f    p=vexTable[head].firstarc;3 r8 Q3 f1 K* h& d
        if(pre==-1&&p!=NULL)
    / T  Y" w: Y0 v3 a        return p->adjVex1==head?p->adjVex2:p->adjVex1;+ T) ]- I+ `4 E# X8 U
        //pre!=-1&&p!=NULL7 C& W1 b4 {9 t1 w$ y; n* g& H/ B
        while(p!=NULL)
    1 O! B& n: M2 I- B+ {6 o& I1 {    {
    $ \  P" c/ v4 f3 v( ?        if(p->adjVex1==head && p->adjVex2!=pre)3 P/ m9 |* J& @: b& M, H' J
                p=p->nextarc1;
    9 V. F$ R# @0 W1 O% b: @6 x        else if(p->adjVex2==head && p->adjVex1!=pre)
    " q( ~" A2 E+ v            p=p->nextarc2;% v. N( {( q" W7 Y( p& I
            else if(p->adjVex1==head && p->adjVex2==pre)/ w# X. a: [$ G3 d
            {
    1 g% d1 I. B0 T8 Q/ X% r% }# N* S- m% ^            p=p->nextarc1;0 k7 x) {9 ~$ G5 L
                break;
    9 J; q2 g$ B. f0 L5 a* b. L' H3 E        }! n! i4 [! h7 d
            else if(p->adjVex2==head && p->adjVex1==pre)
    5 q  ?! b; S) E! a9 B0 S4 ?0 i0 z        {4 J; |2 V* D% {, S8 ?( K
                p=p->nextarc2;
    % k( l- [! g8 w( |/ z; y            break;. ]" I6 _% c6 Y# @, `" S% S) j+ W
            }7 M6 M+ v. [1 J  l3 q: i
        }' {, p2 \% S" [5 h# N4 k
        if(p!=NULL)5 Q& H, {- C4 ], {& v
        {
      H" N4 W+ P3 a7 `: }5 Y        return p->adjVex1==head?p->adjVex2:p->adjVex1;( y3 b2 ~3 y3 ]. \
        }
    + \; M% O1 s# r0 ^    else+ _2 _: ?# b1 ?3 {# h6 d
            return -1;, H( S+ S: p% X6 E$ t
    }% m' E" K6 b$ k" q% Q8 p! N3 S) }3 L" a

    : s2 @% p6 f1 i$ B" v% |2 x
    * i# I) \) n& U" R3 d! f; t9 Ftemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()4 s  a: s4 E2 a  [2 W* w
    {
    8 R: T" x* \/ Z$ q# L6 l) e    stack<int> s;$ Y6 g; W6 s! n4 y
        int p,cur,pre;: p6 {1 _8 u$ u. t  ^- }, d
        //MultiAdjListNetworkArc<WeightType> *p,*q;
    & o, G# O6 k7 R# q; t! f+ K    for(int i=0; i<vexNum; i++) tag=0;//初始化9 I* H7 D2 i- l, C' u8 F
      a; u7 k. h* j; I
        for(int i=0; i<vexNum; i++)
    ; P  `! C4 _. y. T  y    {
    8 r! ^3 T) u' Q" b3 Z6 D$ e        cur=i;pre=-1;& r# d% s+ V. v' Y7 d' z
            while(tag[cur]==0||!s.empty())
    % s( I) Q# }2 {: G        {
    % e2 U  ?5 u# `; Q! l9 q; `* O            while(tag[cur]==0)
    " S3 q# J$ U" n. r' E- y            {
    # H& |+ @1 Q+ G1 g                cout<<vexTable[cur].data<<"  ";5 H! k5 s* U9 j% _$ m1 y( t" Y  v4 _
                    s.push(cur);
    ; b. Y$ J9 S7 T( W: q. Z. K6 ?; D                tag[cur]=1;
    7 B% l8 G9 S1 g% \4 ]               //初次访问,标记入栈
    ) g$ E: q; D3 @2 q* D: T4 g: c5 D: N6 e$ k' J
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点- M% E5 g6 v2 D8 ?9 Q
                   if(p==-1)7 I; s8 R* c8 z0 p% E) j- Z- b$ T
                   {7 y3 C4 j: J% x$ }  _( a" t
                       pre=cur;s.pop();1 [* D# z  H$ x
                       break;' V0 N8 o; k  x8 f4 ~
                   }" Y/ O! q  f" T% @
                   else
    7 O0 b$ L+ V# r0 h' q+ y               {. v; K9 {( W2 S8 u+ L8 F; ^
                       pre=cur;
    / m. H: q; Z+ u$ y% m                   cur=p;! ^% _8 I# H, [
                   }; \% s9 r% a4 q

    " m7 {, o) q6 B# {( \( Y            }
    & @6 T7 S1 v6 A8 a8 G            while(!s.empty())# g0 y; k& z$ ^9 _( h
                {7 a3 n% j: l4 o$ e
                    cur=s.top();
    5 F8 T- {( D0 q; U$ ^                p=GetAdjVex(cur,pre);' U& l) A: V6 N! }$ B
                    if(tag[p]==0)1 n7 ?8 S/ D3 Y1 \
                    {' ?, s, q3 R- P# M
                        pre=cur;
    ! g) ~$ `) Q+ c2 s$ g  y- b                    cur=p;$ v4 ?, d7 g1 ~: }2 [0 ?
                        break;
    # I4 ?" k- {$ m, u% N( E+ z3 w                }% ]7 }4 f* T# O; ^1 z2 J
                    else
      c3 y/ Y& `4 ^3 P                {. F4 ?! N5 _  J: H8 P2 a
                        pre=s.top();
    4 C" W7 f; q! a  V5 P6 G: h                    s.pop();" P$ F; H% `$ b1 I- l
                    }6 y8 H4 q% |0 e  u, _( w: i% g

    6 s1 Q' [, R+ z4 _1 h            }
    5 V' B* y- t. N! Y% z# I4 V; R& d6 X1 t% n+ t- o
            }" S4 [. g3 O" M4 K1 l6 D0 U  ]
        }, Y& P; o* [0 S+ I* F
    }. R7 F0 }, t! x& a8 @7 }
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    8 C2 t* O: {( u% \: z! C{
    * j( U6 v' \. c: a9 @# f. d    for(int i=0; i<vexNum; i++); T! y; D/ U4 T- V/ v: L$ k
            tag=0;0 d! i# P2 m# Q, q: U
        queue<int> q;
    , I# M& a3 H1 {4 J, I2 }    int tmp,t;
    % \$ [: ]! L( h* C6 l    MultiAdjListNetworkArc<WeightType> *p;3 Q4 y( D9 n6 v- [' O
        for(int i=0; i<vexNum; i++): [0 }# m- e2 K, }& A" \2 T
        {3 {4 }3 w$ o* j; M/ ^. z  @" P8 P
            if(tag==0)4 s. M& W* m- ~; c, J  R
            {
    ' G* ~3 b- F$ e$ k            tag=1;
    7 L- q% G5 I# _' D( M* Y            q.push(i);, e2 B& `9 v+ H$ S8 q6 y
                cout<<setw(3)<<vexTable.data;4 G1 ]( }3 l; r( B- q: |
            }# @, H5 \3 n% I. ^4 [' B3 w6 t+ x# p. W
            while(!q.empty())* P" c- x0 k( L+ e4 X" X8 E
            {
    4 l; A% s- S1 i  e8 e6 I            tmp=q.front();
    " f7 S: v/ ?2 r, F6 p+ Q            q.pop();! b6 O! r# Y) J9 T
                p=vexTable[tmp].firstarc;5 l; c% h0 C: |9 G
                while(p!=NULL); s  H7 _& ?; N: `  i
                {& K1 t/ d/ T$ j/ s2 u' l) Y
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);0 t7 e8 w8 l& \1 E3 B, y
                    if(tag[t]==0)
    ( ~* @7 X4 r5 u$ x* D' A                {3 v6 \5 G( K( d( [+ M* b
                        cout<<setw(3)<<vexTable[t].data;7 T" G) }0 [, Y# L2 m6 ^/ s
                        tag[t]=1;
    , T# r9 @+ G) k, A/ a  q0 |( Q% p; N) O                    q.push(t);
    ) U% e) n4 E  G                }
    : a+ i- t4 V) |9 ]2 ^8 t+ V; M# @$ k                p=NextArc(tmp,p);
    # D' ?2 X, `. ~8 _; f            }
    ( O" t5 d  I! ^& x) ]6 z' m! G        }
    - i1 a$ u$ G7 {" f- k    }
    % [' U9 z( d/ V, E; o; {( u}
    9 [' q7 j$ r; F! K/ m+ P, |3 ktemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()1 M1 _* D( P* b7 s
    {3 w2 R; i$ U* `6 @9 |
        MultiAdjListNetworkArc<WeightType> *p;. {4 d' p& t$ f# z% c, w0 {4 Y
        cout << "无向图有" << vexNum << "个点,分别为:";. w- o: }) h% X# J4 K' t
        for (int i = 0; i < vexNum; i++)  M/ c: y) h) R/ h9 W8 }7 j6 _, {
            cout << vexTable.data << " ";8 A/ _/ u) h+ P7 s# M: `
        cout << endl;: K) S9 M8 q0 c' P/ i
        cout << "无向图有" << arcNum << "条边"<<endl;
    3 u! y8 c$ a, t* y5 M  f' P    for (int i = 0; i < vexNum; i++): o; W$ q* n2 h% }
        {! [$ [$ T9 x' ]: _' ^2 I8 ~1 o
            cout<<"和" << vexTable.data << "有关的边:";
    6 S% T+ i7 h& o        p = vexTable.firstarc;& }5 o! A9 f7 x! F/ a6 m' W3 ^
            while (p != NULL)
    5 O2 X  N+ ~. q: E' G5 o$ J. f        {# \$ B4 }5 }6 S! o7 w2 ^3 V' d
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";. m/ @$ E3 w4 ]8 b3 c
                p=NextArc(i,p);
    0 E3 ?6 K4 X& d& a        }
    3 C4 m$ `' |9 B( O) r0 O) T9 ^1 h        cout << endl;
    0 m6 [1 @" o. J* s4 r    }6 Q3 W2 Z" A" `; _" {
    }) w! R* ^! B, x0 ^; q" {8 s' |
    1 x( X# r: X% H5 q

    : l5 U+ V+ x2 _4 N0 M邻接多重表与邻接表的对比6 H" `" _9 F6 g+ r% x; a5 W# Y

    " R: [! C% H$ `; }, E邻接表链接3 G. Y% j6 B* O# E5 H3 v
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    7 o. \, y0 ]8 o6 j6 a. r; z在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。5 o$ l% \# c8 `& e0 R4 g
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
      a2 n2 T! K; K6 y& f% q————————————————
    ' t" [/ C, ^8 Y& a- T# C0 f7 ^版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。% s) {# ?3 L. s1 B: T) w" R. X
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    $ Q7 z6 {* Q% r# B6 D  s( I
    % {  p5 s6 ~2 o9 `6 A0 c! V$ R. ~$ g; D% X6 T0 q

    " A) I$ T* L' F' U0 K- V+ G$ y* Y0 C+ c0 _  N9 |
    ————————————————# A8 m) c( C  a! n* `# O
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。+ p9 w2 o# u% |
    原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669584 P1 S7 E5 @: I% w- ]5 b& X, V

    . A$ `" Q6 d! K5 @0 U3 y
    1 p. ~  Y' D- U1 u! r
    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-10 04:29 , Processed in 0.340187 second(s), 54 queries .

    回顶部