QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1662|回复: 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
    , t9 e1 l3 g, g/ {' d" F
    图的存储结构——邻接多重表(多重邻接表)的实现5 d" E. U5 K: Z+ h$ g+ o
    7.2 图的存储结构
    $ C, x4 ^- t1 q* d% S3 {  s: Z( t3 Q( e! _
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    9 o: S: a! K$ V9 F- f邻接多重表的类定义- s! j( a4 E" {& s; ^3 T2 L! K
    邻接多重表的顶点结点类模板
    " v& C# E5 o/ e3 s, v* ]; R邻接多重表的边结点类模板
    3 d- c/ i* _& [1 n& U+ Q邻接多重表的类模板! g/ S$ I# L0 H) _7 Q" L
    邻接多重表与邻接表的对比
    8 J% b7 U2 p4 F* v0 E& v" Y$ g7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
      e% L5 ^+ c- T4 U  ?
    7 |3 L) v& g, y" _& T在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。( s( V4 }4 s' T% L4 ^$ J
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。) o0 B+ n9 N  ]  i
    3 e* @0 m0 y/ O/ e4 d9 T5 w( |
    邻接多重表的类定义) \) F) y; I2 d! G; [7 l; c, _
    1.png
    1 [9 q* X+ Q/ L. F邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:5 w; U" S* D% _; Q# t7 Q
    data域存储有关顶点的信息;
    ; r9 ~& e3 E, t3 ?9 afirstarc域是链接指针,指向第一条依附于该顶点的边。: r; e0 c* M# I6 e& C1 t4 p, }
    所有的顶点结点组成一个顺序表。

    / d! K, ?9 _5 I  Z* T
    , t2 y$ h0 ^! _+ M
    template <class ElemType ,class WeightType>7 z- `& g% n& T6 T! T, h* r! B9 k' X
    class MultiAdjListNetworkVex
    ; s2 ?0 |) G4 T7 \( H{, p, `  u  P& h1 P4 C( l" u2 Y
    public:( B% Y: t  F: C
            ElemType data;
    3 j  I" F( i! }' r. z+ e        MultiAdjListNetworkArc<WeightType> *firstarc;, J: K9 S2 Y6 B

    % z% i+ X" Q# a        MultiAdjListNetworkVex()
    4 K  }; q: e* y5 @8 z! S4 p  J        {7 s8 }  U3 L5 ^
                    firstarc = NULL;3 Y; Q. V6 q) D) c  x5 e# d' Y
            }9 a  x" ~. Z; `4 A  Q
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    : ^; T' ]; O! T$ l: J        {3 s0 i" E$ T$ `; }- L5 v
                    data = val;
    - S8 T) w' u& Y2 X                firstarc = adj;+ j( R, \' I; f" @' q3 H- z
            }
    % C4 H4 m( s# m! `. V  `};; L+ r& E! Z/ W1 R& k0 ^! [) }
    8 _# M' R% h  ?! l' E
    邻接多重表的边结点类模板$ d- ~3 d: t7 ^& v+ B

    ' s+ o" _! |1 ^; T% ~- q" v在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    ) V0 d- ~2 L; g; q5 N% ^& i& e. gtag是标记域,标记该边是否被处理或被搜索过;5 ]! s" ^, i4 P, D* K4 r
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;8 b$ }* N6 W/ Y: m/ d; \
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    : X* p0 _/ @6 @0 b% Rnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    # b- G1 \3 _! M. y" x( v
    ( L, `4 F4 U" j: m$ K 2.png 0 G  B6 r% V9 K* I) v/ P
    template <class WeightType>2 l$ s! U" s/ X4 E
    class MultiAdjListNetworkArc
    # {3 ?' }8 f$ q" H{0 b6 Y- I$ Z2 g# S
    public:
    2 F7 C) X$ m' E! `    int mark;                                       //标记该边是否被搜索或处理过
    ! o. h  U* q+ e2 j        WeightType weight;                              //边的权重2 V- L  \: ?, J3 U8 @3 b$ K) P; ?4 o
            int adjVex1;                                    //边的一个顶点
    + @! ~& e2 a$ V1 I/ b; k7 z        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    * ]4 m8 C6 B' Z  `        int adjVex2;: r# T6 c9 @; S, c. ?* b5 O5 e0 {
            MultiAdjListNetworkArc<WeightType>* nextarc2;  }& m! z; Q  Q7 P+ ^1 ?7 L0 c9 i
    # a8 F- F9 s* B6 G1 l
            MultiAdjListNetworkArc()
    8 b. j( ~9 `7 H' q9 c$ m. u8 @$ G        {
    / [" L# z  L( b/ X                adjVex1= -1;: a: i  w% s/ y4 ^) o1 @) J
                    adjVex2= -1;6 x, F' Z! ?* a2 X8 p' i; m+ r, q( s) D/ e
            }
    & `- N8 z: z  S* Q  A        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)$ C; m1 Q  ]6 ]4 e
            {
    $ z: {8 F$ M& w/ S6 L/ v                adjVex1 = v1;       adjVex2 = v2;( }6 \8 E1 n6 s
                    weight = w;
    % W+ x* f! `5 W. X8 B! K$ \                nextarc1 = next1;   nextarc2=next2;9 Y# t/ ^5 l! I; R6 w! z$ S# T
                    mark = 0;           //0表示未被搜索,1表示被搜索过, C% l1 H( U& b) a; l! m4 n/ }
            }7 l% p+ Y$ L% S) n/ @! w
    . A. k3 i/ q4 e, b
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>( Q% j$ x0 b9 w1 I
    class MultiAdjListNetwork( G, M6 E; |4 Z3 e7 d2 T8 y
    {
    $ O1 W/ k& L' rprotected:
    ( V* M* W" K/ M: J  V5 c3 U    int vexNum, vexMaxNum, arcNum;
    . b6 U1 i3 ~% D2 w, ?    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    / f& s: O9 Q6 N8 o    int* tag;; O7 J  ~; }, l+ O' }6 b+ ]
        WeightType infinity;
    9 v- g9 e" M. ?
    2 n' Q( Y/ [3 N' A/ xpublic:; O- ]9 @4 B3 A% A
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);' o+ w; \. W3 @" w

    2 o9 F& b6 X; o+ N" K" c# c1 u( t" z    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);" h% C, F. O: ?$ p: V
    4 @0 ^: I! I, h& V9 p" y( ^
        void Clear();
    # C* ]! W. j2 h, U    bool IsEmpty()3 r; Z; w4 }7 Q4 t& t8 \: D
        {
    . m3 D- ~6 L( D5 q4 y        return vexNum == 0;
    2 ~! |; @) j* a& j! U' B) g/ A    }$ U- t* ~4 E; n3 Y9 G
        int GetArcNum()const
    : n$ d, u* v# d, |6 L1 [+ Z: @  p    {
    , V; l4 E9 g! z! k$ {, A        return arcNum;
    4 d# T  P( ~4 M0 f6 I    }% T+ B# t+ I+ y, c6 {" W7 z1 s
        int GetvexNum()const
    5 M! A7 y. r1 G6 S+ |" Z    {5 q; t1 \# B8 C
            return vexNum;
    $ q" z/ S9 l) L& @; G    }
    8 Q, X0 ]$ h8 Z. ~# |( L
    9 N- M7 Y9 F! Z
    3 K, m! u; }3 T0 K0 D3 @    int FirstAdjVex(int v)const;; o1 U4 H) K0 i( |1 o& d) `5 n
        int NextAdjVex(int v1, int v2)const;$ ^" m4 g/ {4 w* I; {1 t) d
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    $ M0 y' a* n+ g    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    ! ^  W3 N+ I( K% m/ J. q# \' I7 P' m  l; U$ F7 Q5 F* J
        void InsertVex(const ElemType& d);
    9 @( v# t7 a: w1 `8 a& e4 k+ R1 f) @    void InsertArc(int v1, int v2, WeightType w);
    + n" X% b( f7 i/ f( n9 x4 [' A; b1 E6 k) X/ h/ A& b5 ]+ N* a
        void DeleteVex(const ElemType& d);
    # [( S6 ^# K% _9 u7 c8 O4 C. M    void DeleteArc(int v1, int v2);4 D' C; @5 g5 L
    + G6 [  z$ o6 r9 h7 B
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    * ?4 A6 h; j" i5 p: g2 s) t) _$ y    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    - R3 }" G% P5 i- j+ ^0 `
    ; |5 W+ D7 i- m    ///深度优先遍历
    8 H& c6 K$ H" T+ r' P2 G    void DFS1(const int v);1 O! _; Z7 _5 ~1 ?3 G/ V
        void DFS1Traverse();
    % j  H, @. ]3 y9 j! Z1 @' Q* X' Q0 b( H    void DFS2();# t* U1 S& U- l( V' V* A

    ' L2 X1 g; e6 U, |7 q    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1. P9 c( v; \6 I( ], d
        void DFS3();) ~2 E. a* p# x9 w0 M$ X

    : X% O6 H' S  y, y$ O7 U( ?    void BFS();
    ) |4 e& ^+ m6 z% j( ]& P. H% |- `    void Show();
    / o1 _8 C5 {' l};
    ! I  v. {* x3 a2 x& U- m, R( q0 _; i+ I- L; C+ c: {4 M+ H  H
    2.函数的实现
    1 K: s6 m& G+ c. N- g  h& Y  m研讨题,能够运行,但是代码不一定是最优的。& V3 T  P/ J: q  w0 H9 k
    8 z( F1 q) g( y
    #include <stack>
    ' W, I# V; G: T' C+ y#include <queue>2 r( K6 z2 I. F" h
    2 H% J( A) J1 }- F1 y  A
    template <class ElemType,class WeightType>
    ! q. G' [; l& ?MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)2 r' z: t6 m" r* }- E  v  m; `4 V
    {
    $ b3 C' k& _: C- N2 X8 S& K    if(vertexMaxNum < 0)
    0 H( s9 O) z  t* X7 b        throw Error("允许的顶点最大数目不能为负!");1 j9 y) K7 f1 _2 z, U
        if (vertexMaxNum < vertexNum)% N8 l+ X' T1 h$ M- z! t5 W- ?
            throw Error("顶点数目不能大于允许的顶点最大数目!");& y; W$ Z9 j1 V) h% J  {, ]5 z
        vexNum = vertexNum;4 G1 s6 v, |4 `8 [" q+ t
        vexMaxNum = vertexMaxNum;
    : {. H1 n' z. ]% x) u' b& a. J) S    arcNum = 0;, e9 o3 w3 p8 p
        infinity = infinit;
    3 \0 {, E# S* E- l4 K* @2 s; O    tag = new int[vexMaxNum];! r6 x4 a# h8 x- F/ v+ d  g+ \
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];- w+ q% x6 ]4 R
        for (int v = 0; v < vexNum; v++)
    ( H( ?* O8 N$ I) }! c6 r8 c, p. `9 t    {
    4 O. T( W/ u  z        tag[v] = 0;
    - ?$ ]7 V* j' T0 k, `  `7 D9 s        vexTable[v].data = es[v];0 ^! |$ R; Q  A% @1 j7 v8 }. }
            vexTable[v].firstarc = NULL;1 ?5 X7 l; O7 L7 Z7 r3 G
        }
    6 |6 ^* g2 ?" D0 Q, h% C: L}
    $ @& K9 s1 P) x: qtemplate <class ElemType,class WeightType>  J) |. f5 N& ]: u8 @( Y3 `
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    ) D! ~! r. _7 T6 Z' q{
    : P2 G& W% V3 a- Q# ^  X5 p    if (vertexMaxNum < 0); a( U6 M0 G8 O! F
            throw Error("允许的顶点最大数目不能为负!");4 _2 R4 A; Z& d* |6 A2 A; `9 H1 z
        vexNum = 0;! ]" ^1 ]- X- I
        vexMaxNum = vertexMaxNum;7 E& P" d+ `7 l  ?* W% Z
        arcNum = 0;
    0 }/ h, g$ d7 l+ m    infinity = infinit;4 K. C5 C& Q+ o& l+ z4 P: H
        tag = new int[vexMaxNum];9 A4 _3 p& Y# C! Z+ t
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    9 y0 f& }. F9 U  o. e, v* `+ _! B# k4 r}6 j; o4 P2 b* z7 b
    template<class ElemType, class WeightType>
    1 y1 [; i6 p3 E! u2 e# Aint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const! m6 s0 ?3 W4 ~8 ]0 }
    {
    4 ~4 a! Y# N; L2 s# M# c1 @    if (v < 0 || v >= vexNum), G1 Z" m6 `0 u, {# p
            throw Error("v不合法!");% a( I) a* T2 o! P$ z
        if (vexTable[v].firstarc == NULL). @+ p& n% k7 N5 f+ S
            return -1;- u9 k7 o& X/ |4 b
        else
      x- b) R- x7 I4 G4 s; `        return vexTable[v].firstarc->adjVex1;9 d6 u; q( F( O4 a" s  k* ^
    }# l& F; ~- I6 \' k

    7 V0 G$ X/ I* a7 `1 Utemplate<class ElemType, class WeightType>+ F& L7 U  T% U8 D- Y, O( l9 ~' x
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const* a+ W6 [( |2 s2 M2 M7 t  T6 ~8 p
    {' D# |* J4 S) k
        MultiAdjListNetworkArc<WeightType>* p;
    8 _/ Q% x' U2 B3 j    if (v1 < 0 || v1 >= vexNum)
    + @( C- o2 [$ M* v0 S1 b        throw Error("v1不合法!");. N% A. {3 Q+ U
        if (v2 < 0 || v2 >= vexNum)
    # M$ V2 Z& J. T& V7 g        throw Error("v2不合法!");6 u, r3 ?. x5 Q. J" v% Z) }$ g
        if (v1 == v2)
    % X/ B9 B$ t1 {. Y; A9 f: e        throw Error("v1不能等于v2!");: J9 N$ x$ e' W
        p = vexTable[v1].firstarc;8 D8 b; s/ i% ~  u) N
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    $ X' f: F6 {0 @& g9 E/ V        p = p->nextarc;
    / X6 E/ D6 {. a: {. F% k8 |    if (p == NULL || p->nextarc == NULL)( P# P& c: G+ t) ]5 C
            return -1;  //不存在下一个邻接点
    1 F4 {/ B  n3 X# f; m+ F8 H5 G4 \    else if(p->adjVex1==v2)
    5 f' Z3 z& B* t2 G: e3 ^        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    2 }, k& a  }. d/ o7 s* Q    else
    : T* D) t2 j$ W0 E  @        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    4 N. v3 C4 P; u# d}
    7 h' j# V* ]7 n, Z0 [7 ntemplate<class ElemType, class WeightType>
    8 a! S/ ]3 Y  l+ h' X4 o0 fvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()3 f  j" p$ D* `6 L
    {3 i6 O$ x  s6 T* y, {
        if (IsEmpty()) return;$ o2 [4 X/ M- Q* R; w) [) `/ }
        int n = vexNum;
    ' L" b& E0 y& _" R' S    for (int u = 0; u < n ; u++)
    7 w1 e5 l  @" U6 v        DeleteVex(vexTable[0].data);
      j& w  B1 z* @- F    return;& u. u3 |( r* G) x# V6 f% m* P
    }
    2 x7 y3 X+ L  s* f9 Z. ^9 ttemplate<class ElemType, class WeightType>
    % K% c, X% Y" A, d  L& c7 H/ H+ yMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()8 x* J8 S% g4 _8 H. `/ N: k
    {$ r' C$ `, c! |
        Clear();9 U' t4 S1 {" q5 }4 t
    }
    2 S0 \' _7 e+ C- f' r0 d; itemplate<class ElemType, class WeightType>
    ) ^, r% F% U+ P! s- ^# WMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)5 r6 V$ b1 Q& k- G
    {* C( E- |* Z5 K6 X) H
        vexMaxNum = copy.vexMaxNum;% R* Z2 H" p% j
        vexNum = copy.vexNum;1 O2 B. F& |$ y6 p/ }4 D5 U1 D
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];! B6 v1 g! w; t6 _
        arcNum = 0;' T8 P! T5 f( i2 R6 s
        infinity = copy.infinity;* Q7 @7 r* u7 C' c& j+ i: L# B' I
        tag = new int[vexMaxNum];# j* a1 y/ Y/ A

      o/ Z: U4 n7 O# X3 |  C    for (int v = 0; v < vexNum; v++)
    & Q2 a- j7 \" J# C8 r* i7 C, T" Z    {: x2 R: F# @0 F0 z# o5 |4 `/ g
            tag[v] = 0;
    , `: y8 p* V2 v9 l9 V3 |3 |8 |2 W3 F7 G        vexTable[v].data = copy.vexTable[v].data;
    ' J+ R: l  L+ k4 [        vexTable[v].firstarc = NULL;
    % J- w3 e2 q7 M7 |; S4 p5 H    }
    5 T7 x4 O* }8 @# e    MultiAdjListNetworkArc<WeightType>* p;
    1 Z# G2 ~  `' ?5 A4 z3 I  W  E6 z% ?) x7 G+ S/ }4 L- x7 P
        for (int u = 0; u < vexNum; u++)' C( h! d: k8 q" @4 M, d9 k
        {0 {9 H5 Z) P, N. f# p6 `# a2 Y
            p = copy.vexTable.firstarc;
    : z; j6 V6 s' j; o  }        while (p != NULL)
    5 G# X, x1 O% Z5 b8 _( \' i0 `        {0 \5 P0 }+ h! B" `7 l$ z
                InsertArc(p->adjVex1, p->adjVex2, p->weight);4 P0 o' q: A) f: A) _
                p=NextArc(u,p);
    : z, ~& n" G: K4 _$ v7 P! d0 p        }5 ^7 y. j/ C+ k" M
        }
    * H4 y# N& l0 O' ?. n. M, F" N}1 ~0 _4 r4 w4 r1 N. @% @
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&5 i3 d4 l) j; ]8 i4 b" {5 f
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)& {9 ?* `& @9 i$ Z! V+ H) J# x% F
    {
    7 ~  x- ?2 p: c0 P  Q/ G4 r    if (this == &copy) return *this;
    8 Y# J& A& N2 g7 c% t2 v( e) G    Clear();, B7 o) o. J+ Z; e/ @8 c: q3 C  B7 c
        vexMaxNum = copy.vexMaxNum;
    6 L- K2 `/ |- _5 m    vexNum = copy.vexNum;
    ( I# J" d6 f* p* V    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];& A/ @7 E- a! A- ?9 p$ @
        arcNum = 0;
    3 E) N0 A# ]( O* V* Z, y    infinity = copy.infinity;
    : t* T9 h& i, Y5 y& F5 O    tag = new int[vexMaxNum];
    ; p5 X' a8 S% [, P$ k! X& L: n) S& T
        for (int v = 0; v < vexNum; v++)
    ' E3 {$ l" @: g  k0 e! Q  E8 {    {$ N9 x: P- F- W2 f7 h2 J# I3 ^
            tag[v] = 0;9 @5 W6 M. m' j. M0 L$ h- h
            vexTable[v].data = copy.vexTable[v].data;
    # b8 p) O' ]+ X! E+ c. s        vexTable[v].firstarc = NULL;
    3 t2 A9 V9 s) v    }
    ) I: X; p- I: E, y  \8 s    MultiAdjListNetworkArc<WeightType>* p;
    ; t0 c3 H; @  `9 |9 A. Z/ a: U6 z- Y8 c0 ~
        for (int u = 0; u < vexNum; u++)
    4 G. {8 y, P$ w5 \8 U: B    {. J0 P& H' Y* Z6 d0 Z% |
            p = copy.vexTable.firstarc;2 f2 h- {! Z) H7 x; l0 T- R
            while (p != NULL)
    ( L6 p. j- @+ I# p  i        {" z" {+ B- I" W6 g& b. C
                InsertArc(p->adjVex1, p->adjVex2, p->weight);7 t& o* z# L6 U; t3 b4 m! n
                p=NextArc(u,p);
    $ J. @1 f" Q6 U& g8 `        }+ c- V5 N  B2 d) S+ l: V
        }# {5 k& G4 B) R9 I0 L" w
        return *this;; ~. Z2 f; Z+ }' N
    }
    , C, z: ^. M- Z* H" w' u( W9 V0 atemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*0 _" e0 c  H% u& S$ ]4 h% y% [2 [
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    . O& q, k2 u! I* S( E4 u) v$ l8 Q{8 l3 {: @& v1 S; q- a2 X
        if(p==NULL) return NULL;+ t* O0 ]3 G" X3 _5 R
        if(p->adjVex1==v1)
    # Z1 f! z* g, v! F) \+ V        return p->nextarc1;
    & Y8 X3 g3 S/ |( n9 h    else
    7 N2 _' R; g8 T# ]% J        return p->nextarc2;1 j" h. D: F( Z* X
    }
    * t9 R* K4 a! |: u( S1 v2 ~template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*+ d& `- Z* E$ `
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const4 i' k% Q  s4 }$ @& b
    {0 X8 }/ W% u0 E3 z% n( ~- {# \5 i7 a
        if(p==NULL)return NULL;
    8 q  ~+ Z, H* V    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;5 [/ {6 H( N* X' k/ F3 Y, L0 \! v
        if(q==p)
    5 \9 A% v% H" X8 Y0 x! u' S9 _        return NULL;8 D4 a( _+ ]1 s. l
        while(q)
      v% z, {1 ]- v2 A    {
    # h: }+ L- U1 |1 A  p        if(q->nextarc1==p ||q->nextarc2==p)5 j( W5 ^$ c, g6 I& w# S
                break;
    + P' D; e7 w7 {5 S8 H+ b% v        q=NextArc(v1,q);0 |! k  m) R5 I) a0 v
        }4 n: }5 ^, F( E9 _" c
        return q;
    9 D4 }0 E3 S4 W- p1 U. \2 l}
    " n  h  u# Y+ K! N2 utemplate<class ElemType, class WeightType>
    ) f% d3 e  b. l3 jvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)3 L0 o% _& S! s8 V3 q' r3 R
    {6 L: E! z$ K# D' u9 N+ I
        if (vexNum == vexMaxNum)0 E! \7 a5 z3 G- M* {
            throw Error("图的顶点数不能超过允许的最大数!");( s$ U) m7 r4 C! `9 J, r* G8 K
        vexTable[vexNum].data = d;
    ! ~. S6 R( Y# G3 r    vexTable[vexNum].firstarc = NULL;
    ' G* J. l7 e! ~% ]& T. o3 o6 O    tag[vexNum] = 0;
    $ m$ U: P$ |; X: W& w    vexNum++;
    + a" H6 o2 w/ H' j, O2 H$ [}4 i/ x, U" e- M# O/ n
    template<class ElemType, class WeightType>0 h. n" j: d3 J6 a& p
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w): V9 d  E8 `( P6 ~0 G7 @9 m9 P. a" O
    {$ W+ b3 N8 I. x, q" w
        MultiAdjListNetworkArc<WeightType>* p,*q;& Z" A7 V# e4 q0 X+ O8 z* J; l
        if (v1 < 0 || v1 >= vexNum)% ^, Y1 J! f, G# ~# _/ g; f
            throw Error("v1不合法!");/ O' H- x- r* y
        if (v2 < 0 || v2 >= vexNum)2 i7 X' L9 H3 `7 N
            throw Error("v2不合法!");
    . M* q8 G* G7 U6 |6 }4 R# a    if (v1 == v2)1 d' o- U  K% @
            throw Error("v1不能等于v2!");& a4 l" C+ f' _% {; ^3 [
        if (w == infinity)* |2 B- F/ X) g1 i7 f" N# S) S( {
            throw Error("w不能为无穷大!");& \$ G0 }  l  C. d2 ~9 _/ S

    % r4 _) W" n7 b1 _. F: Y
    % v- p8 @9 w$ _! l    p = vexTable[v1].firstarc;. v7 z0 @4 J$ z, K- q8 I
        while(p)0 J, e0 u1 z  ]. e
        {( ~9 Z% U3 d2 }2 r3 [
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    * n# J' i3 N$ T$ @3 i* p2 j        {& h) h4 e' ?2 ?. ^" ~
                if(p->weight!=w)
    + R1 i  N5 C3 [. b! d/ Z! s8 ]                p->weight=w;6 x& X6 f' B3 c% G1 X
                return;" p0 m; N! P* p
            }3 c" N6 }! f. I. u

    ! Q& ?0 B; ~+ _; s# v/ v        p=NextArc(v1,p);9 x* w! i; I0 a1 R! o8 L
        }
    2 {, A& W0 n0 {9 P0 X    p = vexTable[v1].firstarc;
    ) A, F8 l0 x+ X( Q7 l7 `$ g2 W9 u7 M    q = vexTable[v2].firstarc;. i( e4 z. E& `2 }" Z' h
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法6 ?( V9 E, ^! {. d" p+ k
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    / @) a* c% y& P, p( ?5 X& ^    arcNum++;' f7 U& Q# W+ `* K& x
    }) }% {1 ], S/ Q% y) ^: ?1 O

    ( H* m' j) \5 @& `- w( Y4 Utemplate<class ElemType, class WeightType>5 H. |4 S+ g" Z- t, a: K
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)+ _$ V2 m+ C9 ?) m* ]
    {
    $ S* r: N/ `9 R+ W- F
    : E8 `6 @8 e6 L" r+ S. p' o3 p    MultiAdjListNetworkArc<WeightType>* p, * q,*r;. q; H, {8 W1 c  j0 P; k
        if (v1 < 0 || v1 >= vexNum)
    4 m( H6 l  K7 p  Q/ X" W$ [        throw Error("v1不合法!");; H! D1 R1 ^+ b2 r  |
        if (v2 < 0 || v2 >= vexNum)5 o" x% _# A7 n. y6 p/ F
            throw Error("v2不合法!");
    6 A6 c: U/ A) q/ l+ m' X    if (v1 == v2)
    " H6 i; K/ f0 e: D* ]4 d, R        throw Error("v1不能等于v2!");
    5 S1 [8 g7 |+ m0 [# L) r
    # J7 Y1 H2 c0 X" P) b    p = vexTable[v1].firstarc;; \0 s2 U' W  j* ^0 c
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    * T+ `7 g; B# |1 C! b  V9 K    {
    7 M& ~9 q$ m- y. p  W0 s% A        q = p;
    / E* {; B6 Q3 U: r; K) Z" V        p = NextArc(v1,p);
    & f( T$ p4 O) q5 K    }//找到要删除的边结点p及其前一结点q
    : x1 R; |2 u/ T' a" J8 z" e
    ' C: m! [) }( O    if (p != NULL)//找到v1-v2的边
    ' w4 h, p. G1 _( k5 \- L    {2 Y  }9 w5 c/ Z& r' |3 Z8 u2 Q
            r=LastArc(v2,p);
    6 Y; W6 @( G$ P( c/ v& S; ]% z' X- f        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    % T7 [5 K! j! X3 c# s2 d2 m+ E            if(p->adjVex2==v2)' v& c3 T4 o) L$ K
                    vexTable[v1].firstarc = p->nextarc1;, C# n( A" X' ?) J! e: @" e; a
                else vexTable[v1].firstarc=p->nextarc2;
    ' }0 {" j9 g3 ^/ |% ?        else//不是第一条边
    " y8 D* ~* @# [7 [. p6 u' E        {$ h# k; f6 a3 C
                if(q->adjVex1==v1)
    ; C7 T: T% w* r# S% L% ?                q->nextarc1 = NextArc(v1,p);
    7 k5 r6 l1 u$ g( a. R% g            else
    $ q$ ?! q6 N9 s+ n                q->nextarc2=NextArc(v1,p);
    . `2 o' J6 I4 h& z( d
    : ?9 E/ n0 h3 O% L% O        }3 ?6 A# w# a! d: Q9 F
            if(r==NULL)
    ) J  Z1 g5 O5 g! o( K3 {            if(p->adjVex2==v2)
    3 z; w7 `  z& Q! a                vexTable[v2].firstarc = p->nextarc2;  `' M) P: I% }+ _, |
                else vexTable[v2].firstarc=p->nextarc1;
    8 r, D6 g+ V+ m. k  Q8 ^, ]9 K        else, b3 X  m8 J* b
            {: l) s: }1 t, U+ {
                if(r->adjVex2==v2)# A# ?  R, L$ t$ |4 O! y9 W7 n
                    r->nextarc2 = NextArc(v2,p);  Y4 T( e: B+ i: \9 a/ ]
                else, Y; ^% e4 ~- Q: o9 [% P; q$ i, R
                    r->nextarc1=NextArc(v2,p);
    ) A6 m" S) M! {7 Q# x3 S+ P        }+ Q, \$ o4 G; N  P# k
            delete p;
    + X2 G- o5 X: X3 H6 ]  S        arcNum--;
    , m9 G% Z# c% ?2 O    }
    . O: e- H7 Z; [0 Y& F
    * P: M5 p  [* c2 H& A: H; O}) D) l" f. ~+ T$ O% t' ]5 V
    template<class ElemType, class WeightType> void
    # _5 S6 b1 b! @5 ^$ D: r) WMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    ( m6 U8 F0 `4 g, j$ q$ J( H4 Z{6 K" Y% H& q, E: D
        int v;: |8 e$ _. `* U5 b: V4 m
        MultiAdjListNetworkArc<WeightType>* p;2 ~; s3 W1 t3 X
        for (v = 0; v < vexNum; v++)//找到d对应顶点: z" {  t. o1 U
            if (vexTable[v].data == d)9 u2 j3 v5 X$ o  u2 r
                break;
    $ z! ~( e1 I- f/ B! `; F    if(v==vexNum)& T' O# n$ N( E0 ^' `' @) G* p
            throw Error("图中不存在要删除的顶点!");. z8 a" w( Z! y% b5 R+ W8 T

    & ~9 C3 a1 a. y( r4 B0 o    for (int u = 0; u < vexNum; u++)//删除与d相连的边
    + r) ^0 f; ?0 L3 G0 q9 W  S        if (u != v)
    , l/ _2 n0 a$ f, F! d, s        {' q' E5 s* `7 ?/ O  h
                DeleteArc(u, v);
    : q) N5 u: K# `1 u1 g2 [: S        }3 }) ~* n# E0 z  _
        vexTable[v].firstarc=NULL;! P. W+ r9 E  [2 b
    . I. C  e- v6 ~' ~9 d9 X
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    , }4 M+ }1 [+ q% o" Q    vexTable[v].data = vexTable[vexNum].data;+ B3 V( K7 n. I! F! [6 Y8 O' i
        vexTable[v].firstarc = vexTable[vexNum].firstarc;
    " I, x, O  D! O    vexTable[vexNum].firstarc = NULL;
    " C' L4 a5 W1 o* `  Q0 R# r    tag[v] = tag[vexNum];9 r* s0 H' I: G" z; x
        //原来与最后一个顶点相连的边改为与v相连
    ( R$ w; r- [! x& U    for (int u = 0; u < vexNum; u++)' R. x, W& Q/ `  E
        {
    , M* T7 x/ Z/ @8 i+ {; ?        if (u != v)
    8 M4 V% V* V% [2 G. f/ u4 v: h        {5 |! P! L7 v+ o1 O* h1 _
                p = vexTable.firstarc;
    , C0 E' D3 O& \7 c) u7 o            while (p)
    8 c+ q/ B% N+ f! J/ G            {
    : G. z  j' ~, X                if (p->adjVex1==vexNum)- Z' g0 n9 K# Y/ ]9 _) z
                        p->adjVex1= v;
    3 F$ X/ ]! z7 C- c                else if(p->adjVex2==vexNum)
    0 u+ J+ C2 x6 |) \2 J                    p->adjVex2=v;; Y9 a8 s% b# f& v5 f
                    p = NextArc(u,p);
    & F  r' K+ r. X, f7 g( y            }* z3 F) ~% J+ I& t  @3 j
            }! E5 E) D* b% j/ `$ z, h- P/ N* y' C' d
        }& X! h" ]/ f# o0 ^. p
    }3 \5 i" l4 m& [( D3 y& m! V' U: Y' X& ^
    ///深度优先遍历% Q5 b( f8 ~# ?: y
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    ) ~* f/ C9 v6 v( o% R% h{
      E% C3 S9 G/ ^; L    tag[v]=1;" b- f$ q8 w$ }; P  \3 h
        cout<<setw(3)<<vexTable[v].data;! C; `/ s( a, o) C2 G  y$ S& e
        MultiAdjListNetworkArc<WeightType> *p;
    5 N8 [( ~# v9 f% w    p=vexTable[v].firstarc;
    5 K) L. @  s' t7 h/ E    while(p)
    ( b  d$ n$ U% V) {, f    {
    + z7 b! n$ i6 ]6 O        if(tag[p->adjVex1]==0): `" J5 H. k; v% B# w9 h
                DFS1(p->adjVex1);
    . u2 M# T' \3 p! a( h3 w' t        else if(tag[p->adjVex2]==0)2 m2 T% k4 {5 w! S1 D, U  a
                DFS1(p->adjVex2);
    0 ?" u# Z0 J" S2 {- h        p=NextArc(v,p);
    9 R3 e. K- o5 E- Y/ B" }9 Y, k    }+ A% j) N5 E) d1 d8 n/ ]
    }8 M$ [5 n+ E5 E7 k: _
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()5 i1 E3 H( V) d3 s+ Z' T4 ~; X
    {
    . w9 P$ X9 I( [2 D% F; h$ @; g2 p    for(int i=0; i<vexNum; i++)
    + q% ?+ c* O& @" e2 P& n: |! [        tag=0;' T5 V* \- y1 C  U, d
        for(int v=0; v<vexNum; v++)+ r- A- b0 c' Z; a
        {
    % V3 {/ A+ v4 J8 W$ _        if(tag[v]==0)
    ( v* o$ j: x  r5 w5 w: F  w            DFS1(v);6 r& ~' B* K- i
        }
    ) O2 g3 O( j: f7 d}
    0 R% Q5 J6 {+ q7 u4 x+ ptemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    8 Y" L7 R9 n$ Z/ s+ _! M5 U8 F% l{; z) B2 c& W1 }6 V) \) v% x& w
        stack<int> s;
    ! L9 X4 S7 u6 c4 K& H    int tmp;: j1 c' p# {9 v3 v
        MultiAdjListNetworkArc<WeightType> *p,*q;+ z& N9 J7 z3 X; K
        for(int i=0; i<vexNum; i++)
    : b( z/ M- m8 x        tag=0;( W1 L/ z$ v0 K3 y  ~( J
        for(int i=0; i<vexNum; i++)
    " K$ `* w  h% ?0 @, t. P    {; j; H# ?! P2 X+ b
            tmp=i;; P6 B$ K0 }. _9 I  k$ }7 W+ D3 C
            while(tag[tmp]==0||!s.empty())
    9 P/ m$ w7 h# k. J+ V: O  b        {1 O8 w! l/ G/ r# C3 p& s- _
                p=vexTable[tmp].firstarc;
    : o% p( e" G# ]; ?& }: V            while(tag[tmp]==0)
    - l% m% L: Y% x" T            {4 ^! x+ T/ [. V& E6 f' ]" M2 \" T
                    s.push(tmp);: d% N( l+ n6 R& ^
                    cout<<setw(3)<<vexTable[tmp].data;
    : ~, l6 @. a1 O8 c  W( e9 V5 p  N                tag[tmp]=1;
    & t3 T5 z2 O- H; G: J                p=vexTable[tmp].firstarc;
    5 \* Y3 ^, \$ n$ z# y                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for3 `0 k3 p; I' ?& U$ g
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    6 A; V3 C' w: A3 I                //cout<<" 1st     tmp="<<tmp<<endl;
    + }6 u7 T/ L% A$ z# S3 N            }7 R. {4 X" Z* M* Y% D% W. x
                if(!s.empty())' v2 s8 B  ]7 L- g; }1 `$ o, P
                {" n$ h  v+ P* d' U2 B* J8 d
                    tmp=s.top();- W! }: u" j) `' l. Q6 B' R
                    s.pop();
    ; `8 X/ Z- @1 g# z                q=vexTable[tmp].firstarc;. O( w- T' T% A! t( Q8 K
                    int t=tmp;
    5 G0 m, O$ J0 J, ^) ^8 \                while(q&&tag[tmp]!=0)
    3 U. A9 |6 P2 y$ r% K( c6 F0 z# X                {
    & J3 L% w4 l/ i4 L( J; i                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
      C) O2 F1 A5 n) N' [) u                    //cout<<" 2nd     tmp="<<tmp<<endl;3 A, d  u8 p  f  S' ]
                        q=NextArc(t,q);& N" I, V: T% a$ R/ c  u  ^6 V
                    }+ c, h+ R+ m  [3 y8 g
                    if(tag[tmp]==0)
    1 K8 Z1 v) [4 k. g. X* @                    s.push(t);: w9 y3 R6 R0 a6 I
                    ///1、对应上面连通分支只有1个点的情况  c% y9 N. F+ i; _; h3 A% W) m
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈2 c2 w  F& |' H$ t! o, b
                    ///tmp要么等于找到的第一个未访问节点,
    2 _; a. g$ E0 `$ [5 r* H/ m) N, m                ///要么等于与t相连最后一个点(已被访问过)
    0 ]( k& b& N1 e- C# a                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    ) W. Z& v6 ^1 n, X            }
    8 h+ E  D( F: \        }
    1 a. v2 G! }2 C' r9 n    }0 R1 F; Q. |. m2 A
    }
      d% m! U$ P% m5 o6 J5 i6 }//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    ' s8 `+ V& g0 n& E* [: B, q% b8 A4 atemplate<class ElemType, class WeightType> int
    # @% x+ ^- A, M/ g: rMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    4 t  X2 _3 l6 w5 {0 K{
    % c/ Y) y" W. [& {. q: ?' s3 Z! w$ Z    if(head==pre)
    # Y& {- Z" n& E* |9 g# ^        return -1;
    4 h7 z" {+ d! X' I6 c$ K& F2 K: i; n
        MultiAdjListNetworkArc<WeightType> *p;* m: T0 C8 x( W6 a
        p=vexTable[head].firstarc;
    1 o# {3 R+ c4 j- _2 V    if(pre==-1&&p!=NULL)
    # i# Y4 s4 B  K$ l( j# d7 T        return p->adjVex1==head?p->adjVex2:p->adjVex1;' Q3 [5 ~% \) c& t; k9 U
        //pre!=-1&&p!=NULL5 |5 J. ~$ F, C! t  G7 ~
        while(p!=NULL)
    ( }$ Z$ K7 }$ y9 {* k6 ?1 [: y    {* o, e* ?3 l* w% n
            if(p->adjVex1==head && p->adjVex2!=pre)
    * V6 {# f  t5 v( W, u            p=p->nextarc1;! O" ~' \2 X! f1 r+ I
            else if(p->adjVex2==head && p->adjVex1!=pre)
    ' y6 a* W+ A; `% \( |            p=p->nextarc2;
    ) b1 n* g8 _5 J. K- p        else if(p->adjVex1==head && p->adjVex2==pre)0 @3 V* g- n7 a; H* `$ H& b8 G
            {$ y8 G& ^( ~' i# Y6 C$ I6 Y
                p=p->nextarc1;, |( b/ V6 _/ J
                break;) B, ], C) h: M! a
            }6 Z! _4 h: @5 @
            else if(p->adjVex2==head && p->adjVex1==pre); q! d, o  k' t9 A& `2 b- h7 N8 U
            {, @1 k+ C0 _; o- w  x9 `
                p=p->nextarc2;
    ' `- W0 Y% s9 X  m5 T- |            break;: Q' o. C5 z( B2 R
            }8 I+ ~/ X/ N0 @+ m' X
        }
    , u) K7 g2 j' {0 f( I    if(p!=NULL)
    4 d3 x; a3 c+ g6 |0 P# X+ W/ `    {
    / X+ P4 l+ @8 B# [) b. }/ u0 J        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    * u2 m! D! ~3 o$ |$ i    }9 F" K2 c& [+ M, P9 C* V1 T3 z
        else
    ' L, _- c* }, E' K/ U        return -1;
    8 u1 \6 V1 x7 P+ l}
    * E! M! c5 u# W% G# O
    ; Q" ?% m0 v, `7 o9 x$ A; t) q
    : P2 ^' K8 W: `( h) vtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()# W% I; I. C& V
    {  c5 D* q' R6 y; u3 @5 C
        stack<int> s;* t% c) t, c3 M0 m5 R  `
        int p,cur,pre;
    ( F% ]6 g5 h, E. \6 V    //MultiAdjListNetworkArc<WeightType> *p,*q;
      ?$ H6 Q2 `: {0 J; v! \- a    for(int i=0; i<vexNum; i++) tag=0;//初始化% J- d% ~7 ~8 M) ]8 c8 h# k6 i4 R
    : t, z) g: D  l( `* W5 W+ W. B
        for(int i=0; i<vexNum; i++)
    6 n# N0 }7 J5 y' [+ z8 t    {
    5 _' D6 @" E1 I% B        cur=i;pre=-1;
    8 o. }/ n& x" E+ W, n        while(tag[cur]==0||!s.empty())
    " C, T! s& U+ a8 C) u        {8 A( X( I+ y8 w0 R
                while(tag[cur]==0)
    8 f& P- L+ c: Q4 d* G. ?" n% G            {' D( R. c$ \, O  M6 S8 r$ V4 Z
                    cout<<vexTable[cur].data<<"  ";" ^+ k3 [! B1 `* r
                    s.push(cur);
    + s- _' i; o1 d6 A                tag[cur]=1;
    ! a& r! M1 o8 [# p1 x! f               //初次访问,标记入栈4 G/ V+ F. n, Y5 t# \6 B
    . R* v4 [8 c+ ?" g: ^! q3 i; p4 ]
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点, E9 l: c% t2 t: p8 i
                   if(p==-1)
    # L# B) ?: b" M               {
    & H8 A  L  I# x9 |$ ?/ H                   pre=cur;s.pop();" \8 b- @% {" Z) F5 F2 ~
                       break;
    / I9 y. }2 J& ~( ^2 D               }
    1 `+ |9 u% y2 m               else1 J. R" k/ U7 j/ e! U8 y7 n0 Z( Q
                   {* Z/ _$ G7 Z& F* P
                       pre=cur;, \5 x% F- Y5 c; _* ~/ B
                       cur=p;0 H  t2 u8 w* {5 v: e6 j5 N9 a
                   }
    + p( S5 Y8 u2 o: H! G
    + f/ y1 O; e  b2 X0 J- t            }
    " n& G0 U$ ]+ [5 \) h  d            while(!s.empty())
    8 O8 J5 i8 ^* ^- j            {- E0 b$ b7 \, [7 }, y9 \* d
                    cur=s.top();: R# @8 h, z  ~7 Y' c" Y5 W
                    p=GetAdjVex(cur,pre);$ R8 M5 l( z+ ~  E2 g7 t$ c- Q% i
                    if(tag[p]==0)
    + W5 N# k5 S. W, n* q! @6 q, d                {
    " l8 C# ?  F  v. e3 K, h                    pre=cur;. {# r7 i. l1 |
                        cur=p;
    ' I+ o& G6 E# N+ B; `1 ], Y* l. a                    break;
    & e& V, O" w/ v& e  B# {                }$ L/ u# _, R" Z  i" ?$ D, w
                    else
    : S. J) E3 [0 N1 k" p) Y& ^5 h                {3 j# T/ B2 P1 T+ E% x, A$ ?. U
                        pre=s.top();
    2 b# \6 d4 r7 a! L8 |% p' D. j                    s.pop();$ G+ R2 v- n, e0 A8 G3 H( w
                    }
    + O& E" G! M2 q7 |3 m! o! m% |4 W2 i* O/ {( K' f( u" h$ t" ]
                }
      N! q6 S& f" h4 _: s! P
    & w9 D8 f: P) F        }
    , D* y6 _. ^) R. e. a    }
    - G6 ]& u$ h5 M. {9 m( j! E5 A}% v$ y1 j/ S0 `' s
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()( {/ o+ ?7 A6 o# i. H( }& d
    {5 F9 j! q( T0 |$ c4 S6 x- Y
        for(int i=0; i<vexNum; i++). B" i- H: R6 [  K+ }- h
            tag=0;" E8 k# ^# T& |, P# o/ |
        queue<int> q;
    " g( Z* L, n  S4 M  B    int tmp,t;/ y/ @. s; K( H) _# z0 E/ J" i5 @
        MultiAdjListNetworkArc<WeightType> *p;9 q% Q8 _) z. l) `! n7 K2 c
        for(int i=0; i<vexNum; i++)( n9 F. |( l! Y( a6 }
        {
    1 x5 ^4 l; t0 r7 Y* Z. b        if(tag==0)/ j- w/ a0 ]/ H. `& c
            {% Q/ u9 ?1 }3 ~8 h
                tag=1;
    $ _' `) u  D' Q# N- R            q.push(i);4 }: a" ]. J) e$ @
                cout<<setw(3)<<vexTable.data;
    : y; S* u' F+ B) l9 _        }
    ! T8 ^1 z1 L1 d1 ~        while(!q.empty())
    , x2 T0 U5 L; M        {
    5 Q& U  _* w! u, l9 c8 p            tmp=q.front();# a8 \, [7 ~7 p$ o( E6 C9 n
                q.pop();
    ; E' X& k1 M7 [% e            p=vexTable[tmp].firstarc;9 l3 ?0 i- u8 O) e1 l" k& y
                while(p!=NULL)6 D$ H' F# O1 r* P- k
                {  K5 S9 }" _: j$ Y( f& M# q
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);! Z% U( A: f- f* }5 w
                    if(tag[t]==0)5 Z1 \7 Z+ z7 w# e. h2 ~
                    {6 S# w$ k. C6 m0 x% w% }* u" V* d
                        cout<<setw(3)<<vexTable[t].data;
    , |. @0 _; e" S0 s3 g% Q1 p                    tag[t]=1;: _1 E. c9 {4 `/ \- P
                        q.push(t);# ?; ^* o+ N4 V, F! h6 v
                    }+ P# t1 B0 f& m  n4 W7 F
                    p=NextArc(tmp,p);! K/ T0 y$ c4 ?/ j" h0 b4 I
                }
    : {+ z/ V# C) ~) y8 \        }
    % o: {( ]% a& M6 g8 s    }6 U- X0 I: P* K# ?: r- g
    }
    ! d8 K+ ?% f8 K" t. utemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()5 D% F) a$ i% `9 J5 x; H& D0 `
    {8 [& G. b: W" n2 P
        MultiAdjListNetworkArc<WeightType> *p;' Z2 w4 K9 g# u# g* C& W, E( a7 Y5 }
        cout << "无向图有" << vexNum << "个点,分别为:";
    ' _# x8 B5 W, A$ I& y( X: c    for (int i = 0; i < vexNum; i++)# T+ W2 u5 A$ A, X
            cout << vexTable.data << " ";
    / [* {# x3 ^, f& I# v: W# T% P, T    cout << endl;
    ! e( w0 D6 ~7 U    cout << "无向图有" << arcNum << "条边"<<endl;' n( [7 R( R7 G/ A) n
        for (int i = 0; i < vexNum; i++)" ^3 \) T2 F; x) ^' n
        {
    ' w6 W4 j. O1 B# }5 _        cout<<"和" << vexTable.data << "有关的边:";6 k0 ^, z4 A, Q% b# L; S1 M4 p& Z
            p = vexTable.firstarc;4 `# p# \) G' E! \8 X* C
            while (p != NULL)/ T- |' X* G. u
            {
    ( h! g* d1 P' K" e' W/ `) R' O            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";0 C2 t# b6 t! E+ h# g* K$ c
                p=NextArc(i,p);2 u$ F; d( s3 p% N! s
            }
    7 Q* p! i: w0 _% s        cout << endl;
    6 P* x8 w6 g7 I* v' i- }9 [    }
    ( ?+ z7 P2 p0 i: ?4 ?% r}
    * Q: Y7 |+ j0 T8 I. c. L) P( @( K  i3 m4 u* s/ X1 ^+ [

    ( M7 a  m. h2 Z5 X0 s! q邻接多重表与邻接表的对比4 k9 m8 @, z9 J% l0 h
    ( `$ ^% `+ v! q+ t
    邻接表链接% Q) O2 J0 \4 M. D3 v3 o
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。9 y: n% M$ a$ j/ b5 d. z& o- _
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。2 p* R2 H. i  k5 N3 k4 R( j
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。9 S2 V9 O9 |+ M
    ————————————————5 M1 c5 D+ f  u0 @, J" a4 T4 R. j
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    / d$ g7 L0 D6 z3 h6 j4 U原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958, C3 ]9 d- m1 ?- {7 K8 l- Z5 K
    % r6 A7 J1 s4 q& M) q+ ]- e
      W) W% E& G& Y( F4 Y' L7 A( q

    0 u; I- j4 B+ O9 \- V0 M  k0 h' p! c8 y8 D, h
    ————————————————
    4 a0 X6 _# M+ g# q$ Z& L& S( R1 s版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    7 s* j. y' ^  x9 }4 D2 @" L0 j原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    5 i3 P8 B' Y" X) y9 J2 m! A; T7 b6 |" ]8 u" K7 r
    2 q! n  q, K$ |) r
    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-9-10 15:54 , Processed in 0.813863 second(s), 54 queries .

    回顶部