QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1642|回复: 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
    5 o& y4 n7 t4 ]9 e* _
    图的存储结构——邻接多重表(多重邻接表)的实现) O& E: v, S8 e% j7 t6 Q7 I* `
    7.2 图的存储结构" n& i3 K9 X/ H$ f- K' w2 f2 U$ ~

    ( O( ^9 `. E* X7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    2 B: f  u3 e& T) X- p邻接多重表的类定义7 \; ^$ g2 O7 p; v, ^
    邻接多重表的顶点结点类模板. R4 A$ H& t5 N1 z: c3 T
    邻接多重表的边结点类模板
    8 L/ U" x8 X) B9 ~/ l邻接多重表的类模板( c+ z/ E+ H4 H; U$ e; @; d' ~
    邻接多重表与邻接表的对比
    5 E3 O8 K. [7 E9 \( y7 U7.2.3 邻接多重表(多重邻接表)Adjacency Multilist+ h( G- G  A' r
      s& ~1 v$ z' `+ g9 h
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    8 f1 @8 [/ b3 Y/ @% q' z5 L在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。" }( S: T7 U: d  f0 w

    6 t+ C' ~/ x- Y; j" k% ]邻接多重表的类定义
    - w4 R+ @% u  k7 ?8 }# D( b 1.png
    5 }& v# r/ b( Q, Z邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    3 d' a: n3 H& kdata域存储有关顶点的信息;
    3 J5 r' X; ]5 G- O3 A8 pfirstarc域是链接指针,指向第一条依附于该顶点的边。& L2 ^' p% c/ I4 V3 j  k! _  v
    所有的顶点结点组成一个顺序表。

    ; \1 n& o/ f& r! `
    ! u4 @9 J% s) Q+ J% h
    template <class ElemType ,class WeightType>& u5 [. K2 |, v
    class MultiAdjListNetworkVex6 x9 ~6 U, N$ r9 K$ @  K9 x2 Q
    {
    + _; x0 W( o) ~# \+ K( K: _public:; i6 c& K4 X! D" _
            ElemType data;
    / L+ B) m+ ]; }6 b' p4 U. M        MultiAdjListNetworkArc<WeightType> *firstarc;; |. r+ [" @& E
    ( A( Q5 c$ G6 F
            MultiAdjListNetworkVex()& a3 ^0 K! i7 p, ~, F8 n
            {' F* a2 ~+ A" }- b
                    firstarc = NULL;- i  V, o6 E0 d/ F0 K+ l+ t8 M6 S6 w& V4 P
            }
    ! C+ K! Y* Q: j0 {& P. g7 O, A        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    9 K% M6 \+ I+ O' Q# G+ g6 W. \: K        {
    & X* B; y2 Q: G                data = val;& \; Y# U: B% t: X8 G
                    firstarc = adj;
    : R; c% t) N2 x. U6 i* ~0 I2 F        }
    ! M! p: O( z0 m+ I/ [. [' U- N};7 s3 g  }/ {, T

    ! S9 ]! s2 h1 F, ~: z: p邻接多重表的边结点类模板5 |* r- L; B* k2 z
    . ?# z$ l" N- i. q! Q( T
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:; t3 P2 q: x& S  D
    tag是标记域,标记该边是否被处理或被搜索过;9 z9 X) v. W- Q5 c* I; D% m7 V
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;  F6 }: M1 Q5 T4 q
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;  D" t9 l/ V; B, N( C. p
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    - |' N9 f, U. X% Y1 \
    3 H3 w3 o" s* g* ^ 2.png
    : y% q& `  t/ l4 itemplate <class WeightType>( j; \9 _/ d9 s, C
    class MultiAdjListNetworkArc
    ( q  q# i; ~& D) l{
    + p$ m& c4 `. g  F3 [public:
    1 y3 s: ?' l+ {+ S. N& q& q" N    int mark;                                       //标记该边是否被搜索或处理过$ h; e! a" U# x% P1 M7 t2 v3 e! y
            WeightType weight;                              //边的权重
    $ \' I( ]8 J* }2 r4 |        int adjVex1;                                    //边的一个顶点
    + M& W0 f  {3 N- }        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    ; {& N$ ^3 `* @$ O% J        int adjVex2;' F. X* z7 ~5 A, x
            MultiAdjListNetworkArc<WeightType>* nextarc2;
    / O- f" m1 s& G( N; p) }! ^: @& X# y& i0 R# ]) D- x! f6 O( s
            MultiAdjListNetworkArc()0 c8 n: L, T& c8 U& h
            {
    ! v& ~* D/ B9 Z9 i                adjVex1= -1;- M6 Y- k* N4 o% x
                    adjVex2= -1;
    * p) E  c9 s. e$ c6 i& N        }' e5 y* ]8 ?5 I) `$ H
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)- {1 `. [. F; y' M% ^  J2 z
            {
    3 r9 ^" ]( ~3 b% Y" H6 T7 i( z                adjVex1 = v1;       adjVex2 = v2;* y7 T" L7 f5 |
                    weight = w;" m9 A" n1 t0 T" G4 _1 {  h/ ^
                    nextarc1 = next1;   nextarc2=next2;
    ( Q/ D6 z# x5 w                mark = 0;           //0表示未被搜索,1表示被搜索过
      B7 {- L- M* K. v$ K        }
    - N# V! z6 @& f# h8 e8 H1 s
    ) ?. P/ S5 E% T/ o$ j3 o- o邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    ( C; ^4 l4 L( J, _( |1 _  O9 }class MultiAdjListNetwork
    : B9 \6 w7 V: r/ x{1 k( H+ r! U7 h7 N0 E
    protected:& g3 d( |# ?$ H4 \* \6 `% [3 S/ j
        int vexNum, vexMaxNum, arcNum;* h: D- s1 R6 s2 D  C* B& \
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
      ^# Z' z- k9 l2 a$ M+ z$ o    int* tag;
    . q' J1 C* Z7 j' a, c/ r1 W3 G    WeightType infinity;0 o$ C0 I2 Y! M+ f

    6 w' d6 W# K' c# |public:* y8 |% m5 z$ g9 @: ?
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);/ G- ]- a# V5 B/ ?: ^( |$ G" p* a+ [/ ?% F
    7 m1 n8 U0 q* l7 D1 f! R' }
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    1 G% x: ?+ q) f) i
    $ E/ n$ o; _1 G1 d8 @$ w) s    void Clear();  G. n' H, R! y6 L2 a  l0 B
        bool IsEmpty()
    / a6 p7 v$ K4 m$ Z" i4 H    {! d' q- k2 [1 ], i! _( X5 D" `% E
            return vexNum == 0;
    # m! r2 s+ p+ q/ H9 _4 U( r    }  s7 _$ Q" c; }/ g( |
        int GetArcNum()const/ {( p, W4 h3 K/ q6 a: \: W  C
        {
    $ d" g. }9 k1 W& \# M4 @        return arcNum;8 x% L6 U) V# v0 D7 p* ~
        }! v1 p. G4 X: x
        int GetvexNum()const: @' Z: k. n% c! t
        {
    1 P' {' z1 V* f2 O        return vexNum;; x; n0 Z6 S+ |" h, L! `1 K
        }* ^: {# S* g' T7 v. {
    ! s  g- W# _( R/ |" G
    : L( \+ w: x& ]# c$ N# h+ D% F5 u
        int FirstAdjVex(int v)const;
    6 o9 U, \- l3 a6 c  e" `    int NextAdjVex(int v1, int v2)const;
    # U  j% Y9 w0 z) G6 l8 Q    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;) }3 x" V7 Z' x" ^+ |* K& k9 q$ \4 U
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    . A0 b) Q  O$ l& V
    3 a- z* J4 i8 C4 B5 ^    void InsertVex(const ElemType& d);
    - X9 p, H5 `4 G+ o    void InsertArc(int v1, int v2, WeightType w);; S% z/ i" R5 F9 s: Y( I

    , S" ]9 r. F9 U    void DeleteVex(const ElemType& d);
    5 z; r) J0 E" @8 r7 R* @$ Y- k( e    void DeleteArc(int v1, int v2);
    4 b% u3 A* C, Q& h' m+ a8 |5 G  a7 A; W
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    * o7 E, Y# m1 I9 E/ M) t* a$ k7 Q    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);& @( Q% ?( \6 C* {  m1 ~

    $ J' p: i& m9 [3 P, E# G6 n    ///深度优先遍历. {- }9 t% O! B" m. R$ r  P7 S
        void DFS1(const int v);( L  q6 J+ N/ @1 Z% K
        void DFS1Traverse();; I4 R. M( O0 N( w6 Q- V1 e' L3 l
        void DFS2();/ V1 ^: |, }, X' C
    % i# H4 t9 e- H0 ^# W" a
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    # d. B$ j3 F0 o8 {    void DFS3();' D0 a: l: I+ W" d0 i
    % }5 Y7 ~  q! Z& W
        void BFS();' u& B: n* v' {1 f  ?
        void Show();5 l/ g. B, y; e. U
    };/ P1 h' r2 S; f" r  |
    4 x' d0 h9 q" S% c) E3 h
    2.函数的实现
    . R0 I9 y/ T* N: s! d3 o研讨题,能够运行,但是代码不一定是最优的。
    5 l; m# z3 \$ T/ U% h: }1 y! M- ?: t: U$ f
    #include <stack>1 a! x+ J: b$ r- e5 L5 g  K4 |$ z3 s
    #include <queue>
    & x( G+ b& R& \) \' K4 E% ?  x0 i0 s8 ]: q
    template <class ElemType,class WeightType>
    # `: ]7 U- B7 ]) ]8 l6 KMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    3 |1 x3 q' H; X7 F# S* P' j{
    ; h8 o$ c9 e. w* |  P2 i    if(vertexMaxNum < 0)
    1 a# ~0 O' ?/ R9 [0 n6 i( Q7 y" x        throw Error("允许的顶点最大数目不能为负!");: K9 w* Z4 s! ]
        if (vertexMaxNum < vertexNum)
    ' P/ `! i' |, O4 |: X, |7 P/ q        throw Error("顶点数目不能大于允许的顶点最大数目!");
    3 ^* n2 ]+ [, Y! o    vexNum = vertexNum;; E9 \" r( E. k8 Q
        vexMaxNum = vertexMaxNum;4 N) z# ?; W% T
        arcNum = 0;  ?- r. V' L9 r& Y4 J% h
        infinity = infinit;
    ( B, ^0 p5 x" w; I3 `: U. P    tag = new int[vexMaxNum];
    0 S$ X0 s9 C. s' o    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];( k- P  l; C! L4 R( A; j
        for (int v = 0; v < vexNum; v++)
    ) @% g2 {2 c! A    {# b7 w/ v4 U+ e; I- Y: I
            tag[v] = 0;
    + d! o3 t3 G. o* d& V        vexTable[v].data = es[v];) \' }' I3 q% Q! [2 N  q3 k
            vexTable[v].firstarc = NULL;7 x" L4 T: W% ?' }4 B6 s
        }. ~. U/ ?! |* r( S' ~
    }( b6 g' h; _, g6 C
    template <class ElemType,class WeightType>+ K3 P+ j5 m5 [: ]
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    ! N, v4 t- Y; m8 _9 G# Y# m{
    . B9 E1 a9 R" k% r# V1 b! r5 `    if (vertexMaxNum < 0)* B, T) v8 \7 r- z# N
            throw Error("允许的顶点最大数目不能为负!");4 y0 y- ?& {& Z3 e+ z
        vexNum = 0;
    5 A% o3 v! a* j' w' C, s    vexMaxNum = vertexMaxNum;6 R  |( V& o; j. S6 e
        arcNum = 0;5 @" _% V$ T. P
        infinity = infinit;
    ) k, M8 |5 M2 x, Q0 h8 I" l( w  i    tag = new int[vexMaxNum];* x' {+ v) J1 S2 D& w. t# u
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];7 B8 N* c( ^, t* L: W3 \! p8 M
    }3 R: j* U3 }7 W& @5 @' g1 Y& F3 L
    template<class ElemType, class WeightType>
    * v0 e, j# g+ x: B$ tint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    # a; V6 E; w0 |& C0 Q{
    ' }9 }& U2 T" c; \2 O  ?0 T    if (v < 0 || v >= vexNum)
    - G! Y) l  T* ]* j* F/ X. E: `        throw Error("v不合法!");
    + O7 Q8 q" R' R# ]    if (vexTable[v].firstarc == NULL)
    3 p( X  K& P  ^        return -1;
    1 h, z3 s$ k7 n& p    else
    ) a! {! l5 o' F. o; Y- B) \: o+ N        return vexTable[v].firstarc->adjVex1;0 |  q8 u5 E8 G+ z) D" ^
    }! M! ]0 M( {5 {7 q( i6 S! B: R
    : n0 g. J5 [8 h) u
    template<class ElemType, class WeightType>7 B/ W$ ^3 I1 G8 `
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    + G1 |' S. ~4 [" @& q  {+ s8 x& l{
    ( l1 m3 n, [' x/ x. i    MultiAdjListNetworkArc<WeightType>* p;1 {5 W: C; g5 }
        if (v1 < 0 || v1 >= vexNum)1 h+ G8 [  c* H' b+ T
            throw Error("v1不合法!");9 s% Z" u8 A' T
        if (v2 < 0 || v2 >= vexNum)0 u* b. H. }' n) ^" {
            throw Error("v2不合法!");
    ; q3 ?8 {* x  d/ c. H    if (v1 == v2)
    $ Z9 y; G8 X  a8 u        throw Error("v1不能等于v2!");
    : N4 S0 i. X) I7 H    p = vexTable[v1].firstarc;7 n) p* g. ?% O" i6 A: c' v
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    ( s' Z7 _3 X5 f4 V" I        p = p->nextarc;
    ) c9 ^" y- j8 c) R. a    if (p == NULL || p->nextarc == NULL)
    3 w6 E4 R5 P! b) O        return -1;  //不存在下一个邻接点
    , |5 B1 ~& B1 t( W9 ^9 Z    else if(p->adjVex1==v2)
    9 x2 z* \' z) |2 I1 S; ]1 r0 d3 ?        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    3 M7 |, I4 Q' O: Z" I    else2 ]! r3 V' I5 X8 b
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    4 M3 Z$ [! i  d, w3 W}9 B2 _3 h& _0 \- ]7 z0 Q7 }/ e& `4 e
    template<class ElemType, class WeightType>  ?4 N& \4 a8 ?7 }
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()
    0 r& F" P# C0 v  `2 Q{! z9 J4 c8 y' I0 s  t! u* E" r
        if (IsEmpty()) return;
    6 v% ~/ w9 y: e# ~9 d" W4 h% v    int n = vexNum;
    9 X! T0 q2 {7 Y! u; \* R7 D  b/ L    for (int u = 0; u < n ; u++)6 H9 [" I1 X' l, X1 M/ [, z
            DeleteVex(vexTable[0].data);  M  R' O" T" c6 l3 u" Q8 a' o
        return;
    9 n7 x  R$ Y$ I' e/ Z1 O0 E}1 Y# Z5 }" K3 W- [1 F
    template<class ElemType, class WeightType>
    # a/ Y; ^! L# SMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()& H: M) g$ l- l2 o& d- z: V
    {, n7 N! s! c3 l8 n
        Clear();# t0 O% D8 N2 e! a2 B7 c
    }+ \+ v; c, E: a# r- `+ f
    template<class ElemType, class WeightType>
    8 x& s0 }3 |2 g" t! {$ D, v8 HMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)& _: n: p' F2 y5 D3 B
    {  W# t( x2 N+ {0 M- t4 g. k
        vexMaxNum = copy.vexMaxNum;
    7 ]3 r+ ]' S! V4 a7 v7 f    vexNum = copy.vexNum;$ v! C  ^0 ?* F+ K# D0 H6 a& o
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    ( p, s$ j( C1 W4 }' }8 q    arcNum = 0;, I1 G( Z/ Z( }% S1 `: l: t9 A. x
        infinity = copy.infinity;8 B2 K; k7 o5 w( [# T
        tag = new int[vexMaxNum];
    ( c3 Q+ G" v$ l% d0 c6 }
    3 U+ F; b) F3 Z    for (int v = 0; v < vexNum; v++)" y' M# E, |$ @* D" z
        {5 P  q4 P. z& w; [+ x- W
            tag[v] = 0;
    * R, d7 s; A4 a8 r        vexTable[v].data = copy.vexTable[v].data;( c- c9 O" m7 I/ M7 _+ ~* Y' ?# A
            vexTable[v].firstarc = NULL;( o; n* f. K- `4 D* @
        }
    / I/ F& d. h3 z. t( A    MultiAdjListNetworkArc<WeightType>* p;
    5 q- F) L% Z1 z0 s* n. i/ U
    * x( v/ Y$ f# |0 C4 X    for (int u = 0; u < vexNum; u++)
    # Z/ {. f. }( p6 d- ?, g' Y    {
    % B; P# W1 B$ T) `+ ~- Q+ ?8 y+ L1 ~        p = copy.vexTable.firstarc;
    7 w# U! G! T- t9 W        while (p != NULL)+ o3 f2 M; K2 u4 Z* O
            {4 ]8 A# ^2 s5 r0 |3 L- G1 s- ]
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    ) u" y$ S$ g) l' n. ?! x            p=NextArc(u,p);: T- T1 p6 m) |$ ~1 N9 {4 c
            }
    * A* a- D% z+ ^( D    }
    ; H: T. ?1 y, Q( e+ [; s: p; ~}
    + |6 ]! P5 b) @& `/ D. U( r( `3 dtemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    - _( q% Y$ J! N, I# l7 _: d' RMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    ( ^2 r( o% }; q0 }, Q{
    6 T: m, C5 b% Z1 Z: ^; D. a$ @6 _    if (this == &copy) return *this;. ?; E" c6 l; i" ^
        Clear();
    % V1 @$ p" m( N; t) g2 m4 f    vexMaxNum = copy.vexMaxNum;
    # T  b6 U+ B# m    vexNum = copy.vexNum;
    # s3 w# U% [/ L& z/ T    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];6 B! f5 e0 B6 q+ x
        arcNum = 0;! s; s; y& w! M6 V
        infinity = copy.infinity;; p% w, L1 G5 }# f/ F1 b
        tag = new int[vexMaxNum];
    - G0 a' j7 m. @7 C- j, V( T$ v* q
        for (int v = 0; v < vexNum; v++)
    $ N  d* `: B" y$ B6 c0 j    {
    " Z* h8 I1 o) j        tag[v] = 0;3 C8 O) J0 n0 E! {6 P7 |
            vexTable[v].data = copy.vexTable[v].data;
    & o2 Q" P4 y; X9 \        vexTable[v].firstarc = NULL;
      @  Z2 I0 n  J    }2 H  r3 X5 x6 ^; P" |+ i. m. g
        MultiAdjListNetworkArc<WeightType>* p;' t; w: P, O% b7 X7 R1 e+ L

    1 e1 ~3 d0 v2 i1 ]5 K; e    for (int u = 0; u < vexNum; u++): {+ Q  ^2 h9 g- z
        {
    ( V- M0 q$ _; }2 h" `0 |6 p        p = copy.vexTable.firstarc;
    # b( A7 {0 {/ h7 k        while (p != NULL)1 X8 i1 _; o1 u) J; w) f
            {! t- j5 \) `9 a% R/ J) X! M
                InsertArc(p->adjVex1, p->adjVex2, p->weight);8 h$ r7 Y$ h8 a, x, A# `; X$ F5 j
                p=NextArc(u,p);& A+ h9 _& X6 n1 n
            }
    0 @0 a* K- x6 a    }+ {* o8 o& j9 m3 S6 J. M
        return *this;, P- O* p  _' M, f
    }# L- K* l6 L; q2 x! e
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    1 u8 G5 l6 C5 XMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const$ P" k5 u4 i; F3 ^: a2 z6 ^) }
    {
    ; R/ I' U. V5 H7 Z3 D1 x    if(p==NULL) return NULL;
    / r) {% X: `' Y+ P- g: z* U+ S    if(p->adjVex1==v1)3 F+ h* P" S* C1 Y1 k
            return p->nextarc1;
    & U5 c) U; }, M5 i$ N- @. u( B    else
    , s6 |5 h! w' [! ^. f        return p->nextarc2;
    % {4 X: B. g  U( p0 w. ~}
    3 o' e+ F8 ^* y5 G2 F( p3 Ttemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    ! ]1 h' i3 L* }% k1 }' PMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const: n' T8 i! G8 X8 Z4 s$ b+ G& x
    {1 p( E+ D0 o7 c* s% c# T
        if(p==NULL)return NULL;
    7 ?. ]% X( E/ E# O/ G+ s: j, P9 F    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;( Z; Z# f+ H4 c/ P' W& U# O" V
        if(q==p), Q3 L: |" T9 Y- i- w
            return NULL;
    . C! @9 j( J3 W5 {* j8 J) r    while(q)
    , _( p2 G, o6 U    {
    ; Z: u" R# N2 P0 [9 r0 g/ B* F5 k5 E        if(q->nextarc1==p ||q->nextarc2==p)
    + k/ |; l9 i5 O2 R6 |            break;" r1 R6 [4 F8 C+ F0 t3 S8 o
            q=NextArc(v1,q);" E. @6 n1 X9 C9 C$ p- v
        }
    5 T& t& f, c9 s6 Y    return q;
    4 e! f3 {( F7 d}( `; g* Y; {3 k# C+ P, Z9 [
    template<class ElemType, class WeightType>9 Z  G& U8 I* b% b
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    % N" X. M. u; `% P" [* R# D) _{) q9 \/ d: N" F+ ^2 m* }2 L& p  R
        if (vexNum == vexMaxNum)
    9 p  [4 ^1 [' b# D' q& i4 D3 \        throw Error("图的顶点数不能超过允许的最大数!");
    . v( R4 `( d0 ]; n# F9 ^    vexTable[vexNum].data = d;! u! r3 E0 ^2 B3 r. T
        vexTable[vexNum].firstarc = NULL;
    % s& X8 h$ u' ?/ N9 v- R3 w    tag[vexNum] = 0;
    ; V5 h' q3 p- [* X9 x# u  A* @5 G    vexNum++;5 ]# Y0 d# e. M% M# q
    }
    / d7 g6 U3 t2 N, v1 K* Z+ \7 ?template<class ElemType, class WeightType>
    ' C- Q3 |: s* x9 Tvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    7 q2 s8 e+ r2 c" \0 S5 _$ L, ?{  y, r+ ~, `9 O3 I( D8 n* c
        MultiAdjListNetworkArc<WeightType>* p,*q;
    + B! P- v$ J5 ?# k% S7 M& }; j    if (v1 < 0 || v1 >= vexNum)
      i0 [$ H$ Y2 r9 V5 [" Y3 K9 l        throw Error("v1不合法!");
    % R0 _4 M  _6 T  V    if (v2 < 0 || v2 >= vexNum)7 O; S9 m0 u" T( d+ g. T
            throw Error("v2不合法!");
    + S0 o! t1 k! o: e  g  h    if (v1 == v2)% M8 d: i8 X' F$ A
            throw Error("v1不能等于v2!");
    / _% H/ B8 G! p# o* h5 Z" c    if (w == infinity): i- o0 X* [* o, Y) p
            throw Error("w不能为无穷大!");
    5 U2 B1 W, j  N$ @9 z+ z+ d: v+ _) i

    : D. ?/ _0 @# b1 V    p = vexTable[v1].firstarc;7 X5 r& O. z1 |) C
        while(p); E' B, i1 v6 h  e! Y1 z( y: z
        {* c' v9 S9 ~: [7 X. l; s
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中$ g: U$ N, s. p
            {: Z% v7 `& A. f$ C0 _
                if(p->weight!=w)
    0 P2 _, F/ Q" V* c, M% e                p->weight=w;+ E* H  O2 x* O$ Q
                return;: F1 K7 k& }8 V, H
            }. g+ u1 i2 M) j8 p1 Z  n* n
    4 p" ~, x# T6 J+ ^9 G8 {
            p=NextArc(v1,p);% S* Y9 R4 x" M! f) t6 F
        }
    6 p" `0 h5 j: i& J* _) M    p = vexTable[v1].firstarc;
    : x; s% Y& x3 v2 o+ L( |1 d+ D* Y    q = vexTable[v2].firstarc;
    ( X9 v  W' A& t) H, U: ?7 j    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    2 P2 W& a9 O. c    vexTable[v2].firstarc =vexTable[v1].firstarc;' ]6 r! p1 h+ i
        arcNum++;
    : Z; x* f; k; j. ^# [}4 p& n7 Y5 ~2 O
    / @  j  x6 ?- r6 n
    template<class ElemType, class WeightType>4 Y, f9 u4 L; a. @( Y% F  w5 m
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2): ?  ?/ B+ ]( a2 S( V" [4 W
    {" h! P4 p7 n( {1 H$ s6 x
      J9 b7 \+ g1 s9 Q: M! M7 O
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    : W) w3 X! [- w5 X  x* g( Y    if (v1 < 0 || v1 >= vexNum)
    . F8 O2 H6 N7 V        throw Error("v1不合法!");
    " G! s" E  C/ x* [* b    if (v2 < 0 || v2 >= vexNum)$ w1 z2 j- B" V" O  g  B
            throw Error("v2不合法!");
    9 L2 J$ F2 ~) o4 K, r5 M: K    if (v1 == v2)( Q% ?$ Q6 Y7 W  T, p$ ^5 [
            throw Error("v1不能等于v2!");
    , r5 [% m+ k, ~- Y. ?& q) e) l+ X3 q& {- {! o; G9 S
        p = vexTable[v1].firstarc;
    : G4 L% h" F2 _    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    3 n# V2 I. a% F9 U! d! K6 ~    {
    * P9 Y) l, U: B        q = p;0 A, n. ~- Z' R0 w
            p = NextArc(v1,p);
    0 h" X$ {5 [" i# z    }//找到要删除的边结点p及其前一结点q
    + Z0 N! G% [. S; A' r+ s* @6 z3 m5 r9 p, _
        if (p != NULL)//找到v1-v2的边
    ( O% q' \* {# [+ B. _; \& G: P+ B    {4 ?  j" T3 k4 F8 o0 ?
            r=LastArc(v2,p);
    . H( e) U# l' Y  o! u5 V( F        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    7 [  G, v3 w3 k. ~- E- t            if(p->adjVex2==v2)
    , N' t9 w3 {+ a  Z' j" B                vexTable[v1].firstarc = p->nextarc1;
    & L6 C6 Q7 T, X; `            else vexTable[v1].firstarc=p->nextarc2;
    8 s  d, d! a- n) X( _. L. }- W: w        else//不是第一条边4 U: H$ X: K4 M+ [# @9 p$ S
            {
    7 N- ~4 ?% `2 V1 h! d2 }            if(q->adjVex1==v1)- v4 T3 ^* Y# G: W6 `3 W2 o
                    q->nextarc1 = NextArc(v1,p);
    : t: z& f  g0 Z2 b% O            else
    1 j7 I; {  k+ q" ?4 U. x0 a! i3 @                q->nextarc2=NextArc(v1,p);* F7 q5 [% M6 a
    9 {  X; k3 [. W, Q  _7 K
            }
    & p- j8 q/ @0 r3 R' N! d1 S3 v        if(r==NULL)
    6 W7 `- G$ B8 N. M6 n0 S            if(p->adjVex2==v2): z9 S; x, C0 e- S4 S1 w
                    vexTable[v2].firstarc = p->nextarc2;
    " v0 N1 u2 a! S7 Q            else vexTable[v2].firstarc=p->nextarc1;
    - o: W0 ?- U- A5 R% x( @8 r        else
    $ G7 Q% e  E/ K" H/ G        {
    : b% {. a% B) ]+ Q            if(r->adjVex2==v2)
    . Y5 a3 g' U& K( i! c+ I                r->nextarc2 = NextArc(v2,p);
    / Q" i: Y% T: @) h6 y, B0 E7 J* w            else* Q# Z0 c) I: {% [
                    r->nextarc1=NextArc(v2,p);2 w. e. I% p4 l6 A6 _: n* E+ M7 W
            }# v9 \: S" L+ c  w" m8 u6 r
            delete p;" {! D, L& J+ U8 W
            arcNum--;6 i% f4 G" D! F2 o6 r- c5 i& C
        }( e3 e; C  R. M+ Q
    0 m+ v0 @5 F) I* X) n
    }
    1 ^  F. Z" s( F# O6 L. ctemplate<class ElemType, class WeightType> void
    8 f9 H% k# S( BMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    7 @# K1 M# P( q7 {+ X" f& g$ @+ n) N! L{( \) _) O% L  m1 z4 a
        int v;) x0 C" P) n: n2 j5 r* ?
        MultiAdjListNetworkArc<WeightType>* p;
    . l% K( m8 g2 O/ @& n  Z9 J; n8 {" D    for (v = 0; v < vexNum; v++)//找到d对应顶点8 w3 I1 Y- x/ X+ c- Y
            if (vexTable[v].data == d)
    : Y  A1 [, y. V3 }% ]            break;
    " P! h2 y2 v% H9 S6 @+ a4 ?5 {. a/ i    if(v==vexNum)
    ; u5 V% Z2 n% r( Y# Q& I        throw Error("图中不存在要删除的顶点!");5 m4 K8 }: k' `; {& G8 i
    % F/ z7 F0 b' W  K, Y
        for (int u = 0; u < vexNum; u++)//删除与d相连的边/ l, r- n* x5 [
            if (u != v)
    ) A1 N+ P) l- u: T! n, }        {
    ( I) x7 B! {; b            DeleteArc(u, v);, d+ U  o. C- p
            }" t% ?+ _# |% I
        vexTable[v].firstarc=NULL;
    ( m+ z# i9 Z) ]% J# o; }/ {" Y3 O/ d' [  M
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    % A. [4 b! I: M( i. Q    vexTable[v].data = vexTable[vexNum].data;
    ; w; E# a7 o( b' }    vexTable[v].firstarc = vexTable[vexNum].firstarc;
    * E1 z& @  \. K: ~& @$ a    vexTable[vexNum].firstarc = NULL;3 {5 D3 e! `1 A7 t4 V1 W# W
        tag[v] = tag[vexNum];7 j# r: w) }, k) G" g: p
        //原来与最后一个顶点相连的边改为与v相连
    ' b0 x/ d, i$ [; l9 h    for (int u = 0; u < vexNum; u++)
    ! J& D: \: }0 ?. k6 e    {
    ( v- Z0 g- A( l; p5 S        if (u != v)
      X  l& J; }2 h7 ^7 M6 D" L& b        {
    3 p2 m6 r! P% Z, t2 ^            p = vexTable.firstarc;  z5 f* v7 [3 v
                while (p)# P7 w' H5 q# m6 d
                {
    ; V, ^9 l6 A$ {8 Y/ F                if (p->adjVex1==vexNum)
    6 a4 L3 M( {+ o+ l; @                    p->adjVex1= v;& u7 F- c' q( M. c% p4 [
                    else if(p->adjVex2==vexNum)
    % Y9 \; l! ~" U6 c$ n5 i                    p->adjVex2=v;
    2 Y: C1 P9 q  ^+ G$ }- X* |7 q                p = NextArc(u,p);5 F3 {9 L! y" Y' @7 W* N2 S, |
                }
    8 g7 Q7 e9 o- _7 H; V& l- v        }3 |6 O; s# C2 U0 I' ~1 q* ^7 V
        }
    # ^9 X% p0 M; T- T6 r}% E- x6 z, N  K- D1 |1 A' E
    ///深度优先遍历
    6 b& X+ M' }4 M1 x, r, I) N9 Etemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    0 b7 @; c  f' ~8 y9 F# W$ |5 ?2 f{
      g& E4 v7 H1 y$ `5 q. f7 Z$ A    tag[v]=1;7 m9 c6 M* N9 g% @# O* Z# G
        cout<<setw(3)<<vexTable[v].data;
    " a- Z# C1 U' \/ H    MultiAdjListNetworkArc<WeightType> *p;5 B; D/ `+ W) p
        p=vexTable[v].firstarc;
    " y) p- P' f3 m3 b' J    while(p). [" ~# ?3 v" u" e, q
        {
    - V9 Q1 y6 |3 v  t. T' g6 b        if(tag[p->adjVex1]==0)
    / }1 B! ^5 r, ^7 L            DFS1(p->adjVex1);
    ; l; J  a  ^- Q1 v2 Q& M        else if(tag[p->adjVex2]==0)4 L$ S, D: y9 ^; `* f/ K8 m& z
                DFS1(p->adjVex2);* R9 g( |: H0 b- m) e
            p=NextArc(v,p);
    $ G6 O$ Z; g5 _    }9 Z) F) E7 t) p% J: B# a
    }
    2 q6 m! d4 I) o( y& Otemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    $ [8 C8 _* u4 A- F{
    % g9 A. c9 ~7 D4 K    for(int i=0; i<vexNum; i++)) @5 y- s" Q% ]: S
            tag=0;7 R) s, d& {: B, I2 R6 K
        for(int v=0; v<vexNum; v++)+ p% h" y1 [$ G* B7 t7 Q& D8 c
        {
    3 ?9 D$ R" Y) }! _- a        if(tag[v]==0)" |0 d6 F  o8 X% E
                DFS1(v);$ v: [: S) h2 V' a
        }
    ! n. _) i# o# @}7 h4 R. S9 e8 m' K
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    ) x3 x1 _2 }6 S& n{
    7 f6 X0 c4 U* u. P/ G) W9 J    stack<int> s;
    2 p! C) j1 g* a- Q! G3 B    int tmp;+ y) I* O/ D4 u0 \
        MultiAdjListNetworkArc<WeightType> *p,*q;
    , B7 r0 r7 [& c7 |6 @    for(int i=0; i<vexNum; i++)" N* w# j1 B; T4 }1 M! {
            tag=0;
    0 o/ h. z6 z( N! G    for(int i=0; i<vexNum; i++)
    , K7 `/ L# [) P( l% J    {7 \5 R8 M$ O! V- k7 {2 f
            tmp=i;6 Z' U8 S0 u* r: ^( j& V* n
            while(tag[tmp]==0||!s.empty())" G1 @- s( y$ F0 ?  G, g
            {
    0 i7 H9 G+ g" k7 I            p=vexTable[tmp].firstarc;- K, g6 o% O) `; {
                while(tag[tmp]==0)
    " I3 k* w; J' c. Q+ @3 r( p            {6 n" g+ P8 [1 o, V8 W+ N$ i
                    s.push(tmp);, @7 u6 }3 E; w( `6 E
                    cout<<setw(3)<<vexTable[tmp].data;7 f1 }* s& z, e' \7 i5 a0 B0 {! p
                    tag[tmp]=1;
    $ b' P# ?* `5 p& G: t9 Q                p=vexTable[tmp].firstarc;
    ! @2 p/ h$ P. Y4 a+ F) V                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for! Y$ E; ^. d+ j, {% q4 R
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);& V& h1 g/ \( E* A
                    //cout<<" 1st     tmp="<<tmp<<endl;8 ^5 g! u. L0 `3 P
                }
    9 z1 X6 {8 B4 o) a            if(!s.empty())
    6 M- p& e! o1 g/ M            {3 F* w$ u. V; R6 [% M8 E
                    tmp=s.top();7 ^/ R' s" _4 x8 w' h6 I. t
                    s.pop();
    ( I! m& w. d: e! g0 D% s                q=vexTable[tmp].firstarc;8 }/ A: y5 q. g( w9 |/ J! B1 n% @; x
                    int t=tmp;, l0 F1 ?+ a3 S
                    while(q&&tag[tmp]!=0)
    ( v# P+ o0 Y& L( P  ^: Q) v: C% J                {
    ; Q* b8 R" I  {; H* l0 D                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);6 ?% x! W1 T# i. r, e1 [8 H6 H
                        //cout<<" 2nd     tmp="<<tmp<<endl;7 y5 Z' T) e1 }$ ~. v* C6 a7 o
                        q=NextArc(t,q);
    ' ^3 R! E: F* p" k5 D                }: w" H% Z% v  _2 ?4 p, M- \& r
                    if(tag[tmp]==0)
    : A8 ~- X4 B' i& o0 ]' J' `# ^" N                    s.push(t);
    ( d; x7 ]4 c9 O0 `, n$ ^                ///1、对应上面连通分支只有1个点的情况
    ; c! H' o+ y. M9 g1 ?5 i9 g4 C  w  S                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    1 g5 r* l$ l) n% w& X$ ?                ///tmp要么等于找到的第一个未访问节点,( V$ P6 _* `  W
                    ///要么等于与t相连最后一个点(已被访问过)
    . w% j6 n$ _; ^$ E                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    6 j$ w. l1 \3 |2 B( X( p/ I            }, Q- s* C% n* w2 d& P, e0 s
            }
    9 K3 f" m8 t6 X2 ?# A3 m/ ~    }
    3 z( d  R) p  e* k' _* w: U2 Z}
    9 g/ |" u2 s. B1 z6 s; R" S9 e; i//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1" L9 D. C5 x* ?0 t4 W. v% Q
    template<class ElemType, class WeightType> int
    6 C: |6 B: {" ?MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    # @! ?3 j; i# u4 `& s0 |( k{" @" k, ]' f4 s+ W& z& q
        if(head==pre)) ~* Y4 J* @" L% i& N0 {
            return -1;
    # M. J. ~: e. J; M/ H' A, ~% g. W9 D+ ~" ]
        MultiAdjListNetworkArc<WeightType> *p;( O9 F  R( W) ?
        p=vexTable[head].firstarc;, k6 U8 m& ^9 h$ h" U
        if(pre==-1&&p!=NULL); B/ k! w* I( f+ c0 x1 ?
            return p->adjVex1==head?p->adjVex2:p->adjVex1;/ P9 ~6 q) Q9 D1 b- w% D; p
        //pre!=-1&&p!=NULL. d6 `5 D' i. [1 b
        while(p!=NULL)
    ) @; n( o" g' W/ L& Z3 s    {
    4 k6 V/ x& a6 d1 n5 ?- C0 P        if(p->adjVex1==head && p->adjVex2!=pre)
    5 L: Y9 `6 A. q/ u# Y4 N4 f            p=p->nextarc1;3 `: q: a9 u; r/ i& C
            else if(p->adjVex2==head && p->adjVex1!=pre)
    , l2 L, ?' q: z  y& o0 D3 ?/ B            p=p->nextarc2;3 O" A2 n4 w1 t
            else if(p->adjVex1==head && p->adjVex2==pre)
    6 h* P& E2 r! V; e        {4 W9 [7 t/ e% G5 O1 I% f
                p=p->nextarc1;
    $ V( g$ _- o5 E            break;3 z# @" _4 L9 Z9 p( ]" }* [. K7 t& D
            }
    5 l' O# w/ \& V1 p' x8 w        else if(p->adjVex2==head && p->adjVex1==pre)
    % n1 {, I( W# p9 U, S        {
    8 u+ ~# n. v8 ~4 H5 \" A$ {            p=p->nextarc2;- W: \# f: e# _+ {3 V# v
                break;
    ; K+ \: m8 g3 {        }
    5 v$ ]" b9 C1 \: \2 W: b    }! ~2 E* n: i& F. [
        if(p!=NULL)/ @" a* [6 H) J; }5 A. e( i) e
        {/ e( f! R/ X$ K
            return p->adjVex1==head?p->adjVex2:p->adjVex1;7 ]& `1 `# k% D% i' J
        }
    3 G' a" l8 X7 X( x# ^# A    else$ Z1 D" L6 N) [. d; x- z
            return -1;8 m- c& \& M' F7 \
    }
      Z+ o/ n" F' {' z$ A$ h
    4 D, |+ y3 a4 L' V, d# o" c) P+ @1 I8 f
    4 }  i& D( W! N* htemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()- x, f! N' ~, x- K0 f
    {4 [/ k9 \9 l$ C6 z: G* r
        stack<int> s;
    4 W; T' q. }; W) \9 J) {# ?4 f  [    int p,cur,pre;9 M  t' ^& w% t' M
        //MultiAdjListNetworkArc<WeightType> *p,*q;
    ' m5 J# C% {! f0 x0 A    for(int i=0; i<vexNum; i++) tag=0;//初始化7 l/ _  B( Y: z2 i8 p

    3 [. s4 Y- F1 A    for(int i=0; i<vexNum; i++)9 V7 c& U- @$ N$ O
        {5 {6 h& K8 D1 f5 R8 Z& u2 _
            cur=i;pre=-1;/ G* |* M4 R* o; O
            while(tag[cur]==0||!s.empty())2 b. P  Q: J% t$ g1 }
            {% w% U, {% X6 W* a
                while(tag[cur]==0)9 i0 y" n  h( |
                {
    $ ]+ e8 k: q, W# T* m! j                cout<<vexTable[cur].data<<"  ";
    0 t. d6 J) W! M8 H; Y2 |6 k                s.push(cur);6 \& d4 {9 {8 F3 N+ @6 Q9 J
                    tag[cur]=1;
    / V3 F" u! O6 M/ i8 Y2 b7 W. G8 E               //初次访问,标记入栈
    : y" [# Z) g% j% l2 C4 V' |! g' m5 |, J- m3 K, i% `, g
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点
    9 i& I& @0 B- w( d; G               if(p==-1), P, x3 O( y. v7 w/ d2 |
                   {$ ~3 D* l. ?' w7 B8 i9 }0 q
                       pre=cur;s.pop();, A. F8 `; v7 @( O
                       break;" E' p5 j) h3 ?/ i( f
                   }6 P) @7 p2 |+ F3 O
                   else, ~  W: R% r: @9 R1 _6 u# W& `  \
                   {
    1 k3 p4 [. b" {" ~! {. e                   pre=cur;% `0 O: F- b' ^' h9 l) Y
                       cur=p;/ U3 o) z/ E% ]7 p! ^. S* E
                   }
    ' e; K  m* I6 a0 y6 c
    5 F8 i! w3 K& W: e, x( U            }
    * r# w9 Y, H" r9 `2 D5 H. Z% P0 z            while(!s.empty())
    % |) j8 L7 B$ j' H1 v            {
    9 r9 V8 [) {, S" ?3 F) K                cur=s.top();, G# @) ?; C$ F; a+ Y* T
                    p=GetAdjVex(cur,pre);
    * b' T+ Q4 k# n" T* P. C                if(tag[p]==0)
    0 `1 J2 x2 e. O1 i2 {                {& a6 e* @* e; Y. W" B5 V, i
                        pre=cur;
    . u+ K& z% c: D2 K                    cur=p;, ^  _, z3 a9 y: `! |% P' h
                        break;
    1 z% s7 B- i1 `6 P& ]8 h                }
    : i5 n  w9 e# j' {- d9 y                else
    , c! C3 o' {# [5 c2 ?2 v                {
    0 Q# x# ~) w4 I- g, `                    pre=s.top();
    # @9 W' F0 g% o2 }                    s.pop();
    ) ?5 ~" W' [4 A  ?' A                }0 j9 G2 k- ]& @0 Z! c

    7 H8 c5 z8 B7 ~/ F8 Q4 O            }
    6 O' j, F7 Z0 z" \, Z1 l/ d4 H/ F5 e- ~& r8 F& ^3 J
            }
    ( ~; e  x7 I- J* e8 B7 x    }8 |4 {& x- Z' N7 W) e6 U2 ~
    }
    ' x( g/ P! p: I' t3 l! j2 ftemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()  k: D$ T, R8 m. s% m
    {( M/ L( {5 X/ S  r
        for(int i=0; i<vexNum; i++)% l8 ^! b* Y9 t& O. w, c
            tag=0;( I) m  h0 ]2 Z. h
        queue<int> q;7 l! \& ^5 M3 P& I- Q- `- l) w/ P0 [
        int tmp,t;! j7 K1 X& U2 `
        MultiAdjListNetworkArc<WeightType> *p;
    6 [, R9 o+ {' W9 Q, O! c    for(int i=0; i<vexNum; i++)" F5 W- |9 {/ ^0 `" J% l
        {
    3 J4 S5 O2 p& K* y, P& w" u' X        if(tag==0)
    9 C! W7 n6 F9 S- q! ]7 v        {
    + F2 T  k# o1 B' h7 K8 i; ?. c            tag=1;
    9 S- w, i: W! O! Q9 l            q.push(i);
    3 o9 b: g4 U8 {9 ~            cout<<setw(3)<<vexTable.data;7 h) Q  X/ ~' k; J% F) }0 U5 I. M1 Y
            }
    + @; r5 s, G- u/ g) s2 x3 |) C' f' u        while(!q.empty())
    / ]" X% C7 V! E5 d        {
      m' J+ j/ N2 b' c  t6 A            tmp=q.front();$ e0 K0 z/ N$ R
                q.pop();
    * {6 i, }9 T6 F. m            p=vexTable[tmp].firstarc;
    $ T6 T/ h3 L! ^+ j# X            while(p!=NULL)$ y9 L6 g- y/ G3 I
                {4 I" ^: o7 {1 l( _% W9 l
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);% E, e# h1 c$ F' J6 G7 z/ D
                    if(tag[t]==0)# L8 Y8 l8 k4 e( `8 d
                    {
    0 O! Q, e7 j- y+ h  j+ D                    cout<<setw(3)<<vexTable[t].data;$ Y! i' g+ P6 \! L; ?2 z- f
                        tag[t]=1;
    7 q1 x3 O- f+ ?2 C2 u                    q.push(t);
    , J$ a5 Z- [/ `; \; U                }
    . d% [- X) R; m2 u                p=NextArc(tmp,p);' x4 N) v& H' z7 G1 d
                }& {8 F" m$ v( ~. m
            }
    ' T7 i( d& [" N% B: K6 l    }
    3 F) w3 s) n1 E. I  O1 R# W5 c}
    ! D% J! e7 {) B! b1 [template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    1 y) F8 J5 R+ z) E& @$ X! w' E7 ^{* @1 B( v, u7 j) o
        MultiAdjListNetworkArc<WeightType> *p;
    9 B$ B6 v0 a5 t/ u- j    cout << "无向图有" << vexNum << "个点,分别为:";
    # z9 G1 Y) k$ @* k4 a9 U    for (int i = 0; i < vexNum; i++); {5 b: b9 H8 b$ w( d* f8 Z3 G% O
            cout << vexTable.data << " ";. B9 \  b/ F1 t1 B) g' U
        cout << endl;
    5 O8 z2 i0 J9 L  k    cout << "无向图有" << arcNum << "条边"<<endl;
    ; t7 y$ w( a' c, E8 k; ~3 ?    for (int i = 0; i < vexNum; i++)
    4 B" Y# C# x9 t* I4 m$ S    {6 M4 s* N7 O. D( [3 Z# l/ {& f
            cout<<"和" << vexTable.data << "有关的边:";. J3 |8 q/ Y! d
            p = vexTable.firstarc;
    7 j: g+ W# m! V1 D        while (p != NULL)
    . H) d% S$ u2 K+ J5 }8 C        {
    & I2 A) ?% H; n: i, Y& g            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";0 A+ z4 k" t! J' Z7 G) B: s% j
                p=NextArc(i,p);2 j+ A' g$ z, |
            }4 P* E5 G, n# Y
            cout << endl;
    4 }' r4 n0 A9 W& j9 A7 n! e1 G    }9 _3 z3 k$ g! ?
    }. ], O$ a! e8 h( B2 w

    6 T4 c* O6 z1 }6 O' }' M+ z, ~! Q0 Z: q$ l9 I, {
    邻接多重表与邻接表的对比
    4 s4 g8 t2 v3 d) O4 i) Z( h0 x4 `
    / h7 X0 @. I0 ^5 x邻接表链接$ z+ d1 v+ X7 q) U
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    & b4 m( c6 O) }& w& N# _& `, a$ @在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    . |+ o: y: K2 e/ a7 f6 d! M% }为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    3 g! h; M# b5 t————————————————
    5 A/ }$ p" K0 {5 W3 j; r- L版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。2 R0 m6 @2 E: {# q# W; k/ k0 i
    原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669583 e* `4 Y7 G8 V$ C3 p5 @

    ) D) h/ u# x" ~8 W9 V6 u0 D- s0 N) T

    6 f& x) v% L& C+ g% s4 o: w1 S2 T- v
    ————————————————
    1 D2 }  ?, c/ n9 K版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。$ F% Z) n+ I2 Y" |, d9 O
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    & T6 B  q3 c# E! Q7 p, }; D0 f1 R- O
    6 O; ~* S- l" q0 F
    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-7-25 18:41 , Processed in 0.418519 second(s), 54 queries .

    回顶部