QQ登录

只需要一步,快速开始

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

    : C4 O' g9 z8 }  I1 a: {& d7 f4 q图的存储结构——邻接多重表(多重邻接表)的实现
    & ?* B" @% R7 x9 H7.2 图的存储结构( u) O3 W* v! G; F+ O
    - \* ~7 P& v6 v% j  e2 Z# _+ a: l) g
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist5 r* q* R; v- I+ v( B) S
    邻接多重表的类定义* z1 e+ u1 ^- f+ r% k
    邻接多重表的顶点结点类模板
    ) @+ z' J! z5 @邻接多重表的边结点类模板
    ) a( G/ V4 M  H6 L: w) u邻接多重表的类模板
    9 u7 \4 `# ~) y8 Q邻接多重表与邻接表的对比
    6 W, D: p' q/ j8 i# Y7.2.3 邻接多重表(多重邻接表)Adjacency Multilist% W+ l4 \. h  _7 C# I
    ! {/ X5 \. C  ~0 J. N8 s
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。- f' n" f% e& U6 l( k1 V( x
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。3 g  o! z" Q* R& f

    & Z1 Z/ y( \, @邻接多重表的类定义
    ) I: V" b! j0 c$ H 1.png / s2 r( `  @( F
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    : H  \3 i( [7 q' W- K8 ndata域存储有关顶点的信息;) O3 Q' b5 N9 h5 o
    firstarc域是链接指针,指向第一条依附于该顶点的边。( R! Y/ Y! \& g! F8 G
    所有的顶点结点组成一个顺序表。


    9 J6 J8 x7 w# t" y  Q* C- M4 i$ ?$ A$ G9 ?; x3 f
    template <class ElemType ,class WeightType>
    1 t2 Q5 z4 L8 h' Q# dclass MultiAdjListNetworkVex
    8 {: {5 B8 f3 u% X{
    5 x( D# ~. K3 L) O) z1 S) kpublic:
    / z, g$ Y) E$ d* O! W9 g        ElemType data;4 g& }" ~, {7 c! W. F, @$ c
            MultiAdjListNetworkArc<WeightType> *firstarc;, i2 |" l3 l0 [6 H0 i" ]4 @
    + J2 g; A8 @& U5 V0 ^
            MultiAdjListNetworkVex()( X% c! E% c6 M# b3 x' y8 M6 ?
            {( p6 C/ ]! y' q4 i" b; W
                    firstarc = NULL;4 b& j  H1 P! d) o. K3 Z3 i
            }
    # e9 X+ y# X, k2 ~4 z: D        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    & Z+ L1 b% B- L        {6 P* v& }3 R; A
                    data = val;
    # w' B, p2 N, C2 o, a, Z4 k+ s                firstarc = adj;
    9 @1 Y& {" p1 X# `# M  i  ~( s        }4 M4 l3 |) \3 H( E1 H. D, i
    };3 {) w) Q6 }, J8 `, }; R

    2 {) D  N/ S3 A9 d( w邻接多重表的边结点类模板
    " R/ x, y$ T- u9 K. K
    8 F! m. Y8 h, ]3 C& ?& L在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:1 d% z" [; {* w. c$ j$ _- y
    tag是标记域,标记该边是否被处理或被搜索过;. g6 f1 c9 e5 k9 q3 r# z9 v3 X( c
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;/ p) h  X. {5 }! {' E- {0 Y7 U* \
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;3 `) Y* p# C6 K* z
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。: l' J& e  Q7 M; P4 i" t7 h6 y

    7 K. z/ u5 y  Q 2.png * _7 [7 Y6 p  h0 M3 d  g
    template <class WeightType>
    , O3 v0 V% g6 P: g' Pclass MultiAdjListNetworkArc
    3 U  a/ }# m+ |2 l6 D$ m  I{
    ; t. [; `5 A* O0 @3 a9 k/ Rpublic:0 D6 n. A1 G3 R6 }! z0 O4 ]. a
        int mark;                                       //标记该边是否被搜索或处理过
    / ^) r! i) D: }! c! |" B- |7 ~, u        WeightType weight;                              //边的权重+ \2 z. n0 o; |* [: Q
            int adjVex1;                                    //边的一个顶点! Q  O1 ~0 g0 O( }8 }' z
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-19 D* \  d. `3 x# x/ u  n
            int adjVex2;5 _0 F& _4 `% n/ c
            MultiAdjListNetworkArc<WeightType>* nextarc2;
    5 D; \  T2 H/ ?! c
    7 ^' c( D  c: Q8 y# k$ s( ?        MultiAdjListNetworkArc()3 L; [; p$ r9 z9 N" V
            {' I& d! u9 I( d* w2 t5 h. ?
                    adjVex1= -1;
    $ X4 y4 i1 P9 z! D* r3 p( z                adjVex2= -1;: @1 r& x1 ?! l7 u' `- t5 L
            }" d( J1 @9 d1 i0 e8 k, @
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)4 R, Q0 ^$ W" ^6 s! D
            {9 \2 j& N' x/ x. c4 h/ r6 c8 F( s
                    adjVex1 = v1;       adjVex2 = v2;
    9 q5 t6 n" N% x                weight = w;
    , U6 T9 V' @+ ?9 |3 p                nextarc1 = next1;   nextarc2=next2;; Y- Z. z: k; H; @" |% w2 K
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    3 }, u2 _+ M+ L  ?8 {% s        }
    & G, ~" H- \3 q' |& Q
    4 r7 P, t2 y5 g! v3 a/ c  s) F4 Y  A5 h邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    ) {% z1 i) x4 b% Xclass MultiAdjListNetwork* K% ~( M; o- u( n+ h6 H& l: |5 |
    {( U; r; d' k, b; C- l- H4 I
    protected:
    & i; o2 N  T: r$ R0 `    int vexNum, vexMaxNum, arcNum;, _( Z9 O( s: t5 d3 Z! G" U
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    / @8 A. u  o7 H  m. c& q3 x    int* tag;1 p, C( Q; E2 y/ m1 I0 B
        WeightType infinity;
      V+ x4 v1 s' A! s/ r
    " \/ G/ M/ e( n8 F& [7 zpublic:4 d9 e, G- R3 }# F+ P( J
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);+ [2 E, P% k8 o/ {( Q, {/ W) G- n
    - R5 B  _; V, Z9 A# k" p# C
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    ; y' `6 g" W4 q: Q8 T: m- j0 {5 z- B' W2 M; U4 k+ B
        void Clear();) Z) t9 O: j& M/ D+ I5 S
        bool IsEmpty()
    3 U- C3 \0 w  H1 g    {9 W7 g5 H3 F) T
            return vexNum == 0;
    $ A6 M% X( P- D2 O$ S* v% q    }
    " w% d- x# j6 S+ Y! f) a    int GetArcNum()const
    6 r9 E+ ?( s3 [; A; W    {( T/ u$ Y$ `8 L0 V) {. ^% t
            return arcNum;$ @. R" v; z% Z! y
        }
    ' v9 L) `  ~1 i) ]+ k) w: Q% ~    int GetvexNum()const
    ! W/ [/ s! z5 }/ M    {6 G! \3 g: o" }- C  ?5 X: d4 \. J
            return vexNum;
    # k) R' t5 y3 x! p! e+ E8 j; ^( Q    }
    # G' V% d0 H: G( T5 Q, S+ q2 ~! |5 E- v  y! y5 `3 m2 i; c# C
    ) g" L7 w2 v! u7 H* m
        int FirstAdjVex(int v)const;
    # ^6 n/ R6 R# w8 [/ C    int NextAdjVex(int v1, int v2)const;
    3 s3 }5 O- Z. U) A    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;0 H' o1 J# ?% c6 v
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;2 w5 q6 [( A% T# }

    : w( E/ c+ a: F; `, \8 R    void InsertVex(const ElemType& d);9 E; c- X* p* [! D
        void InsertArc(int v1, int v2, WeightType w);" ]0 [/ R: I/ a  ?* S  O

    1 D6 ?# w3 H! T0 S" n* N    void DeleteVex(const ElemType& d);. r& ~4 B7 ^% C+ p3 J
        void DeleteArc(int v1, int v2);3 @+ _9 F% Y6 s- u( d

    ! e( o+ N8 p$ Z# N0 C    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);( j5 q: c- |6 c: y( x
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);1 @1 i7 G, @/ a6 J6 A  i
    ) n3 X# D+ {2 s% y( e
        ///深度优先遍历
    & F& d% S% F( K* w3 D    void DFS1(const int v);
    & h, J: ^' P$ Y# u0 v) C    void DFS1Traverse();: _5 P0 c  d! B$ K( G* @3 L$ n
        void DFS2();
    0 J) i0 C( h$ V
    7 u; `" z; o7 i" u, \    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    9 l$ ^3 F3 i9 w    void DFS3();$ ^5 d$ ^. \: W+ B' e( O0 U

    . L& E' F( e, ~9 J: ?2 T    void BFS();
    $ I+ H$ |$ b0 X& W" a    void Show();7 V  S" S8 e7 U7 u; b3 F- M+ P
    };, \" `% q" w6 \. q" H, P" d

    4 b6 V( O4 u) R2.函数的实现9 Z8 J+ c4 `" R7 t9 ~/ ~' z/ H
    研讨题,能够运行,但是代码不一定是最优的。
    . p% I$ A+ M2 x4 C; Y# t! u7 Y% c9 J' ^. V" j1 P  z7 m" r# @# X
    #include <stack>
    : [% ~/ k* L! @: i! T2 |#include <queue>8 g. s% `& r% g2 v) Q
    % {9 A  Z1 W$ f/ ^
    template <class ElemType,class WeightType>
    3 ^2 B4 H4 w2 c" C. Y' tMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
      \! `) s5 M8 Y, Y{: h" `* Y3 }1 m" G/ X+ r% V
        if(vertexMaxNum < 0)
    # w  A" F" B" R5 U* b: g        throw Error("允许的顶点最大数目不能为负!");$ x1 F. c( ]+ d6 i7 g
        if (vertexMaxNum < vertexNum)3 a6 s$ V/ E, W  W$ ~
            throw Error("顶点数目不能大于允许的顶点最大数目!");; S7 h) i. I* m9 G7 _, t6 y
        vexNum = vertexNum;- r" S$ r- c6 N& O
        vexMaxNum = vertexMaxNum;
    3 v1 |# V& b, t: R    arcNum = 0;7 o: [6 ?7 [# u4 [- C* ^% z5 J. o
        infinity = infinit;
    " `6 C: @5 F1 D# b: F8 O  g, q    tag = new int[vexMaxNum];
    3 l; H# Z7 v. X2 W" L3 M, R( a/ o    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    1 b% b4 o) o0 V, v3 K    for (int v = 0; v < vexNum; v++)( }7 }: H: ~' ~! k* [
        {
    / ^. e3 s3 ?8 g7 j" l        tag[v] = 0;
    ) k6 }* |* Q7 ?5 \, H) m1 `        vexTable[v].data = es[v];
    - Q( P$ }: e+ Z. z4 c) C        vexTable[v].firstarc = NULL;
    $ G) l( Y! s/ Y) M0 x- e    }+ n8 C2 C% ]5 l3 T1 U& H
    }9 Y' h+ K) v1 k  K3 x
    template <class ElemType,class WeightType>/ r; g- _: L5 i
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    - M8 a- [, H  J2 [{# v  T- F# u" I2 {+ g% ~
        if (vertexMaxNum < 0)6 V; o  \' M, V- ~7 y. X
            throw Error("允许的顶点最大数目不能为负!");. V4 r* w4 M4 V5 m/ q
        vexNum = 0;  ]2 j: |; l4 _
        vexMaxNum = vertexMaxNum;6 i* b- }3 ], l5 T7 S
        arcNum = 0;
    , H4 V/ _) O) c. o3 G' ^5 n    infinity = infinit;
    4 M, e( R, u5 t7 R6 v  i  u8 o! n    tag = new int[vexMaxNum];
    9 |) V5 ^+ m4 n    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];3 v7 F5 f3 ~, B3 _
    }
    4 E9 L4 o. T4 s# T6 ?template<class ElemType, class WeightType>9 r$ X6 F7 M1 D2 [" m
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const4 Z* Q" [$ x4 |% ~) W
    {
    ( R, F# i- m: V7 r: a/ G    if (v < 0 || v >= vexNum)$ L3 a9 ^& ?7 ^9 V
            throw Error("v不合法!");
    + W6 `$ c: u5 p5 K    if (vexTable[v].firstarc == NULL)8 |0 N) E. O. I8 n9 Q: m( B
            return -1;
    ) D; J$ L$ j, Q7 _    else
    2 S  [$ L  V  K: g! A0 k        return vexTable[v].firstarc->adjVex1;
    ( w3 E  i. e9 G! W! x' O  z}" B- t1 W3 e# J2 Z- X- _
    . f+ w  ~0 ~3 Z5 Q$ N7 B, e5 O& Y. A* Q
    template<class ElemType, class WeightType>
    . P6 _" D5 R% `6 I7 H! fint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    * E9 D2 W) u: ?" F' l{, ~. Y$ q7 _- o4 N
        MultiAdjListNetworkArc<WeightType>* p;
    7 p) c/ u2 {2 c; K( p    if (v1 < 0 || v1 >= vexNum)
    6 M$ M: i" Q4 j* v# g# t        throw Error("v1不合法!");! B0 N2 L) g* J8 `2 n% P
        if (v2 < 0 || v2 >= vexNum)  g7 x$ ~1 t+ f. N4 V2 ?7 |
            throw Error("v2不合法!");( B6 D; K* v- `' n" T( N
        if (v1 == v2)
    9 D) n& W4 B3 Q+ R& k% \        throw Error("v1不能等于v2!");
      p1 J8 U( r" }, O( o8 |8 Y  W    p = vexTable[v1].firstarc;! z! C& H+ ~$ O
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    4 k/ q5 T1 ~3 B' n( q; b        p = p->nextarc;  m/ q( y8 F0 |; \9 R- x
        if (p == NULL || p->nextarc == NULL)8 K5 @+ J  a0 j! [0 L* A
            return -1;  //不存在下一个邻接点
    3 R6 S! S  v3 n- v    else if(p->adjVex1==v2)) i- K7 X/ C$ O0 s8 s: f( Q* t
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);; W8 V5 y4 y  K+ f( ^; u
        else; z2 }) N6 a' J) L4 f1 L( p
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    ; q+ X, B+ O; S" D+ P) [5 ]" N}; Q- q7 H8 I( ]" `5 b+ e6 Z: p
    template<class ElemType, class WeightType>
    & @* f5 A* N% H8 X8 Qvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()0 F, d! w3 h0 f& Y2 ]
    {7 |( z' m, m& ?0 C0 x1 V
        if (IsEmpty()) return;
    $ p7 A8 J+ I7 s6 V) X  F1 s- X    int n = vexNum;/ |0 y9 O  a2 P% O5 `
        for (int u = 0; u < n ; u++)
    : F$ c* F9 v& p. U+ R+ P" C        DeleteVex(vexTable[0].data);
    " @7 F6 U$ T2 ^, X8 d3 ?% n; Q    return;' z. J& P% H* v
    }& q; O0 L8 M  @
    template<class ElemType, class WeightType>; H+ v. w' O/ h5 t, g. i
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()+ k. b$ H8 |4 Y: \
    {
    - a8 n/ f7 B+ `9 X; [    Clear();
    ; O" K- C8 X, }- T}7 ]- A1 {9 _* x5 p. m& U
    template<class ElemType, class WeightType>6 }# Z" b2 \# B2 |$ A, b. s
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)% T5 T1 g: w6 B- T* f
    {
    " i3 c6 _: C2 z  s- V    vexMaxNum = copy.vexMaxNum;: e; S2 D0 r0 W. w+ u1 ~) y" w
        vexNum = copy.vexNum;
    ) O% z, C4 ^% t5 U    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    / }3 d  m. g" Y9 R! m% \$ p8 D    arcNum = 0;* u2 U" s8 ^' S
        infinity = copy.infinity;
    # z# N1 X9 n$ z6 Q1 a    tag = new int[vexMaxNum];
    & e9 Z; G! [+ h2 S. s; b+ `( `# ~( L, W8 `, }1 Y7 T; q! B
        for (int v = 0; v < vexNum; v++)
    - G/ ?, F# A# x+ O7 Y; @    {: J* D1 _3 j+ |- t1 P& z/ w
            tag[v] = 0;
    6 Q: f  Z* q$ c: K- k        vexTable[v].data = copy.vexTable[v].data;
      q2 Q: e+ S: E7 ?. h2 F* n        vexTable[v].firstarc = NULL;8 t3 l3 ^0 y! `) v6 B9 i5 s0 {
        }  [3 n7 d# l- D2 Y- q  f% p
        MultiAdjListNetworkArc<WeightType>* p;- [7 q$ w5 z, L5 o4 s
    : y- D- ]2 e& ~7 ^9 I+ t
        for (int u = 0; u < vexNum; u++); d- e+ p: p5 J" h7 h
        {: M3 J- _! U7 ]) h( G$ a
            p = copy.vexTable.firstarc;" w0 N5 }" [. E
            while (p != NULL)0 R' D' B; v, s; V
            {* |9 Y; X8 r* m3 R5 S
                InsertArc(p->adjVex1, p->adjVex2, p->weight);/ X1 V1 k& y. [) T$ }
                p=NextArc(u,p);; e- Z# u2 V& v# V% a1 b
            }4 y/ e2 @7 N5 }/ {# L
        }  @% p3 q7 Q% Y: e& z
    }# c4 t# n9 y2 i8 a, G/ K5 o* Y
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&, Q( ?- S8 ?& U9 I2 H* h1 r8 G" l; y9 H
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    3 R( g6 G0 J+ I7 i+ n{  u( ?* R& G4 j  j
        if (this == &copy) return *this;
    8 _; k4 b) W( A5 ?) |+ A9 G    Clear();+ M& `9 l- Z% i/ t- ~7 ~
        vexMaxNum = copy.vexMaxNum;
    ( T# L! {/ b: ]' M5 ~9 m    vexNum = copy.vexNum;# U* c) S; v5 _* u7 L" v* C
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    ' N, d) x- r: J( h! B7 _& }' j    arcNum = 0;  A( k0 C9 e! O- T6 ~
        infinity = copy.infinity;( i1 |5 [" x& C1 Y
        tag = new int[vexMaxNum];
    $ H2 S* \$ g# G: U6 E3 z* n' N
    3 P' k* e$ K0 O3 h4 {) \$ q    for (int v = 0; v < vexNum; v++)- X+ Q) W+ Z8 n) F" v5 e
        {3 ~/ F7 ^7 [$ k' n+ o) B
            tag[v] = 0;" j* L9 v/ w- n' ~
            vexTable[v].data = copy.vexTable[v].data;, `  V: h$ e$ B
            vexTable[v].firstarc = NULL;) R2 o0 D6 y1 `/ G  P
        }% i! q) x3 S1 T8 ~1 U
        MultiAdjListNetworkArc<WeightType>* p;% U" B2 H1 \* ?. U5 H
    * r5 x: N" h; ?
        for (int u = 0; u < vexNum; u++)
    * E, f& \* a. ~2 n    {% u/ m, L% D2 F) N1 Z
            p = copy.vexTable.firstarc;! N( V9 p$ }4 Q" X  {  M% |
            while (p != NULL)1 b  f$ C) p! _& J5 x7 `
            {
    8 e# L; t0 x4 o2 v" ?            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    1 Z- D+ n& F/ W            p=NextArc(u,p);
    9 h4 O0 L5 o& m3 }        }3 z! L- g. J1 s5 w3 z
        }
    5 G  I0 n8 l% G' L( ]8 Q7 ]6 M# |0 x! d    return *this;$ }2 o# S5 g+ H- h
    }
    + L# E0 L& k% j/ Z/ r! a/ y+ z! ktemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    / m1 Q6 C3 f9 L- [MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    , {5 b, O9 d# t{
    & I) \# o- L) C/ a8 c    if(p==NULL) return NULL;
    + m- U4 X# d8 @+ Z5 l4 ?; y    if(p->adjVex1==v1)3 j7 [, ~  n# m! X
            return p->nextarc1;$ P- `) b" H% x4 G2 g) ?
        else
    & B1 E. ]/ w; Z9 m% S* v, ?! T        return p->nextarc2;
    " h; \* V* [% s}! g2 `  v% M, s
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*! Y# [" G5 `$ {* P; u" s4 n
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    ! ~1 C3 x. |' j! r  A+ k( y. I{
    ) b+ ?% V' e: ~5 H& n5 O    if(p==NULL)return NULL;) I1 n6 L. C; m/ v8 h/ i0 G
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    2 f' V6 e) `& m3 s    if(q==p)- m5 e" F2 ]. F) d
            return NULL;
    . }: \0 a' A1 M; q+ @/ C( K    while(q). K+ c! J5 E4 U  M% a
        {
    " e- e* N2 S4 n, H+ B) z        if(q->nextarc1==p ||q->nextarc2==p)) e. Y  n+ x# z, g
                break;
    # W7 y: E% Q. \% r, [        q=NextArc(v1,q);' _3 E6 b3 u, h+ o# c. u6 t
        }
    2 r& q+ C# w4 M" z4 ^% a    return q;
    - R0 \- q& Q! J, S  \" f}
    9 R. S4 [" ^2 V4 n& Z, ~4 o8 n, vtemplate<class ElemType, class WeightType>8 ]; ~6 n+ ~9 u+ j1 Y0 Y2 Z& A
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)% c3 b2 K  K7 W2 Z5 k9 f
    {
    9 K( f# s, \7 ^$ @" e4 B    if (vexNum == vexMaxNum)1 i' n" J( z% F1 i
            throw Error("图的顶点数不能超过允许的最大数!");
    . P# T1 k( r0 U6 v5 ~; }    vexTable[vexNum].data = d;. v* w2 q3 z' l, p' f$ N) B' m
        vexTable[vexNum].firstarc = NULL;1 \5 s4 h5 G5 N( V
        tag[vexNum] = 0;0 Q( I9 G$ d% @2 k; U  f
        vexNum++;
    / o1 P' k  v9 t}& W5 N) I; w& a) A5 t$ F
    template<class ElemType, class WeightType>
    . K$ H1 s1 i3 [3 U, p0 G+ a0 a! Evoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    4 s* V& g% e3 b7 L; c+ n- _{
    + G( d6 r6 Q' `8 [5 ]    MultiAdjListNetworkArc<WeightType>* p,*q;
    " y* U; |. i- l" v7 M7 ?    if (v1 < 0 || v1 >= vexNum)( P: r7 p9 r0 d4 I+ e2 G9 q
            throw Error("v1不合法!");& ~' o5 r( i( p3 g! y, E
        if (v2 < 0 || v2 >= vexNum)
    $ S4 h! `8 ]/ f) Z5 H6 S. m% R        throw Error("v2不合法!");
    4 W: N8 n3 X4 f3 E8 Y9 E    if (v1 == v2)  E" W# W& K+ I7 F' C0 [- o
            throw Error("v1不能等于v2!");
    . F% {0 y' \' z6 m/ T3 X# [1 Z) r+ v3 H    if (w == infinity)! Z9 s0 j- ]% _: a
            throw Error("w不能为无穷大!");2 n" y# [$ n3 s9 V; g

    , C" J2 h# N4 J; F' ^( B: h
    5 f7 S1 @2 r1 ?: ^6 ?- _    p = vexTable[v1].firstarc;6 I" f. v/ Q3 y5 N7 O5 l3 F+ q9 Z
        while(p)2 U" |/ E' H3 E2 _! z( W
        {- O0 W3 R- r# p5 Z  |
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    3 G( W, ^2 B2 d9 \3 W        {, v0 I! R6 L6 w
                if(p->weight!=w)
    % w2 v0 f; N, c9 A$ F5 o7 s, |                p->weight=w;9 N- T' D8 h- D5 X+ r/ X- @
                return;+ B% U9 n; s2 i& Y1 u7 q& h* C& P+ X
            }
    % u, r& t- [' ~! ?$ \& i, b% k0 q* |4 e! \  `
            p=NextArc(v1,p);% `+ A* r( ]. g
        }
    3 M9 s4 _/ ?; _1 v3 D    p = vexTable[v1].firstarc;
    0 M4 W  y1 @/ O    q = vexTable[v2].firstarc;% s+ k! B7 H: K2 Q
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法) t  O# N/ d9 N) l# h1 e. P
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    ( ]+ ?0 n7 Z& j. @    arcNum++;) ]0 U' E% P" `6 o: C. n/ v4 W
    }+ K$ s5 ~6 T4 p4 z: @
    4 Q* E* A- Q( u( M0 Z$ x, ]
    template<class ElemType, class WeightType>' R* k6 v8 J+ S
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)  d; i) A5 g6 @( v
    {
    # y3 s  O+ A% T8 p- `. r4 ]/ r' D4 d
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    " g! E& d+ z% X: R  y    if (v1 < 0 || v1 >= vexNum)
    5 u$ B+ F) E+ w. v" S  Q7 L        throw Error("v1不合法!");
    9 l# o- h2 ^9 H    if (v2 < 0 || v2 >= vexNum)" d$ q# g) @1 y" E1 g0 s5 Y
            throw Error("v2不合法!");1 `8 n/ c; x3 y! E! e- u; k
        if (v1 == v2)5 n1 T. Q& Y' z/ @4 ?) N
            throw Error("v1不能等于v2!");
    7 I8 L$ H& y1 h2 {0 B6 r$ _, v4 m, s! `5 a7 b
        p = vexTable[v1].firstarc;* u" `- S- \! P9 r  u) {
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)" F2 c# S* C; i' G" t
        {
    ! ?7 d! {5 U! T' w: D        q = p;
    , p5 ^9 J& A7 Y9 `, R" D        p = NextArc(v1,p);# m, _9 d' A  m( |! C
        }//找到要删除的边结点p及其前一结点q
    . ?3 M& }  Z" ]1 e5 t- F# l9 Q& H& I$ [1 e$ w: u
        if (p != NULL)//找到v1-v2的边7 p1 i8 l* A1 h$ T! t  W) o/ V
        {5 Q8 o. x- ]6 s9 Z' ?- E1 j
            r=LastArc(v2,p);
      W% g3 t7 P& Q- C' `) z2 L& w* E        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    ) ~4 i: C( b9 P4 A. g; L( h            if(p->adjVex2==v2)
    6 Q( t& z3 q* J3 V                vexTable[v1].firstarc = p->nextarc1;5 j* f& W5 D; l' ?! J
                else vexTable[v1].firstarc=p->nextarc2;
    4 K5 J9 h5 E# g$ t) r% N7 D/ X        else//不是第一条边
    ' o! e  N+ P0 v8 M" X' Z' }9 p        {; J: ?) t5 R2 N3 m; c: T) t5 L7 ^
                if(q->adjVex1==v1)
    . q7 z$ C. W; y' k                q->nextarc1 = NextArc(v1,p);
    ' g7 J/ S6 e) K: i8 h            else6 ?! Z5 Q% V$ ]2 A3 V
                    q->nextarc2=NextArc(v1,p);# t7 l; m8 M9 L* E0 s1 Z/ ^7 ?
    # ~! A4 C8 i# W/ t& f( B3 w
            }
    : e# Y. ?2 A* V# t( v        if(r==NULL). @" F, _! n( j4 p8 q* U( w  b$ q. k
                if(p->adjVex2==v2)
    1 t3 X) C- G5 w; a                vexTable[v2].firstarc = p->nextarc2;
    # u- S5 Y/ W: y2 N* Z& J3 u. ^            else vexTable[v2].firstarc=p->nextarc1;: G8 H  I1 ]' Z, w6 h% v
            else
    0 ~3 N. s' K! D1 f2 G. w        {% S# ~3 T$ e$ Q6 J" b% X
                if(r->adjVex2==v2)0 D, p& p9 a, W5 X, N' i
                    r->nextarc2 = NextArc(v2,p);& y. E8 b8 \0 ]$ j' a9 {5 p
                else/ Q3 t- W, h0 b% P
                    r->nextarc1=NextArc(v2,p);0 j5 K/ y. Q9 M: S6 z) g* V
            }
    ' s# ]* R9 w1 Q" U. h: d        delete p;
    9 w9 U2 ]" y  ]        arcNum--;
    0 T3 r+ F- _/ ?# Q2 ]& J; S4 S# `    }* g- f  P6 k6 m( M1 `1 g
    % Z1 B1 v. E7 t  Q
    }
    # C' E- u; A8 n7 Gtemplate<class ElemType, class WeightType> void
    , ?; b( r  w& z( Z+ W  w3 Z9 CMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    4 B8 o6 Y& F5 a{
    ! y3 O$ L; M. @* ^2 |* Y    int v;' P5 z: F1 z2 G
        MultiAdjListNetworkArc<WeightType>* p;
    4 L9 z/ t0 B* c8 r* m( N    for (v = 0; v < vexNum; v++)//找到d对应顶点" `" R2 P" L" y* i
            if (vexTable[v].data == d)
    + O- s, j: g# S4 f, e            break;% I& }( K: R* Z1 X
        if(v==vexNum)
    8 E& t3 G5 I0 Z9 \- M. A        throw Error("图中不存在要删除的顶点!");
    ! v8 g- J) P$ i& E( J& N8 i& I: r7 L# u% K7 C, L9 F- T' D& e* P8 y
        for (int u = 0; u < vexNum; u++)//删除与d相连的边$ ]4 d* F% o1 T! t$ p
            if (u != v)8 d& s! ^9 S6 p; p# Y# t9 z: J
            {
    4 x5 |7 v. r) \; E% d            DeleteArc(u, v);; T  g/ b5 E6 J$ l
            }3 Y2 o3 C3 }# @# G
        vexTable[v].firstarc=NULL;
    : m+ u+ A  u% b( d
      N' J/ n4 i- P* o& D& [    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    4 G4 j/ z& M: v7 K    vexTable[v].data = vexTable[vexNum].data;9 E1 I7 N" l( s3 J- q
        vexTable[v].firstarc = vexTable[vexNum].firstarc;4 I3 J' d3 k+ e' J1 `" X
        vexTable[vexNum].firstarc = NULL;
    ) l) l; {) V: u! I    tag[v] = tag[vexNum];6 L7 Y( U5 r* _) z: q. e. Z6 k/ O
        //原来与最后一个顶点相连的边改为与v相连
    : s% O4 _% a/ S' j$ r    for (int u = 0; u < vexNum; u++)
    - R$ x. V1 W/ \6 n' O. f# x    {/ K4 L7 ?' G! Q1 m2 w0 [* `
            if (u != v)
    : E" j5 X# i9 u/ H5 O        {
    % T1 _8 O. n( T" y5 r2 a            p = vexTable.firstarc;; o/ ]4 o4 J( r9 H
                while (p)$ I9 }7 c/ n, Z
                {
    & y2 l: k5 a' |" `' k3 a7 b5 _0 @; P0 V                if (p->adjVex1==vexNum)! z  t$ b) m* `6 T; {3 Y# q
                        p->adjVex1= v;- ^: L3 W, e, g% z5 }. K
                    else if(p->adjVex2==vexNum)3 V" O0 M9 T0 _1 Z, g9 ]" X
                        p->adjVex2=v;
    ; H  ]5 X, `* c2 w                p = NextArc(u,p);
    ) Q( u  b: P# V5 i) h            }
      x7 J) e- {9 g2 K3 b2 ~  c& t        }$ A% V! {' y9 X% w
        }
    ! |% b2 ^  e" X}+ I' }( |5 E; l* w9 [" y
    ///深度优先遍历
    2 j+ `. F9 Q5 K% |7 p4 v7 D5 A- B) gtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)5 r' ?2 v) M8 C
    {! y# c/ f* s. P& D6 H: K# D% S
        tag[v]=1;3 b, o8 q* p9 Z" Q: Q
        cout<<setw(3)<<vexTable[v].data;
    4 Z1 p. g2 o& H* L5 X3 s1 [9 i  S    MultiAdjListNetworkArc<WeightType> *p;
    ! |+ ~! Q( u1 o& p    p=vexTable[v].firstarc;' D* S8 g$ Y+ M: h
        while(p)2 Y& y! p' t% u/ }
        {. l/ p+ `) ^+ ~- r7 G: f0 t+ W
            if(tag[p->adjVex1]==0)
    * P; v: U+ P9 E% f$ W2 g% T            DFS1(p->adjVex1);
    . @; g& H7 m! F- Q1 e& h  _$ O0 `        else if(tag[p->adjVex2]==0)1 |  F: J8 j) |
                DFS1(p->adjVex2);5 u2 T0 n# n: g; N# y8 F' O3 e! D
            p=NextArc(v,p);; F( Q6 o& w% t: n. Y* b
        }; _9 J$ G* L8 U8 x
    }# O/ w" A) a& a5 R+ ?
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    3 i( A4 d7 \1 j5 y* a& m{, f( C! `$ {5 H( }: ^
        for(int i=0; i<vexNum; i++)
    6 z7 j9 R- }; z/ K. q        tag=0;
    " D/ {. ]( n0 m5 G; c& J0 x, G    for(int v=0; v<vexNum; v++), f6 u" w% d" h" z
        {
    3 `3 G; Y9 \% `6 [- Q2 l        if(tag[v]==0)
    ( J, ?4 x& I# V- O, ]5 `( e; @' N6 V            DFS1(v);
    : k3 ?( D" n$ o, Y! l4 }) o    }
    6 K4 f0 h7 _  q) Q4 i: p+ P! ^1 i) q}" d& l2 l1 }' b, V: B9 b
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()% F- ?+ {7 Q2 X$ o1 t8 I/ d9 O' j
    {
    $ Q3 w" w, _, j" a% p    stack<int> s;
    ( F, j/ ]4 b3 C# G5 q1 C    int tmp;  u/ U' \6 y1 J) P/ v* b4 O4 o# G1 \
        MultiAdjListNetworkArc<WeightType> *p,*q;
    , `; @9 U/ S$ i& E. O    for(int i=0; i<vexNum; i++)! G# s: [4 z1 X- W5 \& x6 N
            tag=0;; e, S$ f7 P; U& m4 L+ Q$ F
        for(int i=0; i<vexNum; i++)# {% B' ?5 B* j( V. S/ F
        {7 h$ M7 Z3 S# t( l. n" m0 l  I
            tmp=i;
    ' ~' r; t; R. }  P$ o& ~, k8 j+ d9 n        while(tag[tmp]==0||!s.empty())
    0 R$ N' u* A. d$ J( h4 u        {
      k, n+ q2 x" r) I            p=vexTable[tmp].firstarc;9 M' t4 @2 }% S$ v
                while(tag[tmp]==0)* x% v. w# y( T) j
                {9 r1 `7 R: e0 Y- D6 V
                    s.push(tmp);
    " c. [/ d" S& M' x& R0 |, G                cout<<setw(3)<<vexTable[tmp].data;* Y! }& B4 f0 w" G
                    tag[tmp]=1;
    ' |$ V: L  n. R3 D' }                p=vexTable[tmp].firstarc;9 F5 {: R1 ?  J
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    3 F0 G( K3 @3 _4 ]2 N, l/ {                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);3 [5 R* f/ o- F/ h
                    //cout<<" 1st     tmp="<<tmp<<endl;
    ) D) C1 H5 ]' t4 ]2 W% {( b! I  y            }9 l* d6 x8 O- l8 E. G' Q) Q
                if(!s.empty())
    ! o& S0 y: L8 |5 ~" |            {) ]* f! L2 c; I8 g
                    tmp=s.top();+ c9 o' Q6 r* ?% ^) g! [
                    s.pop();
    2 H( `' A3 Q6 T9 y! a: b  \. Y% F                q=vexTable[tmp].firstarc;% w' r8 P4 U8 i
                    int t=tmp;
    - q$ X2 H( w, v4 L5 a1 k                while(q&&tag[tmp]!=0)
    6 b$ N1 \* D8 I$ o                {
    & U" Q/ ~! [& ?( C                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    8 p1 J% E+ v. Z/ K( l2 H: j                    //cout<<" 2nd     tmp="<<tmp<<endl;
    ) z" K' \$ ^) g                    q=NextArc(t,q);
    , M# `- k' F+ \4 N8 Y3 Q                }( ?; ^' ?* V  I, V
                    if(tag[tmp]==0)
    0 R' r9 B/ s) \7 J+ l; ?- z                    s.push(t);0 n5 R& Z% j" ~1 K( k/ S7 `$ x
                    ///1、对应上面连通分支只有1个点的情况
    / z) `6 o1 @+ S. X7 s6 S3 t( d+ |                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈1 R- @# a3 ]2 p7 p% c- ?" L
                    ///tmp要么等于找到的第一个未访问节点,5 ]9 u9 W# ?: W7 b
                    ///要么等于与t相连最后一个点(已被访问过)
    ! \( D; `* m! u" n) X& P! `% I                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点6 _" L( a, G+ d* W. c8 o1 v. U3 Z
                }
    + T6 U3 w& s& R+ h9 c% O: o& D# f  ~        }
    & b$ p+ Z% A! M( E1 J4 Q. X    }
    " D$ r6 B' q" A5 u& k}
    , B+ W) K! l2 \, U) |//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    % `5 z4 ~5 f8 P  i! D' Vtemplate<class ElemType, class WeightType> int
    + k  u9 r8 s! e$ Q" bMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    / o( a. C3 ~) C. \9 o& ?{  f6 {- d: c- C8 v( v  O
        if(head==pre): N+ G- e( ^0 F$ U! d
            return -1;1 Q% p( z5 q) u3 q( ?
    * H1 N5 f, H: A  B* j
        MultiAdjListNetworkArc<WeightType> *p;
    & F* ^2 o3 y( v( B) a    p=vexTable[head].firstarc;
    ( G% x  \# `7 _0 h# S4 j: j    if(pre==-1&&p!=NULL)1 x, ^5 |: }; a: e
            return p->adjVex1==head?p->adjVex2:p->adjVex1;7 Z& D+ U2 {) k
        //pre!=-1&&p!=NULL
    5 O5 X" R/ i/ M1 M9 k: S, ?0 y+ c    while(p!=NULL)' {: W: T  y, h* C7 p, J8 z
        {
    3 V6 ~: c1 n# d' r( c        if(p->adjVex1==head && p->adjVex2!=pre)1 ]) T2 _, `" Q1 f3 r2 t2 f
                p=p->nextarc1;
    8 Z& R( X. o1 m- }) M        else if(p->adjVex2==head && p->adjVex1!=pre)
    $ v% x- ?4 ~- ^2 F4 q! Z/ n            p=p->nextarc2;, c5 ~8 `0 ~& J# ]7 t7 @! S2 u0 |) P
            else if(p->adjVex1==head && p->adjVex2==pre)
    " ^  q/ H- e1 ?/ D# ?        {
    & E+ e9 Z! C7 J, z( x            p=p->nextarc1;
    8 u7 J& V9 s# k- m  C            break;4 ~. S5 j6 Q5 x% b9 ^% N
            }
      A; ?8 w7 q! f: W3 |) V7 t        else if(p->adjVex2==head && p->adjVex1==pre)( N# N7 V. z! {% J2 C
            {" B1 C: ^$ ^& H( H8 {
                p=p->nextarc2;, I, O2 V0 _" N$ j9 H
                break;
    3 C- g5 ~/ ^) g0 N' x' `. N/ g: t        }
      L1 I: @' N9 z    }
      m1 m# K/ b4 a1 [1 D3 @6 v/ ?  Y    if(p!=NULL)
    & W! B4 p# E: B* a% h* V    {
    0 y5 [; s" F' r+ Y, @        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    % i/ Z! K0 O; F    }0 p5 ?, B) G% f: `8 ^
        else
    * u5 q! t7 N% K) t  o5 V        return -1;
    * Y& W! N; b$ N4 ]! V: r}0 ?9 _3 V; c% [9 U0 V
    # b5 u" ^0 N" D9 n4 }5 v

    / C; r" _/ d# Z5 L8 r4 Btemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    7 O5 g9 t9 [1 J, x9 S) V6 t$ p{+ P; V2 ~1 F8 P- ~' V4 L) l; P8 r) o- s
        stack<int> s;$ W4 C# d/ ~; J% A: c* m* r/ K
        int p,cur,pre;
    $ x+ C" Z. k3 D    //MultiAdjListNetworkArc<WeightType> *p,*q;. a, n8 b% D5 y% q6 Z: }5 N; T- C
        for(int i=0; i<vexNum; i++) tag=0;//初始化
    . z2 ]# s5 E7 o1 l) Q0 p& D- |  A' U7 Z
        for(int i=0; i<vexNum; i++)
    $ ^# K, Y6 L: v" b    {
    % r3 |0 o  @6 |; [/ m        cur=i;pre=-1;2 l& @& e3 K$ K" {( V
            while(tag[cur]==0||!s.empty())
    2 T8 p/ r0 n/ m& J  {/ q        {
    # S: H' \/ }$ X- D6 V7 O( P            while(tag[cur]==0)- v) c; Z4 ~  W  n7 J
                {5 _$ \# l) r* l. i- N
                    cout<<vexTable[cur].data<<"  ";' n! U  `8 V' F, e$ x. X
                    s.push(cur);9 _" b3 C. y; [) E0 e; G" d
                    tag[cur]=1;; F* R& B, P% t& e
                   //初次访问,标记入栈& Z6 ^- r3 i7 R: E* ?
      d8 c8 k0 |( a! B
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点2 N: v/ U2 s0 s( Q  g5 x
                   if(p==-1)' h  O$ V* [3 ~" S0 Q6 i
                   {# i6 d6 I! |. u( J! Q
                       pre=cur;s.pop();
    & h/ M( U- ~3 f7 ?- W                   break;
    " B4 j( Q3 H. q% |# }               }, m2 r1 }, D# a  ~; c% Z+ p/ O3 t# [/ p
                   else
    $ t( _/ k1 M0 @               {
    ! ~1 W% i- ]: @% p! d4 ^9 v' W                   pre=cur;
    9 w% w! _6 L& V+ S" x                   cur=p;0 y8 Y  ]+ l. @5 @9 I9 o! A0 e
                   }
    " k0 ?" D! E! z! ^" [1 l3 f
    6 s7 V* I/ o9 a! B' r+ e% l            }+ H( e1 y& c4 y* q: N
                while(!s.empty())) _2 \" ~+ u, E
                {( F3 j0 W: Z) [5 m2 M% r& b
                    cur=s.top();
    5 {' A, f% [+ `: B+ p8 _7 ?+ h                p=GetAdjVex(cur,pre);
    ! ]- ~1 p# p8 [2 D0 [                if(tag[p]==0)$ T( N, j& e: a! r) c
                    {+ [' S, s1 c9 E9 k
                        pre=cur;
    6 j1 l$ o& ?8 V9 A  ^                    cur=p;8 j2 I7 T+ Z$ b9 w
                        break;$ e  f1 U) q/ Z" S$ j
                    }! [8 k" j5 ?# l* J" y6 i$ z; b
                    else
    # `# u9 \  E6 R7 ?# n' c                {
    1 l, t. w: F& U: i' n                    pre=s.top();2 ?/ P) E7 [( I' {; K
                        s.pop();1 U6 D' q5 }. ?; W: X( m- z! B
                    }# F6 u2 X+ y3 [3 a1 h

    ' V+ C7 Q1 I! X' U  ~            }" a. {" @- n0 A6 e) {
    % W+ D- x6 ]& l. N, r
            }4 s+ p" G( m/ a: F
        }
    ' W9 d4 A* U5 t}$ Y1 \' Z; `6 ^+ w9 j) B
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS(), v1 X; U5 N+ Q% B
    {
    4 M( g7 S8 i! e$ t    for(int i=0; i<vexNum; i++)& j$ C' P9 h- G8 m5 F2 X- ]' f/ H6 J
            tag=0;9 |5 V* n8 f5 @( D+ `2 X4 \# g) A
        queue<int> q;, [: i2 c7 U; s% O
        int tmp,t;4 T5 D5 e4 I' O# P3 l+ E% r$ ]5 i
        MultiAdjListNetworkArc<WeightType> *p;5 Y/ L3 i( A3 j; M8 k* m: y
        for(int i=0; i<vexNum; i++)- O, r# Q( Z0 N3 T+ Z
        {
    ; ?+ q7 N7 Q7 V) W3 k8 t        if(tag==0)4 C: s' w: a7 h& D( _
            {
    + V: V7 v' F3 ]            tag=1;
    ' m  j0 t1 t* C3 b3 s( U$ i            q.push(i);- p; j0 a0 X; n3 J: `/ j
                cout<<setw(3)<<vexTable.data;
    4 x  ?! h2 z2 r/ v4 n6 _: M        }
    . W1 }& \8 i) Y8 ?2 j: b2 f& p        while(!q.empty())5 B! H! Z" u; z/ S3 S
            {
    ' y. @) E5 L% w$ s            tmp=q.front();
    1 l1 J. A% b' y: F% J* h            q.pop();$ X3 g  z$ _9 G8 O7 ?5 W6 K2 L9 W
                p=vexTable[tmp].firstarc;
    - P- ?  m) z. m. J) ]3 H            while(p!=NULL). W9 V6 ~/ [8 |* B' M
                {
    # L* y; }6 \& L% z                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    # `9 h7 R) }% s2 Y- E* X/ W0 ~$ S) d                if(tag[t]==0)4 a* G4 |4 R& s6 a9 Q9 K0 S
                    {$ ?' g/ \8 L9 b6 R" {
                        cout<<setw(3)<<vexTable[t].data;- O) Z+ H8 h- a) }- A2 _$ ]
                        tag[t]=1;
    $ u; r* t7 j% q; {$ E& \& z                    q.push(t);
    & U. y& P$ c% ]5 w5 r& R                }
    2 K8 b: t7 A0 @. A0 }                p=NextArc(tmp,p);/ B) ?, G/ q+ p
                }2 {0 L+ F1 J+ T4 `, u0 m
            }4 K* \) ?  v1 e6 j0 k
        }
    1 B3 [; E* D( G0 q2 b; m4 [}
    % q- M2 }- y9 I/ O9 {# utemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    1 C) _# E: }& |9 g, ]* u; b8 y{
    + h$ f  G' V6 z    MultiAdjListNetworkArc<WeightType> *p;1 e6 v: T2 k4 p* }( b4 U
        cout << "无向图有" << vexNum << "个点,分别为:";7 p" d0 l! l8 e0 Z( d
        for (int i = 0; i < vexNum; i++)/ }. C( F0 C; k" i9 E
            cout << vexTable.data << " ";
    7 [( s# {' j  f    cout << endl;
    + o; b$ o1 H9 s/ \% `  R5 o- o- ^    cout << "无向图有" << arcNum << "条边"<<endl;
    ) J0 J& A: h: u5 Z! `' m    for (int i = 0; i < vexNum; i++)
    + z& p. z+ F8 t/ p' o1 V( Z. h! J# ^    {) I7 ]; g: i2 A. T
            cout<<"和" << vexTable.data << "有关的边:";
    * z0 [5 o, q4 m1 j. c        p = vexTable.firstarc;7 ?3 L% [9 C, J6 F( G1 w8 X
            while (p != NULL)+ W7 Q0 J: H3 b4 @! e+ E2 s
            {
    % q( F3 x* f  z* u0 [2 W3 p2 g            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";( e! N5 f* y2 s3 y- }: w! {5 K
                p=NextArc(i,p);
    ' a  j+ S: \7 ]" B7 f        }. Z  {$ G" S* B3 u
            cout << endl;
    9 w  J+ b5 B9 L+ o: h& `6 F    }" G0 ~  g' r- I! H, R, b
    }; W' j) x" Y6 B7 K- M. u5 i. Z- @

    1 ^) e  T  u3 L2 V' U4 L  w7 ?( h) u" d( q! k
    邻接多重表与邻接表的对比
    * T: O! t! {4 o" e9 i( B9 u0 {- K2 `& ~/ N# l
    邻接表链接
    9 j8 v# V' \5 p- I/ @在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    # _5 Q8 Q* w" N7 V8 ?/ f: P在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    ( _: u; W& J1 M) I( J  m7 }( U为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。6 O/ ?3 l) ~) \% F  [
    ————————————————
    - ]* R" D/ }9 B版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ! n% Y1 I7 l+ K0 l' q) H9 P原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    + H& |; c4 y/ L& D4 o8 w, h, X, D5 E/ o& i

    5 q/ X4 N- V& F  O# m2 t
    2 Q8 y5 q7 E7 v/ D
    1 F. z7 E' `+ `; F5 r; \. r————————————————) z/ P  z( `2 d1 Y. S
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。& j4 S& {: x; a, q# D
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
      z% f  C+ G3 I5 z( t
    4 i, J9 L% z) ?  `& V# w: [
    4 v- [' `' V0 M3 B
    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-4-20 17:39 , Processed in 0.352219 second(s), 55 queries .

    回顶部