QQ登录

只需要一步,快速开始

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

    / z0 Z) d2 U: c! d图的存储结构——邻接多重表(多重邻接表)的实现
    / G$ y! P7 O; }' I7.2 图的存储结构
    ; q# V9 f& A5 m) b/ p3 k3 h8 g* {. `/ m/ X3 P/ g6 @7 L
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    & \; N0 t$ [) P: h邻接多重表的类定义
    : d1 }& q1 \& C0 n5 h4 |' N邻接多重表的顶点结点类模板7 ?& Z, f: t& X. M& k
    邻接多重表的边结点类模板
    5 m/ S7 b  ^7 Q! A* z0 ?" M邻接多重表的类模板' X6 L1 Z2 q, q( K, T/ _
    邻接多重表与邻接表的对比
    1 d$ D( h9 }2 ?1 y9 r2 ]0 P7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    , c" V) y6 ~7 I9 t+ o! B& Y& [
    . a6 J$ G* r' m! S3 {2 a在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
      J3 G- U' F1 D/ b+ i+ u在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。$ N* B" Y8 ~+ ^; H/ W. g
    - u4 A1 D0 k4 H& ?
    邻接多重表的类定义
    7 B7 \* @1 P% J* w8 F  y 1.png
    : O4 s; X+ u: ~% v" L% S4 _6 w$ w0 f& `邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    % J4 X; G, H7 ?/ vdata域存储有关顶点的信息;" H3 N4 \- n7 E
    firstarc域是链接指针,指向第一条依附于该顶点的边。$ w( l7 R/ g. J( ?
    所有的顶点结点组成一个顺序表。


      s! e6 g" s: }* @- j$ U6 t3 M3 |/ W# @9 m" j2 M
    template <class ElemType ,class WeightType>
    # R$ b7 Q4 l/ a: W, c( h& s7 Qclass MultiAdjListNetworkVex
    ; G) a/ b5 q9 p1 \{
    8 l7 y3 w* L$ o" m" B6 Lpublic:
    4 a6 B6 L# Y7 ?; f& H3 G/ P        ElemType data;
    4 y1 ]0 ^) r* l" j        MultiAdjListNetworkArc<WeightType> *firstarc;
    " }8 o! H1 H3 t; y9 n7 N3 x# c' Z4 X$ H( {0 D
            MultiAdjListNetworkVex()  S0 W" f. E% A  M
            {2 c! v' A" x' f3 w& f5 R3 g
                    firstarc = NULL;# L( u5 w, P7 F  E
            }
    4 F" X% s- H8 B        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    + L7 Q# ]6 x( Z# r& I# L. f        {+ d$ X* v- }0 ?$ Z
                    data = val;/ ?9 R$ p7 j6 X9 l
                    firstarc = adj;2 e3 c+ w- N' t. Q4 w4 M* u
            }- ]( C+ G" X1 q& \
    };
    ' |0 k4 c; K5 y; j; o/ E. B: f# Z+ ?& j! a
    邻接多重表的边结点类模板: E* T& y0 Q' A" G
    . N8 Z+ V% z7 F! s4 U8 v" W2 _
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:, R# W- \8 O7 {
    tag是标记域,标记该边是否被处理或被搜索过;0 k8 o* }; Q  Q% W" q1 U: S
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;7 I$ P8 X0 u6 w! U9 A$ Z/ q6 B% ~
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    + d% l' B! I9 n9 Vnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    0 `# b3 Q3 i) @' S0 E/ J
    ) e6 J, j# s4 J' T/ a7 T- y 2.png
      V  n+ Z" v6 Z# I/ Z; Gtemplate <class WeightType>
    9 J3 f2 R" E/ [class MultiAdjListNetworkArc
    1 R9 p, \& D: f4 e5 D4 x{9 k  E) ?6 I7 U. O' R) t
    public:) f: h6 Q5 N# R
        int mark;                                       //标记该边是否被搜索或处理过
    ( {* }4 B: L8 k7 {  g4 ?        WeightType weight;                              //边的权重
    / E/ W% |# J7 C1 c, [        int adjVex1;                                    //边的一个顶点
    + g* b* \" |8 ?  W1 x        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    7 v9 Z5 G6 c# P5 A( e$ m        int adjVex2;: n; d) O: a  n; a
            MultiAdjListNetworkArc<WeightType>* nextarc2;  U7 B1 A! e! U

    - Q( U8 i3 V2 @( a' L. Y        MultiAdjListNetworkArc()
      S- U0 K  y8 @8 l$ T        {" S& L, J0 s! A) Y. X  M4 f
                    adjVex1= -1;
    . r; Q/ z8 y4 u3 j                adjVex2= -1;
    7 a1 N+ g$ X1 ?6 t3 \: R        }6 _* q6 t5 E) ~6 ^
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    & E: h1 s4 M- Z% I. G$ |7 p        {2 V) A1 k" @; V9 _+ O
                    adjVex1 = v1;       adjVex2 = v2;( q% h) \( Y9 B; _5 f
                    weight = w;
    ( a7 p! ?) l' w( O  h- G1 l                nextarc1 = next1;   nextarc2=next2;
    7 R8 i# W( m4 Y                mark = 0;           //0表示未被搜索,1表示被搜索过: i. X& a1 k, `: O% U9 ^7 I
            }
    8 g- u8 v0 ]( k! J- t
    $ _9 j0 a4 J, F0 D; g/ M  F- ], J邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>+ O. Y/ S# b. j( |1 P
    class MultiAdjListNetwork
    ' \$ h7 G* J: X, D* N; y5 n{
    3 A3 v" S4 @9 V% xprotected:" R/ G2 x. V& v9 z4 c
        int vexNum, vexMaxNum, arcNum;% f' u2 K- x! U6 C7 R* F
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    - l0 Z% M# }: \# H6 K    int* tag;4 }# z4 O# [, b) G  k2 t* V
        WeightType infinity;3 M+ Y# q) V0 A5 r7 p

    7 Y5 g7 o7 g. L* s0 b2 ipublic:
    7 a- @! s! ?6 W/ `7 L( ^  j( t    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);4 _5 s1 x9 M! [: R* G
    / [1 L8 j" Z9 o3 h
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);* k- B, K8 T8 J/ x. G0 G
    ; d; ~$ d/ M/ i0 O! ~( o( b, Y
        void Clear();6 h. W; f5 `6 Q, L& y/ G
        bool IsEmpty()5 p+ j2 ]# W8 U2 q
        {( L2 a, q5 l6 j" \% r
            return vexNum == 0;
    , Z; ]$ x7 I1 ?- r    }
    7 n# {. I4 {9 ]$ n    int GetArcNum()const
    / H% ]5 h( K/ b9 l    {
    . K+ ?7 n$ @  B1 s3 }9 y        return arcNum;4 b( I2 K& M# X3 B; |( O( ]
        }
    8 i/ {- q# X8 }- t; t    int GetvexNum()const
    * [" o* m# G* x# A, F: b    {
    0 E5 e- D3 t$ j/ V6 ]! v) E        return vexNum;
    ! \) J: {: t7 Y9 ~5 J    }* u& y" F# s& z4 {( G
    : z" m: I  _3 [/ x, e; c8 W

    + ^) G+ _* \8 y    int FirstAdjVex(int v)const;
    3 o* ~$ A9 l' o; j8 Z    int NextAdjVex(int v1, int v2)const;! {% l0 G( S! R6 |+ T0 J
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    5 l) x# u, c/ l2 _8 q  K4 V    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    0 `" d3 I% L7 W7 n3 Q
    1 b& r6 C+ q: e) E& D7 `( a    void InsertVex(const ElemType& d);
    6 B* ~& Q7 Z! h/ P    void InsertArc(int v1, int v2, WeightType w);
    8 {3 w5 P6 D7 |5 p
    " C$ ]- }' y( h% y5 B    void DeleteVex(const ElemType& d);
    $ a( J/ P' t9 z. D: A3 E1 V    void DeleteArc(int v1, int v2);3 H( U" q: M7 g6 b+ ^  e9 V1 w4 G$ x

    9 I. j' B6 \, o2 Y    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);" B* B, G$ l* R8 H; w4 p8 q3 Z) u
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    : q3 }: g( s4 Y6 I5 e. ~, o: k) k5 b3 u) [+ z' H
        ///深度优先遍历0 ]% s7 E! K% i
        void DFS1(const int v);
    / C  s0 n) m8 G; [# F    void DFS1Traverse();
    / g6 s/ r. ]# t: o, x    void DFS2();+ h" I" p5 ?, m

    3 d1 O6 j1 j4 B+ d    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-19 j5 C; p5 @, P3 t9 u4 {
        void DFS3();
    * t0 u6 r( G$ F# _3 Z! N0 @- z
    ' o! z  n/ A8 {, x5 n6 w( w# d    void BFS();4 z& W) u5 \# H
        void Show();
    # k+ W, ?5 ]4 k. n7 L! E: V};' c: l, H( S# [0 E, _
    : Q( |8 ~: p( o$ @
    2.函数的实现+ g1 r, C6 Z, O5 W% N8 G$ I9 @
    研讨题,能够运行,但是代码不一定是最优的。
    8 b+ f1 P1 G% u$ D2 r2 ]5 V7 y* V  U
    #include <stack>
    ' q$ d' b" W7 S# y2 g  q#include <queue>9 J! s( k; _* E  p( Y
    2 r$ ^$ j9 n/ I. \4 n9 n
    template <class ElemType,class WeightType>
    . B% Y* Y0 ]7 o, O8 h& [MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)& b  C: r1 R  y. g+ N7 J0 y. Z
    {
    7 ^/ h  N9 T: ~' U; Q0 r    if(vertexMaxNum < 0)
    ( e, W% }2 b7 G  Y  d' ]: K# B        throw Error("允许的顶点最大数目不能为负!");
    ) [, e& \- `% b9 A    if (vertexMaxNum < vertexNum)
    : {, f# ^/ |* C; a% e        throw Error("顶点数目不能大于允许的顶点最大数目!");+ T  y0 X, y1 x
        vexNum = vertexNum;6 \: w5 `7 K! D2 n' k" \
        vexMaxNum = vertexMaxNum;
    8 Q  `+ G! C( R( J9 v9 ^0 v& \    arcNum = 0;
    ; D2 f6 S8 t- o; M1 \    infinity = infinit;% G8 U9 k. H  l
        tag = new int[vexMaxNum];
    ! \) @2 ~# V: y4 u    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    0 ~* Y. C7 d  ~: F    for (int v = 0; v < vexNum; v++)
    ( c- L& ^8 Y5 H6 d7 x    {% S4 N" M' s. k" _* t- d! a/ p
            tag[v] = 0;
    2 Y8 l3 g+ `. J' u        vexTable[v].data = es[v];$ Y# Z$ ]0 J' M& k. I. R9 q
            vexTable[v].firstarc = NULL;
    1 Z4 P0 k& k! D% v2 i    }
    ! J" X! Y- d) L- Y: v}
    5 K/ }! P3 N% p" I: `+ ltemplate <class ElemType,class WeightType>( A1 y2 K$ ?8 i
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    & U/ F. D0 S" {{
    6 h* |) U/ L4 b2 K, E( X    if (vertexMaxNum < 0)0 J/ T6 W8 Y9 _3 E. P
            throw Error("允许的顶点最大数目不能为负!");
    2 J- C6 C0 U5 O9 Y( G% M# h, Z) [" c    vexNum = 0;
    " {# T5 E1 w9 {    vexMaxNum = vertexMaxNum;
    $ f3 ^( N  H5 y" Z  J$ I    arcNum = 0;
    + q/ A/ E1 a( F" Y, M1 w1 D% h    infinity = infinit;
    & k6 X: t7 {- c* ^3 |7 D6 R    tag = new int[vexMaxNum];) l$ a( P4 Z- N6 S$ X3 K
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];; d! i8 H) q) _
    }/ x6 u( p7 x5 t/ ]
    template<class ElemType, class WeightType>* k- l% K5 F2 ?  E
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const  j) d3 e) a0 i/ `
    {) A0 f4 C. u1 V# A  @
        if (v < 0 || v >= vexNum): L# X: F8 N. I1 g3 t
            throw Error("v不合法!");8 a) |- Y1 S$ E* w4 M9 j' s  {- R5 ~3 Z
        if (vexTable[v].firstarc == NULL)
    5 n/ w1 t0 N' K        return -1;
    ) Y/ u8 {5 d* }: b$ O    else( w% \) o# {* k1 q
            return vexTable[v].firstarc->adjVex1;3 W: x! t& `  H, ^4 @; Q5 A4 H9 j7 C
    }; l6 h  _5 c# G8 [5 B) T  p
    9 j, w3 s3 ~; x. ]; E2 P; x
    template<class ElemType, class WeightType>, W3 ~2 G- t& D, M
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    6 G- h: M+ Y- D0 K{5 m' u, `# i: w" m6 i1 ~) M
        MultiAdjListNetworkArc<WeightType>* p;
    / H  Y+ [) d/ M' n( h$ Y; M! i; p0 O    if (v1 < 0 || v1 >= vexNum). N0 g. t7 B7 O- |3 |' R. ]* T
            throw Error("v1不合法!");; s' t& ~% O# ?' Z3 J3 X+ Y
        if (v2 < 0 || v2 >= vexNum)" h% }- I5 V- B$ M- \5 c
            throw Error("v2不合法!");9 U$ t6 h* [* A0 f8 ~
        if (v1 == v2)0 x. F1 z1 k! u; K( N
            throw Error("v1不能等于v2!");4 I& @. ^4 ~  }! d  }
        p = vexTable[v1].firstarc;1 M% S: R& Y; f- U  Z4 a
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)4 e# R% ]+ |  q! `. q( a; L( e# {8 ?
            p = p->nextarc;
    7 z4 ~, N4 b9 Q' n! q4 M    if (p == NULL || p->nextarc == NULL)% z# J% b' f/ \: u
            return -1;  //不存在下一个邻接点
    1 `3 _& G, D0 n9 Z' z    else if(p->adjVex1==v2)$ x0 p9 ]( O& Q- R6 O3 w9 \
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);- T) x% @+ p  I
        else
    9 }7 w: [. v% _& z( X) I) R4 R        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);9 R  [; ~' q6 e3 N6 T1 L
    }
    - J6 d) y* N: J9 W/ ttemplate<class ElemType, class WeightType>
    ) W( k- u$ j4 n9 S! ]0 Rvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()
    3 C% W% q8 T! G8 A: ~5 Y{) S; F1 R/ ?: v
        if (IsEmpty()) return;
    $ r% F- s- g6 N' H    int n = vexNum;
    7 F1 M$ ~1 ]4 e- p3 R1 X' }    for (int u = 0; u < n ; u++)& [1 K# \: c! u/ A( J% I
            DeleteVex(vexTable[0].data);3 {$ q: Y( U+ s1 }% z
        return;
    5 W$ k# p0 A% u9 i& P}
    ' }2 A! x( ~4 \6 S' Q/ h: j+ Y7 Dtemplate<class ElemType, class WeightType>2 w2 ?! T- j- d3 B$ F
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    9 L/ C+ r7 u) w) }3 K3 p# n{
    . M$ G  b$ ^: y! O) t+ _; O    Clear();  P2 g0 M. Q9 V1 N% R' r& K
    }
    " i: ^) h* n- ^9 htemplate<class ElemType, class WeightType>
    - m4 U+ x3 S! C3 O1 z- ?8 FMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    ! }. L# E9 `1 w' v{& d$ p! Z1 d: j  I* A
        vexMaxNum = copy.vexMaxNum;+ P: N7 F; I' w+ M7 R- x
        vexNum = copy.vexNum;/ f% T8 h- f2 u6 R- Y/ \3 A
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];. J; q+ `/ O1 I  q4 N5 q: x
        arcNum = 0;
    & {* N, E& c! y+ W, j# W    infinity = copy.infinity;
    ) d9 ]! ^" U+ Z9 H  C; \+ _5 k    tag = new int[vexMaxNum];
    6 I& q7 [" O( S$ X; ~4 [/ ]5 y# G8 S: L- e+ `+ O" M
        for (int v = 0; v < vexNum; v++)
    $ C3 L4 m" y) ?) a: f9 Q    {
    7 n+ x$ J% A( X4 B7 j7 F6 E        tag[v] = 0;
    7 L; U/ Z/ j2 g- j5 W        vexTable[v].data = copy.vexTable[v].data;
    3 j1 l5 B; [9 D4 [. J# U        vexTable[v].firstarc = NULL;
    7 O  r( y" B/ r% X2 x6 ~  w8 y    }# Y) D( v; v* K% h/ v
        MultiAdjListNetworkArc<WeightType>* p;( z9 s& @5 v! O: Z3 v" I) Z% k

    , }8 H& s! U. [) A9 U1 v) p* T    for (int u = 0; u < vexNum; u++)
    6 L9 u, N1 [, z- i2 |" ]/ q- o    {' x& Z2 b/ u5 G! c
            p = copy.vexTable.firstarc;
    8 o/ l# T* g! \1 w1 U" x- \        while (p != NULL)
    " G& e, _) _5 P/ s$ s$ u# g+ H; J        {7 L! J* W0 g8 b4 l5 F' i; I
                InsertArc(p->adjVex1, p->adjVex2, p->weight);1 B; O; }; C6 ^
                p=NextArc(u,p);
    - Q  u/ L3 f& w% _        }) Q- P+ o) V- j9 ]
        }
    / }7 W: ^9 c- I! e8 t& I: Y}
    8 T/ B0 G, K. l( B, N1 y! Atemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    3 s; X# q: V0 _3 K1 U2 E$ {MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    / k0 C$ I0 \8 o8 S! C8 L{
    5 `3 ?  @* K3 q( V    if (this == &copy) return *this;) h9 [# n* O) ^! T5 P
        Clear();
    0 w" K; h5 j- U6 m8 G    vexMaxNum = copy.vexMaxNum;
    : L" ^8 G+ N; c0 P7 x7 w5 q! d& i    vexNum = copy.vexNum;
    : k7 w3 C( L5 ]. E0 W4 x    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    + v/ H* f" q' K/ \    arcNum = 0;  M3 u; F% j, @
        infinity = copy.infinity;
    ; {" m1 k% ?2 W3 c# y+ q& o    tag = new int[vexMaxNum];
    3 v5 m( z# y8 E* P$ p, z  q5 r5 v
        for (int v = 0; v < vexNum; v++); l" s; T% y! ^& w5 M$ F
        {
    " M4 g7 p) F! A- M* E        tag[v] = 0;8 E0 I7 o: ^/ d. z, h9 L
            vexTable[v].data = copy.vexTable[v].data;
    4 f* ^, q+ d2 D& z& X' l; C3 B! R        vexTable[v].firstarc = NULL;
    - y9 H( q6 I6 ]/ q+ `# d' p: m6 |" S    }
    + v8 p+ p* \+ D, p2 X  J    MultiAdjListNetworkArc<WeightType>* p;  `+ f! S! T9 x
    - C) C* C6 j( ]* z( A0 q
        for (int u = 0; u < vexNum; u++)0 L7 b4 r/ }2 m
        {
    ; S1 C/ ?$ g  I, n5 L        p = copy.vexTable.firstarc;3 X* {( m4 l5 b, J, ^. F9 z7 S
            while (p != NULL)& m* Q. `  Z3 m* ^8 B: o
            {
    " u6 N  a, \2 H$ x: E1 W, G4 |% c2 c            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    / k( c& ?/ C9 K            p=NextArc(u,p);, P- Q: T( I& \, Q- c* j
            }
    ( }* L! i6 Q3 ?( T$ x4 k: f9 \0 w    }8 F' ^9 _+ c: W9 q( n7 k
        return *this;6 c/ q4 f0 |' }# o) D
    }& U$ {9 Q9 l3 D% O5 ^
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*. B- C9 {: s9 \# e2 s. g1 C2 m( N& C
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const3 X- G; q6 p% G
    {
    - h+ ]$ v7 M- J# d    if(p==NULL) return NULL;
    % ^4 D% F" n7 Z7 l    if(p->adjVex1==v1)
    0 M  `3 p5 Y# p% _        return p->nextarc1;
    * G/ a& U- P% x2 Q    else1 O' H% ^9 b1 n$ h: U9 I
            return p->nextarc2;# X. _% m. L& n6 b6 m/ P
    }5 l: K0 y/ C) p
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*0 p4 a( V4 a9 h( d- @
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const) ]# g/ C/ s8 K$ Q# F
    {7 h3 E9 ^" `. e! U; [+ b' ~$ {7 Y! a
        if(p==NULL)return NULL;
    # y1 ~# h  A6 i2 [( u    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;+ D6 q; N& V" Z4 l# S; s
        if(q==p)
    8 u( _  F$ {, b: b& Q3 w+ \        return NULL;6 x" H' u4 x( u' b/ M
        while(q)
    ) b4 X, i! m) Q' ?- g    {8 m( ?( y/ a! n- I
            if(q->nextarc1==p ||q->nextarc2==p)
    9 C' x. V/ t( w- x* [3 ]            break;
    3 m% t( d* T  c        q=NextArc(v1,q);' Q/ n0 B1 R$ D) H3 b7 J$ Z' ?
        }, c1 \. w7 q0 E: j& \* V9 d
        return q;
    9 }/ L6 j. r" I  I& i0 v$ R}) C% F- T' {  l- [- p
    template<class ElemType, class WeightType>- t# t4 P7 q; W5 P
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)2 @5 Z0 @; j) i% U/ N
    {
    ; j( w1 p5 m, F9 b. ?4 [9 A    if (vexNum == vexMaxNum)4 R! S. G: ]' Y( t  \1 J6 X
            throw Error("图的顶点数不能超过允许的最大数!");
    % w9 M' g- O' C! a+ Q- D" b+ [    vexTable[vexNum].data = d;* [6 Y- \# l; u% ~4 l/ m
        vexTable[vexNum].firstarc = NULL;
    : j. \7 [* [; Y    tag[vexNum] = 0;
    9 w+ ]- V# j; G+ y0 x7 Z6 Y' Q+ P    vexNum++;+ @1 U/ F4 |6 e4 p; g  H2 Y
    }
    3 Y& a/ ~' t3 _% Ztemplate<class ElemType, class WeightType>
    ) a. s. z  J/ r) V. Hvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w); e0 X- i5 D0 r" p7 h) K& M
    {
    3 J/ b" R/ L# Q: j1 ~  Z    MultiAdjListNetworkArc<WeightType>* p,*q;" z) g# v0 ]; h6 J, r3 n; B
        if (v1 < 0 || v1 >= vexNum)
    * T1 K+ {, t" K$ \3 u& g/ t, v        throw Error("v1不合法!");
    0 e+ |6 o9 C/ f    if (v2 < 0 || v2 >= vexNum)( X3 A& F  O4 Q8 f
            throw Error("v2不合法!");
    9 L1 I1 x6 b6 }    if (v1 == v2)0 U1 m# k: |- ^% v9 ~- }
            throw Error("v1不能等于v2!");' _' e, w" R& N' I
        if (w == infinity)! f: c! D! j6 Q8 u* B0 J/ K9 J
            throw Error("w不能为无穷大!");5 m6 [- A1 Z3 D" R

    1 Q& I. D2 J& }; x3 W  A' P& w3 W0 w6 G# v. z  t+ N& ~
        p = vexTable[v1].firstarc;
    . s( y! q& H4 u9 x    while(p)
    - G, C9 e" v4 o& }6 |# l1 U    {% C. S  O# R6 D  e0 l& P
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
      E) q8 i; p/ p* o4 P9 W        {$ w; d5 q6 t' _6 j0 _+ |5 T4 i
                if(p->weight!=w)
    " V/ y2 Z- y4 {+ w/ |- G                p->weight=w;
    * U' r- b% C% U. W3 l2 _            return;
    $ i+ H7 v2 U" |        }. p5 }3 E/ d& O7 y( ~4 u( m5 [! _
    - S5 x6 W6 q" |
            p=NextArc(v1,p);
    " x# P0 P% m/ d+ y" n0 \! T    }
    - X% x6 L! A0 E2 E0 n1 m! X% C( P    p = vexTable[v1].firstarc;
    2 I; Y8 N9 c) o! _/ O    q = vexTable[v2].firstarc;
    $ ]8 E* v% I5 j. q; f0 R4 c+ W    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法' E, Y, e: Q$ f
        vexTable[v2].firstarc =vexTable[v1].firstarc;: L3 O  Y. Q. ?/ B( q# J4 j
        arcNum++;/ g9 `! ]$ c8 i9 e. T! \( K
    }9 f7 C) O) |6 \" W  U& N; S* S# S
    ( Q4 I5 b3 J0 e1 E# H" n
    template<class ElemType, class WeightType>
    8 L6 c5 {1 a! Fvoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    9 \) q* o0 b' o, r$ l{
    ' R6 s% x' c  L. }! p! ?& M/ C, T
    ) u6 A. _- q9 z- j& F) n7 |* I3 R    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    # G$ R* c# A8 b, @0 f) ]    if (v1 < 0 || v1 >= vexNum)
    % [0 a  Z6 P7 A4 }        throw Error("v1不合法!");
    ' [' H+ b$ L4 _' ], M( Y) q    if (v2 < 0 || v2 >= vexNum)
    ( D; C' ]& o; q( o) W; j1 q% P' q) i        throw Error("v2不合法!");
    ( v! N6 Z# ?) @- ]1 I+ ^7 [    if (v1 == v2)
    " j$ T$ k5 Y' s+ N3 \* O' p7 T. [2 T        throw Error("v1不能等于v2!");
    " O6 c4 |; E' z2 J6 y7 g4 D4 l! l! k5 B* [6 P% Z/ \
        p = vexTable[v1].firstarc;
    ( F; h1 ^7 b8 \4 q2 g0 M* l    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)0 [, O; J( \. b+ K% t2 d4 V- n
        {
    " }8 d) v4 F$ n* _( r+ I        q = p;
      w% I$ K* G6 y1 A' _        p = NextArc(v1,p);
    8 E* C/ Z5 Y' a, z6 q    }//找到要删除的边结点p及其前一结点q6 w& y' P& t, w# \

    0 q: z  W6 p, U1 {9 b( g    if (p != NULL)//找到v1-v2的边
    - i7 T1 q# s0 C6 O$ U% \+ R    {
    : T/ V$ M6 A! o( E7 A/ \! l        r=LastArc(v2,p);: o' @3 l( J8 y
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL0 o$ `# O) H$ K; {* s4 w
                if(p->adjVex2==v2)
    3 R6 O: w& ~3 c/ [                vexTable[v1].firstarc = p->nextarc1;
    4 X6 r& x5 O- Z* g            else vexTable[v1].firstarc=p->nextarc2;* w1 t" L' V! O. }7 j8 Y$ d
            else//不是第一条边
    ; g0 F9 D: h$ E! j( f        {! v5 K  g1 H  e$ `  j6 l- p, S
                if(q->adjVex1==v1)
    & X  \* u4 J3 ^0 t0 m1 k# E5 j                q->nextarc1 = NextArc(v1,p);, O# t% f* u1 s0 k$ w( V! t/ X
                else
    + M4 b8 i; W- S8 h, n                q->nextarc2=NextArc(v1,p);$ U& H% |/ ?2 m
    1 E0 A+ ]; h/ U0 W4 e! Q- J
            }
    ' j3 }- i6 U! v: }. \        if(r==NULL): l8 {  @7 [% ~
                if(p->adjVex2==v2)3 }  P! N9 ]4 x7 _+ {! @
                    vexTable[v2].firstarc = p->nextarc2;
      ~1 h) t! d; X. J( T$ |            else vexTable[v2].firstarc=p->nextarc1;
    5 |. O- V8 X/ o/ x6 b( S# ]6 U! b8 D        else' E) r. x- B5 F8 v% G( I1 s9 t
            {
    , s8 u. g0 U8 @  i            if(r->adjVex2==v2)
    7 z" d" T' d7 D" r& j% J: y                r->nextarc2 = NextArc(v2,p);
    5 d, T) f+ a) U9 R2 R* x            else# ^: _7 @( S: i! O& L( N5 H
                    r->nextarc1=NextArc(v2,p);' E3 L) d& A& E  ~  g/ U" g$ w
            }2 o# `5 ?0 W8 [! r6 |
            delete p;
    . i$ }% K3 {% M8 X        arcNum--;
    * V! e# [6 Y; |# E4 p2 R    }% i' B8 }, t) _$ l. L% i  o
    " q5 k5 m7 U$ v6 E) _
    }
    ' J9 `- D$ ?  J. Z4 }) C% R2 Btemplate<class ElemType, class WeightType> void! O% e- ?- O  `1 f7 E( d
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    7 T! R9 `  W* {! y' }/ f  ^{* }( m: n: d  u9 s. k% b
        int v;3 u) S- r0 A  [5 m, z& h
        MultiAdjListNetworkArc<WeightType>* p;
    - I5 I$ {: A" B$ m0 `2 Z1 r    for (v = 0; v < vexNum; v++)//找到d对应顶点
    0 s/ H7 d: ~0 g7 g; i        if (vexTable[v].data == d)
    3 O$ N1 ~" Y/ X  E3 j            break;
    , Z- t- x# E. R# f: t    if(v==vexNum)
    + d. A& Z# N+ L- a" H! I        throw Error("图中不存在要删除的顶点!");3 Y9 Y( y' m* N! \+ N9 V

    & u& C: J4 h* ]9 V6 S. ^    for (int u = 0; u < vexNum; u++)//删除与d相连的边
    5 I$ f- o. w; X6 {, ^        if (u != v)
    . Y2 g2 t# A* n1 S: i        {" M, u! h; E) l& \5 I
                DeleteArc(u, v);
    ) r5 j# H, D' x4 }$ C' v  E, y        }
    * c# b/ @, G4 @( A/ W3 d2 Z3 W  L    vexTable[v].firstarc=NULL;
    % A0 M: k8 i! z6 I: j4 h8 y
    9 {+ }: H, Z9 U  S' K/ X! c1 E    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置7 Q, h+ r4 Y* n8 l
        vexTable[v].data = vexTable[vexNum].data;
    - d% n/ s) b$ q0 V! Y    vexTable[v].firstarc = vexTable[vexNum].firstarc;9 a( D8 b/ B% r. Z
        vexTable[vexNum].firstarc = NULL;
    & C6 M. t; m7 K" \- ]; h    tag[v] = tag[vexNum];! a5 g/ y+ v  }+ T
        //原来与最后一个顶点相连的边改为与v相连
    ( I1 T6 z4 i/ a9 f    for (int u = 0; u < vexNum; u++)
    8 P( G% q3 G0 D% c    {
    + I& U! t9 }& V  W' f7 X, |5 _% F  m        if (u != v), a$ \; j1 `0 I& _9 y" \% f( A* ?
            {: z( R; M- `. }
                p = vexTable.firstarc;
    , F% `! a3 m! O+ X6 H: N. _            while (p)2 n* h+ X. j8 e! I# W
                {4 a2 O" ~4 M+ W: n# M9 z; x
                    if (p->adjVex1==vexNum)
    . Z4 m5 D: O/ N- t8 |  M  U1 `                    p->adjVex1= v;
    $ j6 [. f! n- N7 r/ ]0 A8 U7 h  i                else if(p->adjVex2==vexNum)
    + V! l- T# w4 @" m                    p->adjVex2=v;
    ( t' s/ O; }+ f                p = NextArc(u,p);
    ! Q8 G( z# Y+ q$ y  p1 d* f            }9 B6 ^8 P2 T5 {" n1 Q$ P7 l, T  Q1 d
            }
      I$ Z) ~6 c) l" l    }  q/ ]+ W) V( [& P8 C
    }
    - m$ x0 S. }8 T. A6 H///深度优先遍历
    $ U! x6 b) v7 ^4 z/ F" ytemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)7 N! R5 W7 R0 r8 g( H4 Z
    {. {% H1 m/ N* F7 f- f# h
        tag[v]=1;: E3 P6 c' P0 E
        cout<<setw(3)<<vexTable[v].data;" z1 z9 ^5 ?* o4 k
        MultiAdjListNetworkArc<WeightType> *p;- |3 p% C" k8 x6 f, s1 g/ u
        p=vexTable[v].firstarc;2 t( e3 [9 Z6 x6 s
        while(p)
    0 ^! K( d3 x& E# b- q6 Z! e* P5 v) [    {) l- ]( Y3 J0 u$ b/ c9 b
            if(tag[p->adjVex1]==0)
    7 n+ j% v0 K( ?) N            DFS1(p->adjVex1);; ^9 s+ D( g& w+ I5 g0 \$ B- y
            else if(tag[p->adjVex2]==0)1 O. J3 i$ y0 t$ i
                DFS1(p->adjVex2);; E4 C4 V9 Q0 p+ H* Q
            p=NextArc(v,p);
    8 t- _; y; |7 W- s+ z! ?    }0 I# v' F; l( H; C) M
    }( F5 g  A( r1 I- }, h. T# ~$ B
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse(): V( f$ l: U% e7 }/ K( g- ?
    {
    ; r0 }  ?9 E% c    for(int i=0; i<vexNum; i++)% M8 @: {8 d. U% R
            tag=0;3 {$ C9 `5 F: n5 c8 E2 O
        for(int v=0; v<vexNum; v++)4 s! h: o/ q. f" f! A5 r# r
        {* h) U3 t, r. @
            if(tag[v]==0)
    # u/ ^+ j* y) M5 C8 Y7 l8 |            DFS1(v);* X% Q$ i* ]7 Q7 b/ R9 [& D! n5 c( u
        }
    3 ?' T8 r& w* H% E4 g- N7 N}
    ) |/ K! [4 S7 H, @9 t5 U7 _template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    4 k3 _7 m5 I4 o9 z/ q$ Z4 c( F{
    + ]4 e+ U2 @, `) U! V7 M2 a    stack<int> s;# ^$ E! [& B1 U# |- d  X1 J+ ]* l
        int tmp;
    5 u3 l% U/ u& P$ O* ~( R    MultiAdjListNetworkArc<WeightType> *p,*q;% ~. x3 q5 F) f- q; z9 s+ d
        for(int i=0; i<vexNum; i++)% G8 {, _3 D- s7 v' t( v) b0 J
            tag=0;7 X) z0 |  q: b. m+ W# K( l
        for(int i=0; i<vexNum; i++)
    % u# K9 m" U" y5 P8 y9 q" U" D5 `% Z    {
    6 a7 u% v" i" S% j        tmp=i;
      R! d3 y% _7 _6 ?1 N7 ]! p        while(tag[tmp]==0||!s.empty()): J4 n1 C2 J: ~& R
            {- u3 @3 Z8 F6 d. R4 O+ t2 b1 N
                p=vexTable[tmp].firstarc;! Y  U) `4 z, o' q6 G
                while(tag[tmp]==0)! c% Y( x" j* d5 R! e
                {
    1 N3 T: v/ @/ z; l                s.push(tmp);
    ' K: F& B2 O8 |8 f8 }' I                cout<<setw(3)<<vexTable[tmp].data;1 r4 [" [0 v& K* `( t
                    tag[tmp]=1;
    5 H+ K" H7 D; Y3 I7 G- ]" n                p=vexTable[tmp].firstarc;
    * q8 c* `$ Y7 Y8 O  }                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for, i4 x# B3 |# K3 a1 C1 Q
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    / C1 f$ ?3 p: F2 ]3 U; g                //cout<<" 1st     tmp="<<tmp<<endl;
    7 [. Z4 _; B- F% q/ Q6 C            }5 Z4 v3 ^# k% O
                if(!s.empty())! I9 p0 P' ^; j3 @# R  R1 e6 g, T
                {/ ?1 n7 ?' M3 n6 @- G7 ^6 H5 u
                    tmp=s.top();. u1 n& t2 x  W# r) T9 C3 ^4 R
                    s.pop();0 O5 F! u# i- S; h. O% J3 m( C
                    q=vexTable[tmp].firstarc;4 t1 b* d% C+ [( Y* U5 e
                    int t=tmp;
    ) E& W+ p% o! w% ?                while(q&&tag[tmp]!=0)# p% \! c  r! ~9 P& M7 d3 O
                    {
    . h4 `7 Y; a- w3 u, J                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    * J9 e: U  F% I8 S                    //cout<<" 2nd     tmp="<<tmp<<endl;
    1 O/ y) B; c8 f$ g# H: E                    q=NextArc(t,q);
    + Z  D* y8 y" D$ w( ~6 {                }5 B3 D9 v6 A4 Z% t
                    if(tag[tmp]==0)
    2 i+ R6 ?+ Z# _; e/ J6 t4 |                    s.push(t);
    # z0 i% `5 a8 s* ?/ g/ q0 M+ }9 |                ///1、对应上面连通分支只有1个点的情况& h& ?7 V2 K; M! W; A3 U! |+ d
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    3 x! c5 g- U0 G& ?6 S* g1 Z                ///tmp要么等于找到的第一个未访问节点,+ ^1 ?  }' e9 [* ]/ l
                    ///要么等于与t相连最后一个点(已被访问过)
    / q8 b4 u% `, z* L                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    * e8 J* o, Y/ z. m3 q' w; p; w, ?$ T            }
    , X6 B8 e1 |) Z* j        }# c8 e, m/ h' l3 Z  r$ h
        }
    % q) J1 t8 G) B; I# D9 L4 }: L}  t9 j" ^! u4 S2 Z" g  l
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-14 k% K- O6 K$ x' w: s9 P/ K  G' {
    template<class ElemType, class WeightType> int
    8 k  L$ n( V" e2 Q/ NMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre), ?" T; A3 @# @+ q( D
    {
    : W7 Q5 F) N* G) R3 k- c  e( P8 B    if(head==pre)! l+ a  x$ n- L7 a3 G2 ~
            return -1;
    0 X" q% {4 J& q7 ]9 p" x; I! p+ `' D) f3 ]! H( ~
        MultiAdjListNetworkArc<WeightType> *p;
    ( m! C* L8 O5 ]0 z    p=vexTable[head].firstarc;
    2 `. V9 Y- L2 y7 N    if(pre==-1&&p!=NULL)0 z0 i2 l0 @2 |5 m, e% d
            return p->adjVex1==head?p->adjVex2:p->adjVex1;: n5 R; b4 X' w! O9 {& Y0 g! U
        //pre!=-1&&p!=NULL
    7 r& ]6 c$ L  ~* W    while(p!=NULL)
    + S; l9 q  q3 W& o    {
    4 n7 r+ j. [1 {/ L) s2 c% B        if(p->adjVex1==head && p->adjVex2!=pre)
    8 P( O; g2 ]$ O- v5 Y            p=p->nextarc1;1 r6 H1 I. E* N7 H) c- h: X2 [
            else if(p->adjVex2==head && p->adjVex1!=pre)7 L8 Z" Y( M% H. K! y4 T' G
                p=p->nextarc2;
    ) E" e- W. w4 w1 [3 J" F        else if(p->adjVex1==head && p->adjVex2==pre)
    # y" F2 j0 O9 T  D        {: |4 G; |8 p7 E3 K8 K- U5 ^
                p=p->nextarc1;1 K" x0 p5 p) }" S
                break;# Z5 c% p) F6 t( j  D" q' m
            }
    : E) g* _/ B5 l% B; B        else if(p->adjVex2==head && p->adjVex1==pre)
    9 P. k) K% E$ w1 V, K7 u        {
    ; d! p2 }7 ~! o1 ^; [            p=p->nextarc2;7 B4 o& Y& J/ c1 z( Y1 C0 `( c
                break;
    1 _+ J, z, D9 H% |0 B. v        }1 u0 E. I& ^0 ?# q6 f. g* `
        }+ P" T, [4 E- \- B
        if(p!=NULL): }+ s+ a* L* q9 Q5 s8 Q1 `
        {" q7 ?2 u' S" z9 T
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    1 W; M5 X* Z$ @/ ?4 T3 \    }3 e" h0 O6 \' O8 ?9 s; M) p5 x
        else
    0 O- O9 t: W/ e' D# ?        return -1;! `' w5 D+ C6 ^4 J% I6 p
    }0 l  \4 }6 C# Z. w* H8 |8 b

    $ H, @9 l2 n6 U; x  i8 h1 P
    9 E& O$ C* d* M1 |. k8 i6 Dtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()5 n  Y/ |" O7 {! P
    {
    . k6 C7 i' I1 M0 d# A    stack<int> s;6 y, F) U9 H. l) I* b5 E& r* t8 r
        int p,cur,pre;
    . q) s; }* F$ U0 p* S) G6 z    //MultiAdjListNetworkArc<WeightType> *p,*q;
    : e) X7 Q& P+ f/ Y# r1 N    for(int i=0; i<vexNum; i++) tag=0;//初始化4 b% ]- }# C; Q# Z( d" Z# `2 j
    1 N, T; a! O' \3 X5 `' e
        for(int i=0; i<vexNum; i++)
    8 H4 C- D0 @5 Q* J9 Q    {
    4 g0 e$ U1 z* H* ]1 N3 l# R) V/ }7 m        cur=i;pre=-1;( Z. \0 ~3 m5 I0 q8 ~: W
            while(tag[cur]==0||!s.empty())2 Q' R) l: g/ S, Z& w$ U
            {$ x8 S8 z* l1 H, g6 v8 ~8 X
                while(tag[cur]==0)
    ' ]. R5 M% T1 a, p# z1 g' D3 N5 z            {
    , n: K! s( P% C4 v" J6 N) }3 s                cout<<vexTable[cur].data<<"  ";
    2 p8 l* V7 K" A0 J# U: M1 R3 l                s.push(cur);: A' B& |) N- A& ^! R9 B8 s( ?! ?
                    tag[cur]=1;/ U% H2 \6 {# A& N3 M. t; t& t( f
                   //初次访问,标记入栈
    $ H( r8 w7 {" |! T$ m$ R7 q8 R! O7 y
    % z5 B4 n( C& Z9 U  M2 Y               p=GetAdjVex(cur,pre);//p是cur的连通顶点
    2 @8 S7 Z; n9 f7 Z1 }               if(p==-1)9 ~; p! O; m; d
                   {* J( A& ?0 N4 [1 F, h8 m
                       pre=cur;s.pop();
    , N' l" V4 S4 P. e+ L5 p; H. S( k                   break;
    * R7 G8 d* ]  Q; g) M               }
    6 b, C; e6 T: ~4 Y4 ^& v: T               else
    9 `9 R6 M+ h8 [5 l- f: O) K: G* T) @               {
    ( L9 J/ |3 v1 y& D                   pre=cur;
    : ]! K3 v5 y: r* g                   cur=p;
    7 u1 N# l# ~4 ]3 n4 _; m& Q' \" K& C               }! r- ]7 m" y! ]

    ( y5 u# O& n6 @. E4 c            }
    0 v, C( h! ^0 e8 t            while(!s.empty())0 W3 C% w: y2 A) e9 j
                {
    . Z8 C/ s0 l/ G) ?; y% f. {                cur=s.top();
    + A% k: P  u& c4 p3 U/ a                p=GetAdjVex(cur,pre);
    - Y* T' j$ G- Z8 a4 O                if(tag[p]==0)9 R* r8 V" ?' N: X
                    {7 U$ Q5 C  H0 P1 ^* Y
                        pre=cur;1 ?, D# {1 f9 N: t+ p
                        cur=p;& B7 H9 Z: ~* F/ Q: o
                        break;  f, ~2 c' e" w" G
                    }
    ) A% s# r, w; M% i2 \                else2 N8 K" f; N& p$ n2 d9 D9 g
                    {/ M8 b. f8 t1 e4 V: I) Y
                        pre=s.top();$ m+ I' W5 X' t* I: v
                        s.pop();
      D+ k" @& A. ]6 S/ o# m5 L                }/ a  ?- o5 d1 A. }

    * O( F5 u" ~$ q            }
    " u9 M% q5 w6 j. i& M4 @  g  K0 L
    4 @. M' m( E9 W! k9 ^' D$ C/ d        }* q' h* ]7 G% Z% p8 d
        }/ p- n# m. Y+ W$ m# K- J) H
    }
    ! }: O1 S0 n, M( `, `. Ntemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()5 I2 Z( N! O7 ~' M5 ?& V% s
    {
    5 `& g4 O! _; v& |    for(int i=0; i<vexNum; i++)
    9 B& h5 k% F* L. h0 x/ n        tag=0;: @% U  B4 y" k. D$ s- ?# \
        queue<int> q;- H! W# O& I0 n2 J
        int tmp,t;2 H3 Z- a$ T7 ]
        MultiAdjListNetworkArc<WeightType> *p;
    2 p+ l* @! M7 }5 L" H7 b/ s# a2 A) p    for(int i=0; i<vexNum; i++)
    ( v+ ?: ^; t/ z1 n: f) d: n    {( O$ l! `6 b9 q2 x
            if(tag==0)
    ' o) a, j7 V; m+ m# P0 v) W) q        {
    * c" e; @' {6 U" @7 J& ?% {' H            tag=1;
    9 V8 n3 R5 e  p8 A' ^( Y            q.push(i);
    . j1 u& ~5 u8 h0 o5 t            cout<<setw(3)<<vexTable.data;
    5 ~8 d' b8 F1 b        }
    % d9 E2 j' I) C% _8 F8 W        while(!q.empty()); f0 S' a7 Z" ^, j' K
            {+ h' T7 Y5 {( N3 f
                tmp=q.front();' Q; \; L# h+ [& h8 O
                q.pop();
    2 ]+ I* {# B# Y$ b            p=vexTable[tmp].firstarc;: G& X7 ~! g* N1 R
                while(p!=NULL)- T, p* d' U3 A% V% N  ?
                {
    " f" J+ C7 b# j, F* J4 t7 e                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    9 M1 p- W, p: m* f                if(tag[t]==0)
    ) Q& M5 d1 x- |5 }4 m$ y7 ^( D9 D  v                {
    5 n7 z& E8 E( A9 t                    cout<<setw(3)<<vexTable[t].data;
    2 [( a5 {- K. B( V                    tag[t]=1;
    , ^9 w, p" T% W1 k                    q.push(t);
    - m# s% ?' K5 q% g                }
    , I8 p) b1 }( w; J9 a" |                p=NextArc(tmp,p);
    7 f4 k3 K( [7 |            }
    8 G% o$ }9 t4 k. ~  Z& }0 x        }+ @4 s+ H/ _! L
        }& G# R" U* G4 w/ W
    }
      Z. o  S! D1 R0 K. e; \template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()  }, M' E! ~% `7 W8 k1 f5 B
    {
    ( h0 F( s& d5 I: ^5 Q, Q    MultiAdjListNetworkArc<WeightType> *p;" P* }) v. m, F! p
        cout << "无向图有" << vexNum << "个点,分别为:";
      i% k. h. p* h  h    for (int i = 0; i < vexNum; i++)
    * S9 \7 T/ B1 p6 y2 e1 Q! }        cout << vexTable.data << " ";
    ' M% Y* B4 d; ~% [5 D- w0 \    cout << endl;
    0 B$ f, @8 P  t1 E8 M    cout << "无向图有" << arcNum << "条边"<<endl;( I3 L, {2 g  L# R0 U5 L( Y: w  ^
        for (int i = 0; i < vexNum; i++)# [% S; v) L. P' E- b) x0 s
        {/ ?; T, }8 f% O
            cout<<"和" << vexTable.data << "有关的边:";: W! I- ?3 u1 t6 |6 v1 i- A- x
            p = vexTable.firstarc;5 k) Y5 @2 K7 ?
            while (p != NULL)# A1 |( T; k1 Y9 n
            {0 B+ \& Q7 H, y7 f
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";4 m- Q' i& l; _& B* Q8 z. y" e
                p=NextArc(i,p);; a3 z$ h2 q: M( l- G
            }1 W; E8 N9 Q, x+ f; l. p
            cout << endl;7 s) @: g$ H7 n& ^" s: V
        }. t, C( m1 ^" b: k
    }
    - a, G8 ^/ U3 m4 _
    + z' P3 w8 [4 C; j' t. p8 p" ^5 s, e0 K, e
    邻接多重表与邻接表的对比
    " {# p( j2 G; J$ L4 I* w9 `' X0 w' f  d' A2 n
    $ b8 q" e! q+ A3 L# m* I邻接表链接
    . X5 @2 l. ~$ R, N) \6 P在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    ( E" A) M) `/ p8 ], g1 A8 E& e3 w6 K) H在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。2 B- u- ~" ~0 L9 v& r+ J0 o9 x6 y
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。: a2 @" K  T0 @0 y0 M9 J' w) G
    ————————————————
    % M; h4 N6 K: ~5 w# I5 @" T版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    2 ~& @- r; b0 I原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    $ h3 R, T' S( P  N( S# `" ?# \
    * f6 E( I, X+ c, X
    : ^1 }4 ^# k9 i' L9 z2 p. B
    / w% M$ g1 L5 b0 ^1 Q( E: p- i' W0 z6 L
    ————————————————2 C; _4 F" q& A3 I7 j) t
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    7 Z* s7 X; b3 G( [' F原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    : a# L$ q  B9 V6 Z7 s) N
    ! M; S; ~8 C8 j' l+ h
    2 \, O4 V2 I5 J/ p6 B/ 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-1-9 06:49 , Processed in 0.555950 second(s), 53 queries .

    回顶部