QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1658|回复: 0
打印 上一主题 下一主题

图的存储结构——邻接多重表(多重邻接表)的实现

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2020-4-26 15:26 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    3 G/ P; P5 s$ C6 ?
    图的存储结构——邻接多重表(多重邻接表)的实现
    $ r- w; [5 c# l( ?7.2 图的存储结构
    5 e; ~/ m9 o/ Y$ o7 F8 e! C
    % U7 \3 s6 L- B1 c% s7.2.3 邻接多重表(多重邻接表)Adjacency Multilist' |7 Y$ G; ]+ p$ v$ ^6 G4 d; X8 I
    邻接多重表的类定义
    $ A# z  B, k( l# q% o% J2 U( K邻接多重表的顶点结点类模板" y8 R  {: h  t+ A) o
    邻接多重表的边结点类模板0 e8 E/ i( U1 _6 ]
    邻接多重表的类模板
    9 H+ }3 D' l* t邻接多重表与邻接表的对比% |, E! _; y+ C9 i: x
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist5 G$ A) m$ y! @" G! l* l. q

    ( x2 ?6 p6 G4 w+ P7 O/ I在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。. k+ P5 j8 n3 a" k4 s
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    6 E3 s& `- V& z  D/ B  E* p/ J, c5 C: M
    邻接多重表的类定义% r- x% k# K3 ]* N4 S
    1.png
    . X: ~2 g$ B7 }邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    5 t' x- ^# k1 Kdata域存储有关顶点的信息;' t' D& S( V/ `7 P) g3 `8 f- f
    firstarc域是链接指针,指向第一条依附于该顶点的边。
    2 [9 b8 m  i3 F0 G* W9 A# u, P所有的顶点结点组成一个顺序表。


      y* I+ c' L  j" K9 q& e4 u3 [2 J/ a- c; k( W- q4 q
    template <class ElemType ,class WeightType>
    5 m* N! n4 A  {/ l: Eclass MultiAdjListNetworkVex
    ( g1 R. Z( r: \' \2 I% b& s0 a" {{' v2 V, V1 `1 y3 [7 H7 H& k
    public:
    9 f3 H+ T# |2 `; N        ElemType data;+ y2 N; m; g9 `/ a  A# O& z
            MultiAdjListNetworkArc<WeightType> *firstarc;
    4 J4 f3 P* s1 q; P+ a  |5 g  I8 D, q9 G( N
            MultiAdjListNetworkVex()
    4 j4 F, w+ \4 [; Q% G7 v3 j# c- |        {- U7 k2 K7 Z+ V. C4 g# \5 N
                    firstarc = NULL;* ]2 k/ Y1 s0 i$ Z3 v. D- j# l( n
            }0 b& [0 o! o1 C0 n/ K
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)8 m4 u+ j8 m$ S; {1 C
            {
    8 j1 K% Z- i% X  U1 C8 h7 b- [, a                data = val;% C3 ]. _% ^" F2 t/ R  l
                    firstarc = adj;4 W/ _2 z1 s4 D- C6 r, B6 d8 S
            }
    % t: F2 h3 [! `& {5 D};
    . Z3 B0 Q; P" D4 r, D7 S0 h, D5 O7 L  j
    邻接多重表的边结点类模板
    % ]" I0 d/ d0 C3 E) }! ]9 Y) o
    0 L* Q$ d8 m* h: [6 R* p在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
      y4 G+ ?9 g2 [9 Y7 F6 ytag是标记域,标记该边是否被处理或被搜索过;4 w6 D: f6 y1 g. v
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    8 U9 x7 X6 y1 Y3 j8 Q6 o, |nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;. ]2 n5 y0 t/ |1 H7 i3 |
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。1 e* ]: G+ j: z! Y. U, x

    ' b+ o+ X. K! A" q+ I 2.png
    / R& Z; h- p, r: dtemplate <class WeightType>! F" R" N% w  V4 s
    class MultiAdjListNetworkArc
    1 T7 j' k, |/ V( o; G{
    9 l9 e4 i( Q  N" {6 ~1 j) _0 mpublic:
      s: N  f, e% r$ k    int mark;                                       //标记该边是否被搜索或处理过& e. v8 Q% j) m1 b- E2 }0 R. n
            WeightType weight;                              //边的权重
    ' H4 g7 p, k# J4 z) h2 p        int adjVex1;                                    //边的一个顶点
    4 b! c) k- e4 [) m' q, O, c4 P        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    9 r" ^0 M- d9 E1 L" I) v        int adjVex2;
      p: T- w  i" s) s, k/ H        MultiAdjListNetworkArc<WeightType>* nextarc2;! O& w( l' W/ r9 e+ {" d  q

    % F" ?0 \1 ]. u  V  ?/ b9 r        MultiAdjListNetworkArc()- v3 f- |/ A2 ~* g
            {
    5 D* T- E" {/ H2 F& n7 D                adjVex1= -1;
    , m; U1 o6 O; t8 y$ _) w                adjVex2= -1;4 G: |0 l5 `4 |7 v" l
            }
    - T  R% N& e: v* ]) F/ j        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    9 \( A( H3 n; K7 B        {
    * r/ j' O$ a- ~* |                adjVex1 = v1;       adjVex2 = v2;
    4 a) j+ H3 d5 [                weight = w;9 ~: }" b, d" n8 }! ]" m
                    nextarc1 = next1;   nextarc2=next2;% N- j4 S7 w2 x( O" J9 |
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    # x: L9 s. {8 W7 Z1 P  ^3 I  C        }3 T  m' ?; ^! r8 R) a. d7 z

    + \9 k( I: W" q; u9 T6 v7 j& }邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    0 n4 J) c1 F( M; f& Pclass MultiAdjListNetwork
    ) X5 P, c5 R* R9 i2 A- p% |{
    $ B2 _! j9 Y8 d( `protected:
    ; p0 z  [* l; P1 n+ _    int vexNum, vexMaxNum, arcNum;
    $ W( o0 o  H, q9 h# U, A* z    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;$ `+ |" J7 e& e3 N
        int* tag;
    & ~6 j  |2 C5 E, P% E! O    WeightType infinity;, v$ Z) H1 n9 ]  e9 ~) y
    % [5 S- ]' S: R5 Q( S0 m
    public:
    + e' M* e% ^$ t+ {; v% c    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    ( K2 R4 f9 c$ A  B3 F3 x  {8 j7 U0 l  J, B' f6 S% t( F4 {
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);) b; ^7 u+ V. ~! N
    " ?0 p5 p2 p1 m
        void Clear();/ s7 U% b: q' n" a. b
        bool IsEmpty()+ f: y# Y6 d7 y  J* Y
        {. G1 {1 }' c$ n* z" U- F( s. M3 T
            return vexNum == 0;
    * z2 r- g. _, K4 B' M3 p9 [/ [" U    }
    8 f' E/ Z( s$ w. f    int GetArcNum()const
      H0 X7 q! q; F    {# l% ?( G- Q9 B
            return arcNum;7 I* E" y7 ^$ o# e
        }% G; w4 c( o! r9 k$ {- S% f
        int GetvexNum()const8 ]' d* G; j& N5 C: V
        {( j5 c+ S; p" e7 f
            return vexNum;- X8 _# {1 s! j3 O8 J
        }  v2 D: Y/ c' w

    + y! w- g. ~' i
    * o# l# X+ @. ~! s    int FirstAdjVex(int v)const;
    & d- l8 ?4 q0 M. N; l  S    int NextAdjVex(int v1, int v2)const;; H% c  G8 T7 K
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;" J3 b- ?4 I) d' s9 |4 [
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    3 l9 i: F2 G. v& t& c- }6 d/ k
    $ e, z/ Q: I6 E/ j- n    void InsertVex(const ElemType& d);
    ( f' h1 I9 ~5 ~7 ^" A    void InsertArc(int v1, int v2, WeightType w);
    9 d* n* \& ?9 e; L2 n0 I
    9 m( N3 y: H# d* M# E0 K4 I    void DeleteVex(const ElemType& d);) \% J7 G9 T9 Q& }0 W- S  E3 O  Y
        void DeleteArc(int v1, int v2);
    ; \) w- _5 G8 \, d/ M. @/ B$ c$ t
    ) ]3 W0 v7 }6 H; N    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    , L2 q! ?* \" y* u! `) l8 q2 Q  ~    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);& H# {3 g. Q/ u) y1 ^5 J, J

    , K& \5 L3 C0 o6 i  v' W( r    ///深度优先遍历* P- Y* m3 ]+ Z3 P+ A1 l
        void DFS1(const int v);
      _+ P7 I4 R8 l1 J, N& b    void DFS1Traverse();
      @% e4 @7 I% Q8 N+ @1 d$ `    void DFS2();
    2 {5 c% J9 y2 l  n
    1 F6 Y; Q1 _8 ^3 N    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-12 N; Q4 x3 y) g/ a8 }6 T
        void DFS3();7 r: s/ s2 N+ a& R8 f2 C  V

    * o+ g5 S" f# C" d+ G8 z    void BFS();
    9 M/ y5 ^4 e! L/ O/ o% _! Z; W    void Show();
    7 K  t/ `: G* W1 h5 h1 X' @. z; U) c0 P};
    3 {" e% j5 N; ~8 H. A& j/ ?+ ?3 c; p( H: u6 m+ E3 E8 y* F9 K
    2.函数的实现
    . r, Q2 F; L7 j6 h研讨题,能够运行,但是代码不一定是最优的。
    3 K* G' b* ~' V% m; }- z0 \1 R& P. S! K% j6 ^( j5 o5 O
    #include <stack>" k/ _5 \2 E; j& m4 i* I) c
    #include <queue>6 W- ?0 @) o" ^. h5 U' D( A% r
    3 L* \  Q: b* H0 O; m
    template <class ElemType,class WeightType>
    : ]9 t* _! H, _7 F% s* M1 uMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    1 V* K1 w7 L7 C! k{
    7 S+ ^5 z* Y2 X% h# a, v    if(vertexMaxNum < 0); F% \& y; G3 M9 W
            throw Error("允许的顶点最大数目不能为负!");
    6 W1 Y0 J0 c3 L- m5 o    if (vertexMaxNum < vertexNum): h- ]9 B9 U$ o4 c
            throw Error("顶点数目不能大于允许的顶点最大数目!");( \7 h. u9 p6 |- n. N! a  `0 D
        vexNum = vertexNum;
    * d0 ~: m: T, H3 t0 q& j    vexMaxNum = vertexMaxNum;# S5 [: L5 N# \. b7 S! D
        arcNum = 0;" j- E% Y9 p$ {  _+ E) ?
        infinity = infinit;
    : w8 e" [- t( `    tag = new int[vexMaxNum];
    3 B2 J4 C- y( S6 B) W    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];5 A) N, A* a; P. [- X: G
        for (int v = 0; v < vexNum; v++)" _& N+ Q  c! V- ]0 m0 P+ _
        {: Y/ z* g/ W# z: {8 u! M# f8 o6 m
            tag[v] = 0;  }% ]1 D# y! y5 ?
            vexTable[v].data = es[v];
    * X0 S' O; Y$ i5 s& j8 [* p        vexTable[v].firstarc = NULL;! m: o4 L# d- b/ }: [0 F! x
        }
    # s/ l' n4 y" B# ]}
    + ]& c! l7 z6 o8 l4 K& Ztemplate <class ElemType,class WeightType>
    % z% _" P) W' z6 C2 kMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)( O/ {+ _9 u, Q5 S( D
    {
    ' a: o7 z1 T( \    if (vertexMaxNum < 0)
    - j7 \1 G# j- c" q        throw Error("允许的顶点最大数目不能为负!");
    ( G2 f0 D6 r$ |* s    vexNum = 0;9 L1 a. K" e# H
        vexMaxNum = vertexMaxNum;/ ~4 |* n' O! m: b
        arcNum = 0;
    - A5 A$ \8 w( ^3 X- e: t    infinity = infinit;- H& O- F" E% r" D. P
        tag = new int[vexMaxNum];
    9 f7 {; z: I% c# J% J    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    , \& D+ U# i6 m7 n& ^7 H}
    8 J* @0 s* ^- v9 r! c9 o" ttemplate<class ElemType, class WeightType>1 N0 k: A  e! N, S* ]
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    7 i9 V% W/ l" s3 N& X  v9 Q{4 R% c0 i; V: F
        if (v < 0 || v >= vexNum)' F1 C! u! @$ T  R* Y; d
            throw Error("v不合法!");( s5 r  `$ }# Z: D
        if (vexTable[v].firstarc == NULL); K( F# j$ ~; O/ ~
            return -1;
    9 y/ B$ N9 n" v, d    else% y" ^% {2 d) v; n
            return vexTable[v].firstarc->adjVex1;: U8 o. {; s8 G$ |9 q+ z) G* i% Z
    }5 `: M" x& n7 f3 d

    1 \# J/ P/ |  o, w6 T/ s( s/ K9 Stemplate<class ElemType, class WeightType>
    2 D+ X9 w' Q0 e! h- J) t4 M9 }int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    0 r2 ]3 E5 L' I3 W{
    4 `% c0 B; I( [* n& ~    MultiAdjListNetworkArc<WeightType>* p;6 E9 B( l6 m8 c
        if (v1 < 0 || v1 >= vexNum)
    / v" e9 Q8 S8 a$ {. p        throw Error("v1不合法!");7 R) [  `# P7 d* z& \
        if (v2 < 0 || v2 >= vexNum)
    . a9 y: u3 A3 Y% N& f        throw Error("v2不合法!");
    ( m& F5 o$ @: ?" B1 N    if (v1 == v2)& x; z8 W. j$ f
            throw Error("v1不能等于v2!");
    # k% }* ~1 g, T- W" O4 u    p = vexTable[v1].firstarc;
      u# l, ^' L1 ^    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)) S( U" w# x% J7 @( ]& y; D
            p = p->nextarc;
    , B1 x  K) x: g; ?. Y7 U! N4 X! E5 H    if (p == NULL || p->nextarc == NULL)
    / r& {9 g! |8 Y# i" p- x# {. F        return -1;  //不存在下一个邻接点
    ; z( z; C; D8 v# o4 [3 |    else if(p->adjVex1==v2)
    1 S& L% P; i5 V) v  B& z        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    + \" z8 a+ q5 X2 P( @  m2 }    else  q/ g, t" d$ V3 {" ?$ a
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    : y% V+ e$ ?. _( a# d}( `; I( E3 \$ y; |
    template<class ElemType, class WeightType>
    ( l( {5 E( U- W+ y" Q# O3 rvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()* o+ R7 z7 N6 O6 v/ P
    {
    0 A* m* z. [* E' H7 F2 h# P    if (IsEmpty()) return;" k, H  t* K) H& o. D
        int n = vexNum;) _8 u( d4 _, b3 N+ J% }
        for (int u = 0; u < n ; u++)
    3 l# v. X' I6 F# d        DeleteVex(vexTable[0].data);# U% q4 _7 E. B' F" l9 a' S% k
        return;
    0 i3 ?* s' d! I9 j}
    ! O  A( Q) q! V* A( r% K8 |template<class ElemType, class WeightType>
    + ~: N) [3 m2 {0 w2 S9 dMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()( C" s6 ?& ~  r) B+ x- H& o; n7 D
    {. h% }1 m: Z  p" ^2 s* X
        Clear();5 }. L! K5 m2 o' X7 I
    }- c; ^$ N% B5 g: a2 }1 ?9 |
    template<class ElemType, class WeightType>; @* p. R" F5 h4 M- D/ `, m, Z
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)0 r9 I& P4 j+ A
    {
    % }0 u% k5 G, b. \2 {1 @3 n2 |    vexMaxNum = copy.vexMaxNum;
    # J# k9 F8 \5 P6 F' R; ]1 H7 O% l    vexNum = copy.vexNum;' w7 T6 A5 Y+ p( N- h$ V% f3 B
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    ) h0 d& F* P, R4 h  K    arcNum = 0;
    # |& x* Q9 p$ U    infinity = copy.infinity;
    4 `: r- ?4 B9 D. x    tag = new int[vexMaxNum];
    ) M; k  A, n! f4 Z4 I1 q% X8 R
    ! S9 O2 M5 K" Z! V: K( @5 e7 x" Z    for (int v = 0; v < vexNum; v++)8 m/ y* t/ Q3 q, q
        {' m2 V& M3 x/ C  A, T' s" r
            tag[v] = 0;9 M* u3 q0 C9 W5 l6 G3 N5 ?
            vexTable[v].data = copy.vexTable[v].data;
    - g' G; u( A% o- n        vexTable[v].firstarc = NULL;$ c% x$ `$ t5 n( d7 i4 a; w2 c
        }, w$ b& L# z  X1 O- [+ c9 d
        MultiAdjListNetworkArc<WeightType>* p;
    , R7 l4 q8 A/ i0 k% e" j" s9 _' u/ E$ Z1 o7 V, {, ^8 g/ w% T
        for (int u = 0; u < vexNum; u++): B, |, V5 J- t" f" ^; f$ h4 Y* G1 a
        {
    , t( c( Y; p( ?8 A        p = copy.vexTable.firstarc;/ y7 {6 c) I( [
            while (p != NULL)
    ; B- L+ Z( q1 y6 @        {, o. ?- u/ ^% [. W1 \0 Z
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    9 ]7 Q, @  A+ N$ K1 x, G2 G            p=NextArc(u,p);# F) `( Q8 r5 m( _$ W( ?
            }
    4 U- \4 n# E) W7 L5 Z    }
    2 F' b" R5 C& k' Z  s* K: [}( C4 \* i* |! w  v$ i( u% e+ L
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    + ~8 T+ p  Q% Q4 B5 W, mMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy); }) [3 D8 F$ k! W+ P4 L- O
    {
    ! t2 |" L$ H( ?    if (this == &copy) return *this;
    ( [8 z# q3 @3 M. Z+ t% i9 V, ^    Clear();6 k4 _" }$ z; W, v
        vexMaxNum = copy.vexMaxNum;6 l" N8 }: P4 o1 g4 s" U5 n0 J
        vexNum = copy.vexNum;0 q3 V9 C1 h3 S
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];1 t) i) j/ B' @
        arcNum = 0;
    . P' \$ h! d: K. z    infinity = copy.infinity;
    7 V  [3 C6 `  ~, t/ G, F7 D    tag = new int[vexMaxNum];: \* c9 t1 ?4 G( F) N

    0 Y: \5 H0 ?3 ]1 `3 l& P! E    for (int v = 0; v < vexNum; v++)
    ! X2 f+ E8 p" X4 Z5 \% q& n! F2 q! ]    {! \% q) n8 J- v/ C4 P& I
            tag[v] = 0;
    ! v+ {7 K1 D* `% @) m. [* r9 }2 ]$ K; W  L        vexTable[v].data = copy.vexTable[v].data;( O- p" `* ?" R1 k9 v/ S& W
            vexTable[v].firstarc = NULL;/ }0 Q: W, o4 A2 m% ^  D
        }
    " Y& W% }* D  x& \    MultiAdjListNetworkArc<WeightType>* p;
    $ n8 t5 o" X+ p1 {; O$ ~
    ( b4 b1 T) }; k/ x' y    for (int u = 0; u < vexNum; u++)
    0 W- Y$ L" d8 Y- n& q9 _    {8 E+ f; d, W9 m% h9 k
            p = copy.vexTable.firstarc;
    & _/ u) Y7 P( j* H1 n- m' \        while (p != NULL)
    * b( _! I7 W: S' M/ l        {# p( J, n; F. e; j0 y5 g
                InsertArc(p->adjVex1, p->adjVex2, p->weight);' {2 _4 G0 T  N3 F+ m
                p=NextArc(u,p);/ U! Q5 ?/ b- {! M7 u1 l7 w0 U$ W# {
            }. }) _: b' H9 x- |1 w( ~$ j  E
        }
    * L1 Q7 [4 W: T    return *this;
    ) }4 P4 x# z2 j0 ^' a7 @}
    * I" Z+ {5 v+ W2 Z  btemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    6 L5 S0 h( V* }MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    , R( r) z, [+ V( ~{
    / b2 x/ ^" N0 R8 }2 ~4 V) N' G    if(p==NULL) return NULL;
    4 ^  _0 J8 Q1 D$ v5 I    if(p->adjVex1==v1)
    ; S, F9 _! d8 i5 S        return p->nextarc1;' y2 d( h. {+ y
        else3 f+ j) u; I+ N: ^3 T; T2 s# c
            return p->nextarc2;
    " r5 ]$ [4 r, m! h+ c# e; Y}/ L) \: I' u8 n/ o
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    ( O$ f) S  U* K. q: b* iMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const/ E0 k/ i4 T. o  T
    {: [7 b/ S) R$ y- Y$ z: g0 A
        if(p==NULL)return NULL;. G. e/ A( I; s2 Y; \
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    ! s7 W9 [2 n1 Z* I/ }1 W    if(q==p)4 N; r. Y6 k: `) r
            return NULL;( J4 X* U5 E" }) t! Z0 y
        while(q)* g: s+ V( X" U+ Y. u
        {
    1 R* t9 K% j- r( \& n! Z        if(q->nextarc1==p ||q->nextarc2==p)
    6 C* P& [& x' a; |2 K9 A            break;
    5 y! X, U+ @+ D& \9 B% G- h" u1 L( ?        q=NextArc(v1,q);& G# H# G* P( v
        }  h% O! c! ~- x0 q  O0 H
        return q;; V. P: V1 F' ^3 h# j/ @" ~
    }5 {3 X1 q" L; }6 h$ h; H
    template<class ElemType, class WeightType>
    4 P5 Z+ @7 f. U( Mvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    7 h* {/ o7 j( S7 R3 j{
    . |2 q! w/ o3 _    if (vexNum == vexMaxNum)/ s/ M% A7 t* S, y9 S
            throw Error("图的顶点数不能超过允许的最大数!");
    ) k: O8 h; Y8 I0 i    vexTable[vexNum].data = d;: N3 s: m; v/ j
        vexTable[vexNum].firstarc = NULL;3 j/ w+ b# p% G  W: E5 X
        tag[vexNum] = 0;
    " h, N" v9 p" p# a1 p! J% P1 k    vexNum++;
    & H5 E% Q* I& U* _( ^9 y8 q7 I}
    ' p4 u- T" `4 b) ztemplate<class ElemType, class WeightType>
    , _# G( D/ R( f. o7 {void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)0 ~6 i" U2 W9 |( M- a. g
    {
    9 ?8 x* x9 G, D* C7 E    MultiAdjListNetworkArc<WeightType>* p,*q;7 ^5 a; A; c3 ^, e
        if (v1 < 0 || v1 >= vexNum)
    8 Y1 V/ ^3 d% q' Y) B9 O! B) R        throw Error("v1不合法!");
    6 U: O3 ?! {0 y$ I8 |# Z    if (v2 < 0 || v2 >= vexNum)
    2 m! s6 A4 o+ V- f% K4 ^  w  `: X# I        throw Error("v2不合法!");8 J) b4 q4 P0 T- z# Z0 d3 d' T% U
        if (v1 == v2)
    ) n+ B" p/ c! B3 G        throw Error("v1不能等于v2!");4 [: o0 a3 \) g4 S2 H$ ^. e) z! S
        if (w == infinity)
    ' ]  N+ U2 H8 H1 h* O  K) e        throw Error("w不能为无穷大!");3 n0 L+ K8 O  M$ V! k/ e

    + R! _& o! w/ F! ?8 z
    2 I2 b5 K2 W& y: x& Y  G! \" _    p = vexTable[v1].firstarc;6 W; p/ {2 O4 e- I
        while(p); c! `8 ~! e- ~# y5 z! C
        {9 ?$ _+ z3 I6 |% b6 _  o
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    . z5 I4 |5 B0 ~8 P' z! k        {
    " Q, M, a$ ?+ ]6 M; f            if(p->weight!=w)9 _1 P; h, p, N3 i  r0 V
                    p->weight=w;9 x% T& e3 e  F' A
                return;" y4 E& i- T" A9 ^# c
            }
    / Y5 H! m: J0 Z2 n1 ^
    5 q6 U% @' E: U. L5 I4 i3 o        p=NextArc(v1,p);
    , {& c5 j( E& S3 }/ K3 m    }
    6 N" [. ?' ~- H) B. c( c# w% b    p = vexTable[v1].firstarc;) Y4 f/ `* N/ n4 o$ n) W* [5 G
        q = vexTable[v2].firstarc;
    ! _& _3 V% i3 Q; |8 k5 s/ H  g    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    ) e' o) Y# R; O1 \9 K; Z# }, M    vexTable[v2].firstarc =vexTable[v1].firstarc;/ k. N9 J; J5 l. y, h  @$ q
        arcNum++;
    , Q+ z, l# T  Q  _( l}9 T7 d$ [+ H( ^- S3 u9 z) r0 x! y
    ; m6 y8 `8 t" J3 U3 t8 L, E2 K$ c" t8 s
    template<class ElemType, class WeightType>% p* j, d% u3 |. a( L6 I+ c
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)) c$ X+ Q( K0 J9 N  F& ?7 w
    {
    5 Z& J9 X$ V2 K! w5 V/ j0 W' z- L$ J5 q. r- O+ h9 {
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;# i7 N# d1 ^+ N) k, |; P8 C* e) Y
        if (v1 < 0 || v1 >= vexNum)
    ) Q& c& o* z+ v  y5 @/ V        throw Error("v1不合法!");
    0 r) V( W3 z7 T4 a" p+ g    if (v2 < 0 || v2 >= vexNum)
    7 e0 T5 ~5 y+ W- f' n- g/ y        throw Error("v2不合法!");
    ' P6 ~' F0 Q6 T; O2 m+ A$ C  `    if (v1 == v2)
    ! X; h- o+ a5 `1 B8 T2 n        throw Error("v1不能等于v2!");5 u2 z4 @* y$ U/ T' [

    & Z+ v! V: ]& Q8 K$ w    p = vexTable[v1].firstarc;" x' F. X, P3 f2 R( X5 j! R
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)+ w$ I. C) L8 B+ O$ f% [, [) F
        {9 h$ g% W1 e! R2 Q. c
            q = p;, m3 ~$ p+ r. s! V
            p = NextArc(v1,p);" C# E1 Q. R1 f
        }//找到要删除的边结点p及其前一结点q7 Y" A, R% L, F

    9 A4 I" C  A+ f0 R2 w* i    if (p != NULL)//找到v1-v2的边
    1 x4 f$ Q" x  p3 u  h, p2 K    {
    7 y! H, @* p" P, ~; T" b! F) ~2 t* }        r=LastArc(v2,p);
    7 r! ]! K* r7 I1 U. i        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    : d  [8 V4 [! ?8 h            if(p->adjVex2==v2)
    ) F  P- c9 z2 s( H                vexTable[v1].firstarc = p->nextarc1;& |  E( B! E* @/ G3 u2 L  h
                else vexTable[v1].firstarc=p->nextarc2;+ e! I0 @/ H$ y- C- q4 n
            else//不是第一条边5 j5 g3 `+ ^5 v8 s
            {
    $ E- g3 s- ^$ X; k* _5 C6 ]; T5 [            if(q->adjVex1==v1)
    ( v! a7 D# L! t" I7 ~                q->nextarc1 = NextArc(v1,p);
    ; o! I, v  ?: E& |6 F# E- L, I+ d, j- f            else
    " o$ ^5 a6 m1 v% A                q->nextarc2=NextArc(v1,p);# `; U% L- S7 n0 M& Q/ O7 n2 y

    4 N" N; s( i& ^' ~4 w) V5 |        }$ {4 L/ }9 L- g, |) }
            if(r==NULL)
    1 h- r4 \7 `* O# O            if(p->adjVex2==v2)
    ; M1 g+ ]. A" j                vexTable[v2].firstarc = p->nextarc2;. D  x, y& c5 h9 y0 R
                else vexTable[v2].firstarc=p->nextarc1;, ~! {1 w+ h) d/ m; c
            else
    - K8 I' d$ O; }: X        {$ a; Z9 E- c# I" g
                if(r->adjVex2==v2)- |5 Q7 U- ?; i
                    r->nextarc2 = NextArc(v2,p);
    5 i1 z- v& A5 e! l            else' }. K& `6 e) U( I& f6 p5 w) ]
                    r->nextarc1=NextArc(v2,p);
    : A% A5 z% [$ ]4 _/ `1 z6 B2 c. f9 o: W        }
      f! e0 b' A! q& ]# K        delete p;) U$ @+ A; a" `0 m
            arcNum--;
    & \- H3 ~- [1 Z3 C' z$ |; a8 ~    }! _: D* L4 X" h" P& Q2 E) f3 h* E
    7 w$ i  O4 F+ R6 p. J# V% j; Y
    }5 \2 W7 F% v8 H
    template<class ElemType, class WeightType> void" ?' l; ^, p3 j
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)/ H6 u, e# x, t- j. ]& O7 q
    {7 E) B- B( E) O
        int v;. _; C' E5 X& i5 [0 }
        MultiAdjListNetworkArc<WeightType>* p;/ Q. ]8 N7 z( z7 v; y% e3 _7 r
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    9 M" z6 g' p6 K) q  Q; t2 F        if (vexTable[v].data == d)& F4 R( n( c' l8 E  r* J
                break;
    & o% B4 u3 u9 P' {4 d( o    if(v==vexNum)
    . o* ?$ e9 q. h7 Z/ G% |        throw Error("图中不存在要删除的顶点!");
    ; E" A' ^# U  S! b7 [! p. ^8 C) f; _
        for (int u = 0; u < vexNum; u++)//删除与d相连的边9 t5 W" I% W9 I8 [0 b6 [
            if (u != v)
    # a+ N/ n' U5 O/ z        {
    6 q( {+ \9 G0 M8 O  P/ b, D            DeleteArc(u, v);- r- P; K0 B2 s6 P( V
            }
    6 j3 V5 V  y6 F& T5 n3 n* B; A' e    vexTable[v].firstarc=NULL;
    0 x2 U4 A2 n% Y% E( o9 w
      u& i6 O% e. Z% x3 m& Y    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    4 ~) ^' Y2 M  ?; Y" j' a    vexTable[v].data = vexTable[vexNum].data;+ m0 m# @4 H: L3 M
        vexTable[v].firstarc = vexTable[vexNum].firstarc;1 w" m, C9 K. `" |- ]5 i
        vexTable[vexNum].firstarc = NULL;
    $ i5 r; s; y$ S$ C2 |    tag[v] = tag[vexNum];
    $ y' o+ N. x5 B: _    //原来与最后一个顶点相连的边改为与v相连
    ) U4 w5 Z* n- d$ M3 e: I0 `' s6 q    for (int u = 0; u < vexNum; u++)& s" e) M, p5 V# o7 d" \7 c
        {
    - b4 e2 O2 k4 s! F- |, W        if (u != v)
    4 H0 E$ A8 H% |4 b9 k        {
    3 a  Q* T0 V7 S, [            p = vexTable.firstarc;
    * W0 z* J" m: u( ?2 i            while (p)
    - N" z$ b' p# K% r8 x! _, A            {
    ) ^7 L( P) s  o( _: F" a                if (p->adjVex1==vexNum): E" K4 Y# [, J! z/ ~
                        p->adjVex1= v;- ^, k( j9 c' L7 d  n$ \. n
                    else if(p->adjVex2==vexNum)% E0 V; @8 m+ `6 u- D: S
                        p->adjVex2=v;$ m# v) j7 C, q
                    p = NextArc(u,p);$ Q2 l8 I) M3 V7 E
                }6 }/ x( s: {3 u5 a
            }! R; n* E% U! u# ]9 H/ f$ F: G
        }
    % ^* y+ R. w) b# t, J}/ W" e2 }8 v: A: W2 h1 I4 M. C
    ///深度优先遍历  ~8 Z' T7 Z! g& `
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    " `/ Q4 p3 }7 ~- |' @: b{, C) T! p% a& Z
        tag[v]=1;, K( ~- X  w' z8 {- `
        cout<<setw(3)<<vexTable[v].data;
    2 ^* A2 B* f3 F; n6 q; }) T0 F  t, H    MultiAdjListNetworkArc<WeightType> *p;
    : B! G; P( t# ]+ Z; q    p=vexTable[v].firstarc;) q$ v" v% j* U( _" D& ^
        while(p)
      H* B6 F7 ]! q  f3 F- j    {
    ' G  J9 P+ g9 s' r  d% @6 h        if(tag[p->adjVex1]==0)" H* C* s/ p5 |: {5 _5 G
                DFS1(p->adjVex1);7 D4 p+ I) s, T5 }7 [- [& h7 Y
            else if(tag[p->adjVex2]==0)7 I9 b. A! R5 B* ]& _( r
                DFS1(p->adjVex2);
    ) ?9 j3 k/ N2 @        p=NextArc(v,p);
    5 S, a4 ]* c, z& @    }* v8 t8 j& Q, x7 ]4 L
    }" l$ O5 k# _1 K
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    ; N, n& g  w; J0 b$ {7 J1 e" ?* X{
    : A3 d3 v4 R9 G8 W    for(int i=0; i<vexNum; i++)1 m: v" v) B& y/ E
            tag=0;: b; }7 n; Y4 e/ F3 r; F# p. H& Z
        for(int v=0; v<vexNum; v++)/ s  C  x& A" N0 S: b
        {
    & W* H  X" W# k) K' |/ N8 K3 C/ `6 @+ h- i        if(tag[v]==0)
    9 g* L. F" B8 i, L& @6 K            DFS1(v);
    # @0 l. Z1 G* U/ p    }7 w2 v) j( K( k6 G) V) D! V2 n  j
    }1 U2 T$ a! M7 n7 K3 |# V
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()% |( k) j( k1 x! q' I" l
    {" w  ^; o' r9 Q  K- z
        stack<int> s;; m7 X9 m  I; k: D) e6 R) j. M5 K
        int tmp;4 j0 d- a* [4 P; `  C
        MultiAdjListNetworkArc<WeightType> *p,*q;
    ! x( k2 [4 |1 i    for(int i=0; i<vexNum; i++)4 U5 F8 }3 s" d7 g% c  b
            tag=0;
      J/ ]5 @/ E6 p& H6 ^" V9 n    for(int i=0; i<vexNum; i++)7 ]2 [4 w/ d1 B1 b. B6 G+ }
        {5 l9 a" s* q2 b, C1 d! t; @3 n+ q
            tmp=i;( v( e8 t  c% Y9 |: l7 @, a
            while(tag[tmp]==0||!s.empty())" D$ F- g% o+ z9 v
            {  d/ c$ n7 k7 n' `; n3 R0 |
                p=vexTable[tmp].firstarc;: }! P- ]! d: M$ m+ D% K, A% @
                while(tag[tmp]==0)
    ! {3 J0 @2 Z( R0 Y( @1 K  P& g            {9 ?5 Z. L( f( [5 |5 e) k5 v8 E
                    s.push(tmp);
    : c0 w. I# @0 ?: e, s6 H1 Y, e5 o: ]                cout<<setw(3)<<vexTable[tmp].data;. J# K! z$ b. w$ X
                    tag[tmp]=1;
    - H8 Y; K! I  b- X7 O! k                p=vexTable[tmp].firstarc;" L- I5 e& O& O% i' ~; \7 a$ w
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for. |" A1 [( `: }3 j' `5 [
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    : V. g1 d. u+ u( k. @6 j                //cout<<" 1st     tmp="<<tmp<<endl;% _5 V/ n" M3 v, W* c1 i4 E% O
                }
    % H; M) Z/ m1 \4 F1 \            if(!s.empty())4 W$ K7 V( H$ B, T
                {
    1 }3 q& y  Y. _7 o" N6 k- {                tmp=s.top();
    ( Z8 D6 A# i& h1 U: `                s.pop();5 S1 U2 L7 W9 a8 m( I' y- i% Y
                    q=vexTable[tmp].firstarc;
    * M* ^4 }4 H; {2 x                int t=tmp;
    9 k8 ]/ b. A) L- r                while(q&&tag[tmp]!=0)% |; D& _! W* r+ Q
                    {
    5 `# D' x% v; `& Y                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    ( Z) |$ V/ u2 U                    //cout<<" 2nd     tmp="<<tmp<<endl;: r; W- p) n- ?4 I
                        q=NextArc(t,q);/ Q8 Z. @6 v7 J) o3 E4 s
                    }
    6 f+ R0 J% H" B+ D$ I3 s4 V                if(tag[tmp]==0)% l( J3 x9 O2 g& i" e6 x$ b
                        s.push(t);$ Y$ J7 j* c% d# p
                    ///1、对应上面连通分支只有1个点的情况
    4 I/ d' k: x- {# |7 W; f7 m2 m                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈9 @( V+ a% ^$ i' ^/ \& [
                    ///tmp要么等于找到的第一个未访问节点,4 \4 j( g- r# t# g$ r  G: J+ i* p
                    ///要么等于与t相连最后一个点(已被访问过)
    * ^% r; Z' A  u5 p8 {, V- e* S                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点/ P/ n$ |7 @: x
                }! l2 \) [- i  K9 n
            }
    ( G/ o2 f+ ]0 U3 E( I9 s    }
    ( f# _' q3 f( k' ?3 n}
    . v: O$ |2 z( q$ M% j4 V//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1& c' A( D6 W" M
    template<class ElemType, class WeightType> int. D) s. O- d. W" G7 ^9 h$ u. f
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)  c2 O2 n( Q3 I8 ^' o& b
    {8 r# p- T2 i; L
        if(head==pre)' W  Y( P5 z1 D0 j+ j/ R! P5 a
            return -1;
    + @, |4 k* @0 n3 i0 W( A8 {1 G; ~+ p8 m  g/ j5 y
        MultiAdjListNetworkArc<WeightType> *p;
    ) V. D2 K4 j. ^  u5 G/ F. ?& `    p=vexTable[head].firstarc;
    , q; O% ]; l* R    if(pre==-1&&p!=NULL)
    ; q" A# m2 f$ H2 ~        return p->adjVex1==head?p->adjVex2:p->adjVex1;! S1 X1 P& p, x0 }2 o% e% d
        //pre!=-1&&p!=NULL  R! ?' B& q: [9 U% c
        while(p!=NULL). ]' S; _. H% N! W9 |! \( D
        {
    : s2 Z' Y  |1 O6 W! E        if(p->adjVex1==head && p->adjVex2!=pre)
    3 Z5 k" t- \0 ?& n- G( N7 S            p=p->nextarc1;9 X) Z  o, H" R  G  A# m. O7 K# |
            else if(p->adjVex2==head && p->adjVex1!=pre)) V7 w$ `4 P7 W2 @
                p=p->nextarc2;4 l+ A$ B8 @' u$ y: J" L' m
            else if(p->adjVex1==head && p->adjVex2==pre)
    # x1 x0 R7 i2 }2 ^        {
    ( A' p6 R4 i  T% b7 X8 A            p=p->nextarc1;
    . z! A# M+ ^# N# C$ y2 m1 v/ Y8 B            break;- x  N; A/ ]  n% o
            }
    4 |/ T/ D" J4 o8 l        else if(p->adjVex2==head && p->adjVex1==pre)/ o8 A" a  X4 i+ A( z
            {7 ^# n8 z$ T) V/ w9 l
                p=p->nextarc2;6 O5 d; _& \9 [6 c& Q7 I% @
                break;$ s0 F, F- `  T, v( H
            }
    " N, t/ d- g' J6 ~    }. q  Q7 z7 {! H
        if(p!=NULL)
    6 x$ J8 D" r8 Y% R6 i    {% W( }' u+ u0 G  t1 M
            return p->adjVex1==head?p->adjVex2:p->adjVex1;/ E8 f" |5 _7 L( a+ n4 Q) _
        }
    % D! k" t7 x) s0 y8 ^' v; `- R5 L    else* z: H! d$ ]- c6 h  n& ^
            return -1;, \3 m! i0 o: @& f. ^. v
    }+ X+ y+ B( ]! e3 Z, |1 e$ f4 V
    ! q7 ^% p4 C7 c* \6 `7 s- A/ H

    % y+ r  ~% b' \4 J3 D3 \template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()+ L3 v# C$ r& {% g! D# y( u
    {5 n6 I4 o% G" K8 ], X
        stack<int> s;& R# |- g; ?4 ?
        int p,cur,pre;
    8 Z3 r/ \* I( J    //MultiAdjListNetworkArc<WeightType> *p,*q;
    3 f+ |, E8 Y3 W. S    for(int i=0; i<vexNum; i++) tag=0;//初始化
    9 Z, e# `; o8 o$ l  U# F3 K6 }3 |" V6 [, |, o6 x; {9 k4 Y3 d
        for(int i=0; i<vexNum; i++)# ^# ^& n2 N' f( {
        {  g. K2 D# J) U' L7 c1 c* E$ g! j
            cur=i;pre=-1;2 k: G1 V4 W8 V3 F% C9 b
            while(tag[cur]==0||!s.empty())4 I4 ]& _. E) f* s7 o5 A" t
            {3 e8 |8 C' m6 X' r6 \: h2 H
                while(tag[cur]==0)
    5 q6 X7 w% V& y( i* m" N  f            {
    : D! |5 D+ {* V8 z  _( I' d                cout<<vexTable[cur].data<<"  ";+ p* c% r7 w) l9 l3 Z
                    s.push(cur);
    1 u* J; `. B$ J5 p5 p* N5 ~                tag[cur]=1;
    * o5 z; Z* j$ v2 s7 v3 Z7 G               //初次访问,标记入栈4 @  d" w" @: c& d/ k/ k

    1 X; C& s1 b  \! M* a               p=GetAdjVex(cur,pre);//p是cur的连通顶点
    + b8 z) t# @9 P0 S               if(p==-1), D6 T' G. @& R6 {* y5 H, E
                   {
    . U6 C: B, _  I# H5 U, k                   pre=cur;s.pop();
    " X* g/ M. g& N" w' o7 E2 G" C                   break;
    7 M+ `! P  U# _9 B               }
    6 W7 h3 P7 I5 w7 @0 k8 O               else
    * Z! Y* T9 G" f: s9 w               {, Y# r5 j" a2 ?3 Z$ D4 N1 Y
                       pre=cur;
    ; a9 s% w7 L$ j/ Q- K                   cur=p;4 o* M4 ~/ I/ r+ ^. ^" T
                   }; ~8 Q2 P3 D. K7 C7 T

    ' @& U7 q! w* J5 m" h3 q            }# K- P/ r; Y6 E$ d/ e9 V8 r! b
                while(!s.empty())! w% [3 V8 p# Y, w, m
                {
    ; r" W$ I2 _: C0 @' \& U                cur=s.top();
      D4 `8 g* A0 v" i! O/ {9 E% z                p=GetAdjVex(cur,pre);
    ) \& M+ P& ?7 F3 v! j5 ]                if(tag[p]==0)
    7 i1 n' ?! {% ]. X3 ]. G6 O  V3 L) _                {
    $ @. M8 M' w& C0 t9 e                    pre=cur;
    6 v3 E# ~8 J+ S6 y" S  L                    cur=p;; K+ G1 E" A2 W8 }! \
                        break;
    % s* ^$ [: g! p6 o& U                }! |( _" Z% d+ |( T: \+ w
                    else
    . P3 f0 n* X6 c  z8 W' ^& ]: O                {1 ~  u8 P& P3 K( \6 S
                        pre=s.top();/ ^6 y  Y$ m2 P& |7 k2 `; R
                        s.pop();
    , f/ x& J* T6 e0 H                }
    ' y  q$ t" U$ X8 @: W/ k  {( g, v- E& I8 x) ^
                }
    9 Q  f2 R% t9 D- n3 n2 D5 b" n5 c* L) [% G
            }
    " t) f! a9 S% P# w* p. c    }* a5 q! h) d! ?0 g/ W
    }
    . B# c4 Z* P6 D# D3 ?) Xtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    * z4 g! e! K: G! Z9 L{$ H! }. @4 c% @- z
        for(int i=0; i<vexNum; i++)
    1 q* S4 }* l. z" h0 Z1 k        tag=0;; ^6 _8 N- h5 m- R4 }
        queue<int> q;
    # U, ]) ]# ^  o% ~) t( t7 Y    int tmp,t;
    5 y( R- F, _; c2 o0 I( I  E/ Y    MultiAdjListNetworkArc<WeightType> *p;! V$ l* Q. ^) d4 L1 W6 J7 L
        for(int i=0; i<vexNum; i++)
    / Z5 _& o4 w5 J+ m" k: ~; o    {
    : G& V% x/ P  T- Y        if(tag==0)
    ( Z2 ~: k( E( L4 H* I/ g        {
    & t/ o, e# Z0 k+ a            tag=1;0 I4 @% U. ~" D. b* ~4 h% a
                q.push(i);
    $ S3 t0 t, x9 P8 m            cout<<setw(3)<<vexTable.data;; M% J2 C) x" k! n+ D
            }
    % ]) F+ S6 A! G; U+ [& o! B. X        while(!q.empty())7 @1 ]3 }/ S, x$ Y- o1 t" J
            {" [" q2 M1 }* \4 j. _. X+ n
                tmp=q.front();0 l% ]1 c( X# R' R- N
                q.pop();
    $ L8 q# J0 y+ {; }            p=vexTable[tmp].firstarc;
    + ]" D" ^# V7 \9 P2 o+ J            while(p!=NULL)" T+ T6 W* \7 y' F5 w
                {8 N2 G( W# U+ R" r+ j: y4 ?' ?" H7 L
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    7 I  q* }& Z0 ^/ R                if(tag[t]==0)
    " U3 X, d0 f  ]; ?' \" H/ b+ G                {$ M# E+ s7 e% J
                        cout<<setw(3)<<vexTable[t].data;! S# c/ q7 ]8 O% t% E
                        tag[t]=1;
    3 D9 \2 s5 X6 P$ H- a3 D                    q.push(t);
    6 @- Q% k% G# d4 s3 R# B) e                }
    * C! J8 a- n9 ?  p                p=NextArc(tmp,p);
    % g1 B% {8 ^8 m6 [5 G            }! z; w1 e" D( ^. f) `& }
            }. Z, [5 a$ `. s: E
        }1 V* {2 o3 a9 s& f
    }3 h4 q" Q" W1 R& Q! N4 I. S
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()( Q7 f/ W' @$ e0 V" _0 `
    {4 Y+ {  C) N. f& `8 v  V
        MultiAdjListNetworkArc<WeightType> *p;* s- e7 t, E0 X6 k# O6 k' n
        cout << "无向图有" << vexNum << "个点,分别为:";
    5 `5 r& l+ W2 W. E1 E7 |/ d+ G    for (int i = 0; i < vexNum; i++)- k9 P- t  G. w) z% w5 S7 ~& g( w
            cout << vexTable.data << " ";
    ; m9 [: L9 m3 Q' d) B! T1 C    cout << endl;
    6 r' k" n/ |! S7 Q    cout << "无向图有" << arcNum << "条边"<<endl;) [- L5 m1 w/ w% ]1 \$ ]
        for (int i = 0; i < vexNum; i++)
    . |5 V, w/ i- b$ ]  u    {
    , H# D7 h, G# W/ f( ]1 {, j        cout<<"和" << vexTable.data << "有关的边:";
    + N+ q0 l, U, c" J        p = vexTable.firstarc;
    ; T8 G% {* K! s! H: }        while (p != NULL)" D; f' f1 G5 @. B7 d+ L% ^
            {' V% \. y( b0 `! w  |
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    ( U, P& L9 p4 x. A1 `            p=NextArc(i,p);) L, A# _* o, h* L2 `
            }& h/ F0 p( p; h5 y# O
            cout << endl;0 p9 G4 [7 T5 U9 J; B
        }
    $ P( H! \) N# c& c( M4 i}
      U0 z" S" q# H: o/ V& V( `: C! z$ ^
    ; D; _" S- Z. ?2 L' B" t6 Q- e7 N  C( k$ l/ [5 d1 T
    邻接多重表与邻接表的对比
    ' _4 U: k7 H# p" H5 c  i8 k& w( j  b( l4 q+ X/ L9 `
    邻接表链接. X% M' ]: f$ X/ [2 z6 G. q3 n7 P
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    * w( l, c- t3 w9 y% j在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。, B% i% B  v+ w4 X) b/ G! h
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。# b( \5 ^& x; O0 I: L7 `
    ————————————————" F. Y, N1 p! z* A) |1 [% _" h- h
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。3 F" v( g3 Q5 X$ J8 q! H
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958, v4 d- f( `6 p; {, I+ H  R. I4 Q% P) B

    3 l' j0 M, t0 d$ K: i0 L! G) `% B7 O# L/ t3 {' C
    2 q9 e  p1 c, e$ @& Y* s0 V
    . B1 d$ C0 `3 N! C+ L1 L
    ————————————————3 K. p4 x- W' a: ?  A
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。4 \3 D0 v+ M- j
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958+ b6 L- d; Y  k4 A7 v- H

    % K# u9 a6 D/ o/ t; r" f) g# b0 c  f4 h) c9 h+ K. M
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-9-10 10:33 , Processed in 0.691385 second(s), 54 queries .

    回顶部