QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1625|回复: 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
    2 \" U; u& G; l3 z8 J. c
    图的存储结构——邻接多重表(多重邻接表)的实现% ^2 t$ z8 N4 ?, t$ d/ n. k
    7.2 图的存储结构
    0 K. U9 _9 I0 f' T" T+ L8 ~; |6 k9 u2 B+ `) K( C$ L* x
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    + H. Q1 I! x7 K& Y2 D邻接多重表的类定义
    6 P1 r5 X% U/ x- C0 B1 m% U邻接多重表的顶点结点类模板, m  b' r# ]( G( I! s
    邻接多重表的边结点类模板- z5 P2 `# c) E8 G
    邻接多重表的类模板
    ' y8 a+ x' @/ O) d5 R2 ?邻接多重表与邻接表的对比
    7 z- T+ q9 F* |( `7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
      N- G' B; u( F( Z% r
    # _6 K8 W+ s0 I* G- z& s0 N" F在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    # [# t; v. y. |& J9 _在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    3 s# y6 _8 e6 j' ]- f% w: p* _
    " T6 X+ L. W, _: ]6 M邻接多重表的类定义
    , u# D% ?5 H+ D" o9 j: B7 e 1.png
    , w% a2 M8 E$ ?: X邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:. \) o# ^% y: N! M# N; X9 |
    data域存储有关顶点的信息;
    8 G/ b3 }  L$ g2 B$ Sfirstarc域是链接指针,指向第一条依附于该顶点的边。
    & o% R6 I/ e) n8 k2 p; U( V所有的顶点结点组成一个顺序表。


    2 Q" `( }0 E/ S' g. @4 S8 x4 @) ]- ~3 j0 `( `/ J
    template <class ElemType ,class WeightType>
    3 h, }% t7 R" V1 r# q+ Lclass MultiAdjListNetworkVex
    , K, L  i* f9 y0 k{
    - g# O# Y% u+ y- x  P0 vpublic:+ Z3 ~; B# d# u  a% R2 b
            ElemType data;7 x/ E( P7 G* {# W
            MultiAdjListNetworkArc<WeightType> *firstarc;: s, Y1 Q8 \8 R$ P$ i8 S2 X

    + f) K) Y; @* A7 t        MultiAdjListNetworkVex()
    # L9 R- s2 R, p* c8 k        {- E4 f% F. u. m- r9 c2 v
                    firstarc = NULL;3 o! r2 Q; E$ t; ]5 }
            }
      D% ?) Z* I' H0 ^1 c, e  B6 W% }* L2 u3 J        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)0 F' ]& j- i- u5 a* V
            {' I% Z' h: L2 f& T7 b* Q* C
                    data = val;
    * x  z4 `0 d! E% ]- z) C5 n                firstarc = adj;
    ' Q6 \1 x7 Q2 f2 I. ^' b" H  L        }2 l% P5 d5 |! |7 P
    };
    / S" d% J! L  Z% T
    % B) [" P$ L5 l* g  M: F* E0 M邻接多重表的边结点类模板
    & T5 r4 `+ v( S6 _; p' s% Q6 T/ S" V- E
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    , m$ Q- x3 W6 y4 w6 Dtag是标记域,标记该边是否被处理或被搜索过;
    ( V1 T/ i: a3 _9 e  ]$ @& lweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;7 `5 k# g0 N0 s7 R9 c. y
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    ) c% A' @8 N( `0 D' F# m/ p1 T1 t  ~nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。1 f, n7 t' o& i4 A$ Y5 P: E5 J6 Z
    & s- I& K3 _  ?
    2.png & g1 R9 [6 {$ B& p8 O% J& S4 j
    template <class WeightType>
    " r  z' i" j% G: v$ b6 Yclass MultiAdjListNetworkArc
    2 E# z6 U- V" J* d{% k! V' i: m; o6 |; X
    public:
    & Z4 Z+ t  y" q" y# g9 D3 e0 R    int mark;                                       //标记该边是否被搜索或处理过
      L* Q* {  }4 Q" f& P        WeightType weight;                              //边的权重9 K/ o, q2 f0 K. m2 r
            int adjVex1;                                    //边的一个顶点' Y' o( I6 y+ s9 \7 X# H2 w, r
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    % j& L) J6 E$ L. B        int adjVex2;3 B+ F2 B- J9 m% H; p
            MultiAdjListNetworkArc<WeightType>* nextarc2;
    * _) n6 w" F2 X, u' x
    ' D! @0 G4 ^2 c0 f. D- }$ A        MultiAdjListNetworkArc()
    6 x7 o5 ^/ C! N        {. A4 R7 |0 w6 g
                    adjVex1= -1;
    6 D, E* J( m8 F; d                adjVex2= -1;
    0 \% `  T; E9 K, V  z8 T, K% N2 O' b; r        }
      J/ h, Q6 q3 k3 {5 ^( }7 b        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    " W4 F) O- u) f# ^, l6 Q) t        {$ X8 S, g6 e$ a5 n0 h& q
                    adjVex1 = v1;       adjVex2 = v2;
    4 x# [, R2 Q9 j: f                weight = w;3 G3 i" T, q! `! h/ M6 L0 G
                    nextarc1 = next1;   nextarc2=next2;; p& T' ]" ^1 |! l4 `' _) A
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    - [2 S- o0 L% }+ I8 t        }' _8 w( G* T4 e- A5 d
    & {/ y: {* K' k
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>* |7 D9 ^! r! N! ^: l- ^
    class MultiAdjListNetwork
    ' l: P5 t$ J) C* h9 X# _9 h$ b2 N{5 v$ w& U2 \- T" S, X% ?$ e4 d
    protected:
    ! l5 ^0 J5 w5 g' y3 |* P$ n% h    int vexNum, vexMaxNum, arcNum;
    5 I3 t& q. I5 k    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    ! R: x6 q& D* S    int* tag;
    7 R8 z: N+ v5 [! q, [    WeightType infinity;
    ; k+ p* _* p2 V+ I: O4 \: `7 d* v7 h, j0 P
    public:7 s; ]/ ]3 O% a7 _
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    1 T: S5 ~2 G0 ?9 Q, d5 b% @* V" _  U( X5 T
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    ( l9 _" D. |; v
    * r$ M. Y$ n& ]% P- V& E    void Clear();
    + X8 i- t& H. A& A; ]+ ?* j    bool IsEmpty(); Q* z" j8 }  q% a4 [" ~# ]% T
        {, m# N) G; u. V3 T( @! A
            return vexNum == 0;8 L1 b( x9 S+ g# ]% u9 E3 N
        }
    , V! q- P5 ^$ `( G1 W! z+ d    int GetArcNum()const8 C# W& `- o1 ?, [2 R" k
        {. J. p2 @3 ^% g' ]5 n1 d  `
            return arcNum;! u* B0 |4 E# ?! y
        }
    * n9 R' G4 B; B9 ~' t+ C# V    int GetvexNum()const5 v0 C& N, Y3 T( C- o& x8 B
        {- S8 e4 z& b' ]0 V
            return vexNum;; D& \/ @& h3 N4 ?5 L* w/ Z, q# q
        }
    . H7 g7 C  v5 c1 @. x- o0 @
    1 }4 A& p# p: k! X5 e8 X& x& _7 a" T1 @) u2 |" M$ F0 o, @, o' t
        int FirstAdjVex(int v)const;. R. `& k. O) r
        int NextAdjVex(int v1, int v2)const;) U" ~6 y4 R! G( j3 R4 M4 h9 W7 J
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    " B$ j% u9 Q  d$ i; m    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;+ U1 I9 h- `$ [6 j7 p1 H
    5 ^5 u  s1 b0 j; E- |9 ]" x
        void InsertVex(const ElemType& d);8 D) z4 ~/ X! ^( p6 M0 V3 e
        void InsertArc(int v1, int v2, WeightType w);: F7 m" ]. ]! @: \0 W$ L

    1 c$ {+ k( A! u, B& u& t    void DeleteVex(const ElemType& d);
    6 I) w, J+ l; m" N; R: p+ d    void DeleteArc(int v1, int v2);% W" M( a. C3 h
    3 p* x; x9 ~6 V
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);& \8 B. w/ v& B: i
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    $ R/ Y  @( {9 ^5 W# J/ |5 W7 r
    " D  [9 s0 A% q, `3 g" U% {# i    ///深度优先遍历- R7 ?& v: K4 s
        void DFS1(const int v);
    " d# M( ?' @: @; d# n    void DFS1Traverse();/ \) C: j$ ]) c8 p( w; F/ g
        void DFS2();+ y: Y) u$ B: j! i3 {; c+ I* Z

    8 j9 R4 h/ M, R& B2 n8 b/ ?* w$ Q    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1' m/ L- i  I, x. t; h5 }
        void DFS3();, S' E6 N9 I2 @% M7 t) W- ^+ \
    " Q0 t) X. h! r8 z4 y% {- ~3 F. N
        void BFS();
    ) W( D) E  ^6 |' h) o( F: J    void Show();/ Q  y$ _! `+ I# N5 N$ Z
    };; H) I" E0 X  b; P

    / Q) @& h# N  V2.函数的实现
    1 I9 c5 X- G+ d0 w0 i研讨题,能够运行,但是代码不一定是最优的。% n# V! J- m$ t2 T1 r
    ( `4 p3 M7 f7 V
    #include <stack>
    $ I+ S4 U5 c4 S$ A7 O#include <queue>
    0 n# z6 t$ \  h- M: F; H+ t  ]2 }$ e" D3 Z/ z& I
    template <class ElemType,class WeightType>$ |- y+ r( [  u) c* p
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    , l5 u7 L. u" f2 n. F+ @' R{) L% W' e' s, a. b$ @  U3 l
        if(vertexMaxNum < 0)
    ) f, O1 N0 f7 x5 I0 ?5 X& I        throw Error("允许的顶点最大数目不能为负!");; H( y' w" g6 Q& V
        if (vertexMaxNum < vertexNum)
    $ V# J; i0 s. Z6 Y* K        throw Error("顶点数目不能大于允许的顶点最大数目!");
    ! `+ K6 {$ z7 E1 v6 d    vexNum = vertexNum;+ u4 o1 ]: o7 Y. n! U# x7 m. @
        vexMaxNum = vertexMaxNum;
    * Z6 Y4 B$ ~' w! w" G    arcNum = 0;
    ; ?9 u6 w5 Y3 N, |* k' C9 a9 c$ ]% _    infinity = infinit;/ ]: f! a( \. M' ^" ^4 t7 _1 t
        tag = new int[vexMaxNum];
    3 ]4 y3 x9 _0 q) V: u) k0 y+ `: v3 a    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    # O$ f) e+ s6 N! K) k    for (int v = 0; v < vexNum; v++)% J8 H# P- Q# a$ Z1 b
        {
    $ V- n( y1 E8 K" w1 C        tag[v] = 0;
    + K. n6 w6 c# J, J        vexTable[v].data = es[v];
    - q9 a, B# b9 T; `  e$ v5 x3 C        vexTable[v].firstarc = NULL;. A) ?- U7 e: T% l4 B# @
        }
    - k- t0 f# K& k* J! D}& s- a; I$ z0 L9 G' v
    template <class ElemType,class WeightType>
    + y6 ^5 q* e( z0 k8 c; \# dMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)# S( T  |$ z! e1 ^* [
    {
      H0 N: T. Y9 `2 O0 h$ j+ s1 [    if (vertexMaxNum < 0)+ C& y8 [. u- D1 e5 T4 Q, r' O
            throw Error("允许的顶点最大数目不能为负!");& M) w  n, c3 {$ K, r$ |. Z9 n" ^
        vexNum = 0;
    5 }# V% ^5 k- G6 K    vexMaxNum = vertexMaxNum;
    " a6 @) z' v6 _0 v+ F) b    arcNum = 0;, \  g5 R. s) ^, I: v* a# U4 @
        infinity = infinit;& c2 c) y8 |1 Y7 U  A
        tag = new int[vexMaxNum];0 E+ T% R3 A# {) d' d1 c( \
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    / w) t6 R/ J" W, b  Q}
    ; i: I+ x' o7 g3 R0 }template<class ElemType, class WeightType># y+ ]% ?5 `5 y
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const2 L4 U8 w$ N6 g! `
    {* [$ _2 Y6 G0 U( G  ?
        if (v < 0 || v >= vexNum)
    ; b4 k- S: z$ ^: O* y  ?( T        throw Error("v不合法!");
    7 b# X* b1 v. r7 X$ C! x. f2 _    if (vexTable[v].firstarc == NULL)
    - |! e- p: H1 t+ ]        return -1;
    ) |7 f3 _" R/ t) N% P" z( k/ x8 B    else8 ]) K# G$ A8 o$ ]0 @) E
            return vexTable[v].firstarc->adjVex1;7 i  p/ e+ y8 ^# E  _6 E
    }: O. m: |& c# T

    3 V- [( A: C$ N) P' t, D% r! atemplate<class ElemType, class WeightType>) S. B) {2 y9 C
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const+ P& G0 u& I  R- q
    {- b) p% g/ d6 j+ j( M) P
        MultiAdjListNetworkArc<WeightType>* p;+ F* S; d: H' d" d7 Z: R( a
        if (v1 < 0 || v1 >= vexNum)
    ! p* K9 F3 R+ i% c3 U) @- C        throw Error("v1不合法!");" j" D$ R! s4 I! S
        if (v2 < 0 || v2 >= vexNum)
    & I9 s( d- h# u( v        throw Error("v2不合法!");
    + v- e* o/ M( @! U8 ^. o$ G* P    if (v1 == v2)" q1 U: V) @& P6 v. @4 ]+ o
            throw Error("v1不能等于v2!");" ]8 X1 e: M2 }4 X$ c' K
        p = vexTable[v1].firstarc;
    - a8 d  L" J- W0 f7 ~    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    * T- m9 d3 \! s% k3 m        p = p->nextarc;
    ' x! l" D  d! H6 S    if (p == NULL || p->nextarc == NULL)$ L2 G' [, u3 j+ Q* t0 q7 U; C
            return -1;  //不存在下一个邻接点( B0 \7 @: S! {$ p# ~; X7 W+ W/ t" l
        else if(p->adjVex1==v2)
    ) q5 m' F% K2 q( z5 y4 {        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);8 u1 G6 [; p6 p* L3 W
        else
    6 P9 u$ b) e. [" ~4 S  @! y        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    : @8 V/ m# F6 o2 s) a7 `}
    9 y" G: ~: M1 i5 Q. g/ Mtemplate<class ElemType, class WeightType>
    . {5 e6 X! g. Z9 G3 n) Fvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()$ Q3 X. o2 j4 X5 ]
    {- `  ?2 o8 p7 H/ ~- O! ~
        if (IsEmpty()) return;& q, O- l. o4 U" U; z9 h) @' _
        int n = vexNum;. n6 e( V* V4 @0 A1 [# _7 C* D
        for (int u = 0; u < n ; u++)
    ' P; Q" Y. j, i! j8 Y7 I        DeleteVex(vexTable[0].data);
    2 ]5 I# p8 D. f. F' h* e    return;, R9 k, R9 ]: d6 ^0 O
    }
    - M5 j8 v3 B( v* q7 D% ~$ Htemplate<class ElemType, class WeightType>
    7 @4 y6 i; }+ ]3 lMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()* W. C$ o. R! V
    {
    . V: A% K( O) F$ @" K9 a    Clear();
    3 y# b5 ]$ f3 m: ^1 C}' _2 R2 k4 l+ |: r- Q
    template<class ElemType, class WeightType>) M5 O$ m) H" s8 w7 U
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    - J1 }" t! `$ t0 M7 p9 ~{
    # N* y5 b9 P0 Z9 P' t4 {& O    vexMaxNum = copy.vexMaxNum;
    , {% C; {4 H5 b: n    vexNum = copy.vexNum;( v, u9 d& K/ U" Q7 d& ?9 M
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];8 j1 r* z1 i0 y  B2 c
        arcNum = 0;
    ( K& f" I, K- ~) l3 d4 }2 K- |* C: l    infinity = copy.infinity;+ B8 F7 h1 G6 k$ D' a+ @
        tag = new int[vexMaxNum];( q8 y  K* m5 a7 r
    5 X3 G+ X" ^* j8 f6 l  T; l: }
        for (int v = 0; v < vexNum; v++)
    ! }4 W3 ~7 l; c+ _" H    {
    . ?2 }( v$ J7 {% ]        tag[v] = 0;
    2 V, ^: M7 @- S% a" X& h* y% \        vexTable[v].data = copy.vexTable[v].data;
    : @7 g6 t9 s' O! a0 c        vexTable[v].firstarc = NULL;- Z3 s5 i3 W/ y. u' @& a, [( u
        }
    / {3 }- u# F8 ?$ n2 D7 H+ M4 H3 e    MultiAdjListNetworkArc<WeightType>* p;
    * O1 v* }: V2 c0 ]
    ; e- T: X& w+ i& z    for (int u = 0; u < vexNum; u++)" x1 _$ s% R/ A, a' A% X1 V
        {
    6 n) r: X4 @1 a3 [) _        p = copy.vexTable.firstarc;. y/ Q* O8 L+ E. R' Z
            while (p != NULL)2 c  O9 W4 }) j# C
            {( Y* |9 D; H2 a; L" @- i
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    ' N) O8 a  r% ?! o! O7 b            p=NextArc(u,p);
    ) B' ^2 Q3 I, c* o$ ~1 k        }
    5 T* a; j' Q9 `8 ~/ v    }3 F0 e8 E( L/ ?8 u+ N
    }( a8 d% f  C- P6 C
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    - v$ I* ^5 J$ C; r/ }7 x/ w2 ?MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    ; g) i  M4 O( x# u8 X0 |{
    # ~& D: I" _4 T& f    if (this == &copy) return *this;5 |# N- X! w7 D: `, Z# G$ x
        Clear();
    3 {# t+ k) n6 B+ Y( j/ _5 X    vexMaxNum = copy.vexMaxNum;
    ( ?8 O  @, H' ]    vexNum = copy.vexNum;
    , w7 u1 o. z' ^/ w$ U, O    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];) m. R" }5 n$ K! H4 h4 _
        arcNum = 0;& l# D4 @6 \9 x0 c
        infinity = copy.infinity;# ]/ h. o- Z# L; M& i3 R
        tag = new int[vexMaxNum];
    1 @* F+ {( i, z& C
    / X, Z* H8 p, V5 e    for (int v = 0; v < vexNum; v++)9 e& \) u/ G3 U5 @1 i- T1 U
        {
    $ }4 L8 ^5 Q4 t        tag[v] = 0;
    8 w% Q; T2 M, g# I( {" V) I3 `) R        vexTable[v].data = copy.vexTable[v].data;7 S8 U+ t2 G# U# N2 R, I2 t
            vexTable[v].firstarc = NULL;/ Z$ x. H! e4 L1 k
        }
    ) F5 q6 y$ t& s" a2 M7 _; k    MultiAdjListNetworkArc<WeightType>* p;
    8 v' p. s% f5 Z% ?: [" v
    ; \7 u: f, }! t8 K: S0 ^$ D, S    for (int u = 0; u < vexNum; u++)+ w( j* |) G& ?: x, Z3 P
        {
    $ R6 A4 K' {9 }! {' a6 C0 H% v        p = copy.vexTable.firstarc;3 H( d0 X, F9 q4 S) R' H' [) M3 m
            while (p != NULL)
    ; Q9 L# p* j! E* n1 g. H        {
    . I6 j# d& D5 b0 P( @! p7 q0 K& L( W            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    2 p1 j5 \0 X: w8 H, _6 h            p=NextArc(u,p);2 }' Q0 J' b. A- N9 V
            }( }" l6 E# ?4 f% N
        }; l- S. [& k/ n& I( Y; Q% S
        return *this;
    ! J, @2 P6 l2 Q; Z) F7 K, A}6 g) `4 p# ~+ y* k
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
      l0 H* m8 d/ |MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const( H2 u( Y/ m) ^. R9 |' n
    {
    $ r2 [# q$ I9 R& ]7 H, O1 v    if(p==NULL) return NULL;
    9 ?6 o, [3 l) t7 I+ f+ P! r    if(p->adjVex1==v1)
    ; L$ \+ V( ?9 D- s# _  y, \9 s        return p->nextarc1;: X, L- G5 W+ B
        else% l& G5 r; S& k+ ^# M, J
            return p->nextarc2;/ g, V+ P" U" x- ?3 D
    }
    & C3 x7 p- R$ M, Z6 _template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*$ x; k' |5 W8 @5 r
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    6 v' E: b- f+ I4 A6 M{
    1 i2 q5 Y4 _/ c. X" P3 l    if(p==NULL)return NULL;8 a7 k% a/ ?( ?; Y7 }) j
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;" A1 s# ]: S1 Y/ l  K# T
        if(q==p)
    $ A$ k/ I4 H" Q$ M! U: v        return NULL;
    ( U' L0 {4 }( D( L" ~' ~2 A    while(q)
    % x- d& A3 s7 ?# p, c2 B6 [    {
    9 Z: `4 p. p! s. K6 I        if(q->nextarc1==p ||q->nextarc2==p)
    8 D9 B$ h$ w! u8 I+ f9 i            break;
    7 J- Y# D: v; T' C+ A) V        q=NextArc(v1,q);3 P/ C% u# \0 D2 q. {$ B$ T
        }$ f  {- r8 w2 O& O6 l
        return q;
    + |, d+ ^7 }! h) P" i; G+ z' l}
    " t: N) a5 t, {4 F; e! Ltemplate<class ElemType, class WeightType>2 N# T5 E8 P% _
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d); q. c! c  ]4 n- W0 U8 w/ D0 a
    {
    & I* s" a2 Z% T/ d. S    if (vexNum == vexMaxNum)6 e+ A' K; b& d/ F0 E6 w
            throw Error("图的顶点数不能超过允许的最大数!");1 ~0 C/ _  j* L. |8 e" H! m5 Y
        vexTable[vexNum].data = d;  @0 W9 o; G4 J1 l
        vexTable[vexNum].firstarc = NULL;
    - D5 X: ]3 o' _9 u) T  W) s    tag[vexNum] = 0;
    & W; C4 q6 `/ W  _    vexNum++;
    & s! Y5 ]; d) J' A3 N}5 q; \0 H! H' V4 C, l+ K# s& {" W$ X: _
    template<class ElemType, class WeightType>" o, A( l& c7 O8 T8 f3 A
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    . T6 J& u5 z3 ]3 ~  z- H9 b3 o{
    ( h0 z6 ?8 g' l. s    MultiAdjListNetworkArc<WeightType>* p,*q;
    / e/ g* z, @% Z8 i& k    if (v1 < 0 || v1 >= vexNum)7 L3 O* w5 _/ t0 p. m- P0 ^; e; z& m* N
            throw Error("v1不合法!");
    / D% Y/ j: N, B$ e    if (v2 < 0 || v2 >= vexNum)3 R! x7 _! Z1 |: x" V
            throw Error("v2不合法!");
    & i- M% F2 ?4 x0 w, D6 H+ F    if (v1 == v2)
    8 N5 k$ @: b1 o        throw Error("v1不能等于v2!");
    5 N& G; V& C+ t5 x/ N% n! ]8 A  W    if (w == infinity). ^+ g2 A0 J- b  L5 t  c  r
            throw Error("w不能为无穷大!");
    & R' E7 K: c) A; d7 T
    5 N- @: X7 V0 c
    2 L8 [2 p, [  h    p = vexTable[v1].firstarc;: X- X& K/ q  b1 K5 V
        while(p)
    9 H5 F- C' G3 ~1 Z: z. Z$ k2 e    {
    , C" r% J! c1 ^+ {        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中# i$ a! y. a7 q' p- |5 E* @# D5 }+ Y
            {
    / G9 z$ o6 J" o( n            if(p->weight!=w)
    * k0 Y# d. z  k$ v                p->weight=w;, I' _8 A9 K4 r) [0 {
                return;
    & J+ s  u2 o  l# N        }
    2 n7 P  M- Z7 s' J- [0 [& ~2 h
    , p' [: h' ?+ s* ^: d- J+ }1 U' A        p=NextArc(v1,p);
    - X% K1 o: a9 F$ l0 z    }
    % w. U4 s  x7 K- o: w+ V) q5 @    p = vexTable[v1].firstarc;( l8 h* x) g9 V, e3 c$ N
        q = vexTable[v2].firstarc;  ^% i/ t  |- T5 {" x5 O
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    4 |9 {. }& A* w9 u    vexTable[v2].firstarc =vexTable[v1].firstarc;4 n, S/ n2 |: g1 d, T
        arcNum++;
      Z. {7 D; G2 @9 H2 G6 x8 G& p}
      z+ r& u" F5 D# e% m6 X$ o& ^& d" D" Z6 m% g6 X% Y
    template<class ElemType, class WeightType>. \+ b8 ?  w4 Y
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    & Q0 M3 L& q$ N4 k: C  _8 X6 l5 Q{
    : f! d; {7 Z* D0 @" p  m4 J- f
      M  i3 g; y# _1 w6 h    MultiAdjListNetworkArc<WeightType>* p, * q,*r;0 A3 }& i5 T# h, s; Q
        if (v1 < 0 || v1 >= vexNum); O' a& a7 G; e% O! J
            throw Error("v1不合法!");
    9 ^' b& X  y; G( E* _7 a    if (v2 < 0 || v2 >= vexNum)# W  P( v7 G9 _" `$ {
            throw Error("v2不合法!");$ E1 ]$ Y4 S0 @) M1 \2 z' S
        if (v1 == v2)
    / r1 x2 }) y; V; D/ J        throw Error("v1不能等于v2!");
    1 t0 G# ^1 `' W- N' i! ^$ ?, n. a
        p = vexTable[v1].firstarc;, H! h5 c6 D. j9 o7 ^1 C
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)  [: D2 D5 Q3 g( s$ \* e
        {3 ~6 k& W& B6 w1 Z% u3 P) m
            q = p;
    " K! S& N7 D8 G! ^- G" ]& r        p = NextArc(v1,p);' t' v+ ]# u& A' j, ~2 X2 B) B- R
        }//找到要删除的边结点p及其前一结点q4 E: r- `; D& ^: h8 ]
    9 B4 G6 K" r$ i' d2 U
        if (p != NULL)//找到v1-v2的边
    9 O* T' Y! y: @5 Q2 x; V* d    {
    ! h- [( \& h: W2 l% X% P        r=LastArc(v2,p);' g" Z9 Y* U& d' q
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL( w2 A; O# S! }- q
                if(p->adjVex2==v2)6 B  C- g  }9 s( [: L
                    vexTable[v1].firstarc = p->nextarc1;7 r9 h) M) `# O$ E# q" f0 S
                else vexTable[v1].firstarc=p->nextarc2;
    & B/ B- s7 H: h* y( \        else//不是第一条边( ^3 F. Y# ]# C2 Y, Q
            {6 f' F$ i5 z+ Z- S
                if(q->adjVex1==v1)0 r0 G+ K  L( Q' Y- u
                    q->nextarc1 = NextArc(v1,p);3 O& P& s6 E2 V' L  X
                else
    ) t9 U8 P( k/ n+ |2 \4 F                q->nextarc2=NextArc(v1,p);
    , o8 T, Q" i; N" w) q
    % [9 m" j* Y9 F7 l: L5 y# S( Y3 T        }3 k+ p, }6 k! y, w% ?' H  I! p
            if(r==NULL)
    6 g% I, ]% P  O8 X" ?/ n; S            if(p->adjVex2==v2)
    ; a4 N. j! V- O                vexTable[v2].firstarc = p->nextarc2;" H, r4 L8 n3 b9 k( [
                else vexTable[v2].firstarc=p->nextarc1;: |3 q% w% h3 b, f$ ~
            else
    * L; ~1 m8 O7 r4 Z# p* W8 U! }        {
    / l' C& }/ Z8 ]; s' W( q. q3 C$ K            if(r->adjVex2==v2)$ h7 `8 y: L4 W" B7 M$ \
                    r->nextarc2 = NextArc(v2,p);
    : z  Y) z5 G( H; D            else
    : Z1 ?: m. c9 v; Y5 D, A* T                r->nextarc1=NextArc(v2,p);% {: D4 l0 g/ A# N  |
            }: L0 b/ Q7 o* f
            delete p;
    0 x/ s# @% C# g5 q        arcNum--;
    0 C) Y! L5 [4 j9 N1 U% n$ k; p    }3 S6 I% Y, B6 A* K8 p' c' _
    " V1 y. A% k. M2 C& k: [
    }1 k7 D; {" J, d4 d) N+ v( L
    template<class ElemType, class WeightType> void+ A7 q& j7 \. A" b7 v
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)! g9 B" {' h/ y6 v
    {5 f/ |! c; ?2 a4 h+ E8 X. C7 ~" b6 d
        int v;
    4 s0 I; Y9 g; n    MultiAdjListNetworkArc<WeightType>* p;  O5 C' t1 F* n0 @  f
        for (v = 0; v < vexNum; v++)//找到d对应顶点4 \( e1 a% E5 M! T  Y: b
            if (vexTable[v].data == d): }1 U+ g* L/ m* c0 m6 ^# m0 D
                break;
    3 m' L2 H, ~' @7 I4 t& n# {    if(v==vexNum)
    " E- f6 C' l1 m" ^        throw Error("图中不存在要删除的顶点!");* }$ Y0 q. ]; |9 `1 E4 h# a" a; V
    8 A5 A; V/ i1 E1 w
        for (int u = 0; u < vexNum; u++)//删除与d相连的边
    , H( Q3 y' @: U# @  ~: Z# x        if (u != v)
    ; n2 A' }) c- P8 d0 E1 K        {
    1 D- u' G& }2 ]0 m: \& ~- N            DeleteArc(u, v);, V$ f- o/ w9 g, Y. Q) I
            }8 J8 }2 s, F$ x: i1 m
        vexTable[v].firstarc=NULL;
    3 N. `" `: Q8 r# {) \% q+ {7 R# C' l0 f0 K
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置" g# `. K! J7 P1 M
        vexTable[v].data = vexTable[vexNum].data;
    ) P: D9 _" }6 ^0 d    vexTable[v].firstarc = vexTable[vexNum].firstarc;! ^8 L' F& B+ \$ b5 n8 E
        vexTable[vexNum].firstarc = NULL;
    . \2 @/ D& f& i3 z8 t3 ^6 G  I    tag[v] = tag[vexNum];# w. g3 G  Y$ O
        //原来与最后一个顶点相连的边改为与v相连6 }9 ]) _* }& w  t
        for (int u = 0; u < vexNum; u++)
    ! ?, D/ w5 e, ]* G0 l# x    {
    . W  z+ c% o" T8 M5 \8 [( W3 z9 \        if (u != v)# [" l( M( z% w1 J0 ?& f, _
            {
    ; N$ u- Z4 [8 i6 D. h) ?8 s            p = vexTable.firstarc;2 `1 s( N5 \8 Q) |) y" E
                while (p)
    8 [5 [* j% z& `& b5 J' V            {$ n; q; A* v' ]4 }9 g  C! N7 `8 p$ V
                    if (p->adjVex1==vexNum)
    0 E* C+ B. g4 E* a" y( n: j( T                    p->adjVex1= v;
    - B- ~" W4 ?) i! b                else if(p->adjVex2==vexNum); k2 c8 M) F0 R7 f9 O
                        p->adjVex2=v;$ P3 o  W0 P5 K; u) v' p
                    p = NextArc(u,p);1 y4 {. s" V" u2 `: Q  G
                }
    " B& V& z: F9 n+ r7 X. K( l% V" ]        }- z) S% l3 P+ j
        }' Z( |4 z  V% U$ `
    }. v, Y- V2 W0 L0 P9 C5 ^0 i
    ///深度优先遍历
    ( n& m5 {& m1 R0 dtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    . l: J6 \, _; b4 Z{
    ( Q* p) S. e# [& D    tag[v]=1;
      W$ e! t! z3 i3 e, \; l2 e" k. w    cout<<setw(3)<<vexTable[v].data;
    5 ?( t) d; M9 ]    MultiAdjListNetworkArc<WeightType> *p;
    ! d! Z" s1 H6 V    p=vexTable[v].firstarc;5 ~. C! I" i1 M! Y0 ?
        while(p)5 L* I0 L! l; d2 a, q0 K! y8 B
        {: P4 }! Q+ L. j- n! q+ ~
            if(tag[p->adjVex1]==0)
    ( c* R4 P+ ^3 O# e1 W            DFS1(p->adjVex1);
    9 b6 Y5 g: P" x. A        else if(tag[p->adjVex2]==0)) W( K7 T" J+ c; N" Z  N9 `9 Z
                DFS1(p->adjVex2);
    * i( a; c. X) S& m6 r' B) D, t) s& ]3 T        p=NextArc(v,p);# a: t9 d6 J6 F" a9 M' Z, h- u) g
        }
    0 B! k% B& B# G* U. G( D}' C! s6 R: x$ N0 l' L0 a
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse(): c$ K) s0 h/ v  ^9 N- r
    {
    3 L  G0 \- ~3 m! G  E    for(int i=0; i<vexNum; i++)" Q5 Z+ Z- Q$ E. h5 _8 \# h0 S
            tag=0;% \1 g+ [& h1 Y3 ~, E1 h1 _1 z
        for(int v=0; v<vexNum; v++)/ D# E+ Z9 D1 ?8 ^) f% h, a
        {' M: X, {9 j. p% [6 \
            if(tag[v]==0)
    * _5 \* D+ X/ q4 V0 J            DFS1(v);  B7 v2 s6 _  D! L4 G, o6 S# r
        }
    , v& ?  V- j0 U: K) Y}
    2 Y8 h8 s! x3 A3 u3 Ttemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    ; @  x& t) e$ [# K{
    0 V) W+ V9 d2 |    stack<int> s;
    % [. W9 m% y# R) L" k9 {3 k    int tmp;
    4 Z+ H/ N7 p  ^4 h; N( e( n    MultiAdjListNetworkArc<WeightType> *p,*q;
    . w/ z  W2 {0 F    for(int i=0; i<vexNum; i++)" I, e/ w; W7 o9 @
            tag=0;
    7 g; q; B0 {* x    for(int i=0; i<vexNum; i++)
    + B' y7 A9 X- e$ |    {) Z! Z1 \6 ?  P* e7 \4 [2 V
            tmp=i;
    " w' P5 [$ O7 b, e        while(tag[tmp]==0||!s.empty())
    ( b( D" ]. [: o) t4 Y6 D- X        {
    3 J  Q. Q; g( l4 d  q            p=vexTable[tmp].firstarc;8 k9 L$ K6 |# e5 h( a! d: V
                while(tag[tmp]==0)) Y% `( Z6 I; C& q$ h) |. J
                {* h7 ?* C0 i- C% p* [- ~
                    s.push(tmp);
    % L' u: h; E" C4 |3 |# J# B) g  r                cout<<setw(3)<<vexTable[tmp].data;8 A+ Y. ?0 Y* L+ E) b. f
                    tag[tmp]=1;9 @. F$ A) g3 v0 n% y
                    p=vexTable[tmp].firstarc;4 n' X% v  v7 f) W
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    / [9 u( F/ ~( Y, P* o                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    - x9 @! z: m& c- a; t  d. W                //cout<<" 1st     tmp="<<tmp<<endl;
    0 ^& Q' @  g& W' l# o4 z; q            }
    8 b' K) `7 R8 f/ \            if(!s.empty())
    + b5 |  z3 ?- g) n3 ~- t) U            {- A" j/ X! O% K/ R8 |0 q: ^) c
                    tmp=s.top();( x) P/ i8 j3 f# L1 K" g
                    s.pop();
    ' r, s( [' W. @& O; R                q=vexTable[tmp].firstarc;
    / X( j, E! {# z9 ~+ F0 C                int t=tmp;
    " ?1 W' M* r$ ^                while(q&&tag[tmp]!=0)
    7 ]; |* ~9 O6 w+ O8 t- F" h                {( [. E! c+ S4 [! _3 ~
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    2 B) G4 p7 f  y. g" E; s  w8 `                    //cout<<" 2nd     tmp="<<tmp<<endl;, l. R; R8 \) Y( ]
                        q=NextArc(t,q);
    + h1 c! o! ]2 c  n7 p& I                }
    ) @+ r6 |* k( b4 `; S) {3 e                if(tag[tmp]==0)
    ' W6 E) v3 g0 g7 i# `                    s.push(t);% P# m8 \+ _( q8 Y- Y+ S
                    ///1、对应上面连通分支只有1个点的情况
    * H3 h% W- Z2 y4 ~9 O                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈* O- A. G) E) B' Z; Q
                    ///tmp要么等于找到的第一个未访问节点,# f/ H  q8 K1 |; `- d- F4 S( C
                    ///要么等于与t相连最后一个点(已被访问过); u0 S4 ~% y& \2 l& @' \! y% I
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    1 C) I' P" ?- p$ _/ k9 A            }
    % A. t) V" h+ \+ G4 T3 R: g# e5 G        }4 [9 ^* X" Z4 ~( j9 K
        }
    + F# T  Z7 f1 n. F}
    ; p( Q, k0 q/ \# X, l) e: U+ M: ]//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    # q' N( i9 a2 V( Ytemplate<class ElemType, class WeightType> int1 g( G! x1 P% B8 o! S1 I. ?# \) t
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre): I, W+ x( f. U0 ?' j1 j
    {) @7 J1 I# k% @% B2 x
        if(head==pre)
    4 z' _' r2 \+ m" r5 z        return -1;- b' d0 Z$ A" E& u% [$ R7 n- k

    3 }# ]/ l! e3 x/ |: d" E    MultiAdjListNetworkArc<WeightType> *p;
    ; ?1 o; @7 d, m# _7 O    p=vexTable[head].firstarc;2 s/ }. u- L5 H1 [# V) t4 c. H
        if(pre==-1&&p!=NULL)( I& b: M. Q8 \/ }: x0 |
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    2 X  H" X4 M" W' C# W: T    //pre!=-1&&p!=NULL
    ; j6 m6 z# y5 ~9 w* L" I* Z    while(p!=NULL)
    ' _! E4 `# b6 o5 q; C    {- f5 o% r) ]- V. R1 L  R7 S
            if(p->adjVex1==head && p->adjVex2!=pre)+ j2 N# k# i& n0 b8 X. w- ]
                p=p->nextarc1;
    + ^/ b: p( ?9 o; s        else if(p->adjVex2==head && p->adjVex1!=pre)
    * F( x7 Q* p* \9 V            p=p->nextarc2;6 B1 W8 b, K; n! d1 u9 S' p/ [$ M  c
            else if(p->adjVex1==head && p->adjVex2==pre)
    9 b+ c5 W% C. ~+ X' k        {7 X, B8 z7 Z) B9 o
                p=p->nextarc1;
    7 a0 r5 {0 O+ @9 a* Y% [            break;) R) g3 G  c2 @( r
            }
    % x4 E( b7 q4 b9 m( `) o6 a/ e! B* U) ]        else if(p->adjVex2==head && p->adjVex1==pre)9 a2 t6 D  W8 e+ \% o
            {
    * s0 V9 f4 H9 c9 A, D& `( s            p=p->nextarc2;0 g; d4 l2 O# C8 R- `
                break;& Q* j4 c7 \! ?8 V" T
            }$ I4 s% _) }  ]5 k
        }" V/ j8 Z1 ?& W! ]- I; v
        if(p!=NULL)
    , k$ B( _) B9 Y    {
    7 v$ ]% m; v. b        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    & j) Z) y% i% w9 r/ U7 }5 [: C6 g2 f    }* {& c# C/ y- Y' A
        else
    ) O% F4 S3 [- O0 q; \! U' g        return -1;
    ' W! y- I9 y7 t& p7 [}
    & ~4 n, u. f2 l1 a2 `, d
    ' J: h6 H# D5 e4 k  V9 q
    8 N% S4 G1 X! @2 Otemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()) G. v! b6 o9 e% [: U6 P! _
    {
    / e0 ?' h) A, p# f) b    stack<int> s;
    ' t" y: b+ Y7 F2 I; E% [! I1 B. C    int p,cur,pre;) \, L' n" L* C3 U$ s1 X
        //MultiAdjListNetworkArc<WeightType> *p,*q;. N* W$ S5 H' L- @* r5 Q" u
        for(int i=0; i<vexNum; i++) tag=0;//初始化; U" A6 E4 b8 T, L+ [
    % Z( Z1 h! a7 K1 J# O' w
        for(int i=0; i<vexNum; i++)- ^! Q! q' B. g
        {- ]; [& X7 ^% Q. q8 J+ j
            cur=i;pre=-1;' O0 s% Q) K& U
            while(tag[cur]==0||!s.empty())
    % {" Q7 o4 v" f        {- S* ^. _; m& N$ d5 g' c
                while(tag[cur]==0)8 i- a4 }& q; R6 O# L- V+ [
                {
    $ I" n7 \5 N' Q- k                cout<<vexTable[cur].data<<"  ";% a/ N" ]/ Y' O; E, m, S* g
                    s.push(cur);  [; ?' Y  c& P& J
                    tag[cur]=1;1 E0 _, ]3 X* s/ X/ z
                   //初次访问,标记入栈- M2 p9 I* t# F+ Z

    ' M' \! Q3 C* [               p=GetAdjVex(cur,pre);//p是cur的连通顶点5 Z7 V9 d& _  _0 `  o' V' Z
                   if(p==-1)8 y4 E3 x, f% t8 ~2 @& m2 {4 R
                   {4 t$ y; I  z0 Q$ Q; _
                       pre=cur;s.pop();
    ( X8 `# S  N( }# W3 y                   break;
    $ A( q2 `! T/ j/ t( {               }
    . u0 a. d9 z# |; g! n8 R               else$ S; P% m/ ?& Y! R) `) ^
                   {
    ! u$ l$ J% D7 ]% S7 h; E4 @                   pre=cur;
    1 s' \$ c7 k  V; I; w8 F                   cur=p;
    0 R1 K( K1 Y7 N+ h) y1 c) V2 r4 d               }
    ; k" C/ N8 s) j
    ( ]) Q: S- \: n. C2 w            }4 p" A: C8 G5 c/ \! ]: ?- P5 j
                while(!s.empty())9 E' D" l, X/ o
                {
    # H8 i9 p3 m: y                cur=s.top();! u( Z( M8 o7 }) M8 J
                    p=GetAdjVex(cur,pre);) E/ a( ^9 T% g5 K3 ^" z# m
                    if(tag[p]==0)
    ' I5 \1 r" a" x' N; T                {3 ~9 p% P4 v# y3 v1 T
                        pre=cur;
    ( ]5 W# ~' W6 ]- u                    cur=p;
    9 H9 ^! j) b2 h* ]                    break;
    0 d7 a/ A. \( s9 S. G                }
    * j8 @  v: d  Y* D; g3 w7 D                else
    * T2 v$ K7 f0 {* e" Z0 z                {
    " [" Q: n- U& k8 Y* h3 X                    pre=s.top();9 ^( X  u+ X6 u8 K4 w3 u! z" T. l
                        s.pop();
    9 L. w3 L3 }* H; \' Z3 L                }, M7 O) e+ T7 K: \0 m) Z- s

    3 q1 q4 y4 ^& F& t, y% i: e. j& P            }
    ! O& Q# D  e. O2 d! C7 u) l: `
    1 [* u6 C; S! q        }& g% n: X* |" [$ f9 X  ]( U$ B
        }
    ! ?- ~" D! W- ^/ H3 ~}
    7 C" z+ q% y* ~template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    2 _  t1 e1 M* t{8 _: N. g1 U3 A/ k
        for(int i=0; i<vexNum; i++)$ [- ?+ |0 e: B) @2 z
            tag=0;. O+ d, p5 _: J/ R6 `9 E
        queue<int> q;1 |" r; q$ L, F: f
        int tmp,t;( o" k: q4 b& `" B8 D6 G
        MultiAdjListNetworkArc<WeightType> *p;
      y( f* C3 Y3 d( w# [4 ~    for(int i=0; i<vexNum; i++)! |& a7 Q! k1 U+ j* H
        {. w: `3 h6 r  B- v
            if(tag==0)
    + K& m, Q0 N2 H9 E( C        {
    ' Y3 L" K0 b+ W/ v# t9 l            tag=1;  q" H+ a2 N$ r( s/ B  J
                q.push(i);: P" a6 Q/ [9 k8 k) Y$ f
                cout<<setw(3)<<vexTable.data;: S) c5 }' A8 @1 q
            }6 v+ R- y* r8 O: w, r
            while(!q.empty())
    7 N1 k7 C& [1 b  |8 r" l+ r        {- P/ W8 `: j; Q! |0 V5 X# u2 V
                tmp=q.front();
    ; ^6 u3 r6 ]% Q5 c& `5 R1 {            q.pop();9 I7 D# }) N% Q) y. C
                p=vexTable[tmp].firstarc;
    1 c9 K6 N* M6 q% |+ g+ }& Y            while(p!=NULL)9 v/ m# i1 N% z& N
                {
    6 R- B. ]  q- K7 k3 |4 M                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    0 g  R1 g7 v; f# i5 h                if(tag[t]==0)
    : A! D7 _" c/ [$ s; {' M                {. H2 I3 `- m. }7 ~. A
                        cout<<setw(3)<<vexTable[t].data;
    7 s1 e6 c1 g5 X1 J! }* ]                    tag[t]=1;
    ' x& A7 Q/ B3 K5 i9 ~( b" J0 b5 Z                    q.push(t);* V- o! I7 \  _3 }) N. I8 j* |
                    }& j% ]  _1 P  d+ z# g6 @6 y$ \$ d
                    p=NextArc(tmp,p);
    1 Z& j" |4 j' K% }! y# S4 I            }, j# f6 C/ [  B9 L7 r
            }
    ( X' @8 x' ?$ {( W: W7 n    }! V' ]% d8 B7 _/ ~; l
    }9 P, z3 \  E" X0 y- q- P
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()4 Y2 U& z, ~5 O! |$ T  u6 l
    {3 ]( C# h2 O6 y
        MultiAdjListNetworkArc<WeightType> *p;
    # d/ P! L& S% x& g0 D/ a    cout << "无向图有" << vexNum << "个点,分别为:";
    8 Q7 Z+ n$ Y( _( K: X# ?8 _% Q    for (int i = 0; i < vexNum; i++)& c0 \( {% E2 Y- p" _
            cout << vexTable.data << " ";
    " U! [- m  L9 ]& G* \% @# ]1 F" A    cout << endl;
      d5 ~/ G& R5 j. `4 R; t    cout << "无向图有" << arcNum << "条边"<<endl;
    : U; S" B% s% m3 G    for (int i = 0; i < vexNum; i++)
    2 @' x7 k2 ^* d/ P. A% q/ ^    {
    ! H$ N! q) x& R1 d+ M        cout<<"和" << vexTable.data << "有关的边:";" M; q* s6 O% b
            p = vexTable.firstarc;' c1 {4 X( S8 `; n/ W% v1 E  g" e
            while (p != NULL)
    % ]* Q, b3 S2 t1 ]! Q- f* l: S        {7 j1 c! x- r5 ~0 t
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    ) N; H1 w3 z" p4 W" c            p=NextArc(i,p);6 j4 u/ f0 C8 F& d" m
            }2 \+ ]; ?" k  }
            cout << endl;6 p5 t$ q1 t0 q2 \
        }
    9 B' r0 |( u- k# `0 F4 ]}* c$ }+ d. G* e) n* j$ \2 M$ ^

    ( J" ^$ Q, N* x* b! L# d9 U& r8 e0 p' }8 s+ m0 K* T" Y4 f; l
    邻接多重表与邻接表的对比
    ! o  Z2 n8 C5 Z/ K/ }
    2 V# `( p# h6 c6 O邻接表链接
    5 S* T" ^; z( S. \7 w7 {% |在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。1 ^4 d) }, O: x6 z- C( p" Y
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    3 w$ H3 `0 R9 J7 T/ d7 I6 X4 }. y# O为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    / C$ B9 A! H! b) l————————————————; P1 Z1 O) Z2 ]
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。* f  b1 g* Q4 p
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    " x4 q  x" v! d) m1 I7 J5 L2 n% q) }" y8 d. g
    / F  M: C% k% l: C; A) c

    " ~: X; I% G( V9 _7 Y# Q* J4 O6 Q# u$ m3 T0 T0 D
    ————————————————
    ' a. b2 \3 U: j版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    - b) C- ?& J" @8 U原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958  Y# x8 I1 A! ]! A( e0 j

    6 K% |$ Q9 G1 a  T. S8 u% K
    - C+ ?3 D/ b1 M6 z2 K0 \
    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-6-10 04:28 , Processed in 0.501842 second(s), 54 queries .

    回顶部