QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1386|回复: 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 K2 {" D# [& m& N/ X2 u
    图的存储结构——邻接多重表(多重邻接表)的实现
    " r! o2 O1 g, F: a$ G1 X/ U+ {7.2 图的存储结构! ~0 _+ r% n1 B& a' a
    ! m, s& b' c& Y* i
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    * m1 d- f) z& O. w* }, ^# A( K邻接多重表的类定义% r: B* `8 _8 N) T" b
    邻接多重表的顶点结点类模板( ^7 [1 X$ _$ p1 M% Q% u/ W2 g
    邻接多重表的边结点类模板% V& S2 z, d7 Z" s8 A! |) C
    邻接多重表的类模板
    # J- o  ]* j. K0 x3 O邻接多重表与邻接表的对比
    0 d9 J1 t$ d( G) L7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    0 G8 A/ y7 g5 f  U8 ]: ^
    - S2 ?9 m! n5 r在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。& g3 `  V# H8 a6 p" i
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    , X4 M( W3 @( [) ]- D2 d# f
    ' @. U3 F$ X4 h* @! N邻接多重表的类定义
    # [5 r! [8 L7 x# e6 R 1.png
    $ s+ F$ }8 t. Z& k邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:0 O5 q4 j/ \3 [" u# O1 H2 ?
    data域存储有关顶点的信息;# f: b7 i+ C! W# n2 p% Q
    firstarc域是链接指针,指向第一条依附于该顶点的边。
    ' n* }& i; }! Y6 D+ R所有的顶点结点组成一个顺序表。


    3 E# o1 n. J$ n- P0 {8 u, J8 `7 w$ G# V; [# F: g) \
    template <class ElemType ,class WeightType>
    % c' t8 z5 k; d" N) ~' Fclass MultiAdjListNetworkVex7 ^, J7 h/ r- Z# T, O
    {- H9 ]$ ?8 i8 W: @+ ~% t! V
    public:
    - X7 ?" @( P, m        ElemType data;
    4 r/ S" b2 j0 e/ E* S" F# m5 D, _7 P        MultiAdjListNetworkArc<WeightType> *firstarc;' b! X2 T1 {+ D1 x3 X+ [8 G8 D( e
    ; k& }* {0 Z/ K
            MultiAdjListNetworkVex()
    . X; e$ a* |" z% t  v4 J0 C        {
    ) e" h1 C0 T! L, V" \! F" z                firstarc = NULL;+ u0 S; m$ M* z7 T! h
            }
    / t6 ^6 T, Y( j        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    , b* C: R3 Y2 w" D! r/ [* Y        {
    2 o( ^+ F' Y+ p+ A4 N8 r                data = val;' }5 R/ t) \/ p* z7 L
                    firstarc = adj;+ M6 l/ r+ P8 A: M) R& _
            }) w, @0 \# J0 w5 j+ g# z
    };
    . l; ^" I8 A/ h9 y. d, G) J2 H: v: B
    ) R7 X/ I7 U5 s! p7 A# N! V邻接多重表的边结点类模板, Y8 P' ^* H7 A" n7 B

    $ t3 e: L, v( l) S! e1 m3 Q% g在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:* |- l( l6 W; K/ l( o. g) J3 Q1 o
    tag是标记域,标记该边是否被处理或被搜索过;
    : F- E5 \3 M8 x( Q1 X$ p% v: s5 f+ Iweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;! Q- {1 l4 J" g" F" U* T2 _; p
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;2 t4 L) F4 M% P3 o8 V
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
      k/ V" K* f: d2 n# n$ F5 p8 o* c; f# R( K: p" Q; B6 i/ W
    2.png
    % B; H2 J! O# M  jtemplate <class WeightType>
    ! B; C+ S, w$ Cclass MultiAdjListNetworkArc
    $ f+ m2 `4 L+ A! T0 `{" G& q5 ^: M$ i- b
    public:
    ' n: x- L7 r7 q    int mark;                                       //标记该边是否被搜索或处理过
    / D3 y. \8 z' R$ k8 A( V        WeightType weight;                              //边的权重
    ) G0 {( m  D9 m        int adjVex1;                                    //边的一个顶点8 {" `& B$ K( c  a4 a& V! S
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-18 m$ C/ z: b( r! q; h# k
            int adjVex2;
    . d1 \' |* o( l% l* R* s! V! v        MultiAdjListNetworkArc<WeightType>* nextarc2;
      X& {/ H9 I: ]% \1 @, U  ?( n; O. r& k
            MultiAdjListNetworkArc()
    5 t4 d9 C, L0 H5 l* g! N        {, Q( D4 }# N& N# E( t4 R/ @, k
                    adjVex1= -1;
    1 S: q6 _* C% T' |& e, ]                adjVex2= -1;- O! \! ]0 Q8 x2 x1 N5 q4 f7 f" U
            }. J3 y3 [' M( \  k" s. {6 O
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    0 l% l- T1 |0 z1 W$ l        {
    0 ?" ^# k6 K# ~' B/ m                adjVex1 = v1;       adjVex2 = v2;5 _' B0 @$ j- e' z; k
                    weight = w;
    0 Y/ N# I  a9 L( x8 V                nextarc1 = next1;   nextarc2=next2;
    3 ]2 E& A1 h9 G0 t6 q2 n: n                mark = 0;           //0表示未被搜索,1表示被搜索过
    " u/ `9 v* I6 R6 r+ v4 r9 G        }
    8 j7 ]+ L4 E7 h) T& Y( {
    7 n- b; S* u( b5 F5 ~/ |邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    4 [+ P! T7 M0 V: C$ p0 {class MultiAdjListNetwork; Q8 `/ r  @" x. J
    {7 `! S' {$ m) M0 f
    protected:
    1 H) m% [" ~/ ^6 F2 ]1 o( e    int vexNum, vexMaxNum, arcNum;; m0 O. G) r/ {, C
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;6 S% ]% a: v- g; c& C. p
        int* tag;
    , L/ P- g' n: Y5 Z    WeightType infinity;3 I3 R+ B3 Y/ D/ z
    / l; m3 N( |, l0 X5 l
    public:
    6 L9 o  y# w# h. s: m' N    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    6 Z- I- Z/ ?0 O. }! `
    ) v2 N+ o" q. Y6 O3 Z    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);0 U5 Z8 E! `7 R! |
    9 X8 k; Z& M5 J
        void Clear();
    . c5 c; S- Q' {/ M! F  G! b" D* n" I    bool IsEmpty()
      W9 T' d0 T! o. `, W    {8 Z, r* `8 w( F, ?  A" x- z
            return vexNum == 0;
    0 q6 o- Q8 z+ w, e% A* Z    }5 x) h1 e) i8 u! S6 x
        int GetArcNum()const
    - H/ T% t/ d& ?    {
    ! I+ n5 l3 o9 [' }0 @; F        return arcNum;5 f5 ?4 c( W$ @" ?
        }+ M1 m; S# q) g2 m9 |: ?( C' ~6 O
        int GetvexNum()const) j9 R; Q" l7 s, _
        {
    8 W8 @+ x: t& E6 G: C8 |% q3 X9 ^$ C        return vexNum;
      B* f- l# K0 E; k! g3 k    }
    - r2 P" R7 ^2 q! [7 L: y2 T5 h

    + Y$ K# [9 S3 y" t/ g& }    int FirstAdjVex(int v)const;
    % H4 \( d3 g1 {    int NextAdjVex(int v1, int v2)const;
    - N0 }% q& ~+ K/ \0 r9 I3 [    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;! z( p2 k9 f2 a4 P* `
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    $ G& G  j, {1 J, b5 V7 R) D) u3 c2 X8 p6 V% J' z! U" E3 t/ }- L
        void InsertVex(const ElemType& d);
    * _# c. H1 v; R1 c    void InsertArc(int v1, int v2, WeightType w);$ N+ t( R$ H( e* E$ I

    3 \) w( X1 r& W    void DeleteVex(const ElemType& d);6 I8 X( ]: C9 x
        void DeleteArc(int v1, int v2);
    . ~$ U0 W* }8 [# s7 U. ~# Q8 r1 p3 E. _5 P  z
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);  t9 T! T1 s' w
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);+ S) k; {$ |/ {3 ]2 f/ W
    " U  H, q0 r( W( B/ @
        ///深度优先遍历
    + w8 d; o$ l" k    void DFS1(const int v);
    , X3 \  \2 I  ~; V    void DFS1Traverse();
    ( G! S1 h% ^8 `+ V    void DFS2();
    ' ?1 p' `. w$ v1 I$ i
    ' W* G2 |2 w3 L, }    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    - g/ V) [/ p8 K7 L& a! {. v& e% J    void DFS3();/ H3 w8 C% G: h/ h

    # S' w! E6 d2 m! n6 w1 Z9 T    void BFS();
    4 X8 k+ q6 O; |/ x    void Show();% d% o+ h7 t, R
    };2 \7 ^! y- l# P0 G( R; U+ M& |; Y
    " {" P9 k0 E" z( z7 |
    2.函数的实现0 l6 ^0 a1 B0 D0 C- U8 ]3 H" M( z
    研讨题,能够运行,但是代码不一定是最优的。5 B/ y2 j- g: Q% b, Q; f& E

    ( p- O/ R1 d4 b/ A: @* h#include <stack>, I4 Y* x0 `/ w$ g8 L0 s/ m8 n
    #include <queue>. @+ m) v. ?4 C/ K  n7 `
    9 U8 ~) v) L6 i2 u7 L  v
    template <class ElemType,class WeightType>
    $ V* H- {8 b2 N$ L$ a6 F/ I+ s& I7 oMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    6 o( @/ U! B9 P% x; R& Y{9 ~6 t' k5 m2 n$ ?9 F8 M4 `" c
        if(vertexMaxNum < 0)
    # W$ g1 X( v4 R1 N        throw Error("允许的顶点最大数目不能为负!");
    5 K- h; p" `; j8 R9 L    if (vertexMaxNum < vertexNum)* R2 @( N; G9 c% L* A& {# x
            throw Error("顶点数目不能大于允许的顶点最大数目!");
    4 _; v0 P1 k' k3 O    vexNum = vertexNum;
    0 T3 b- t( `( V! _$ b    vexMaxNum = vertexMaxNum;
    . d- J) u- \6 }/ s; v/ \$ Y) r    arcNum = 0;
    , t3 S: y( k* `' l    infinity = infinit;
    . g, w! e6 `) T    tag = new int[vexMaxNum];5 E( K4 ]) N: h/ B
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];& \' U$ Y) f2 d' `( {/ ~. j
        for (int v = 0; v < vexNum; v++)
    % {/ ?' x* g) `( m9 u    {
    ) F8 q  N; O4 G/ ~# r: k        tag[v] = 0;% z: J0 J# v% j; I0 C! @8 J% @
            vexTable[v].data = es[v];
    $ o( e7 x( U" H( s1 W) x9 H8 Z4 h        vexTable[v].firstarc = NULL;7 m; o, A$ h( M- i/ c
        }
    2 c) ]+ _2 T, C, c6 @}* m# p+ d9 ]! r2 F
    template <class ElemType,class WeightType>
    , M4 {4 C0 U( M0 C9 n2 K0 l- MMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    ; J8 @( f4 v. B: {$ [! a{
    % ?" L) q4 m5 f+ u$ k7 w6 g* \    if (vertexMaxNum < 0)
    " k' U+ `  E3 ~, e5 t        throw Error("允许的顶点最大数目不能为负!");6 b3 g0 k1 g) W1 Q& t4 ^, _
        vexNum = 0;
    0 i% w: b4 d% A- Y6 I8 b8 G( M    vexMaxNum = vertexMaxNum;
    . Q9 N  f, D3 a% c6 [    arcNum = 0;
    ' I* v5 e: z$ C4 p+ p& D; A3 u    infinity = infinit;
    5 L( b" q; S9 C' c7 o    tag = new int[vexMaxNum];& J6 z; R5 U3 H! u9 c# i0 O# ?9 b
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];/ |6 W6 O+ r8 t# m1 w7 g( T
    }
    + F, M6 Z3 M, b" G; B2 J+ Ytemplate<class ElemType, class WeightType>: C9 b8 A) W4 g. u' c
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    6 k, g2 A5 U+ f' K, h/ ~$ K{
    % ~# n; ~6 X$ v' K# }4 Z% b    if (v < 0 || v >= vexNum)" O' ~, P9 H) [8 U
            throw Error("v不合法!");
    7 E7 a  D; W* C1 J5 |% T' |+ y& m    if (vexTable[v].firstarc == NULL)
    ; G) E# ^/ S7 @4 U& i% n* C1 J        return -1;
      u5 M4 G# O: ~& n% R    else
    : \5 w) _1 a8 ~) b% ]        return vexTable[v].firstarc->adjVex1;
    2 o5 Q  y0 S3 B5 y: k7 }2 k3 p}5 Z0 B( p( k9 s( W0 v( }

    3 L) S. N  e$ D) S1 A8 Itemplate<class ElemType, class WeightType>
    - }* g# p" g0 F* r; k: I4 ?int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    ; D5 ?& l: r* N. h, Z{' k3 D: C+ U  q2 g
        MultiAdjListNetworkArc<WeightType>* p;
    3 ]8 ^) `3 L, O- O* h% {    if (v1 < 0 || v1 >= vexNum)( {6 ^# z) p. B; E3 B; x( c
            throw Error("v1不合法!");
      Q( y9 @9 |+ d    if (v2 < 0 || v2 >= vexNum)
    # N* @7 \3 b6 _: k" A        throw Error("v2不合法!");
    2 T7 Y8 c* P" R) w) c  Y    if (v1 == v2)
    9 ~- d* L# y# a, F/ o) P        throw Error("v1不能等于v2!");. S" H# ^, r) ~) Z* L
        p = vexTable[v1].firstarc;
    9 L7 r4 m/ J1 H' h+ D! T    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    % i% s4 `( Y8 i) X( Q$ t1 l        p = p->nextarc;- ?% F, o" k# s% F3 ~6 l. U8 K
        if (p == NULL || p->nextarc == NULL)# Z: U  ?3 q: F: ^# G
            return -1;  //不存在下一个邻接点
      E2 s8 O2 x: [8 z3 V    else if(p->adjVex1==v2). W$ t' x+ c: N3 d' [3 a1 p. ~
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    / Y. o' m9 C+ ?! c+ P! G' i) w& t    else
    ; \9 ?6 K9 C4 W        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    ) i! e  ?$ _* q! v}: l0 W! G4 a/ Q. x
    template<class ElemType, class WeightType>% h7 `8 n* O+ g. J$ [4 _9 A! f
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()
    $ I% t% r& T+ I: j: W. v{
    - g4 X$ H0 ^1 ]( {6 P+ J% F    if (IsEmpty()) return;6 }# V' q5 w$ X& l! T1 x
        int n = vexNum;' [! U! K7 M3 Z2 j1 _+ F7 M- B
        for (int u = 0; u < n ; u++)
    ! I5 u- |8 j5 B0 R) d6 P) x        DeleteVex(vexTable[0].data);. c  h1 c2 z( J
        return;# W2 z# D+ L! T8 j4 r
    }! f! ]# ?! G3 J) g/ z4 c) R; P; A
    template<class ElemType, class WeightType>
    * h7 h+ A& s# Y1 X: k: F: @1 jMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    # h) A7 O+ u: f! k3 A6 R, n{
    ' {$ a  ^8 p. S5 }    Clear();$ H# U- L5 U' n3 I, C$ `
    }+ ^) B, E) O; a6 v1 d4 V
    template<class ElemType, class WeightType>% Z# ^! Q* h, \0 w" w9 [7 h2 I. j  ^+ }, b
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    - Y# X6 Z9 q9 {' A. |{3 X: w# A$ b! ?# v2 J% o" u8 Z
        vexMaxNum = copy.vexMaxNum;& L1 e9 r; A, f
        vexNum = copy.vexNum;
      r1 A" v! m3 s" ^, S' a! Q, e    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];( `$ j5 i/ d3 }- i7 M7 D& L
        arcNum = 0;! Y& C% Z: h/ r9 T7 l" r
        infinity = copy.infinity;& s1 X5 F  j3 @5 Q5 P
        tag = new int[vexMaxNum];+ Y9 T0 v+ @* S) t! [5 h
    : O- b! l+ t' @
        for (int v = 0; v < vexNum; v++)
    : R7 |" z* w2 W0 x0 H* Z) o2 P    {4 M9 w: W5 t5 B& h
            tag[v] = 0;
    ; f( \  U: B, O3 f' s        vexTable[v].data = copy.vexTable[v].data;
    / @0 ~+ ~3 m$ J; i& |+ X% O/ b* \' J        vexTable[v].firstarc = NULL;1 z# z$ D- W- d1 o- {% w
        }
    + d, _; @8 J3 o: r) ?    MultiAdjListNetworkArc<WeightType>* p;
    2 c: W$ v  u) ]" a" p! R7 A& w5 N6 F
        for (int u = 0; u < vexNum; u++)
    ' |; `0 w& o% ]    {
    3 z1 U( Y: z6 u  a5 ]7 `+ |        p = copy.vexTable.firstarc;
    6 h1 e$ p) i8 N        while (p != NULL)
    0 O# X; J7 ~0 E5 r6 Y        {
    : K) K/ |4 R0 R. K& n            InsertArc(p->adjVex1, p->adjVex2, p->weight);
      U( ]! ]+ j; ^1 N; E            p=NextArc(u,p);
    7 z& O6 d$ O2 E: m5 b" F, e: e! W6 G0 P        }9 X, ]6 c* r2 C) x
        }% J- p9 k! P" l: x$ K% [; B2 `+ C
    }! s2 q, ?( E( s  `. G, B
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&: y! ]6 c: c' Y. X7 `0 e; r; V
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    ) R/ H( d3 G( r, ^{; J0 l& t; Z4 o. C
        if (this == &copy) return *this;
    : r0 }/ @- _. e) u. d5 E    Clear();9 }, H- [4 L6 Q
        vexMaxNum = copy.vexMaxNum;
    & \1 C; ?- W4 C# P4 F6 R: t( t( ?    vexNum = copy.vexNum;5 h" n: q* E! A  C; Q( K4 Y2 r& D
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];0 p) B6 A2 U; K; @
        arcNum = 0;! |" g, A" g5 g. l
        infinity = copy.infinity;
    7 S: C, K- s7 d2 K* q    tag = new int[vexMaxNum];
    2 B/ ]4 A5 \3 T& o
      B9 z# q/ i; O  ^8 g2 q8 c: w    for (int v = 0; v < vexNum; v++)
    7 M6 {) q2 f' E) Y* |) h, i    {$ l0 v$ {) R& t" C
            tag[v] = 0;
    : \9 ~6 v  P$ J) Y4 j; w. y        vexTable[v].data = copy.vexTable[v].data;8 X0 L9 ]1 [: S, H, ^0 F
            vexTable[v].firstarc = NULL;
    $ c, S, S/ |1 q! ~    }
    $ O" O! q. V, `    MultiAdjListNetworkArc<WeightType>* p;) s- v1 @( L6 G8 {! o  J* M

    % @3 R4 G$ r! e" h' x    for (int u = 0; u < vexNum; u++)
    . L3 I, l7 S6 h: }    {
    + A# F, T; p/ y' z7 u- T% ~* b        p = copy.vexTable.firstarc;" }) T7 j% z8 H/ _
            while (p != NULL)' f$ F! f6 _& E4 D# w+ A- }
            {
    0 Z3 I' @& m- T3 N) B( Z            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    ! m% P8 |) ~7 W% P; g1 t0 D            p=NextArc(u,p);
    ' ]# g7 ~$ s3 S% N- V        }; v$ ~" S6 L2 o  H
        }
    + g9 i( X) _( D0 ^! y4 C1 \    return *this;5 a( a# H  W% L9 [% N" Z% i* I* z5 V
    }
    1 }/ r  x% m) P( Jtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*2 K8 a5 f) C* H5 N$ `' [
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const4 I3 C% f: i# J6 E5 s1 m
    {
      ~" T" }2 [( O: C    if(p==NULL) return NULL;
    0 g& j7 h3 d$ R. l1 J0 g) H* O" d    if(p->adjVex1==v1)# \+ L3 x3 A! j/ R% ^
            return p->nextarc1;; ~& X6 [. m3 s: j9 f
        else
    : g& y) t6 H9 h4 k% f/ D3 W        return p->nextarc2;
    ( |- H6 L% C, r: U}
    3 o- ^" l5 h7 T. B2 x7 Mtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    # l9 y% l% A! S& RMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const6 B9 g% T8 y0 d# |5 ?: X1 W
    {2 A1 Y7 Q% _7 a, @% F% R
        if(p==NULL)return NULL;
    + N2 P  s7 O; S. s6 i. g    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    0 k1 \6 `' x" ~5 U/ L7 j5 j% U    if(q==p)
    5 C; V% H' P! u: A) ]$ u        return NULL;
    - P  m; j! F) q: K0 _8 \+ d! l, I    while(q)
    . r- n  e3 ?, }5 O$ W- x) N    {
    % _7 C6 P9 r" h2 I        if(q->nextarc1==p ||q->nextarc2==p)
    ( W, K$ [! R/ m7 }8 `0 R            break;* w; u2 ~9 @) a5 f: v- D
            q=NextArc(v1,q);" O6 Z* C* n2 u) Q5 L
        }' M( j- @, n! t. D
        return q;% x9 q9 R  P: X1 C' Z
    }4 z* `* R; k+ T4 j* U
    template<class ElemType, class WeightType>; c4 g7 ]/ S6 I/ z: `7 r. ^
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)" b8 `$ Z* c$ g. i8 d
    {9 H8 n; M# s- Y, H3 R
        if (vexNum == vexMaxNum)3 J# r+ H* f. V5 l
            throw Error("图的顶点数不能超过允许的最大数!");
    2 @+ }- B0 \8 K    vexTable[vexNum].data = d;
    $ [  R) U8 `8 |% {& E& R- j. Y# f    vexTable[vexNum].firstarc = NULL;" M& S2 Y4 a$ T
        tag[vexNum] = 0;$ `0 L) ~# Q# `# P7 n2 T
        vexNum++;
    & d/ I7 d/ _( L# G. X}; Q3 [$ x" `# E; A( T, h1 G% n
    template<class ElemType, class WeightType>
      `0 J+ F1 ]. t- F8 ^. v' Ovoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)3 B' |+ G' Z6 s1 @; b8 d1 I6 S
    {
    4 t9 F- G, Z# ]    MultiAdjListNetworkArc<WeightType>* p,*q;
    $ x* K6 i. g/ n    if (v1 < 0 || v1 >= vexNum)& o1 X7 s( h/ w
            throw Error("v1不合法!");' q- Y: G+ P3 h
        if (v2 < 0 || v2 >= vexNum): s& C0 F* o1 r1 Q9 P2 y
            throw Error("v2不合法!");
    7 V# C$ c- r# Y8 |& Q9 D    if (v1 == v2)! a+ x; S" r6 ~/ D& F8 g  D
            throw Error("v1不能等于v2!");
    : F  p- u" d1 B& z# B7 p  v: k& u6 n    if (w == infinity)8 ]! w  b+ Z% H6 Y3 X! t3 `1 r
            throw Error("w不能为无穷大!");( P& X# }; p4 j. V& t

    6 P  o8 f5 ?" z# |* m+ n# Y
    % v- |; o; l# S7 z- @/ U    p = vexTable[v1].firstarc;
    # U8 x& h2 d- H7 m4 l' S    while(p)# Q" V/ Y' j: }2 }) B4 Q* J, g! |. o" o
        {
    " ~/ S* q, x! Y        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中' ~$ q  c* `- g( B9 m
            {8 _7 H9 G0 d2 `- V( o: N5 g' Q
                if(p->weight!=w)
    1 H; W$ G  O" r# Z  f7 S                p->weight=w;
    2 z6 ^; |7 @/ \6 U3 _            return;
    / j% _* |9 ]! A  b        }! b4 M2 R1 l% R

    3 N6 \2 [' f4 |. _) c" {) w        p=NextArc(v1,p);" @' [4 X  @& h3 L4 E( p" n
        }
    4 f6 G! i' o" q* D$ ^' P: n    p = vexTable[v1].firstarc;+ C' E2 B4 I! K: w; r  S7 @
        q = vexTable[v2].firstarc;
    6 b+ `. G# ]8 V! G3 Q    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法" z3 d8 v; q8 m/ Y
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    . M2 J" M% n' K! ~1 W( W    arcNum++;
    0 b3 B9 N- w0 e2 l}! P+ s+ O$ }1 n4 A" y
    4 G. S  U; `, \) o! v0 F
    template<class ElemType, class WeightType>
    4 ~" `+ F! P, [" H- K  M- D$ Evoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)1 }& y! ^6 w. x9 r6 d
    {! A. y( r1 o7 e% G% o
    ; H4 Z9 g4 f' v9 X1 K
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;1 h* V; k5 T: Y  x2 Y) t  z+ B" `
        if (v1 < 0 || v1 >= vexNum)
    1 S# X7 Q  X$ c1 T. S, Y8 J        throw Error("v1不合法!");
    , f3 g9 m4 ?2 P    if (v2 < 0 || v2 >= vexNum)% X- `4 L  h# o0 q, E9 l; e
            throw Error("v2不合法!");
    6 q0 J0 r/ s$ p1 B7 Z, A& I* x% t. P    if (v1 == v2)
    4 A0 {& Z! g% R5 i3 ~        throw Error("v1不能等于v2!");9 f& A' j9 ?" q7 m2 G

    5 B& T* A! s* S( Y  C1 a4 I    p = vexTable[v1].firstarc;2 q9 o; H. w; _1 n' ~( [
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)) N! y% j  H3 d& g# z! s
        {
    5 {* n/ y9 k& u8 J        q = p;
    9 L& s4 |8 F- t, X/ x, q        p = NextArc(v1,p);
    6 N& G! L. ?/ p  S7 c    }//找到要删除的边结点p及其前一结点q& S: s$ {9 t4 M+ ~3 }' j  D

    5 A, |  m; T! G& d7 }+ r- @    if (p != NULL)//找到v1-v2的边7 R" e, e0 f" K0 P+ t" z+ a! Q' W5 E; M
        {
    ( ^2 C% T$ ~) l5 s& [9 C        r=LastArc(v2,p);
      {. ^" t, c, u: a        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL( {0 B  A' f$ g
                if(p->adjVex2==v2)5 e; N* H" P" H7 C$ Y9 C
                    vexTable[v1].firstarc = p->nextarc1;
    / R  ]- V4 E, Q! i8 g7 V            else vexTable[v1].firstarc=p->nextarc2;
    - @9 V# h( D% `3 V5 b5 V1 U        else//不是第一条边
    1 N8 B( x% u* ~' L; C        {
    - u1 v/ i! u4 i7 j, i            if(q->adjVex1==v1)
    % [( |5 R- G  T. D3 x$ m                q->nextarc1 = NextArc(v1,p);
    ) H0 n# r! W# C9 a% Y            else8 r' s- t6 w* v& O
                    q->nextarc2=NextArc(v1,p);
    5 z( Y  f$ |0 }6 ?, r% S# T, J1 J" `! x) s5 S
            }
    9 R/ \0 S- B% s2 X; [2 l' x        if(r==NULL)6 {& K5 C" l# E8 b* s
                if(p->adjVex2==v2)
    ) u, ]* Z! a1 p8 }( m& j5 W3 [                vexTable[v2].firstarc = p->nextarc2;
      y) Q$ z: E+ L: ^            else vexTable[v2].firstarc=p->nextarc1;2 @4 n2 F! M0 ~" s
            else3 j' w, _* h9 m5 T4 Q) S# {
            {  E. t+ L* f$ f( S+ j' i9 o
                if(r->adjVex2==v2)+ f" l: m- R) E% _) B
                    r->nextarc2 = NextArc(v2,p);8 L4 Y1 B& T9 e3 l7 V& Q
                else
    6 T; J# z0 V3 F% h" T: K2 Z- j                r->nextarc1=NextArc(v2,p);
      s1 z2 I( D+ p3 l5 z6 K" u        }
    " B/ \0 U3 }5 \2 S" h# W        delete p;
    8 C  y1 J% R( i- r( `, S$ \2 Z        arcNum--;
      l3 t0 ?3 H8 w- M3 M: v    }* y. O( r9 }3 D6 M

    : N' W" S- q% u3 b7 m" p}3 L( k7 d8 z8 F6 ~) P
    template<class ElemType, class WeightType> void
    . E; l1 {/ L& [& t: y( O: cMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    ( O! m% S3 v% u' g{
    * `6 b8 Q" e! {* ^- Y    int v;2 Z2 M) E7 I: u0 a
        MultiAdjListNetworkArc<WeightType>* p;& v( |; J/ ?; z6 K! u
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    $ _( M/ C% j  H5 t+ P. z9 F        if (vexTable[v].data == d)8 ]+ x  P4 |& H, v+ s& V
                break;9 n7 I  @( |$ ^  M3 Q3 ?
        if(v==vexNum)/ I+ U! B4 H: x1 x6 H; {: c
            throw Error("图中不存在要删除的顶点!");
    + Y! m1 S9 ^* @
    5 j% x/ N0 ]# f9 c1 w2 R    for (int u = 0; u < vexNum; u++)//删除与d相连的边
    0 F& i' }* ]9 y        if (u != v)" V& a, s" Q! Z. `
            {8 G. V8 m8 o8 i& c8 ^3 k
                DeleteArc(u, v);
    3 b4 t& y1 }6 P        }: B8 g3 `- g% y- i0 |' {& [9 q
        vexTable[v].firstarc=NULL;' k$ j. g( \0 @$ t4 A. o* d0 w

    ' i1 ?0 N$ P* q7 V" R    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    * I* @4 u3 l7 [. P% E% `    vexTable[v].data = vexTable[vexNum].data;
    " A1 [7 O0 t. {3 V    vexTable[v].firstarc = vexTable[vexNum].firstarc;
    - L; B- O( q& S+ J  d% y( r9 N    vexTable[vexNum].firstarc = NULL;
    ! O1 M- w- P8 {0 X, o! J0 r    tag[v] = tag[vexNum];
    " C6 T* ~5 @! ~, A1 y  o    //原来与最后一个顶点相连的边改为与v相连& w* e) v( K$ B& u0 d, B: y
        for (int u = 0; u < vexNum; u++)  a- u) E  `0 n/ P: A
        {
    , J2 p4 `) R- b        if (u != v)6 s6 e5 N& g9 H- h- W0 I8 u
            {
    5 E2 x3 }8 Y" ^. o1 Y  W            p = vexTable.firstarc;
    * Q; _  G. ]# u, s; S) H6 x            while (p)* J( P6 y0 v/ o3 z7 d6 L6 |
                {
    6 b* L/ Q. k4 M# A- A                if (p->adjVex1==vexNum)* H/ _! b7 X7 f
                        p->adjVex1= v;/ r! M9 I, i& O/ l. Q" h/ I8 N
                    else if(p->adjVex2==vexNum)
      M! p0 l* I& g2 }7 h                    p->adjVex2=v;: P! R" N( _5 ]  m$ w+ g5 K
                    p = NextArc(u,p);
    , y2 _1 R4 Q) H0 b            }
    6 z# Z& `5 z& j        }
    " a1 W5 |* Q% H- @    }
    ' v) S7 _- z0 O+ y. C}
    & S3 L( P: E, d& @0 J0 O///深度优先遍历
    8 P- o# N* G- Htemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    : ~) L5 g- N! t& ]  W- E$ x{
    ' K9 o$ E% n$ a# p  ~. u9 |    tag[v]=1;
    " P+ B! I) V! I$ ]. {    cout<<setw(3)<<vexTable[v].data;2 q1 Y( v6 V6 P
        MultiAdjListNetworkArc<WeightType> *p;
    5 k" T6 o0 O, |9 G/ h( E    p=vexTable[v].firstarc;& ^: O: Y) L% M, Q; |1 r+ v
        while(p)! i3 q/ K, u- \1 N# |5 E
        {5 \& S" f4 g7 d$ c8 R
            if(tag[p->adjVex1]==0)
    . Z; b' e/ j1 E. B# `$ Q$ A& G            DFS1(p->adjVex1);
    # j. C: D' u( L) e8 U2 y        else if(tag[p->adjVex2]==0)
    2 m0 _1 a* w2 Q( B            DFS1(p->adjVex2);! \/ `5 l' L9 @. M5 L3 J  w! L- W
            p=NextArc(v,p);
    0 l8 [& E+ L8 o6 Z* X2 U    }
    ( A, o- u, o1 c4 v}
    : u& S7 b! D  A( jtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()" e8 ]  j9 p7 B/ ]
    {7 B. N$ X% L6 i$ v1 ?- {
        for(int i=0; i<vexNum; i++)
    6 q0 g: B0 C* ~8 v5 n. ]7 a8 |* n) h        tag=0;7 ?7 L  F4 U) A9 ^- q& M. Z. P: Y
        for(int v=0; v<vexNum; v++)
    7 J. Z  p% E3 G    {
    9 o7 C6 V6 M$ O/ d, P# L        if(tag[v]==0)
    , Z- u/ z. C3 ~  c  F            DFS1(v);
    9 G4 Y- E! s- l1 ]+ X+ @    }: I1 p/ c0 [! i. R0 I
    }! R% m% i+ z; R
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    ( h  _; l) F" B' O  l( p{
    3 s' M1 m4 |/ C/ T    stack<int> s;
    5 H" Q  r  u& S; t. ~3 k3 D    int tmp;
    3 Y2 G" ~1 W, \; V( c2 r0 M  I    MultiAdjListNetworkArc<WeightType> *p,*q;
    4 U- d( l/ `+ j7 h; E4 a# P9 ?    for(int i=0; i<vexNum; i++)
    - R$ E$ `) J5 I        tag=0;
    # R+ ~9 ?8 W  s1 h1 U    for(int i=0; i<vexNum; i++)
    * g  I6 w; ^! Z    {+ n* \% Q: e' _# S$ z
            tmp=i;
    * Z1 r3 @! D- H        while(tag[tmp]==0||!s.empty())
    # k) d. k" ^  Y% W, K9 ?" K0 Y  u        {
    % X6 Z( m3 W2 t7 Q# t            p=vexTable[tmp].firstarc;6 D6 M( e3 P3 S2 w' J7 q
                while(tag[tmp]==0)
    * d" C4 p- e7 H: ?2 l, q            {8 K  v! T. m$ f3 |8 F; o! [; p8 c
                    s.push(tmp);2 Q1 e, z; I) p% l3 y3 Y
                    cout<<setw(3)<<vexTable[tmp].data;
    5 o* K/ |, A4 ^  k" R1 \. S* @                tag[tmp]=1;. c+ r( A7 b0 z8 f0 t
                    p=vexTable[tmp].firstarc;9 Y0 u- ?7 U. O1 F4 p% T/ B
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    $ E  g; z0 ^0 e3 J3 U) H                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    6 \3 {4 B& }& A9 V" S* J                //cout<<" 1st     tmp="<<tmp<<endl;; S  Q# [: t( N% ?" i
                }
    1 i' E: s) c6 o0 F8 F0 G            if(!s.empty())
    + M0 h2 v' A0 F- }( F            {
    9 _6 ^7 }5 e7 L7 @  X' S                tmp=s.top();
    . x" Q/ ?. D7 l) D                s.pop();
    ' E3 m% s  L3 C                q=vexTable[tmp].firstarc;
    - M8 n9 n6 l* ~$ S# D+ o( }3 E                int t=tmp;
    ( C0 M- c& K' X+ K( c                while(q&&tag[tmp]!=0), L/ d" J  e" o7 t! F" n7 o
                    {
    3 Q# L" E; ]  w% f* @                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    . g( }/ f5 y6 t6 Q2 C% v                    //cout<<" 2nd     tmp="<<tmp<<endl;1 M7 J, @3 ~) r
                        q=NextArc(t,q);/ v4 Z' a5 Q' r7 @; \' a, p0 N6 y
                    }
    # b6 e4 G, [% Y                if(tag[tmp]==0)
    2 k& ?7 y6 L. z$ n  M2 }1 \- c                    s.push(t);
    ! i% ^& q/ C- V3 i* P7 {* |                ///1、对应上面连通分支只有1个点的情况8 M4 p2 b2 i! h
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈$ }6 W7 a  @2 X8 J) p9 `6 a/ s) o
                    ///tmp要么等于找到的第一个未访问节点,) u  C* W) r1 z% a3 N  y: P1 b
                    ///要么等于与t相连最后一个点(已被访问过)6 [8 [$ {! O# k9 x6 t
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点: h* h# [- H9 |: b% P
                }4 ^6 r" K& A" s: m! Y% H! `8 z
            }
    5 j2 q- \3 f. S; s    }0 w6 B$ X" \. z( G
    }, m7 v7 S0 {. _9 E& q* y# ^: s
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    5 A: J) O5 }0 I4 Z. k) }template<class ElemType, class WeightType> int
    0 Y5 c7 F9 m. C' l9 R& JMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)6 u5 `' i: s3 x8 j$ b! Q. `
    {6 h  Q3 {- q# T( `
        if(head==pre)
    3 [! }& c) {4 N        return -1;8 c" S% T, M" E
    8 @5 x) ]# c+ k( a6 j
        MultiAdjListNetworkArc<WeightType> *p;- }" `# ]) v* ~" l. u
        p=vexTable[head].firstarc;
    $ A9 e  F5 a) P9 }7 L    if(pre==-1&&p!=NULL)4 b6 \6 Y- h0 A
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    & N9 q, b' Z% l8 F  S, W    //pre!=-1&&p!=NULL$ d( r4 m& \7 [7 S2 `5 X
        while(p!=NULL)
    3 r9 F- a( g8 X! t# \    {
      q% O7 k  d2 O- g        if(p->adjVex1==head && p->adjVex2!=pre)$ l1 o1 a& G* C8 _/ X) _
                p=p->nextarc1;2 {7 \' @/ w$ b+ `4 t& S" M9 \
            else if(p->adjVex2==head && p->adjVex1!=pre)
    , @) \6 T. F0 i  j2 A6 Q  i            p=p->nextarc2;$ y$ b; V  K9 }3 h9 i$ J2 T
            else if(p->adjVex1==head && p->adjVex2==pre)! h* A# S4 H9 R/ r$ T+ j
            {
    . g. M' J9 t: S6 z9 d5 ]8 f$ l* Z            p=p->nextarc1;
    4 B* D4 {$ O0 s            break;0 E( l, d; N5 |8 ]* ?6 [" r3 a$ m+ f
            }( p* g  D6 Z# y* i
            else if(p->adjVex2==head && p->adjVex1==pre); n% q/ R% g5 q! Y8 V7 p- j
            {4 A" x$ Y! Y# B& `2 ]
                p=p->nextarc2;/ a/ U% i. z6 c7 U' K& z
                break;$ Y$ R4 \6 k% i$ F
            }' f5 g% y8 o3 e2 a% z0 R
        }# U3 {. Z" f! `, x
        if(p!=NULL)
    % q# v7 o: ?0 E" B( g    {
    ' l. e* U1 A7 `" E: I3 P        return p->adjVex1==head?p->adjVex2:p->adjVex1;, H) K6 L" q) j5 E( J5 u
        }
    ! K, n* c+ P) z# L. a3 P' n. z5 ^    else
    ) S* c( I3 B: M5 H        return -1;
    5 Q! L7 c. _5 j9 R+ M6 P4 [}
      q9 a  ~; Z9 M# ^' J
    0 j% \' t! p, D3 V2 o+ g# L; h4 ~/ U7 D# S) B2 c( z
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()# w4 `& a8 Q8 o, p
    {
    % o! ~0 R7 |! T3 a4 S# B    stack<int> s;
    & P, V# s- x0 g* M+ i% G  P" r9 B    int p,cur,pre;
    9 a( S2 c; G/ _) C4 h    //MultiAdjListNetworkArc<WeightType> *p,*q;
    # n* A+ ]1 k1 H# P- |. q    for(int i=0; i<vexNum; i++) tag=0;//初始化
    2 \9 ]' N& y* Y+ m# s' ^" H: Y  y0 }
        for(int i=0; i<vexNum; i++)# ]" S2 ~) `- m/ i( g/ }! {1 ~
        {, K+ u+ Z# @8 [- c6 m5 p2 S. L
            cur=i;pre=-1;2 y* D7 M' o; s  k
            while(tag[cur]==0||!s.empty())
    0 o$ m8 W2 ^* i2 `0 ~        {4 K$ d5 p) i% G7 |/ O) y& y3 }) b
                while(tag[cur]==0)
    ) p( B1 \" _" z3 A4 R9 X            {
    . D) y0 j0 `, Y- o3 n6 p                cout<<vexTable[cur].data<<"  ";& d2 X2 w0 w( ~' u4 q  L6 U
                    s.push(cur);
    # h4 P3 l. [  }9 v                tag[cur]=1;
    % w$ k5 I$ h# `               //初次访问,标记入栈6 g6 e" l. s* f  h+ T
    + M( [. k' w2 {7 b0 a
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点
    * ~2 u- G. k5 W               if(p==-1)
    / e8 f+ a  L9 T- K& _5 p+ s               {/ @9 `# P" _' I# `5 O
                       pre=cur;s.pop();3 O+ L4 ]& |7 }5 V
                       break;
    3 `2 \) {$ `- X; M6 x               }
    * s" R* h' S3 T& h! f" p               else
    ; E# C: r6 N; k8 m; j               {
    ) h1 b6 j3 I. O! {6 L                   pre=cur;
    1 O- ~+ Z4 s% ]- k1 Y% G, n                   cur=p;" ~& h# B2 K$ v. L
                   }
      B5 a5 u1 ]! X" O
    " I+ u5 W6 ~0 |6 }# }- n            }/ _1 |/ Q! M' ]4 r/ V! E. M& t
                while(!s.empty())
    % h3 m9 U' |+ v  s# W. X* p            {
    4 z3 k/ T! F7 y4 _; P2 b                cur=s.top();
    / ]$ L5 L: p6 Y( u                p=GetAdjVex(cur,pre);6 d# `1 Z1 J. h9 v0 a
                    if(tag[p]==0)8 r$ \* ]5 A- U) N% W( S. w
                    {& K' x" a' A3 o# a6 f
                        pre=cur;
    1 n, z/ ~  C6 {& k8 |" R                    cur=p;* f0 Z0 x* J8 q- e: B
                        break;
      z' S3 G9 S! W, x* B  ^6 ~                }& U) {" N* P* t  [. A5 K4 z, P
                    else
    5 C0 ?! B0 T( T% K+ v6 T) [5 E* G                {8 D) X1 Q3 m$ y$ A. l) h( U
                        pre=s.top();# v5 p* n) O# a% d
                        s.pop();8 v( q- {0 ^! g, Z9 B; ~1 t
                    }. O) `( B+ I/ a& r( q) }9 p8 H

      r1 R' `( W1 h            }
    4 V: a7 N1 I" A) D, K: h* D; }$ B9 b( F8 m3 t# e( \
            }
    - ?) n* S1 P" C6 F- i8 G2 D7 D* F    }4 |/ a, O* l6 u6 I( s) z% m' o& |
    }
    # E- k7 z3 T0 v3 Z  S7 Ttemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    ; Q& I$ B2 l$ Z- A) v{+ P3 h' h8 ]5 s3 f1 P* u
        for(int i=0; i<vexNum; i++)
    , M* ~! `4 j) i3 F; j/ r1 R        tag=0;0 f- ]  O, }* C! O% H; j6 U
        queue<int> q;
    0 i6 |- M. [1 k    int tmp,t;* X8 n  k' W# ^/ j& n7 C( V; d
        MultiAdjListNetworkArc<WeightType> *p;6 T6 P* w+ H$ q! Z0 H9 v! }
        for(int i=0; i<vexNum; i++)
    3 F7 l) n$ d3 ?8 V! U) c1 G    {
    ) i0 S  a/ d5 x+ t, ^  e! ~$ k# M; g        if(tag==0)
      ]& k0 X0 z9 t* B. ~5 e        {
    9 C; Z' Z. A8 k2 n( K; x4 M            tag=1;
    / N/ p' ]$ @" a4 ]6 q1 c            q.push(i);$ R2 t! a, {$ `2 I/ {
                cout<<setw(3)<<vexTable.data;  q7 f, N  ~+ T8 w' H  c7 N
            }- U% z0 ]0 a! r2 h8 V' v& U& s3 Q7 d
            while(!q.empty())- R' j; ^" s9 n+ `
            {" h$ N9 F1 s7 v4 l
                tmp=q.front();
    ) ?5 N) l0 G/ ]( }            q.pop();# _0 G0 N- ^2 q- b# t
                p=vexTable[tmp].firstarc;
    ' G( M. t. G6 d, d1 I; U- a! T            while(p!=NULL)% B4 y& P- e8 J( w( t
                {
    3 A( K+ L# b: T5 K, y, E                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    ; M/ \0 r- K9 p                if(tag[t]==0)+ v/ h! y8 V- [* T/ _' m7 G
                    {
    8 Q8 t" n% L! d+ ]' D3 M% N                    cout<<setw(3)<<vexTable[t].data;
    * v6 L5 {; t( z2 O( ^                    tag[t]=1;& Z& }: U1 j4 H; q) V5 H
                        q.push(t);
    ; g# H( i: F3 [9 _                }
    * \( X* D# m7 L5 q9 o                p=NextArc(tmp,p);
    ; G* Q& V# ]$ {6 x$ l$ u! ?            }
    2 P5 l- L6 d4 D  E, Z        }8 k) N6 P7 V4 f/ Y" R
        }& t* J$ h* p8 f+ m; I: ^# A- s
    }. b. w& ]0 x" i3 t/ [
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show(). H' o4 H8 [# t2 E; ^* \3 h0 H
    {8 L: S( e1 J# W. j' N1 C* B
        MultiAdjListNetworkArc<WeightType> *p;
    1 K8 g7 L1 v# Y6 V2 o2 b' ^    cout << "无向图有" << vexNum << "个点,分别为:";
    $ W4 y3 t+ s0 |. i8 X; I    for (int i = 0; i < vexNum; i++)
    8 u3 H$ w9 n: [        cout << vexTable.data << " ";7 ~) |# c+ s9 [( d
        cout << endl;5 Q; |. a3 N$ }# `, V% `& m- `
        cout << "无向图有" << arcNum << "条边"<<endl;
    $ K  x# P* m/ q    for (int i = 0; i < vexNum; i++)" V3 l1 S# b8 h* p: p8 a9 F
        {
    % y; j1 S! R9 }# t! [# ], H6 W/ Q        cout<<"和" << vexTable.data << "有关的边:";
    $ A* d) X# Y* z6 d        p = vexTable.firstarc;
    0 x# x/ g& v/ A6 A9 R! Q7 B        while (p != NULL)
    + v& o/ Z" @' }        {
    ( D' s- n' k. B, i! f* W! A            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";* L( i" N" H. F1 Z& U
                p=NextArc(i,p);
    3 f8 m& g- W$ O& X0 @. E        }
    2 i! F8 W" F7 a1 ?9 g0 I0 T4 T        cout << endl;
    . y6 d" h8 n- ^* C6 a2 K    }4 h" Y" |- e6 @% N
    }6 v+ c1 j) r0 B% z/ S% U

    ) |0 I0 a5 w+ G( ~) b" P! ?% R" S$ _4 e( t7 K% P
    邻接多重表与邻接表的对比
    / }0 @+ N0 o+ A& Z1 ]" B
    ) R0 i$ I- h" r邻接表链接
    2 R6 k6 X  M: Y# P/ _4 f' V/ V9 P在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    ' P$ w( V+ \# d  }) e在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。, l( t! X6 |  y; r3 U1 M  [5 J
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    : [+ z. l' N. K, f, o. {————————————————* [) k3 p! o6 V$ h, ~4 }
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    + D; B8 p6 g8 v# o8 O原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    4 m3 F# q5 `  k. k7 O% Z: M6 h
    + O1 f! O; s& L* g. Z3 s- ]
    : s4 B, N- W% l9 c$ f- m$ G! t" X" q3 Y* ^5 s# {6 w

    & W& g, w' e( A' l: E————————————————
    + p) N9 R" p* c: ^) o5 K; ?' U5 v/ a版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    4 H- [5 t1 D/ j; M+ H原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669589 q. ^8 g% ?. t2 B

    7 z- B# T9 O( G( @; |4 ^- l; P  M, t/ [  m2 c+ w0 }
    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, 2025-7-31 11:25 , Processed in 0.436584 second(s), 53 queries .

    回顶部