QQ登录

只需要一步,快速开始

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

    ( r5 Q: x4 n- B$ A, l" Q图的存储结构——邻接多重表(多重邻接表)的实现- K) B. r1 ]3 P
    7.2 图的存储结构; d! P8 g( _% d/ E3 K0 n

    + z$ A: X6 h% B. J! b. b' S7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    1 p& j' _* w0 i  r" L( ]( a# n2 [& ?邻接多重表的类定义2 ~( z  d+ i3 n" w
    邻接多重表的顶点结点类模板
    + Q0 a3 A* P3 i& \# [  X邻接多重表的边结点类模板/ `" |5 C$ {5 x$ u! h, n( S
    邻接多重表的类模板
    + c7 ?3 o) G+ z' m邻接多重表与邻接表的对比
    " i; Z, [1 F7 X. j6 [7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    $ l- Y2 I2 G, T, V9 P. C
    . w6 c) G$ W. J) d) N在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。% f/ S* C; B$ k# v
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    # l# p5 l8 {8 u2 D4 [2 g- `
    2 ]9 c$ e0 X' J) i1 {, _/ C0 ?7 R0 Q邻接多重表的类定义
    ' l$ o8 l( Y5 Y" V) w8 q 1.png - U2 ^+ b; T; s) A) f; n9 G
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    / }8 g  |+ M: N/ xdata域存储有关顶点的信息;
    # ^: |' [- k2 i% D1 b/ ifirstarc域是链接指针,指向第一条依附于该顶点的边。
    8 E7 w7 c$ @# B4 J' O所有的顶点结点组成一个顺序表。

    , k3 N3 Y4 j) o: g
    ' o% W4 f: h% o3 w5 `% i" M
    template <class ElemType ,class WeightType>
    & L4 M4 z* n# J' b$ Iclass MultiAdjListNetworkVex
    9 ?. U* c2 @! t' y5 P8 {{
    ! v7 M8 _5 D" Y4 U* Z" j1 apublic:
    5 i% m& f  C) G        ElemType data;8 ?, o+ s0 j# L3 p1 ]3 o8 p
            MultiAdjListNetworkArc<WeightType> *firstarc;
    / ?/ O, t% b0 z5 U# a  X5 j* W
    % |, T& f8 C7 a1 ~        MultiAdjListNetworkVex()0 B1 V5 y. Y  \. W  W' Y4 W
            {" {8 d, F2 \8 O6 z. D4 \/ d1 w
                    firstarc = NULL;) C5 d. A) \" o, v
            }  c5 V# A/ U9 B/ A
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)6 b  E/ G4 s6 g- w( O# @
            {( ~! A0 r' z0 k; I0 R
                    data = val;- b% i& s* j) x5 C
                    firstarc = adj;' p# s5 \# a/ V; m
            }
    7 P) r1 b- c# r" H};! h- Z5 |4 M' b' D6 p" B
      o8 y" O+ W* _& m3 \2 N* h
    邻接多重表的边结点类模板
    & F! Q# G$ }/ g" I  q% Q' q7 @6 f/ v3 a4 w& M- A8 l
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    ) t+ F3 D6 d5 btag是标记域,标记该边是否被处理或被搜索过;
    % d( f# [8 g5 X3 Iweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;( _0 [' i1 ?1 S* B6 F
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;5 M' Q5 o3 V# i( F( F3 w
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。8 l3 S0 [$ n7 P! d

    1 _1 W0 |1 d0 V& r6 j' U9 N6 @3 ^ 2.png   ?0 D4 q. J  }3 o' y2 l- i: Q
    template <class WeightType>& N( O9 b5 P* \8 {( K: Q3 l  s
    class MultiAdjListNetworkArc
    % G$ z2 v3 A8 ^6 B9 f{
    8 r9 q- Q& [7 \, @2 B  |( V' @public:
    1 P, t" Y( E) r  w3 u: M    int mark;                                       //标记该边是否被搜索或处理过8 T7 T2 {5 ~8 K8 x
            WeightType weight;                              //边的权重
    4 r5 }9 u1 Y4 p% _8 @+ A        int adjVex1;                                    //边的一个顶点7 U( Z5 \, Y0 e5 Q9 y* \
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1* M) n6 q$ a$ G0 s+ w- D% o' w
            int adjVex2;+ {- k' |9 r' c1 n7 R
            MultiAdjListNetworkArc<WeightType>* nextarc2;
    % k) r( f( k0 a3 W& q  f4 }3 ?7 X! S( ?' x* @! S
            MultiAdjListNetworkArc()6 a* H) x/ d1 k$ R' X9 C2 b7 C. A
            {! D" u# v# B) A+ M: Y0 i
                    adjVex1= -1;3 w1 ]+ K: E2 H) i% \8 b" p
                    adjVex2= -1;0 v$ h0 Z. K/ u. X5 x+ R
            }
    ( E  A) \( `* N! x        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)  m/ y. ]3 q2 U5 {
            {
    7 }0 ^8 f9 k2 A  H5 X4 ~: j: i                adjVex1 = v1;       adjVex2 = v2;5 t2 v3 z6 P  [; J# Q1 u& K/ Y. I
                    weight = w;
    5 i; T* Y3 b2 f0 q6 b% S                nextarc1 = next1;   nextarc2=next2;0 ?; J: o6 o. I" y. C$ G7 V
                    mark = 0;           //0表示未被搜索,1表示被搜索过5 E4 b# a  _) A. S; a$ o: k- }$ h
            }: o. e& t' C) n* `2 D
    7 `! {+ D* w2 L
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>& L. b" c4 ~. ]7 g8 K
    class MultiAdjListNetwork
    0 b3 v( U% w5 ^4 y# e- i3 W4 O- _{  h& `7 |. _( Z
    protected:+ G* {6 Z  g, K1 ~4 ^4 t
        int vexNum, vexMaxNum, arcNum;7 i( c9 [2 g& p7 T) E3 o
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    6 w) y" P+ \, r9 V4 y    int* tag;
    * w; g% O. _8 Y, e# i5 M- f4 [+ e    WeightType infinity;2 N4 b* o! w9 U
      [5 h. R' D" ]) K
    public:1 \3 b* T# E& L5 D$ Q; v0 Q- A
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    ' T  T" @4 s; Y* g0 L0 \5 e, e+ T
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    9 `# t% l3 _) P% @
    6 O* O4 A7 Z. d/ B) Z2 V# G    void Clear();
    2 p  Z: w, I$ x/ B6 p' o$ o8 l  s    bool IsEmpty()
    ! X8 d, Z/ w" B3 O    {
    2 g- m% g. A0 k( _/ |* O        return vexNum == 0;
    ' {+ c! {  S1 i/ P) T* w4 B+ H    }3 \! U3 h1 A* B3 b
        int GetArcNum()const. f0 I# t* y/ Q# p2 W* {0 q
        {
    1 p) A% A0 a+ C0 d* D' u        return arcNum;: l, P4 |+ W3 B* E4 o, g1 z
        }% E) i$ u; f0 `9 D5 ?; I2 J
        int GetvexNum()const
    - C- ?) x# v$ j4 F+ v# u6 H& T* i, J    {
    % k7 [* P6 S5 D        return vexNum;  ^% f! |0 q5 U* r& c2 d- u
        }
    / T. ], y2 ^( n" S! O& r; s8 c' ~3 K# @! F' y
      K# O1 i% I, a  p. g
        int FirstAdjVex(int v)const;  ^# L6 p2 B6 x+ G3 ~
        int NextAdjVex(int v1, int v2)const;
    ; P- _% t7 ?$ @, d) h1 y    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;# Z# g& f) F; w3 @3 E1 r
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;9 e3 P2 ?/ A5 y) w: S  j5 G9 E
    7 e, T, G# q" B9 j, T7 N; ]
        void InsertVex(const ElemType& d);
    , Y1 u; w. e* K& l$ ?. ]( }9 e  H. u    void InsertArc(int v1, int v2, WeightType w);
    & t+ K( s( E' ]* A: t/ F0 i: R: p6 \. ]- B0 a: \
        void DeleteVex(const ElemType& d);7 r! F0 }$ L4 D6 k) a; p% C
        void DeleteArc(int v1, int v2);/ \3 V- `# C5 p/ k7 \. Z

    / p4 P, r; c# o    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);/ E  p7 Y  j; T/ {5 D8 U- a  v
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);3 F% T; d9 ?7 h

    ' {+ p  {/ y3 O    ///深度优先遍历
    / F* u) R) P6 }+ u    void DFS1(const int v);
    - d( [2 D+ Y( Y3 z    void DFS1Traverse();
    2 e0 o3 J: Y/ _5 ^9 V    void DFS2();
    / a' L* r% [6 M- m) j1 P7 z) t) g. ^5 ?, v  [6 {3 @
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1# ?2 g) B8 [6 J$ w8 I* u2 A
        void DFS3();5 B  g$ R- M: ^2 s2 I

    . ~2 R; j8 d7 n2 A3 X    void BFS();5 W( z; u" `; J( E
        void Show();! b2 ~1 K* _- ^5 e1 M
    };
    , _2 ~& q: k$ w( f; P- p1 y- q0 I9 |& H' }* O! p+ B8 M) C( n: I  \
    2.函数的实现
    1 z! Q2 m' y( ~7 H9 j# _研讨题,能够运行,但是代码不一定是最优的。' i  n4 S+ J7 l) W6 k  A
    5 M0 X* W7 D  y
    #include <stack>
    " q7 L0 e6 M3 L+ ?4 s3 ?: F#include <queue>4 m4 i4 `( b3 \2 K9 k) j" ^' t

    4 _* C! v; f4 Q7 y3 `8 h2 _template <class ElemType,class WeightType>
      B+ [& i/ N( {3 [7 RMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)- o/ l* H1 |- U& n% [
    {0 g  L9 h& S, m/ T' H
        if(vertexMaxNum < 0): J9 h% F( K# x) s" ]
            throw Error("允许的顶点最大数目不能为负!");7 D9 {& Z5 v. N% y5 B
        if (vertexMaxNum < vertexNum)+ U8 u3 A6 U3 M  C: J+ v0 H
            throw Error("顶点数目不能大于允许的顶点最大数目!");
    + \9 X$ u; u+ X" c( N5 ?1 i( w2 x    vexNum = vertexNum;
    7 B% c* ~+ a8 J6 x6 J3 D6 L1 V2 T    vexMaxNum = vertexMaxNum;
    0 e9 U8 G* ^' j9 S    arcNum = 0;: l9 ?- w, N7 b3 F0 r
        infinity = infinit;
    9 E$ F7 i+ E0 ^$ G    tag = new int[vexMaxNum];3 ], K7 v3 b& n" o4 J
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];- ?. f1 ^6 b& F! s% q% j$ V
        for (int v = 0; v < vexNum; v++)4 e. s1 }. I: Y9 J, S- k4 w# y
        {$ U- y& b$ v3 o2 O/ Z# |
            tag[v] = 0;
    3 f0 }& Q, X5 X6 ?  S9 O        vexTable[v].data = es[v];
    / @) k) {; Z& Y2 f7 W5 s  K" v* T        vexTable[v].firstarc = NULL;$ ~; ~1 @2 h+ M$ j: ?
        }5 s2 k- d; R* w' E. e, q5 i
    }# u+ G" a4 j0 _* Y: b9 q# F
    template <class ElemType,class WeightType>7 w: q% y& [% {0 s
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    ) i0 w% R( X: I7 q7 A9 Z{2 j) v! C* \; Y8 ~8 L
        if (vertexMaxNum < 0)% R, O) k% R( e: u% U
            throw Error("允许的顶点最大数目不能为负!");
    0 N  `: K( T5 L$ C8 a    vexNum = 0;
    8 C! N, m8 y" }6 i; y: ]* T4 @    vexMaxNum = vertexMaxNum;
    ! P2 @3 `; p) I% ^/ U, l    arcNum = 0;
    4 f; X; F% `- K+ T. S9 D    infinity = infinit;
    $ s* a2 \& ]& G. U( s6 ?* q4 p    tag = new int[vexMaxNum];
    ) d: [2 l: d  f# B    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    * L3 V( Y5 R, t}; M% S9 x0 S# n! R9 g
    template<class ElemType, class WeightType>
    5 E- J( e0 M, |4 g  s6 |int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const4 f" i) a( H/ F2 G
    {
    % ]2 Q% E7 U( W5 s* W# F    if (v < 0 || v >= vexNum)
    . e. R6 e, K) Z3 H: e% Q1 K        throw Error("v不合法!");1 d3 H, }6 `6 b' M; h$ H
        if (vexTable[v].firstarc == NULL)
    ! f) ~3 n& m2 t7 _$ u% s) p2 {        return -1;
    . r( v! I/ w& J" X8 H- W. P! {    else0 V( Y( T9 M. B# N/ n2 U8 j
            return vexTable[v].firstarc->adjVex1;
    - G1 `% k, N' O6 \' D: v}
    " y2 a  w& `! W: D$ N
    ' ?( v$ `, d/ _7 g' q6 \template<class ElemType, class WeightType>
    & M# x$ O  {5 P0 P3 ^int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const( O4 s: M- E& v
    {6 {" p7 o/ a: o8 s2 s! Z6 l  v5 h. _
        MultiAdjListNetworkArc<WeightType>* p;: ^6 |* h6 n+ w* U
        if (v1 < 0 || v1 >= vexNum); M  W( U- ]/ A- f
            throw Error("v1不合法!");
    . |+ U' w0 K9 j- o! t    if (v2 < 0 || v2 >= vexNum)
    0 d% d( N. f3 f6 Y6 T        throw Error("v2不合法!");
    , r4 ?" a$ k; J0 w1 n& p9 R    if (v1 == v2)3 y+ Z, _! }  u3 `3 c* y* K& \
            throw Error("v1不能等于v2!");1 [/ p6 z: k4 Z7 N
        p = vexTable[v1].firstarc;# g9 [& G7 r; e+ V. H. K6 `
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    / }& L9 _% V4 U! W        p = p->nextarc;
    + w( v( j/ @( [4 a; Y+ o7 w- |7 ]5 h    if (p == NULL || p->nextarc == NULL)# z1 S6 p/ t, w( a& w5 \
            return -1;  //不存在下一个邻接点9 w5 x/ w, d% U- R5 ^" X
        else if(p->adjVex1==v2)3 F8 `7 }+ S, z. |
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    4 k$ R: P* d3 U0 B1 U1 A1 ]    else
    / @/ x- v% a: _2 I% W        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    8 g5 a; w! g" `' V' r$ R}' ]. t- u2 V0 g- j; k% A+ `3 [
    template<class ElemType, class WeightType>
    ' K4 S6 P1 f  \2 a% i! D0 `2 O5 @void MultiAdjListNetwork<ElemType, WeightType>::Clear()
    ! U4 ]7 o* U4 ^! u6 X{
    ( T9 F  f' V  N' v    if (IsEmpty()) return;0 i' N1 r7 _( W5 k
        int n = vexNum;* X; Y, N# a0 k4 }  a7 v
        for (int u = 0; u < n ; u++)
    ) \8 C7 D4 ]$ Y        DeleteVex(vexTable[0].data);
      w2 v( y/ z$ _    return;
    ( \' B9 S3 c& X3 h, b6 f2 H}
    + [8 |" P- K0 x* o1 D+ etemplate<class ElemType, class WeightType>
    ) t2 P. u6 _/ _- }1 f+ ]MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()0 R3 z. |9 N1 t3 |5 ~
    {
    ( L6 V" x: e( H% s/ w9 W: L    Clear();" l( R8 q7 ?: r
    }
    0 ?: B' C9 m7 v* H/ k1 N5 p5 W' Rtemplate<class ElemType, class WeightType>7 w+ e  j1 @  }/ N3 _& U2 x
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)1 U- @/ I1 h2 B" v9 E" W
    {" b+ W3 @) ?% `! o! D
        vexMaxNum = copy.vexMaxNum;/ e) M0 T  r4 p& Q$ c7 @8 y
        vexNum = copy.vexNum;" C% O+ K6 U! s) s7 N
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];% B  F  J4 _3 O
        arcNum = 0;+ X) a- q$ P9 b9 h3 k/ B( L& C
        infinity = copy.infinity;& g- \5 {$ b9 g4 V
        tag = new int[vexMaxNum];
    ( J! u# F! Q$ t* X5 o! Q
    - p7 G  @. y" d5 q+ U& h" k- O4 D* q    for (int v = 0; v < vexNum; v++)
    * ^8 [# ]  U( ^, z0 K2 n) v" c    {
    7 ]6 O/ E+ q3 ^# }# ^* s        tag[v] = 0;
    9 O! l2 J5 m+ {  u8 {& b$ b        vexTable[v].data = copy.vexTable[v].data;- Y- Z# O  t: e) l
            vexTable[v].firstarc = NULL;
    : w6 I9 p0 a) c# m% o# N& ~    }8 i6 g+ x  g" U0 z! J$ u0 m0 [
        MultiAdjListNetworkArc<WeightType>* p;" R1 y$ V- l4 j  m- {  v
    ' k+ F/ Y) y: q5 a! R
        for (int u = 0; u < vexNum; u++)
    2 X3 t8 Q" D8 U+ _$ i" G3 H4 t    {
    : {9 W" T, U2 F" t9 o' @        p = copy.vexTable.firstarc;
    1 T* y: m% K$ |! R  o        while (p != NULL)
    ( H' r# [" s. t  b) k        {
    5 V& r. H  B, m/ A, m* n0 O            InsertArc(p->adjVex1, p->adjVex2, p->weight);" k. c5 G* \2 w: b9 ~& L
                p=NextArc(u,p);
    : g* T2 W9 c3 K  P        }$ a  k3 h1 _9 ?+ ^
        }0 [/ B$ m- o- F3 E. ^* N8 h7 \3 i
    }
    ( O8 V& b: y1 i' n6 V  h' E1 gtemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    $ S0 u2 ~! J4 L( DMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)2 @* K) |; J# O+ }# M
    {5 l( W, t/ }; ^( D5 [+ i" k7 X
        if (this == &copy) return *this;: e3 c2 |: ^) g/ [" T$ X
        Clear();; ~: Y, M" ^! w, Z9 v' N
        vexMaxNum = copy.vexMaxNum;4 K0 [; N( g* _! I, e8 O
        vexNum = copy.vexNum;
    4 B* r# P) i/ h3 ^    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    " [7 E9 {# R1 m    arcNum = 0;
    % p1 X% ?# e' ^) K" `    infinity = copy.infinity;
    ; y1 X' ]+ J- ?$ ]; w    tag = new int[vexMaxNum];
    / S4 `( E# t( \" u6 K
    6 C, b$ q* F% v1 f& l. [$ E    for (int v = 0; v < vexNum; v++)4 C3 Y1 d. T- a7 z- Y
        {
    2 r, R* H9 m- ~2 Y4 S        tag[v] = 0;
    + i/ A. h$ M- s4 `        vexTable[v].data = copy.vexTable[v].data;* W; i4 n( H$ K
            vexTable[v].firstarc = NULL;
    ! M* o! u, D1 ^4 p6 c0 {2 ?    }5 b, |; W: P; I4 a
        MultiAdjListNetworkArc<WeightType>* p;8 B" D( O8 Q3 A0 W& O) F' U
    , b5 [/ {- r" ^
        for (int u = 0; u < vexNum; u++)7 v$ Z$ y3 I" z5 r* Q  R, H
        {
    ! M* j0 o: B* [2 w0 w6 @3 f- C        p = copy.vexTable.firstarc;
    5 v. P5 l1 [$ Z% M( `0 M" }7 B        while (p != NULL)  u6 k! g: |# k& M
            {2 J. C7 A  }/ O
                InsertArc(p->adjVex1, p->adjVex2, p->weight);& U  a& w0 K  t) o. c% f
                p=NextArc(u,p);7 O3 [- s; [4 S4 X7 C0 B. N
            }
    + Z) J- ]) ~! e7 G    }
    1 F$ [4 Z5 b: m0 P4 I2 x. o/ Z' w* w    return *this;7 X( s6 D: b! v! P! F# j5 R
    }, C0 q1 c0 P3 r4 M
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    6 H/ b2 a3 t3 v( w& j; rMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    ) N/ `5 X/ R- l/ r' P: R{+ B% S0 F$ |2 j* I- e& `. [  [
        if(p==NULL) return NULL;
    , ^9 g; f# Z# V7 i    if(p->adjVex1==v1). M; W! V0 K" |$ i: A
            return p->nextarc1;% R+ s( d( m  i; e
        else! w, D. X( k- A; O; @) E  M
            return p->nextarc2;. `8 ]' @0 z: X
    }; \4 l, u4 O; H7 ^6 q: R, K
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    ( o7 ]& f7 d+ t, n4 z2 YMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const1 b! s9 v' F6 d; j' O! |* D
    {' I: @2 F$ T" E" J7 o: `2 F
        if(p==NULL)return NULL;! `" i9 X* v1 f, }' y) [1 ?0 e
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;0 w2 _; D( W3 m! w: M8 q
        if(q==p)* I) Z% X0 Q7 l8 j% P* \
            return NULL;+ c; C( w9 S7 l
        while(q)5 Y' _; c6 w# ^5 y
        {5 `" @. h+ C7 k* d5 x; c
            if(q->nextarc1==p ||q->nextarc2==p)
    9 |% x( E2 ~( v            break;
    ) Z& _* N% J% @, L, m% y9 u5 m        q=NextArc(v1,q);
    ; S5 ?8 L! ]6 ], H    }  e5 B7 Q1 ]' l
        return q;
    * N: E: L$ l# |3 X  G* O}  L& E- J7 p' V+ O* M! z$ P
    template<class ElemType, class WeightType>
    ' e3 i' {4 v+ h1 Hvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    ( x0 R: L4 P; k7 t, J/ \{
      w* t2 a8 Z$ z2 C2 z8 k$ S0 A* ?    if (vexNum == vexMaxNum)
    8 E! `- G! K  H  o        throw Error("图的顶点数不能超过允许的最大数!");4 Z, z+ y! {; I2 l: Y1 x
        vexTable[vexNum].data = d;
    ) D5 o* r: }0 W7 D    vexTable[vexNum].firstarc = NULL;
    * \5 m! P( b8 y9 i    tag[vexNum] = 0;
    6 O& X1 N, y0 m; @    vexNum++;# R7 S2 ]' U8 K
    }
    9 A/ F# `8 `2 A2 ^* stemplate<class ElemType, class WeightType>
    & j, a+ {' ]  o0 j& |; cvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)# l/ j% i* \0 B2 M8 Q1 K: n$ x
    {+ \. Y% w; q' s5 X- u. `+ b
        MultiAdjListNetworkArc<WeightType>* p,*q;
    ) ]6 ^  e" P  s  B3 }; L! q! i    if (v1 < 0 || v1 >= vexNum)
    $ f; I& ~. f3 N/ R- [* H: g6 p5 I        throw Error("v1不合法!");8 G  O% f$ n3 Y0 j' u5 w2 I% o0 ^
        if (v2 < 0 || v2 >= vexNum)
    ) ~8 E( R* |& G        throw Error("v2不合法!");
      Z6 t8 C$ M* d. R    if (v1 == v2)5 _7 m6 E6 K% ^  u& a* O" D+ O
            throw Error("v1不能等于v2!");
    " e3 M' c! Q9 h* Z8 ^; @  O    if (w == infinity)
    ) P; S7 x1 \! W4 l" c        throw Error("w不能为无穷大!");
    ( i! H( |+ }8 Y, Y; V( u+ `
    2 t1 K. W$ ~. L3 G8 H
    ! w7 O, v3 o: j' K$ P* d! g    p = vexTable[v1].firstarc;
    4 j2 o( n1 k- h6 v6 g9 d    while(p)  e5 S% |% s& e$ t+ Y1 o( L
        {
    $ z! Q* b4 |1 @- B        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中5 g/ T! h8 y8 A  R0 z) P$ Y
            {
    ' H9 L5 `' h8 b* o            if(p->weight!=w)$ |- e$ P1 J* x4 p9 o
                    p->weight=w;
    5 z3 w$ @7 j2 t6 d2 ]  w            return;
    ! S- \2 n7 N2 t4 K' S6 A" r* o7 _( [        }. i$ }% V. S5 M8 e. S* z

    ! \1 u, |9 u1 y* l7 K0 \0 R        p=NextArc(v1,p);
    , @6 E/ m3 R4 y/ k    }; a: n0 ^4 R# B; @( ]5 O- X
        p = vexTable[v1].firstarc;
    ) [1 }8 \3 X- O+ J/ Q    q = vexTable[v2].firstarc;
    ) a: o( I  {3 B3 ~/ c1 Z* L    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法+ ~. h- B" K, I
        vexTable[v2].firstarc =vexTable[v1].firstarc;; F: [. F5 `3 ]) s5 h) I
        arcNum++;
    # M- W8 U8 K& H( X( ~}
    " q# P/ i% `5 ]0 S4 _1 g) e; m) M8 P- {6 o$ q
    template<class ElemType, class WeightType>1 k6 l( }% _% c7 R
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)6 d- ^0 E$ R8 j, M: Z( p6 A
    {7 P5 |9 C' d, Y: O% L. d. ?; Q
    : C  I$ D" n% r) @7 u
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;
      N: K$ b  X0 n5 Y1 {    if (v1 < 0 || v1 >= vexNum)
    ! }; k' N/ h+ i6 `/ K        throw Error("v1不合法!");/ O, s4 g1 I8 b8 K+ Y. K2 s
        if (v2 < 0 || v2 >= vexNum)
    + n. w3 {# d4 l+ H* o$ O        throw Error("v2不合法!");
    0 B; z7 g- P, K5 S! `9 E    if (v1 == v2)# Q+ h; `8 }$ u& g
            throw Error("v1不能等于v2!");
    , r1 y' N( }- s2 I( M5 C) _$ s( l- ^3 k' c# Y2 x
        p = vexTable[v1].firstarc;
    7 a; Q6 l" x; q. w3 L& K/ M    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2); V& M6 L) W) s& O
        {$ W9 v' G- ]6 j
            q = p;
    , d* Y/ s) E! ]6 T& S! K" ?        p = NextArc(v1,p);
    7 I' N" g8 F5 w( M& U0 t    }//找到要删除的边结点p及其前一结点q
    4 e4 W  i# c9 H& A( A$ Y' K+ P* l
        if (p != NULL)//找到v1-v2的边$ x3 E# _7 D3 z" _9 U2 Y
        {
      k" J6 l5 C4 d1 S; L0 n1 ?9 Q' s        r=LastArc(v2,p);! V8 D. l. S; z3 ^: y$ ]4 x! u
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    # u, D0 G) s# }. B+ _. G            if(p->adjVex2==v2)
    " b( ?' M- H! t: h3 o                vexTable[v1].firstarc = p->nextarc1;  _+ ^2 Y6 q: T9 ~- U. S# T
                else vexTable[v1].firstarc=p->nextarc2;
    - [8 u; ]2 ]$ y; L        else//不是第一条边5 U- T) ?. h+ u; z
            {
    1 T3 e  A" N! C$ ~5 n8 F% J            if(q->adjVex1==v1)
    # }2 ^  Y5 X- Y( l- @; s2 d                q->nextarc1 = NextArc(v1,p);
    / c6 e% }- F/ M# [3 T4 r            else: r$ N3 z5 H+ v0 x
                    q->nextarc2=NextArc(v1,p);) U& {* N& J4 ^2 H
    8 E4 k! h- P) N
            }5 x' O. z5 H& |/ u' }7 t4 Z- S
            if(r==NULL)3 b% h8 k0 \7 W6 g/ |
                if(p->adjVex2==v2)
    / G: r* k* H6 V                vexTable[v2].firstarc = p->nextarc2;$ o; j' V0 E+ |. R1 M
                else vexTable[v2].firstarc=p->nextarc1;
    2 Q: `3 l9 k5 |7 P9 x: e1 [        else
    & J9 U8 y2 f- l) S        {6 v% B# P4 Z9 h) E: K  y' n
                if(r->adjVex2==v2)' I3 z6 p( Y8 b0 ?9 Y
                    r->nextarc2 = NextArc(v2,p);6 V8 B: |* F( s& f
                else6 |. G0 t  T! T- ~) c
                    r->nextarc1=NextArc(v2,p);' I2 D* p2 h! q6 R/ H  t+ b& {7 B
            }6 J& p5 n. w" o2 M) O- l
            delete p;
    2 B# F& o) ~! D7 j' g. X        arcNum--;4 Z3 }4 G, R8 k3 Z, N
        }8 w" _5 g9 M. Q
    ; X6 p: z: ?4 H$ P
    }, v) m$ P% W, h' G
    template<class ElemType, class WeightType> void: h+ V% Z! y  @- u9 f* F  g6 M; z6 s
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)5 ]0 y( t7 G; Q% j
    {8 _& Q3 z. L2 N, k
        int v;
    , }' s, _4 p1 J1 Y7 U) t( A    MultiAdjListNetworkArc<WeightType>* p;
    5 N2 j: l# i& I1 l    for (v = 0; v < vexNum; v++)//找到d对应顶点- D: H% j) {/ k- _$ d; s
            if (vexTable[v].data == d)
    4 h4 D8 m$ I& v. O2 N  L            break;
    ( k2 K3 [& h+ U( d' r8 a    if(v==vexNum)  E2 y! s1 h7 |- S* P9 s  I# Y
            throw Error("图中不存在要删除的顶点!");
    9 v9 k# _8 G& j: g* X) ^9 b8 |0 X+ F8 O9 y5 c8 c, D
        for (int u = 0; u < vexNum; u++)//删除与d相连的边
    9 }. o: W  G- N) l& `5 @* }        if (u != v)" J; o" T) `5 N  i8 u8 i
            {. h2 s& q% Z4 c4 I" Y  s
                DeleteArc(u, v);
    " P  V, ^6 a. ^  b$ _0 Y2 y        }$ Y1 u' a$ L3 g( D! @0 f
        vexTable[v].firstarc=NULL;
      S; D; F; H. G- F  i4 _1 ~9 r& C/ C
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    ! H* ~5 c# _- U) G7 d: {" S    vexTable[v].data = vexTable[vexNum].data;- [5 z" H/ ?$ m4 x! _
        vexTable[v].firstarc = vexTable[vexNum].firstarc;1 O. q" Z! d8 U! Z
        vexTable[vexNum].firstarc = NULL;2 s, [8 X  X) a. N
        tag[v] = tag[vexNum];
    2 h8 x1 C( A; F2 P5 I    //原来与最后一个顶点相连的边改为与v相连
    ! \) t' j6 W0 N/ S5 @' X    for (int u = 0; u < vexNum; u++)
    % D" {1 i0 @: r' a- k    {
    % f- n$ ]- ~- v& }9 d& D- G$ l        if (u != v)
    + ~! S- a+ [4 N3 m$ B, [        {4 ]7 f3 S) R, J  l
                p = vexTable.firstarc;/ ~; u5 A0 Q* H3 w" q2 [
                while (p)
    & y4 }8 U5 D( Y& ?( o3 C            {
    0 s; \1 {9 g& h7 e5 ~& n! ~" m                if (p->adjVex1==vexNum)! g! \5 }5 q1 [3 L6 Q9 v
                        p->adjVex1= v;; g; k5 C! @% ?
                    else if(p->adjVex2==vexNum)
    2 y& h! _* [6 C3 \2 T$ ]2 G5 x                    p->adjVex2=v;
      T3 k4 I, |) t1 L3 T  l                p = NextArc(u,p);
    % @1 H  ~' x. G. j            }- E* ^/ J0 T2 s; q
            }
    / e9 q6 m/ l3 b8 ]9 v; ]    }
    1 r2 ^0 f2 r* j. g$ P}$ n: `. Q. R. u; i- I' u
    ///深度优先遍历1 R. x) j! p( c
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    " i, S( s7 t8 M( [  W# _) O{' q3 J" Z' c1 N4 z2 q; ~2 h3 i6 e
        tag[v]=1;
    ! r. n2 b) J2 Q7 G4 T% M( J    cout<<setw(3)<<vexTable[v].data;, M  C! ]- J4 j/ K5 e2 `1 Y0 f$ [0 B' N
        MultiAdjListNetworkArc<WeightType> *p;
    5 \9 j  X3 l  }0 k' p    p=vexTable[v].firstarc;
    / W9 I+ D# r0 D$ P; |4 L/ f    while(p)9 o4 j8 e3 E- h
        {* g' O2 c" h) m1 l
            if(tag[p->adjVex1]==0)
    8 ^* D4 O& B3 |$ R$ G! ]- A9 s! x            DFS1(p->adjVex1);: T' `9 O4 o: ?2 q  T! r9 {
            else if(tag[p->adjVex2]==0)) L- a% W' J  n# J, M  h
                DFS1(p->adjVex2);1 c7 k, S0 p7 {9 e9 d, q% H
            p=NextArc(v,p);. e+ Q  @7 l. Y1 Q; H$ n3 a3 H
        }5 m+ g' y  [  f5 B5 Z# ?+ L
    }' X, ?% J$ K' J% M% l& r: ^! K; M+ f
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    . G8 V2 M, n2 K# Q% s{$ e! u1 K- q9 a1 A
        for(int i=0; i<vexNum; i++)8 S0 F+ s) j- G. A/ \
            tag=0;3 v# s& E+ C! \# j: n2 V# f
        for(int v=0; v<vexNum; v++)& M+ k  q8 J; |/ H/ Y" [- G1 `
        {# ~/ b7 }0 g6 y
            if(tag[v]==0)
    $ D) ~, V( U4 Z2 z            DFS1(v);
    ; q* J+ N  x7 y+ ~" x' |    }! ]4 g* c0 O. N  z
    }
    6 z8 Z) J% m: i5 |+ M* Xtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    , C7 W8 p. e/ N8 I; E{. \' \! y0 W/ n9 p2 l3 c- w
        stack<int> s;: B1 O, u, }# B2 N% |  ^# l
        int tmp;7 Z( X7 |2 b- E/ b
        MultiAdjListNetworkArc<WeightType> *p,*q;
    ! z. k, k6 p+ t+ |    for(int i=0; i<vexNum; i++)
    % I& x# w- i' Q        tag=0;9 N4 R9 p/ n. D  h
        for(int i=0; i<vexNum; i++)' ?+ g. E& _* r+ k6 G
        {! j( B8 b( A0 F' v0 v* X  D8 \5 x7 p/ C
            tmp=i;5 F& q% t& O, c7 S4 x4 a
            while(tag[tmp]==0||!s.empty())" G) V2 ~" {  d- s) B( i1 c
            {" V+ |; |: w5 Q$ W$ `
                p=vexTable[tmp].firstarc;% U4 t! ~3 x+ u* V4 n
                while(tag[tmp]==0)
    - P, L  X6 h0 |. a            {
    6 d4 V7 s: X& l                s.push(tmp);+ r4 A( p1 C: u4 G, B, A
                    cout<<setw(3)<<vexTable[tmp].data;8 }# J% E$ `% T/ b5 Z
                    tag[tmp]=1;
    ( M3 o5 T' }; v: l9 x                p=vexTable[tmp].firstarc;
    - ?& W, L4 K, I0 n8 ^                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    & ?" A$ K1 d) h                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);. |1 Z% _; s% O2 [7 ?. V/ u" S. i( |% l
                    //cout<<" 1st     tmp="<<tmp<<endl;
    ! H2 W3 r& o- I1 q) D+ S            }
    6 x" X2 Q- M0 e' W            if(!s.empty())
    ( n5 W+ H! ]3 g- W            {8 k4 u- \; R- d
                    tmp=s.top();
    ) H- _. M" `0 q! }6 u( Z                s.pop();
    % _- Z3 z; X% M" w8 w                q=vexTable[tmp].firstarc;
    ; U0 P8 O9 i* C- o0 A                int t=tmp;$ e6 A; d) u5 l! x
                    while(q&&tag[tmp]!=0)
    - k, P! x4 s8 {7 }. ?: E                {
    ' K0 t: V# Z6 M                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    ( |) r! {; ]& T8 c& s: R% ^2 q+ K3 d, m4 V                    //cout<<" 2nd     tmp="<<tmp<<endl;
    6 v4 |- s; J7 h                    q=NextArc(t,q);
    - J: z6 y4 N5 j$ t7 U                }! I9 h/ J  U  o" c% r+ m
                    if(tag[tmp]==0)0 e7 x2 U( _$ ~! \' n
                        s.push(t);
    8 S; N/ Z/ r* D! |4 H- R9 U" R                ///1、对应上面连通分支只有1个点的情况( ]7 C& ^7 U1 i2 T1 O2 i1 X3 h
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    - n; t, L! U9 e/ e& `' L- `                ///tmp要么等于找到的第一个未访问节点,+ k$ M3 ]( w$ Y+ E, O
                    ///要么等于与t相连最后一个点(已被访问过)
    # o, [, l9 B6 c                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点9 l( |$ n  b' U" b5 \
                }0 w* h+ A- t" p3 i2 I  l
            }: g& C; Y5 T1 ~1 s
        }
    4 f5 t) V: j. T' `}
    0 w2 J4 h: \9 ?1 y( m  x//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1; l2 p) l9 a+ R/ E3 l
    template<class ElemType, class WeightType> int- g: D2 c0 q, ]6 N
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    ( \) D% V1 b+ f9 e% J; h{
    6 |- A9 _; y3 @, `% O    if(head==pre)
    7 a8 C  @+ ]" j+ j5 l7 S        return -1;
    + L2 ~  ]( h2 g  Z3 }( b- y5 _) g4 r
      q  P& ~. g4 L& |" i/ f    MultiAdjListNetworkArc<WeightType> *p;& j, V$ R0 C+ x& l0 ~! h
        p=vexTable[head].firstarc;5 M! d$ @7 u% f/ V2 L3 L5 m6 @
        if(pre==-1&&p!=NULL)  A& @5 v6 x* ]/ d( g& o
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    6 K9 I4 H# U0 a4 K3 m    //pre!=-1&&p!=NULL! k4 \% Z8 H8 y+ F+ V2 ^+ i% P
        while(p!=NULL): W  ~2 n+ H6 b5 v. h- c6 B
        {& n: l9 ?' I7 a! d
            if(p->adjVex1==head && p->adjVex2!=pre)$ j( u8 G" g  G( y6 ]  r9 l0 E# M9 h
                p=p->nextarc1;- `1 ]+ y$ y0 @
            else if(p->adjVex2==head && p->adjVex1!=pre)
    ; A$ y! v! Z) w# W7 P. y# t            p=p->nextarc2;
    8 s# I3 Q1 A# |+ Y- b/ B7 n        else if(p->adjVex1==head && p->adjVex2==pre)1 E( G% Q: ?4 O) g* C) X4 e$ G+ a3 B
            {
    3 o1 d9 R" w- f! O" m9 D0 P6 T            p=p->nextarc1;$ C% Q! a9 V( ^" M$ L/ |& E( N3 K
                break;' w$ l1 g' q0 \
            }
    ( Q/ O; p# q" f        else if(p->adjVex2==head && p->adjVex1==pre)4 Y9 B" H2 U& O, ^& R* q# P8 M
            {, P0 J( c  T& s" r9 o! g. E5 c
                p=p->nextarc2;; _/ _& i* q% o& S, O
                break;& j& u6 {) L# J" I' E3 {0 u
            }
    & ^/ u, V$ O2 x  A4 n$ H1 z, X* l    }4 J- f! r- R2 Z- B
        if(p!=NULL)
    2 p; M3 f: b  G4 ~    {0 W; _6 m( h7 q, \0 d4 Q- p6 N
            return p->adjVex1==head?p->adjVex2:p->adjVex1;( T9 v! X) \' ]# n1 s5 Y( s
        }
    8 Z: p/ l+ R9 J    else
    0 o* I) |1 f6 L* ^6 {( H        return -1;
    : i. L& X* K" w}
    # @( E3 \/ e0 a' W
    + s: q/ {* z& K' ]  }1 f' @
    + V' t2 f, {( a; E: c. C7 E9 L1 h/ Stemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    ' ^$ F1 p. S2 z; Y0 \  M. e{6 B: g+ B5 G/ X; |2 H  E3 w9 K
        stack<int> s;
    ; c& ^* F3 i) o8 r$ n$ q# c    int p,cur,pre;
    : Z9 y) X) x: A3 L    //MultiAdjListNetworkArc<WeightType> *p,*q;  a. X6 ~4 F# K2 ^/ t, ?* L
        for(int i=0; i<vexNum; i++) tag=0;//初始化
    ' I, v$ j% W5 N; b
    - ?5 S3 y  J! m3 D5 V    for(int i=0; i<vexNum; i++)9 u5 s9 Q$ a7 ]2 Z
        {
    9 A, H8 L# \3 o0 A        cur=i;pre=-1;% i# e% |0 b6 y3 n* W0 n. M2 p
            while(tag[cur]==0||!s.empty()), |0 ?; w4 W: m3 _0 D1 N4 h
            {0 x9 |: D/ Y% K( p
                while(tag[cur]==0)# y  h1 _% N: ]
                {/ `% h' k' y2 S# L; l% o
                    cout<<vexTable[cur].data<<"  ";  _! S4 Y# |, z# P( G# q
                    s.push(cur);; D, ?' V' M) J- d! y
                    tag[cur]=1;
    8 ?' |/ x. }# ^& ?# c               //初次访问,标记入栈
    * w: C; ]. A4 D0 N5 F
    9 W) y8 M4 d% q/ ~! J               p=GetAdjVex(cur,pre);//p是cur的连通顶点
    8 I" Q8 U: U2 I6 e, `8 |. Z# u4 U               if(p==-1)- J6 y3 @4 Y+ n: @+ e
                   {
    9 D' u0 ^! b7 Z& d! [1 p                   pre=cur;s.pop();
    5 Q7 ]# ]' X7 G3 _, P, a                   break;
    7 @+ p% w1 f. W  R* d5 ^5 d! M               }* z- I; M; I( X
                   else
    9 I5 r# M' N# X! c7 U- C6 a               {
    3 W: p4 {6 _0 M                   pre=cur;6 s. Y2 [$ I. y/ W: S2 k; Y( r
                       cur=p;
    5 Y) s3 F' @. t5 {1 U               }* P+ }" R1 m* S: P( @% L

    : K# V7 m% \. v4 r7 H* s% D            }8 I% ~" B( \- `$ v3 {' g
                while(!s.empty())2 c8 f: R, R+ ]2 `
                {
    5 S$ P; p- D( b& W                cur=s.top();
    8 k; C! v/ x. a6 E; h                p=GetAdjVex(cur,pre);0 l! a# a: m5 I1 d
                    if(tag[p]==0); J8 D: F0 |8 f$ H, d, M$ N9 f
                    {: q# L4 R8 a9 p: b! b& e
                        pre=cur;
    0 g! D) o  j7 M                    cur=p;3 W" r& j$ H1 S, p1 p
                        break;# _, c5 |' S: K, p  U0 K
                    }  i' K/ m. A  ~- |8 W8 |8 }
                    else4 K5 z4 s% T. W
                    {
    , r# e4 v8 t) w0 O: |                    pre=s.top();2 y4 f% }$ p8 h, c. [2 j6 m3 c
                        s.pop();, ?4 d* Q& M" G' N% a( U/ D
                    }. |* P4 o& L9 T

    * ^) z) n8 d7 H            }
    , _( L. B% y& y4 ?8 ]- Y. X1 I3 {' `5 i* H
            }8 C* l* E+ Z5 S% f! p& {6 a( H
        }
    ; M& Q5 S9 L; ?' k$ q. ~/ N' p" W}8 v0 W) t. R0 @/ j6 E
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS(). {  z% u% Z' i+ o* E8 Q, ~
    {
    / b# O8 ]; y( c; \; m    for(int i=0; i<vexNum; i++)
    $ g8 H  P7 C& ^' L' F! O+ t. j2 [* Z, L5 ~        tag=0;
    3 Q1 {1 |" E6 H$ [# u    queue<int> q;$ K0 r' k" j, R  Z) V
        int tmp,t;$ J5 h; A' l) e; v1 b6 @  Y
        MultiAdjListNetworkArc<WeightType> *p;1 Y7 U% H" b6 w" J4 I, s2 M/ x
        for(int i=0; i<vexNum; i++): W( P( g, a* r- j2 E: ^. m' W
        {* u8 E4 E* R) I  I' T! B
            if(tag==0)
    / y0 D4 W$ k5 _$ B$ {        {: D7 l8 i* i. H' `
                tag=1;3 g% u% ~) g5 l4 Q8 Y& z" g+ u
                q.push(i);1 G7 a6 T' k' H# K
                cout<<setw(3)<<vexTable.data;7 G2 h$ W( [' q" j- m$ M1 L
            }$ ?/ Q6 o6 M. F, W6 q7 B8 |5 A
            while(!q.empty())
    - F9 a( g: H2 W1 [# c        {
    " ~$ B# X% z/ D/ {6 M            tmp=q.front();; o, I. h- v* s: v# Z% E4 I
                q.pop();
    8 k' M0 A! t) X$ p' Y6 g            p=vexTable[tmp].firstarc;; `  N3 {  y: z; `; w( s9 i" ^
                while(p!=NULL)
    ! [7 H1 A# l! x7 I2 @            {
    ( T$ |1 X7 P% t                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);& O. e" k. l6 ?& @5 D
                    if(tag[t]==0)
    # D/ z8 g: ]- c/ y$ a( |* M                {& ]* Q. e: G! h% g- e; ^' z  P5 k
                        cout<<setw(3)<<vexTable[t].data;1 G% u# R* ^/ z8 q% E2 I5 E
                        tag[t]=1;5 v6 G+ e" L3 ~/ I, C7 k
                        q.push(t);( I! o+ i- Q8 Q( M6 c
                    }
    ! G6 B7 \+ S5 m* E, ^2 E                p=NextArc(tmp,p);: i& H1 u- U; @/ ^5 E# }
                }" I0 s" ^/ i7 q6 W
            }, }8 m5 ?$ ]2 }! F* z! s' B
        }" |& U' x$ N- Q9 S6 p
    }- Z1 d- a/ G. J; o- l
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    ! U3 ]6 M4 y9 I( W! m; V: [/ T( y{3 B" H* O6 I7 ~
        MultiAdjListNetworkArc<WeightType> *p;
    / V) [0 i5 I/ P8 k0 w0 |3 C8 h    cout << "无向图有" << vexNum << "个点,分别为:";( ~" h- e0 t  R
        for (int i = 0; i < vexNum; i++)
    * C2 G8 k% ~! Y! Y9 t* {        cout << vexTable.data << " ";
    1 q- B: h$ k# s% V9 ^    cout << endl;' L- j+ l3 ~; j, g& _
        cout << "无向图有" << arcNum << "条边"<<endl;
    & ]- |  E+ u: G    for (int i = 0; i < vexNum; i++)
    ' T$ h4 M0 O! Z    {! E7 k5 Y( ?. ?! [
            cout<<"和" << vexTable.data << "有关的边:";& r4 l+ N$ b# I2 a! W
            p = vexTable.firstarc;
    & N) M+ y# U1 v# [* b: F, o( \        while (p != NULL)
    $ D9 v8 r& L. @: r6 V. W( f        {
    / u: c1 z/ |5 S: c- C5 b            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    0 P. C9 ~- b; V7 p! h            p=NextArc(i,p);/ B; j4 U$ m4 S3 A8 |* x7 j
            }& d8 I9 r7 {/ X4 H# s
            cout << endl;
    0 R$ d4 ^. ~0 K    }5 w+ j1 `& [& E1 p' O
    }
    " K0 I5 X7 o6 W+ W  N6 ^/ l+ t- D+ K; o. ~# G9 v/ k* n
    9 z1 h3 x5 i3 J* X. Z. X3 D& k
    邻接多重表与邻接表的对比
    . M' L9 I* o+ t1 n( G, Z4 V- A0 v  X3 b0 a* W
    邻接表链接
    $ n/ o( \5 p/ m4 S+ J6 \/ f# x3 |2 ~在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    " ^$ @& U; h$ }0 {1 i- h" I在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。& h# E1 u# p. ]7 G
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    3 \  k8 v/ C1 n; b& T- b, T————————————————
    7 B) S: |! i* v, Z2 `版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    5 T3 B# C) J' X% ?原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669584 ~$ o) @. u3 Q
    - d! e3 o7 \  s- X$ G' T( l! r
    6 l0 X8 n2 g- [* a
    ) _. m1 A3 \5 c% c

    4 K; f# Q8 D, a; _————————————————
    ' i0 C" d0 ]8 }8 h1 n3 q- z& O. p1 ^版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。" V3 X, U9 Y0 c. L' |) L+ F1 E
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958; B1 E' [/ @. E5 v1 Q6 n- y
    & J4 o+ ]( Z2 U/ G9 p3 {

    $ L& x7 ^9 j4 r* y7 e% n6 g' p
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-7-25 17:31 , Processed in 0.498523 second(s), 54 queries .

    回顶部