QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1366|回复: 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
    7 `, u1 x4 L9 K/ ]+ K$ d0 I+ S+ y6 @
    图的存储结构——邻接多重表(多重邻接表)的实现
    # `& g- ^  b8 q, X) c0 m, t7.2 图的存储结构
    / ^5 u+ N) T) I- P; g6 t5 T0 Q" W. E) A7 x1 h
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    7 |1 _( M# v" g2 Y, v) K( T8 ?: Z邻接多重表的类定义7 z# c' q! I9 s6 [6 }
    邻接多重表的顶点结点类模板
    ' h) E0 x! {, U4 Z$ }邻接多重表的边结点类模板
    % |. Q4 }- L/ U邻接多重表的类模板
    3 I; l# P7 F7 t. Y邻接多重表与邻接表的对比
    8 B+ A8 m; b0 v/ U  a7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    ; y4 `6 f0 O9 l5 ]
    4 x" a, x0 {4 t5 c. m% y在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。* H  y" f7 z: f# q. m
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。# o. m2 D$ M4 e0 p
    ( w' ]1 k1 F: v
    邻接多重表的类定义
      ?) P( G4 ]# x" _! I9 K, W 1.png
    : h! m7 G5 O6 O+ u: p7 l邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:7 B4 y* w4 A! o: |
    data域存储有关顶点的信息;
    / S6 K+ B. J) I/ Pfirstarc域是链接指针,指向第一条依附于该顶点的边。
    ( s* V' d! d" A  ?: B所有的顶点结点组成一个顺序表。


    + t1 @$ R4 n) n" s$ v* L, |3 Q- b) j$ F! T, t
    template <class ElemType ,class WeightType>6 N/ ~2 M8 s( Q" F
    class MultiAdjListNetworkVex
    2 r5 C. a0 ?7 c4 f  l6 T{
    3 D9 R/ R9 Y) J7 S7 l2 ]; d2 G; [/ rpublic:( V  ?, J6 k: g& [  u/ q8 e: t6 N. l
            ElemType data;
    $ r( ~, F9 F4 d6 x4 v  i& m% y0 ]        MultiAdjListNetworkArc<WeightType> *firstarc;/ ]9 W+ z1 u0 B' k' @
    7 K$ p1 Z& o. P/ i
            MultiAdjListNetworkVex()
    8 J3 g. z6 Z: ]  q, x2 Y% c        {. j- o4 {5 B. A& h& {. l
                    firstarc = NULL;1 l0 |1 b0 R: [7 n( Y
            }
    ; x. \' M$ N+ g" X  y  w! x        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    1 Z8 h) x# b4 O. a1 l        {5 N; {& _& c# M- {' l* s
                    data = val;
    3 B! m0 [4 q( n/ D; K                firstarc = adj;
    9 A2 [. _2 Z2 n( I& a* g$ `        }
    ! d. W0 B4 R% n! E# Z" ?- Z1 U};
    . m( w+ V; E" R, o6 z& M- i% y" F8 s
    邻接多重表的边结点类模板9 [# {3 Q7 ~. L# f

    ( z8 I, J4 S6 z. X, \$ j- U在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    & G8 s* F0 `* X' u7 V4 n3 B/ \$ M8 Ctag是标记域,标记该边是否被处理或被搜索过;8 t; x  p) _& l, t
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    & F8 J- h6 I$ t6 ]: Znextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    ; s1 ]1 k, B6 P7 [  h5 v0 j& |nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。( Q3 T; ]% F- S3 v0 Y

    8 O) P% _3 i& X/ q5 r0 B# j 2.png $ }, F: g, I9 j2 H0 ~, E* g
    template <class WeightType>
    8 j. u0 L! b# T7 l- Rclass MultiAdjListNetworkArc0 k* ?9 b' R$ A$ v
    {
    & T$ ~& t8 d! p2 ]public:5 x. A: f6 J1 [3 Q' z! ]8 m; ]
        int mark;                                       //标记该边是否被搜索或处理过( m& M  f  T5 a4 ]5 d2 Z
            WeightType weight;                              //边的权重, @4 t# Q! R- ]: I& I- D
            int adjVex1;                                    //边的一个顶点
    6 @' D2 R+ i% M, w0 L  y7 \7 ]        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-19 _: p0 e6 j  e( x! `& K
            int adjVex2;
    ) M$ U. ?- N! @4 ?: C        MultiAdjListNetworkArc<WeightType>* nextarc2;6 z( j/ t. }3 k  ?' j- a
    8 W' M  r% \5 I0 Y" \, y; o2 t
            MultiAdjListNetworkArc()1 a1 M4 x) {; {+ C( i/ J( E" G
            {
    2 I$ R1 \' Z! z* u) g3 f                adjVex1= -1;7 ]3 e% ~& b# `- ^! q
                    adjVex2= -1;
    ) w/ i6 ~8 W' [, D" \+ F        }3 N' b% F8 {. D, g* G1 K  N8 T$ l
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)* ~) B8 G6 m2 L- v& K( O3 B7 Y
            {
    , `5 x& L* ~. \# P7 e. o7 W                adjVex1 = v1;       adjVex2 = v2;& l; u  K9 r9 D2 g. K  A
                    weight = w;
    - V& p% b5 ]. s                nextarc1 = next1;   nextarc2=next2;
    3 _: C/ v: {; s" Y7 v. a) Q  n                mark = 0;           //0表示未被搜索,1表示被搜索过
    $ C# [, {2 `2 }        }) m$ }( A2 |" \. }& v8 ?( L
    : [: s9 ?) p0 m; e. M
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>% C- e% }4 M0 B4 P& i  N" X& H: n
    class MultiAdjListNetwork
    $ B! b, m" T/ F$ _+ w. X% o{) ~5 N# q4 B! I
    protected:
    * k7 V6 `. l! A0 D* I    int vexNum, vexMaxNum, arcNum;
    3 R% b* i, |8 ^    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;" f) B& i$ n# `
        int* tag;9 m: t+ W* A8 f5 R
        WeightType infinity;
    ; O$ O( \: r8 B, `" c2 U) y% ^; [! K4 S% |
    public:* k: u( x+ G/ B; c0 g4 v6 _0 Z: u: w
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    3 c( m% ?* _+ d3 ~, p4 o
    * o7 }5 _$ S& Y    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);: @( E& N: s. \2 Q( C
    ) j* o# M1 E, z: J! }
        void Clear();
    , l4 j' Z; ?; f5 \, z    bool IsEmpty()9 \  H2 _2 E1 ]/ z
        {
    1 f9 X5 H: X( F4 U        return vexNum == 0;
    8 f0 O9 ^- H/ J/ ?, k# t* \    }
    ' b" T2 ]  B" o1 T$ l    int GetArcNum()const3 b$ K- D! q  M! W' m) M+ w
        {
    " \$ a& `# Y' t$ P0 a" L- a- g        return arcNum;
    / L$ c! E1 [0 m( u+ H    }
    ! @& g: u/ r4 c5 a4 ~2 Z    int GetvexNum()const' ~0 r9 m6 k1 B# r
        {
    ( p: l4 I$ b9 T& ]( u8 }- M        return vexNum;% j5 }* A" q# Z8 F; U
        }) L: `, R; I, W1 A# d
    ( {) r# n& Q  Z+ n, m2 t) T7 U
    / o7 {- [& O3 G; j6 [
        int FirstAdjVex(int v)const;% G- z6 |. S' ]- }  ^  N
        int NextAdjVex(int v1, int v2)const;
    - o5 R( `, @" |) F    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
      f3 l3 s( V& a9 B    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;( Q- b$ C; `# m; A1 N, n
    $ `/ g' A; @" y9 D/ B" u. S
        void InsertVex(const ElemType& d);
    5 M5 L8 ^% a3 Q* ?; _8 [$ {! [! s    void InsertArc(int v1, int v2, WeightType w);
    ; O5 {& S+ O( U" V1 m8 S9 s3 v1 @( m" d7 ^& T$ y6 [5 r1 O
        void DeleteVex(const ElemType& d);
    / N5 Q5 f# W. f) `5 ^6 G    void DeleteArc(int v1, int v2);
    # Q7 Q$ G  C9 N( p, {1 Y
    & ~- s  E3 M! v$ F7 n4 [$ f% {# B    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    * @2 H& ~8 V7 m9 V1 J- e  N% H    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    ; C8 Q7 \8 d5 {3 Q, r
    0 F9 p2 G* b! t; D1 N    ///深度优先遍历' x  y" H) d* ^5 w
        void DFS1(const int v);
    4 o3 D9 G6 ]7 g7 {- }# R    void DFS1Traverse();
    4 p& m/ |# Q( q    void DFS2();
    5 T+ J/ w  L5 N% G* g* f, Q& H7 B0 B5 ~, {( X# k. R9 V& V
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    & `  c* \0 n5 \0 O; u' F* ]* {1 S    void DFS3();
    : _  }9 ?9 n& Q% \  c4 Y/ {" b/ U9 _# F7 y8 l
        void BFS();
    5 W- {4 g  S) H    void Show();$ P% N% R3 s( x: a/ V' J& O2 t
    };  o3 a7 u: z2 ^: _7 Z

    " b9 r- C- r' U. j2.函数的实现8 F5 A/ ]3 {; s1 Q- K" ~
    研讨题,能够运行,但是代码不一定是最优的。
    ; q1 ]7 J( H! C" I$ M, x% R3 A8 z, A8 V/ G$ P" {3 g
    #include <stack>$ v3 e1 C. k' L" Z1 L( w
    #include <queue>
    7 D* q. P% U8 y8 d5 l0 z2 g* U: r; k9 C% s8 e+ Q& b
    template <class ElemType,class WeightType>. v/ E3 j0 K0 ]2 S. |( f, v% S. s
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit); r2 L; \& \$ q7 x3 ~  ^
    {: Z: i* p9 U- T) r
        if(vertexMaxNum < 0)! e* t6 [+ T4 A; R$ Q; Q0 v
            throw Error("允许的顶点最大数目不能为负!");' Q" F& A; B/ k6 Q
        if (vertexMaxNum < vertexNum)5 M6 I+ ]8 `1 A7 p" U' g
            throw Error("顶点数目不能大于允许的顶点最大数目!");. p: R! j0 z; C4 X8 k
        vexNum = vertexNum;3 k+ X+ f; ]+ Y7 y3 z: L: L
        vexMaxNum = vertexMaxNum;1 O- }" j% ^+ x7 \5 T+ t
        arcNum = 0;, c4 v0 k5 P- C+ s% U6 N- C3 a
        infinity = infinit;
    1 B- m$ N* Q" k* J! q9 r' O4 Q    tag = new int[vexMaxNum];' v7 S: ^" Y3 T' V/ n
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    ' {+ _- o6 Z) H! @& F6 m- T    for (int v = 0; v < vexNum; v++)
    8 U+ F8 T) N2 l5 P( S" a: d    {3 c0 Q; m1 Y# C, F7 Y" M7 A
            tag[v] = 0;1 L9 ^9 i8 B' w& Y) W4 x
            vexTable[v].data = es[v];" n& c" b. ]: o5 A5 n
            vexTable[v].firstarc = NULL;+ z7 b: R; l* @; p; n, I  v7 J
        }
    6 k9 b, _' @! o* y6 m6 u}
    & _9 r, _# X8 U# ~% s+ S8 L$ r& B& Ltemplate <class ElemType,class WeightType>) R7 }4 ], ^0 z
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)* O& D$ B# I1 E' V% S) G: M
    {
    " H+ s( F% ]" ]! y  n    if (vertexMaxNum < 0)- s: N2 N" w# r7 P
            throw Error("允许的顶点最大数目不能为负!");+ y3 M! c5 A; [
        vexNum = 0;  [: p. W' i0 r. o# k& F, i$ Y
        vexMaxNum = vertexMaxNum;: c% ~& Q8 u" y- W  r. P
        arcNum = 0;/ M$ ?/ U7 i* s3 |" X" ?
        infinity = infinit;( u  }; b2 o* U- W& y! B7 J+ j
        tag = new int[vexMaxNum];
    3 P. S- _  Y( [9 e* F- K1 p    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];# V1 V' r1 W8 g' p( U) y6 l8 w+ y* A
    }5 M1 f# r1 l. C5 }1 T' A8 I
    template<class ElemType, class WeightType>' [% V7 i3 r, M5 Y0 c$ |$ L
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    . k& x& j4 y8 Y+ _7 k{
    9 e1 h' `. ^; D( g8 c8 u1 {    if (v < 0 || v >= vexNum)
    , w) b* p. }- w/ D0 B% C( x: T1 d        throw Error("v不合法!");
    : A  P+ {" y$ P    if (vexTable[v].firstarc == NULL)
    9 \. |' ?( ?) Q/ u7 o7 ]        return -1;
    5 u! K% ?7 s: T' _    else1 {3 A2 T3 `  W& j8 d' E
            return vexTable[v].firstarc->adjVex1;; M( M% w& @5 G2 r0 p
    }# G6 B1 ^" B) Q* z1 Q, f1 q
    9 f' Z( {0 n, h# I: f# O
    template<class ElemType, class WeightType>
    $ i) i; n# J& a( O, {7 P; rint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    * ]/ D0 t- `$ a9 c3 {' l{
    ' W: o- r: j7 F& d2 ^3 x  A6 J    MultiAdjListNetworkArc<WeightType>* p;+ w  r6 T! G" h+ H; j/ \0 k
        if (v1 < 0 || v1 >= vexNum)
    5 [5 `# q2 X7 j' w) j$ T3 R        throw Error("v1不合法!");* M& a7 R: ~" s1 s
        if (v2 < 0 || v2 >= vexNum)
    $ {$ X) A( y2 ^' x' b# _  K        throw Error("v2不合法!");& [* O- k/ w3 c+ C& R
        if (v1 == v2), D6 C( S1 b% [" h5 h
            throw Error("v1不能等于v2!");/ g8 U6 i1 q' o: v2 t
        p = vexTable[v1].firstarc;( Y) Y/ P  w+ Q
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)8 @9 {1 l: F8 A
            p = p->nextarc;
    ! @0 S$ C9 w+ B1 p2 f    if (p == NULL || p->nextarc == NULL)
    " i' [! e  u. V/ p6 V        return -1;  //不存在下一个邻接点
    ! M/ I2 ]3 t! t  j& @/ n  V    else if(p->adjVex1==v2), _! J! ^' h0 }( `" H
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    ' ~1 J' ~3 \. q% L% P1 v; L4 v    else% g5 n+ ?6 ^1 U  Q. K2 j) x
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    9 q  i  P. p1 e8 K8 ]}
    / L' w' U  r6 ]* A" ytemplate<class ElemType, class WeightType>
    2 k# X) f# B, c/ J' X1 _7 }$ Hvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()0 D# y0 J. b" [
    {2 m/ s# e  ]# h+ k5 {5 g' ^
        if (IsEmpty()) return;+ W  M! v  \* n, ~( q1 F
        int n = vexNum;
    + |7 x0 X# }3 B    for (int u = 0; u < n ; u++)
    7 H% h% g) [  E) m4 W6 u        DeleteVex(vexTable[0].data);. U& Z3 D0 z9 C& X
        return;
    . G9 |( |) L( n: G: }& d}
    ) C1 [/ T! V8 D2 n# V+ c+ F% p5 ztemplate<class ElemType, class WeightType>5 v2 B. M4 h1 J7 V) Q! D
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()9 [$ [+ E; i- f+ n2 f
    {
    " Q# [( @0 N; Q' _" F8 b3 T  t& M    Clear();# U+ T# q7 X, h9 Y/ [, m& x+ P
    }1 |2 c4 m+ e  J$ K! X+ ~
    template<class ElemType, class WeightType>
    ! s6 b" v8 a3 u/ S5 \$ O9 C8 b" YMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    3 j2 L/ z' W( C2 x3 D  I{- W, a5 d$ f- R9 Y! Z; y- \! o
        vexMaxNum = copy.vexMaxNum;
    7 f( L2 k4 t3 i6 H9 K. l2 k! p: A0 s    vexNum = copy.vexNum;0 s" V7 W- N5 s3 A1 T' d7 [
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    # ?# f3 D/ P" o" k2 v    arcNum = 0;: E; W1 a- X& Z: r2 f
        infinity = copy.infinity;
    / P' \: V- d6 R5 P/ R( E8 ~    tag = new int[vexMaxNum];/ r$ W/ I$ R* H5 K
    6 ~) @/ Y  o9 A! o0 E
        for (int v = 0; v < vexNum; v++)
    0 h! P+ o. T8 m    {6 f7 Y- a: X! F8 o8 e
            tag[v] = 0;& {# L0 u8 m, U7 x: t
            vexTable[v].data = copy.vexTable[v].data;$ E8 Q/ m' R+ i# A! w" u2 [
            vexTable[v].firstarc = NULL;3 |  v0 q8 [! j3 Q- n, j3 t7 s
        }
    : v/ ]' Z; E. }, f, t: |; e+ `" Z* L    MultiAdjListNetworkArc<WeightType>* p;
    ! g* G# d8 Y7 G& l5 n* {9 S0 ]$ H7 c3 h8 N) G, x+ q' P' x2 q
        for (int u = 0; u < vexNum; u++)" c$ z4 M1 ]- L# m" l2 V3 G
        {9 b: r3 d' q" k+ j7 n  f  W
            p = copy.vexTable.firstarc;
      ?7 k# d, l/ y0 f" |$ K) R        while (p != NULL)
    2 a8 R# \; E, q! _) Y/ z        {
      o2 U% g1 H. L# N# \            InsertArc(p->adjVex1, p->adjVex2, p->weight);( C# N) {7 }; i, _! h8 c& B% Z
                p=NextArc(u,p);
    9 v& n5 e3 t3 ]" T  N' G        }
    . `+ J  v+ u- G    }
    7 J! u, X8 x% d}
    , U4 q7 d7 R. N/ d2 Ptemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&% S( g6 e: l4 Q- S- k  @3 M. f" H
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)( W7 b/ @6 E7 z4 ?8 e+ N+ h2 Z( [9 y! n
    {& e. ?0 a: w4 A  j" s" g$ x: d, U
        if (this == &copy) return *this;# T" T/ K  U5 a
        Clear();
    - p. I6 Q7 A" @2 l# x( b( I6 P    vexMaxNum = copy.vexMaxNum;
    % a8 Q7 U' P2 p/ f    vexNum = copy.vexNum;7 [# X7 F/ a! p! U! H
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];1 T0 a: B/ n. I  L$ r0 j
        arcNum = 0;
    : n! ]) d4 h) |* j4 w    infinity = copy.infinity;2 C3 `" v7 J+ X5 d/ D1 u
        tag = new int[vexMaxNum];
    " ~5 Q0 W: l6 B: J( S! e+ A
    5 M% i) n& H2 c( Z    for (int v = 0; v < vexNum; v++)) i) V% v. O- q' q
        {
    % z$ ]$ G2 G* `) W% J7 N+ U        tag[v] = 0;
    $ e4 \* e& A3 w1 b+ Z- k( D3 W6 G        vexTable[v].data = copy.vexTable[v].data;5 l0 i) h$ p1 b* E; Z, L$ K: [
            vexTable[v].firstarc = NULL;
    # {' ?) n. t5 w' p    }
    # n: X  E; e, }  W! H+ Z/ W    MultiAdjListNetworkArc<WeightType>* p;
    1 a) L/ E  Y  `/ N) @! ^
    ( S6 |, m2 F  s    for (int u = 0; u < vexNum; u++)
    % q( J1 O- ^( v% |" e    {
    6 j+ p( C7 T  f* t/ T% c        p = copy.vexTable.firstarc;
    3 U, c% K7 u& }$ o& ~( V        while (p != NULL)( ^1 x5 m' X: J3 d  l& O$ X5 j
            {
    3 }3 e4 c: F! [            InsertArc(p->adjVex1, p->adjVex2, p->weight);# c* m, k! e* M+ v
                p=NextArc(u,p);$ \3 H2 X# K& Y, }% z/ v5 q1 Y
            }3 o2 h$ w/ w+ V* Z7 q
        }  f" \- i( ]. t
        return *this;7 _+ ]0 j( `: `7 `, w" N
    }" T  m+ ?8 Q( f, I4 k
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*9 S9 ^7 x! A4 j( x; \
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    5 {0 O/ G  a9 V, S  W{
    ' n' ^1 q6 E: q  q    if(p==NULL) return NULL;% s4 d0 |3 j- d
        if(p->adjVex1==v1)
    ! p  n- j; W% t0 u        return p->nextarc1;
    4 w. d* N8 p$ R2 a    else
    8 n+ j7 F4 p9 S+ o( d- s8 f        return p->nextarc2;/ S6 I: q. O+ m) |
    }
    9 v+ N* ^% ^6 x: Mtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    ! B/ m$ m0 F: c8 Q% e1 e- I8 t5 VMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    . I0 Y$ I7 p3 F3 E, n{' f8 y! J: F/ ~. H- Q. ?
        if(p==NULL)return NULL;
    2 L3 Z4 p; U, E( g# o    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    4 o' t# R3 U5 s2 O# l* u) s1 w    if(q==p)
    . L* s8 C% F! V) z0 e; a        return NULL;! H" b0 \& |- D
        while(q)
    - V- t7 N, I) T6 ^$ M6 E/ Q    {
    . K  s" T& \; v- p4 ]8 {& D' W        if(q->nextarc1==p ||q->nextarc2==p): [6 L, P- T% m" J# f6 V+ L
                break;
    " W2 o1 \: Y$ _  x- j. w        q=NextArc(v1,q);/ N: J8 L2 l, a. j8 i! P7 x2 e
        }; h5 X) j7 {6 u, Z, ]! E
        return q;% E5 d9 |6 u3 X- p
    }6 w5 ~5 L- A0 g
    template<class ElemType, class WeightType>
    6 o! N! r$ h/ \8 @/ \# Hvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)( b& G9 [1 Z0 h  a" p# c  }
    {8 ?" I* L1 ?$ b" _
        if (vexNum == vexMaxNum)) M* [' s6 w  n$ N7 T; w
            throw Error("图的顶点数不能超过允许的最大数!");
    + k9 x" R  d+ W9 O& K" z    vexTable[vexNum].data = d;0 k' F; q0 w3 ^; N! G7 `$ l( [" a) f
        vexTable[vexNum].firstarc = NULL;1 x7 R1 l0 ]+ U" J5 T. l
        tag[vexNum] = 0;
    . q, h( _& p8 Z3 w+ R$ d    vexNum++;! V' [7 m. }, l! R( v, |# H
    }
    ( r, K5 P. L; z; N0 z) ]template<class ElemType, class WeightType>% }  }8 t7 i+ Z3 y0 L/ H# |# `
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    ! T& N4 t$ c8 b3 b% Y1 L* a3 ~& b{
    " z3 u5 b7 V* Q* f2 x) R& q/ m; ^    MultiAdjListNetworkArc<WeightType>* p,*q;5 d2 v# K; H0 U" S) ~
        if (v1 < 0 || v1 >= vexNum)
    0 ~) h6 D' c" ?5 Y9 ?' o        throw Error("v1不合法!");
    & }, l: a  |/ l; [) D    if (v2 < 0 || v2 >= vexNum)
    1 U' Q4 M) I: x  U1 S) f$ i        throw Error("v2不合法!");# \! H- o1 K5 t, J+ I8 q6 e
        if (v1 == v2)/ E" @! J- B' o7 `; U7 X1 E+ u
            throw Error("v1不能等于v2!");. I# @; |6 M7 U( |' x- u5 e
        if (w == infinity)9 F8 ^; x( s- H  ~6 A
            throw Error("w不能为无穷大!");
    / R9 s2 y3 g9 e& k1 C) J) @) I! J: q& w! y) o+ Q

    ( @& g3 M& }+ s' I( L1 ~    p = vexTable[v1].firstarc;2 g: R: C) D! f* b
        while(p). n- g0 n7 E; H( V: w9 S* |) j1 x
        {; K, `+ ?, _% U, j6 C
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    / X! k2 F) \, @3 v% F) M! O+ u2 l4 Y        {' d6 \& `2 a" d, ~$ r, x
                if(p->weight!=w)
    9 V5 t( }& A6 j& S/ G2 q                p->weight=w;3 a& R: ?+ g+ h; F8 H
                return;9 k  {4 ~! v" R! L& l4 c
            }8 p$ k3 h; k# H/ k% F, B
    ; D: y5 @# F+ ]0 F- P
            p=NextArc(v1,p);1 e  Z) r) H9 Y# Z; h
        }: t/ h  s) r# e
        p = vexTable[v1].firstarc;. X) G0 X* S0 a, T
        q = vexTable[v2].firstarc;
    6 y8 z/ b7 v$ q1 ^/ u2 G    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    4 a  J6 \. j$ F. T    vexTable[v2].firstarc =vexTable[v1].firstarc;7 @: S& x9 X& y! q
        arcNum++;5 n( r* L4 U7 U* t& t% ^
    }
    6 G; L9 ~+ H/ v/ Q6 B4 O+ |' M6 x: }
    template<class ElemType, class WeightType>/ O' Q& B0 V; Q. L& `$ Y/ p
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    ( m( ^0 m2 Y  ~" d{. Z: ?* {3 i8 a& @% z, |  G
    * b  W0 Y- T6 v+ P0 ^
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    , b; i( ~9 O3 f6 I    if (v1 < 0 || v1 >= vexNum)
    , S) v  e, C1 j* A        throw Error("v1不合法!");
    9 X1 t3 E9 X) X$ u    if (v2 < 0 || v2 >= vexNum)
    % R; F# S8 o5 \. |        throw Error("v2不合法!");; W, t  T* \7 n: A7 Y( r
        if (v1 == v2)  s: P! y# v8 A. R0 T; @
            throw Error("v1不能等于v2!");' o. w$ O+ b1 m7 d* d, r) \
    ; i0 r' v3 @' j' P/ {- P
        p = vexTable[v1].firstarc;/ T5 T9 R$ P* }6 g
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)) ]) p" t. M" `8 y- U
        {) [# Y0 C8 R1 A: d! u6 |
            q = p;6 R3 |! {+ l, c* r' I
            p = NextArc(v1,p);
    & M8 Q# l1 l$ z8 x    }//找到要删除的边结点p及其前一结点q' }2 }, f, Q# ^5 \9 G* e

    2 v' W/ M- u! `- K    if (p != NULL)//找到v1-v2的边( E- @, }# b6 ?, K' H: n
        {
    9 U4 W% b. D- @: O% b1 n        r=LastArc(v2,p);) z! w  _; C5 f& ^. p- `/ G, q
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    * |* M; Q% l- z; l% `            if(p->adjVex2==v2)6 g$ @$ ?6 |0 e4 M" A9 Z2 B. U
                    vexTable[v1].firstarc = p->nextarc1;7 W& D+ A/ q; @: D
                else vexTable[v1].firstarc=p->nextarc2;
    5 H; Z8 F) x2 w* @5 t2 G' c* y7 m        else//不是第一条边
    ) s3 \& g  @+ s. K& X- ^6 c        {
    5 `8 S) R5 ~; O* w4 O- w$ Q0 k0 E            if(q->adjVex1==v1)
    ' Z) ~- h5 z: w) a+ `" `! l8 f                q->nextarc1 = NextArc(v1,p);5 m( ~( M% E: z4 J2 J6 S( @" D
                else
    ! C: h& w! H; o) g* e' y                q->nextarc2=NextArc(v1,p);9 N5 I0 H. E- N2 m0 m( \; L
    % s# w' D# T7 p- k0 M# |: j9 M. S
            }9 D6 m6 O# }. k' x; D  w( {
            if(r==NULL)" O/ Z- `7 j9 O% J7 H# f
                if(p->adjVex2==v2)
    3 |, d; ?" S4 l6 O0 H                vexTable[v2].firstarc = p->nextarc2;
    ( o% i! v, Y& u2 r# i            else vexTable[v2].firstarc=p->nextarc1;
    % ~2 n  _/ @' e& J+ x        else+ Z4 Q' K; n/ S, C; l, O& L
            {' B7 @; @/ H" U* {, u1 R
                if(r->adjVex2==v2)
    & F3 O0 e7 N  {& A! y                r->nextarc2 = NextArc(v2,p);; F- ^( @; l# |1 w4 B+ M- ]
                else% C, A5 {& M9 M* H, V  n
                    r->nextarc1=NextArc(v2,p);" O* ^1 k; L' {* f( G% i6 k
            }
    . C7 a# j2 L% j; ~6 A6 |! t        delete p;
    " T7 r; c2 Y! X& K3 D. {0 Q        arcNum--;
    ; u* V9 E3 x9 E2 w8 Y, k" S! K    }: S, |2 `% Z$ i  R! D

    2 E  O. [; R0 Y}! S5 N4 F: o( g. N) w# y
    template<class ElemType, class WeightType> void2 y, G4 r5 ?9 O; k6 ]/ l
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)- I. F; A, o3 j5 d
    {4 R8 U% G+ o2 w  A" f: j3 I
        int v;+ M  Q. ]% L% d) r
        MultiAdjListNetworkArc<WeightType>* p;. A* o' J8 q. G7 I/ P. B, f
        for (v = 0; v < vexNum; v++)//找到d对应顶点1 A( y$ e( T" ?( R, o# K
            if (vexTable[v].data == d)) {- j8 k  i6 T: Y6 m
                break;# O8 C" {( |* L) S' }. [
        if(v==vexNum)
    3 v3 b. N9 {, t, f/ Q5 [7 X% t        throw Error("图中不存在要删除的顶点!");. ]! t6 |! e3 S3 m* S2 ?5 p8 _9 }

      _! G8 |: u' r. V- q" u    for (int u = 0; u < vexNum; u++)//删除与d相连的边6 Q7 T! o0 c8 Z9 J$ z
            if (u != v)
    ! I* Y" F# v/ D+ X" L        {4 _2 B3 a  D# ]3 c; _$ k7 }
                DeleteArc(u, v);! J7 ]6 ?* Y  {; w
            }
    4 N5 z+ p* s7 u: |# u1 E* `# ~    vexTable[v].firstarc=NULL;
    / \4 Q# w% d( L9 G4 Z
    ! _8 V4 W6 Y& V  O* ?& n% D    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置3 g, u6 s* ?/ h, C$ H0 J% a& t
        vexTable[v].data = vexTable[vexNum].data;! z( ]7 X4 {6 h& u; |7 q( T
        vexTable[v].firstarc = vexTable[vexNum].firstarc;
    / d, x' O2 a6 f/ f8 r. [& r    vexTable[vexNum].firstarc = NULL;
    ) x2 K" K' n; g' K: b$ [) _! g. }+ U    tag[v] = tag[vexNum];
    , V& g- l3 {' A9 g3 M: h- V+ R    //原来与最后一个顶点相连的边改为与v相连
    8 e$ t* P! r8 U" {0 [    for (int u = 0; u < vexNum; u++)
    ( e4 u5 L( y: \' k1 h; q3 }    {# g% Q: g, H) y/ C. o5 |
            if (u != v)
    * v$ y7 l0 H& J: C! F        {
    . O% y: i$ A3 t8 q            p = vexTable.firstarc;
    " K6 H+ X0 o# b: z+ V            while (p)6 L* ]3 M6 U1 }( h# t: i9 x7 O
                {
    4 |3 K. b% G' K: b                if (p->adjVex1==vexNum); @/ p, ^4 {5 B- `' {0 G; z+ K9 d
                        p->adjVex1= v;4 f" h8 z6 q& a$ v- T" x/ ^
                    else if(p->adjVex2==vexNum). k2 Q7 F9 k) {5 H
                        p->adjVex2=v;2 y/ O7 k; ?! i2 @( d, B1 i' z
                    p = NextArc(u,p);7 f& u4 \' U7 {& W: z# ~! ]
                }
      G" L2 l7 j4 E        }
    # ~# n* V$ G. e4 y% P    }
    * E/ C) l6 _5 Q9 v6 x}; d$ Y& ^4 N; G! S5 H! @8 Q9 m
    ///深度优先遍历
    % b' n4 z  v+ z2 H+ Q- atemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)$ R5 @( O: y4 P5 B
    {4 J1 y; q& N2 p8 t0 _9 z# x
        tag[v]=1;
    3 j0 {* A' }- a6 O& U    cout<<setw(3)<<vexTable[v].data;
    , y/ \) Q5 @% s7 O- g    MultiAdjListNetworkArc<WeightType> *p;1 P& b2 `9 V# R7 a0 A# n+ x; G
        p=vexTable[v].firstarc;. z" t: _* f8 J  Y/ r
        while(p)
      ^9 [9 C3 _7 e$ j/ {8 Y$ p( F$ z+ a5 D    {4 j; C+ M* l# K9 {* \* M) ], x
            if(tag[p->adjVex1]==0)
      X+ l( A7 O6 t* ^) |& r            DFS1(p->adjVex1);0 [$ p3 A# `, {
            else if(tag[p->adjVex2]==0)
    7 z$ C, b5 g+ U" \' r            DFS1(p->adjVex2);! G+ O7 g- x6 Z
            p=NextArc(v,p);
    + e  m7 U" Z$ }! H1 t3 g3 \- E    }
      n% o3 r9 C' f0 [}
    & Y3 r( f- \" R+ }% ytemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    ' t# m4 t# _1 t3 Q" C% E3 H1 d5 D{, M" s7 w1 N' P& _
        for(int i=0; i<vexNum; i++)
    % d; o! ~, K; Z5 p1 f        tag=0;* O% }4 [& [/ Y$ _/ ]+ N. F) m! g
        for(int v=0; v<vexNum; v++)( k+ z# t( C; U* U, z4 N
        {
    2 ]1 N7 g6 @* ?        if(tag[v]==0)
    ' R7 h. e, C3 F" i1 V5 d            DFS1(v);
    2 w1 a! c! c( R' a    }
    1 I) z9 E/ j1 [" e! S" k5 t}
    5 T6 W0 g) ~+ H* m/ wtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    8 y4 _( B8 l4 m{
    # [3 [3 @; o2 o( B: e    stack<int> s;
    3 k, o5 B$ W4 |& ?/ W* _+ z* ~    int tmp;
    5 R! E( R  O/ e4 y4 \7 [  w, T    MultiAdjListNetworkArc<WeightType> *p,*q;
    + d0 \: R: g- b9 \* F( X6 Z7 |    for(int i=0; i<vexNum; i++)6 v' E1 Y. w! h+ O  Z2 s
            tag=0;
    ' I% a: s- F, P+ i    for(int i=0; i<vexNum; i++)
    3 S" A8 a4 h" \7 }: M1 f    {# J1 p1 z  k1 f! H  X8 o: x7 y8 p
            tmp=i;, F! E& w! i- l) P5 S$ m
            while(tag[tmp]==0||!s.empty())
    - U" y7 s, h$ P# V+ E8 f- U3 _. d        {: h6 p0 h$ ?0 D0 L; }* \+ R5 S
                p=vexTable[tmp].firstarc;( |! K4 B, q8 E. o
                while(tag[tmp]==0)6 r- _  F% }) }2 u0 u9 V
                {
    + t0 Y( [6 e5 ?4 r3 H% d1 e4 E# m6 F                s.push(tmp);
    # i, Y6 y8 E- h1 V+ f; I                cout<<setw(3)<<vexTable[tmp].data;- S" a8 o: _' g
                    tag[tmp]=1;+ G- n$ N& ^4 m* l/ k- v7 p2 V
                    p=vexTable[tmp].firstarc;8 Y! I1 G0 }4 f2 k- L& o2 B
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for8 t! f8 ^1 |) r( d% b+ Y, U
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);( s! D2 g7 b0 y0 j( c2 e# b
                    //cout<<" 1st     tmp="<<tmp<<endl;
    ' q; P0 ?2 u/ O& b) h            }/ e- ^1 O( v. W$ M9 ?4 y9 B7 t3 H
                if(!s.empty())5 n/ k* M8 U5 h
                {1 n) ]5 e2 l  T
                    tmp=s.top();, F; z4 ~, B3 p+ J
                    s.pop();
    + i  v$ H9 }' @4 a- [3 \                q=vexTable[tmp].firstarc;
    / O: ]# o6 q, ~; u7 Q: T3 r                int t=tmp;2 f  l4 f* G" Z# Q- h0 U% ~
                    while(q&&tag[tmp]!=0)
    1 B. V  A/ ]7 L# i                {! R. h# m9 W5 c$ d
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);! r5 I1 h, g( |* t- \+ U: x5 w# x+ p5 o
                        //cout<<" 2nd     tmp="<<tmp<<endl;) l/ C# y3 ^9 I3 l$ _; D
                        q=NextArc(t,q);
    4 s' n5 J, {1 j! d                }
    . \+ v3 n# i% S# l                if(tag[tmp]==0)
    . ?# {+ D0 T. X, g; l, ~/ t                    s.push(t);7 M( ?5 T' d) N2 B3 A
                    ///1、对应上面连通分支只有1个点的情况
    ( i9 w! T: ~3 p                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈7 f2 E9 ~1 b( l! ^
                    ///tmp要么等于找到的第一个未访问节点,
    ( b. A% D! j' p8 c) q5 G                ///要么等于与t相连最后一个点(已被访问过)$ J. U  R! }. f' Q* c6 \, V2 |
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点9 \9 H6 w5 d$ K# p1 A- [8 J
                }
    3 O  O1 X. R/ ?        }% c' n; ^, d- ]7 A
        }9 A* M2 a. T  p9 @+ \/ y! u
    }
    # B9 y) n/ I0 G$ s6 ?! I9 t* d//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1" W( a8 W. ^3 G7 ?: U( L& s4 J
    template<class ElemType, class WeightType> int
    2 b! ^" d3 P; ]$ SMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    ' H0 W& o1 ]0 y; s0 @{& F3 i2 _- n# J, ~
        if(head==pre)
    * e. l. B& C, b, z        return -1;
    8 G3 P) ~9 j: r4 i1 N! c) }4 D
    , G$ o' p) r4 x5 I" l8 N    MultiAdjListNetworkArc<WeightType> *p;4 {6 y) c( w% R2 b+ V8 O
        p=vexTable[head].firstarc;- ]" Q% I  B4 L8 F' g7 E
        if(pre==-1&&p!=NULL)
    0 E' s6 V6 `0 D& L3 Q8 ~( S        return p->adjVex1==head?p->adjVex2:p->adjVex1;6 a* N$ t# N! @) ?1 N
        //pre!=-1&&p!=NULL
    ' e  s7 Y) L" {+ t+ ]; m8 T    while(p!=NULL)0 y' H: A5 n  d6 }+ b+ {! i
        {
    1 c# \, f; `! N        if(p->adjVex1==head && p->adjVex2!=pre)8 t0 ~8 U" a3 k. g( B1 E/ V$ \9 T7 F+ ]
                p=p->nextarc1;, N% L2 U! ?; Y4 C
            else if(p->adjVex2==head && p->adjVex1!=pre)
    , S! \3 t) K6 Y: `' g$ c            p=p->nextarc2;
    : I3 [3 @7 h6 }! [6 k* \3 T        else if(p->adjVex1==head && p->adjVex2==pre)8 J$ y# ^$ o/ X5 D
            {9 n. R! }  E4 I
                p=p->nextarc1;
    * p+ n+ J6 V$ a( L. Y  m            break;. k# p" ?% f% j5 E
            }, u0 ~! p5 l, ~
            else if(p->adjVex2==head && p->adjVex1==pre)
    ! _% U% ~2 }- V) d        {- v8 R- S) w, @; T$ X( i" G
                p=p->nextarc2;+ f* K9 P; A8 R  Y
                break;! P$ N7 t2 I' U
            }
      q. k* I6 n7 R8 V    }
    " v) [" v! m( Z& W# a9 M, h    if(p!=NULL)0 H% d( l( m, b# i
        {0 g/ j6 q3 o) z: T- u/ L6 k, u3 g2 Y
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    . J6 w/ b5 G- X! C3 V8 N    }7 b: o0 i3 u: B( g3 |/ w
        else
    , x; Z6 ]2 n' E7 [/ d( h, N        return -1;" R( i2 O, |$ r0 ~
    }" V3 p, I7 Y8 U4 m( f* |

    5 ^; K  r. i; W$ F5 D0 s4 {8 J. R0 I
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()/ |/ N* f9 T) Q1 R: b% Z9 j
    {
    " I3 u6 ?9 A. W/ i# M) l6 w    stack<int> s;3 `1 [0 H) `& T, ]  L
        int p,cur,pre;
    2 a3 _! m3 i4 l3 n    //MultiAdjListNetworkArc<WeightType> *p,*q;. d0 x4 g- k4 Q
        for(int i=0; i<vexNum; i++) tag=0;//初始化9 O/ ~9 [/ I# E7 o4 h' Y( C
    7 I' s5 B% t# \: ^' F
        for(int i=0; i<vexNum; i++)
    ( m1 h7 ^, x. Y3 b1 B/ @' m5 G    {  Z' |! M! @( D
            cur=i;pre=-1;
    ; Z7 p% W* }+ ]  b$ W        while(tag[cur]==0||!s.empty())
    2 K9 ~; t8 R  P* Z; ~        {
    ; R8 K* I" W( v( f" v/ v            while(tag[cur]==0)6 b, J) Y  `- L, W( o! L* y
                {- t! G  J9 T7 g6 Y3 f$ p: _% b/ o& ~  `
                    cout<<vexTable[cur].data<<"  ";
    3 y) s, j2 f, e# y+ m2 \                s.push(cur);
    ) B- Y/ |& h; ~1 h3 M- ~                tag[cur]=1;
    5 P* d* c3 P7 k& s9 s               //初次访问,标记入栈1 E6 N7 L$ i& i' Y+ I

    ( P. g6 M2 Y: y. l. u+ m               p=GetAdjVex(cur,pre);//p是cur的连通顶点
    2 C; i! e; D. J. r4 C1 c7 N& l* z; C. H               if(p==-1), F+ v2 W- m( [) m
                   {
    8 B) `8 n: D- ?. b. A7 s                   pre=cur;s.pop();" A+ b! C( j3 q2 o; L
                       break;/ e/ J0 [, y+ @+ D2 g- {
                   }* R; `& z1 n! E  R6 U; o0 n
                   else: K6 @" F; i* h/ J
                   {9 E% L, P6 X+ X7 i1 m6 `
                       pre=cur;
    9 ~1 y! `" N) V3 S2 x                   cur=p;
    7 T+ Q& J) q# X6 N1 R               }& c& Z6 ^* Q& k9 \2 ~6 X: S
    1 u. h  ?) ?, `* C
                }
    $ p. h& T- y4 l2 c: @            while(!s.empty())
    % g0 g7 F* u( y; x$ r3 K, d            {- k- i: I# {* g
                    cur=s.top();
    ( G4 ^" y6 q4 O4 t+ K, Y+ d                p=GetAdjVex(cur,pre);
    " j. w1 S" e; ^' ^; S6 z' Q) j                if(tag[p]==0)
    # Q) |  r- R# }! W7 f- I$ g                {) Z4 G/ R- g0 s6 u6 l/ x
                        pre=cur;
    ' J8 {$ i9 N: S                    cur=p;
    * z* R1 W& m% r8 x) d                    break;
    % E8 V+ n  h. d& T; K/ C8 ~, j                }
    4 m- L, |* ~: c# a8 H4 ]                else% ?/ Z- m2 y: h+ N' T
                    {" `+ i" r0 \/ L* m+ n
                        pre=s.top();
    4 O. z1 D. Y. z" f3 B8 [7 i% F                    s.pop();. B8 a* W: |& Q) u$ k6 L
                    }1 a$ Q% A, L' [
    5 V4 L% S8 D/ |+ f2 K4 r
                }6 b# S( |1 S- J& [' N3 G

    7 q( s' k/ L, h7 {        }
    7 d' X0 b: d" j    }
    # W* c! f: y5 B: D, `5 x}1 L4 J$ a1 Q& n1 t, X' J% _5 n5 i
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()9 T, P$ K) m; U0 c
    {  v/ t: G+ y5 h) z
        for(int i=0; i<vexNum; i++)
    ! K8 s* L' Q- I% X1 v$ H1 N        tag=0;
    : T3 A; L5 L9 ~- i9 `2 H; O- E7 c- ~1 E    queue<int> q;
    . G6 }( A$ k* y5 z0 q    int tmp,t;$ n: J; c; C; E
        MultiAdjListNetworkArc<WeightType> *p;7 U, B; A) a; y5 S4 ?- W
        for(int i=0; i<vexNum; i++); }; l& z1 [3 m) Q  H
        {
    2 n! l  O% X* T$ B$ z% U1 A% r        if(tag==0)
    3 q) U1 d* V. s4 X$ P        {* ^. R! t* E3 T9 A3 w( ?
                tag=1;  @7 s5 J7 F/ |- a$ y, j
                q.push(i);
    ( f$ S3 x0 P1 Q0 w4 k9 M            cout<<setw(3)<<vexTable.data;! }( P8 i$ B2 ^+ P! F6 f( h
            }
    * ?6 G/ C' h$ f5 m" d8 V% [+ Y        while(!q.empty())" ?1 D9 g' V! O& F4 ^3 p
            {# B4 ?% O2 v/ u7 M1 }' K
                tmp=q.front();
    9 q, G7 T; n0 e' L8 j            q.pop();
    4 t; `  {4 R+ Q' Z& E9 q            p=vexTable[tmp].firstarc;8 E  L6 D) R- X/ ?) B3 M: Q2 B" Z" g
                while(p!=NULL)3 {! V& B- M9 x9 y, Y$ i; ~
                {  s1 C/ t6 e* ?, ]
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    4 H8 ^( c3 h% K, ?8 ^, y" \9 T                if(tag[t]==0)
    $ b. W, e" T" c3 X6 [" S                {5 B' D+ q/ {& O/ m' A6 f
                        cout<<setw(3)<<vexTable[t].data;0 _0 L3 V" T0 \5 X1 n) _
                        tag[t]=1;
    * {9 w9 }. J5 B8 O                    q.push(t);
    , W2 F0 o% q3 `+ {- U                }- R- g' P2 H  m% F( ]5 W
                    p=NextArc(tmp,p);$ ^: p0 Q8 H* P. I3 i: q
                }
    : p' W  H0 B& I! Q3 r        }, j, |! F& Q: @
        }
    5 q3 E3 d8 Q5 a: ^! h, m- F}6 U0 G6 P/ K% t2 X2 N
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()! [) W- S) m) k- _* B& a4 T0 t: H
    {
    8 A5 a! }$ \# ~4 s: o! _2 Q" [    MultiAdjListNetworkArc<WeightType> *p;
    1 E9 y. Y9 w' Q+ U3 b8 ~/ K    cout << "无向图有" << vexNum << "个点,分别为:";
    7 C! `6 w: V/ l9 X! _) A4 o    for (int i = 0; i < vexNum; i++); d8 q6 R* p# S( a) t; Y
            cout << vexTable.data << " ";" H' h3 \+ d* G0 v# \6 x
        cout << endl;* W$ H+ w+ X8 s( p( P
        cout << "无向图有" << arcNum << "条边"<<endl;, z& S+ n, `& s( d% s% s
        for (int i = 0; i < vexNum; i++)+ @( u) e/ X6 Q8 L3 y5 f; }4 v* c
        {
    6 y/ O8 V0 D2 G6 ~* a        cout<<"和" << vexTable.data << "有关的边:";
    . D- T, n$ c3 s  w+ K        p = vexTable.firstarc;
    , c2 h3 [+ H) \  u        while (p != NULL)
    - m$ y) d% j, Z  q6 |4 j        {! a: v! C- _# t7 |
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    + M" Q7 }! W" x6 F- o7 A3 c            p=NextArc(i,p);
    - Q( k0 Q9 i4 G% y        }4 u( ^' y0 ~! E. x7 j9 ~* O
            cout << endl;
    2 g5 j2 m# h( C& |& D2 z& I, c% \9 \$ d    }( H. G0 `. b2 `8 n6 G! T7 ]* o# P
    }7 C' y: X$ Z3 c! U# O* ?& r) L

    , ]2 k0 |/ g. m6 M$ E6 v1 R4 w7 x; _& o4 r  U$ I& \* @9 x9 a
    邻接多重表与邻接表的对比
    - P3 H4 W0 }8 S0 J, O/ e  D1 j. i7 t9 @/ e* P! g( ^$ \
    邻接表链接
    $ {2 Y9 ~) D- b5 F, d1 s5 [在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    ( B& R4 F- @2 j( o在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。4 k/ I0 E$ m7 a3 A2 f+ s+ m7 v
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    " H& T7 v7 H' |  S) P————————————————( n8 M5 W4 ?5 G
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ; h; h& ?; J4 q* @3 b" ]原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958* O$ U( h- L* I6 L( q8 Y

    5 `& y' `' I- D0 }; d+ {$ b
    . |8 w  j# Q' ?$ O$ |% |
    , z/ H* }, @  U; u* R! B
    1 q" ~4 E, M* k* A————————————————
    8 @" K- W( l, F- y! t7 l版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    % `4 \6 ~: x, b; i7 m+ |/ T* M原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    $ A, t! B/ s- U) [3 P# a+ S
    % C* t: B* v. N0 y
    & S4 s$ |9 S3 ~+ B1 X
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2025-7-20 22:23 , Processed in 1.182051 second(s), 53 queries .

    回顶部