QQ登录

只需要一步,快速开始

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

    ; q. ?$ k* ~6 ~* ^! y  x" J/ M3 K图的存储结构——邻接多重表(多重邻接表)的实现# K( b/ S6 \  d+ @9 H$ @
    7.2 图的存储结构
    $ o, p* j* W: W2 E$ d
    9 x: G6 F! y# k6 Q7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    7 k5 r6 I1 a) w% }6 \+ n2 h) W邻接多重表的类定义! F) i: V/ C4 d0 f: v
    邻接多重表的顶点结点类模板
    # ^6 u* T, m6 O$ X& L邻接多重表的边结点类模板
    ! U" N  m" ?& q) p) U邻接多重表的类模板5 I, Q, y* ?7 R+ T8 |! ~3 P
    邻接多重表与邻接表的对比2 F6 f0 _1 T) f. k3 K% U
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist1 Q- r- D2 a) \
    ! w. k- x5 p" J/ u& g
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    ; B" z' c8 Q! n9 ~9 z2 W在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。# b- M. d. b# u/ a; S7 v1 C6 l
    2 f) @7 \* ]) {: d# A2 O
    邻接多重表的类定义4 G5 `0 W+ |( d
    1.png
    " l8 Y6 x1 R5 ?( A5 l6 U邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:% U4 f6 u# O2 f& Q* ?
    data域存储有关顶点的信息;; B0 E' M- e" y
    firstarc域是链接指针,指向第一条依附于该顶点的边。& i: Q% |! Y: r+ [
    所有的顶点结点组成一个顺序表。


    ' U: G( l. h1 m- r  k! u( ~! z# k
    $ M4 J0 y( K9 Q3 t( i; Dtemplate <class ElemType ,class WeightType>
    " k9 B# K, Y, V: c! ?: jclass MultiAdjListNetworkVex
    9 k& b! C+ s1 B4 v& \$ s5 a2 f1 C{/ z0 {& Z0 E# ^( k: h0 L& y) e3 W, k
    public:
    6 V: o8 [0 }8 D" H: \0 o        ElemType data;
    : R0 v- ?" G( x9 O: {6 t' A8 f        MultiAdjListNetworkArc<WeightType> *firstarc;  D, Y" `2 z* C9 g8 \8 M

    . \& n5 H; W" H7 o( `6 s        MultiAdjListNetworkVex()
      t" a5 [: R. l        {
      ~; C8 B6 y1 P& G% ]8 }                firstarc = NULL;( Z9 W( t+ C5 m: V
            }
    9 O) ]4 m+ t3 {% c        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    2 b8 t7 O( L* i. z3 v9 C        {
    0 L" @5 `- _9 L- N1 w0 H  c                data = val;
    9 [/ F' i$ Y/ i; A; W2 q3 ~  M* H                firstarc = adj;7 {/ E2 a8 s, f3 G5 P( o* y
            }- Q6 Y" ?2 [* l3 h; \
    };8 ^$ D7 S5 n$ K. [& q
    9 U3 [2 f  e$ i* x
    邻接多重表的边结点类模板" @# E: X2 E: R. {* _' z! d' G
    , H1 C) [" H1 V; j% S; d8 K" d& s
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:- K' ?9 v* s2 R4 D
    tag是标记域,标记该边是否被处理或被搜索过;: N5 f9 \( y+ C
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;  i  x/ b) O1 w. {1 @( f6 O* D
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;+ d8 l! e2 }# G9 N+ e3 N
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    - y- ^: ^0 {+ m9 c* s
    6 p6 n+ T. f! K1 U" W2 n8 o) s, B 2.png 9 [, ^. b. Z0 O% h4 T0 l3 M
    template <class WeightType>: g8 h* J/ E! }7 B
    class MultiAdjListNetworkArc! i$ P# j: [* n0 b* q5 D
    {
    $ W4 r0 D% K, q0 ipublic:
    # i- V6 v; m8 E/ o    int mark;                                       //标记该边是否被搜索或处理过
    2 y& U3 x! X8 d: y2 Y; ]        WeightType weight;                              //边的权重/ n. h# `4 ]" S' J/ M6 g2 x
            int adjVex1;                                    //边的一个顶点& K, P0 u' q5 \0 Z/ `
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1$ V" o6 k0 M6 m( |  _( N* M5 h
            int adjVex2;: M' [/ I6 Y! w. g0 s% v
            MultiAdjListNetworkArc<WeightType>* nextarc2;
    % K3 T  r0 \* H& @) m' n7 O, P6 ]) s8 [' k& o1 G
            MultiAdjListNetworkArc(). `# Q% r! a5 ?  {
            {! R/ T# ~. a6 y9 m1 n" b$ H& J+ H
                    adjVex1= -1;
    : S6 V. ^0 p! ~                adjVex2= -1;1 z: W4 f. ?% _* A& E
            }
    7 {4 J, n2 _5 [# ~( B& p        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)+ I0 ^/ A$ }8 y5 b
            {
    / @) h' q0 [2 H5 k/ w                adjVex1 = v1;       adjVex2 = v2;
    / j: C8 f9 ^1 ~/ q0 w" _5 p                weight = w;
      \; b8 n8 ?" u$ |! d% k4 t                nextarc1 = next1;   nextarc2=next2;
    - x1 u, P: W/ C+ ]/ }3 q                mark = 0;           //0表示未被搜索,1表示被搜索过
    , d" S# g9 f% L3 n) x3 F( J        }
    8 h# v# X* O# x  Q  _+ b! u* H/ A3 ~* ^
    8 G/ z. G' M! r# Y" y4 Y) r9 D邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    2 `* I: g7 C5 M/ P$ k0 o& J, j) M! Yclass MultiAdjListNetwork
    3 d2 p) w( m; U1 C{
    1 |/ q" R) v- g- w7 @6 Bprotected:
    ' V: A7 }* @* t- M: @# Q9 ~& \* d    int vexNum, vexMaxNum, arcNum;
    - ~' L2 i1 \7 X0 c- H0 z    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    7 |" u0 M: C( o  [2 `' D    int* tag;
    2 I* w- _* N6 b( u9 j2 v    WeightType infinity;
    % E8 [7 c6 x" z! d
    1 U2 a! ?! c( k" s0 ^) Gpublic:/ ~1 l+ Y, g8 K; L( z
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    1 Z( R$ L8 c8 A! m! L2 A+ _0 j
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);9 ]  Z- t, ^2 L. r+ e7 [
    / C2 Y) d, x1 [) J$ ^( u# O
        void Clear();4 [% F9 a# Y4 L% }
        bool IsEmpty()1 g0 s9 c6 O! E3 b9 O5 u
        {
    ' A6 e) a, w# f/ G! D- H        return vexNum == 0;
    1 ^9 Z" z1 `0 a( s$ g. l# v    }
    ( \8 |$ b4 ?' N) h3 h    int GetArcNum()const/ y5 N# N/ M4 q) o' ]
        {
    & ~- m5 ?9 y. N        return arcNum;
    8 l! n& R0 X3 R  }    }
    # \4 }) I  P% |; d) N5 U6 q+ ?    int GetvexNum()const
    : Q- M" ]+ r5 ~$ t5 Y    {8 s; j, A% V5 f  d( D% z! t6 R# q
            return vexNum;' F, C3 w' K4 L5 C  J
        }
    4 v0 S0 P4 V$ s0 G( A+ z$ Z( C

    # K+ h' [* P4 b- A0 E, h6 `3 H1 }    int FirstAdjVex(int v)const;
    / |+ ], @1 V: Z4 Z' [- ~( O, ]+ g# y    int NextAdjVex(int v1, int v2)const;
    3 T* M6 k* Y2 G# e    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;0 V/ @$ h- w5 z$ G. a3 w# Q
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;' e" T6 Z# [7 s  l( W. A4 [

    % t4 y- E2 j0 @( {0 Q4 s1 ~% `2 t    void InsertVex(const ElemType& d);
    1 _4 W2 y& F1 q; H( [  K; h7 y2 \    void InsertArc(int v1, int v2, WeightType w);
    3 l7 h' }) X1 ?$ c9 o$ _: ]+ A  i
    0 F+ j8 \( z/ H8 v, @6 i! B- r    void DeleteVex(const ElemType& d);0 ^7 @: d0 t, H+ ?7 P. R1 T' j! a
        void DeleteArc(int v1, int v2);
    8 d0 k/ k- Q2 r( a' |, C( m: T
    , y# D+ R8 S) R) t: \6 T    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    9 l8 m* S; M  W/ v# C, {    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);  t+ X2 H9 X+ ~4 [$ n( O  A
    , z1 Y7 d( _$ D$ O
        ///深度优先遍历
    ! X0 u+ j" S0 }; J; ?    void DFS1(const int v);
    $ ~3 u6 i; m: ?& f) g1 H    void DFS1Traverse();
    ' X! [; {2 O; a* g, G  w    void DFS2();
    % k0 B" E2 ~5 Z2 f* A4 Q
    0 s# U9 H8 q+ j' G, j5 |    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    ! @' |4 C/ w0 W6 |    void DFS3();8 L: d! r" @' P; }' Z" g
    9 e: F; q: V+ w0 s; G& j% _
        void BFS();
    5 l2 m  p/ f+ f7 |3 B    void Show();
    0 B/ d4 R& L' ], |3 ~! i" ^! d; v};1 w( d. _  n, Q
    * X& W0 Y: V- H' ?
    2.函数的实现
    2 I; ~0 U+ I9 u研讨题,能够运行,但是代码不一定是最优的。( U( R! m: V3 ~+ p! z7 z
    3 h& d/ `) ]6 k, H) S
    #include <stack>0 U' s' i0 A, i0 L1 Q+ u& t6 x; n
    #include <queue>
    % P1 B' e3 b2 [! `
    0 u& H1 y) M2 U( mtemplate <class ElemType,class WeightType>8 T+ y3 u6 }: a9 W! x
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)6 p4 x4 [' e. `8 P, Q
    {* D6 |% E. ~% x; @9 B- h; j
        if(vertexMaxNum < 0)  U, Q2 H, V% f9 l4 p
            throw Error("允许的顶点最大数目不能为负!");
    / G# W3 `5 s6 L  m0 \& s    if (vertexMaxNum < vertexNum)
    - e: t% ^/ h$ Z        throw Error("顶点数目不能大于允许的顶点最大数目!");6 r8 V  y- Y' A3 `! ^
        vexNum = vertexNum;
    : u' ?- p3 r+ p( [. J, G6 }- g% _% U    vexMaxNum = vertexMaxNum;
    , a/ q* p8 D' D0 A/ O1 M    arcNum = 0;- d* i" R+ d% m& j8 \4 ?9 n# J- v+ _
        infinity = infinit;* Z* B2 u6 }; Q* w
        tag = new int[vexMaxNum];; I2 ~5 G. @& Q7 g. m- z
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    - K, \" q1 e9 ]. ?5 ?2 k) q, Z    for (int v = 0; v < vexNum; v++)
    $ t, _/ n& M$ |; n; ]" i    {
    3 m2 g6 k" _) a        tag[v] = 0;
    ' ]  x. \! ~5 B  W        vexTable[v].data = es[v];6 u! k4 k0 q8 J* h' S) f# f0 c# V4 r
            vexTable[v].firstarc = NULL;2 D2 G8 C/ d  `2 W
        }
    1 c9 G( @& Q' l4 ]9 c}2 o: V6 t; Z$ g) D# d4 U
    template <class ElemType,class WeightType>
    " N/ f$ m1 D( V7 H5 ^" |0 U7 A' }* jMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)* ~3 s8 ^; y! s+ g/ a/ q$ c
    {
    - H9 i, X) V( p5 l! l( Q    if (vertexMaxNum < 0)$ e& P+ W5 \! M. z" m$ y1 m! V
            throw Error("允许的顶点最大数目不能为负!");
    1 ^/ R( V5 [* r% }    vexNum = 0;% `& ]6 j+ M2 K3 U
        vexMaxNum = vertexMaxNum;+ h  f7 S7 A& @# {
        arcNum = 0;
    ! X% d! a( v7 }1 H. C6 k    infinity = infinit;$ j0 J( a+ G. f7 @0 u
        tag = new int[vexMaxNum];
    ( _/ N# |( ~! n; D3 }& ?' W    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];! z2 E0 P* F# L3 x5 d+ n
    }3 U: c4 e; a" L* r6 V/ p
    template<class ElemType, class WeightType>
    0 o" T+ s: ?" u8 \1 d% S7 O6 xint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const# n1 C/ b, F; o. s+ y* Y, J
    {
    ; U" d6 _, M" V1 E    if (v < 0 || v >= vexNum)- o; g9 h0 _. s3 }& P7 q6 P& D! I
            throw Error("v不合法!");
    8 O; v* o- Q. }/ E% \* ~    if (vexTable[v].firstarc == NULL)
    + g  Z  v: ]) R        return -1;5 R' w! ]$ ]/ G4 x
        else0 t3 h+ P0 o; D7 F+ O5 c9 k" h
            return vexTable[v].firstarc->adjVex1;
    $ ?# b, ^9 Y9 d}
    4 U9 q6 a5 U. N: i) z& @) _9 I6 g+ m9 ^7 p
    template<class ElemType, class WeightType>  r% ^. }; y4 H, u' f. i& C' y! a
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    1 T( O0 L' z9 X2 O) F{5 b$ A3 c9 b9 Y) B7 O% n: o' x
        MultiAdjListNetworkArc<WeightType>* p;0 |( F. V/ S3 \9 X: l0 O3 X
        if (v1 < 0 || v1 >= vexNum); @' P! n1 R* ?
            throw Error("v1不合法!");+ [, F5 _( k; r9 F
        if (v2 < 0 || v2 >= vexNum)
    ; K8 ]8 A+ A# m- e$ q1 T+ I        throw Error("v2不合法!");& S& p; y0 k7 O! o
        if (v1 == v2)% i3 l  c% D7 `8 n+ w
            throw Error("v1不能等于v2!");
    0 B7 W$ T# s1 i! z$ h2 B    p = vexTable[v1].firstarc;5 N; z7 J- c- h
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    + o% x/ A0 k+ m8 v- N        p = p->nextarc;
    : U8 f) ^/ A2 ]5 n    if (p == NULL || p->nextarc == NULL)
    7 ~1 Z1 y6 g2 L# s7 n        return -1;  //不存在下一个邻接点' _9 V! e( _6 L& U3 k
        else if(p->adjVex1==v2)$ ~8 q" s/ l1 _: w9 L
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);- A7 r( r& d) R+ }. V2 e
        else1 r. Y- O& m8 w/ o- _
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);; G0 g: X) `! W, I
    }2 Z" a8 w/ @+ X% `) A: w4 `0 @7 s
    template<class ElemType, class WeightType>
    % P% ]$ i( n( o, [0 C: vvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()
    " O$ ]) S0 a3 v$ e" `9 v{
    ( R9 R1 h% Z5 X# J4 j: W5 O    if (IsEmpty()) return;# @1 v2 V# U( {
        int n = vexNum;
    " r3 ~2 y" j& x6 B    for (int u = 0; u < n ; u++)" S3 L9 F) z: t. c* _( q
            DeleteVex(vexTable[0].data);
    ; _6 F& S. {/ E& d    return;
    3 W, U* @2 d/ C% q' l7 [# X}
    2 p# m; G2 m0 B1 Z4 R1 S$ Vtemplate<class ElemType, class WeightType>2 C% i$ E+ E) C7 G4 ?+ L$ z
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    % y* B8 ]8 B% d/ s{( V$ }: D3 G/ G" b+ I0 E0 x
        Clear();5 ?1 O+ u* T# e6 d7 @
    }
    ) `  R* k) m/ h( b5 _template<class ElemType, class WeightType>7 v# G% ?* |' x* W6 D/ d
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    ! t& W$ ]- n% S2 J{/ a7 w1 E0 w4 C/ S8 `) o
        vexMaxNum = copy.vexMaxNum;' l2 |+ i$ Y' R) P( ^4 w+ d4 w0 e
        vexNum = copy.vexNum;! @9 P8 ], H$ o9 [  p# |
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];; O/ P" q8 H* E) |4 t% ]
        arcNum = 0;
    : i( q3 w$ S0 s, U! S    infinity = copy.infinity;
    2 b- k4 J  V3 o, E% U9 z! D' M8 i    tag = new int[vexMaxNum];/ d3 f/ u# M+ F8 h+ L6 C& d
    " t2 W4 L+ Z( k8 `
        for (int v = 0; v < vexNum; v++)
    ( Z% ~# f; K9 \' x2 P, x5 D0 x9 _  o    {
    / U6 v! _) T5 P+ x1 h! c# N        tag[v] = 0;1 G4 r+ x, B0 {7 M% Q( |$ w
            vexTable[v].data = copy.vexTable[v].data;/ P: Z2 j& {6 N* d
            vexTable[v].firstarc = NULL;* f5 [8 Q$ k2 ~  ~4 Z
        }
    : x# Z. p4 t; C8 ~/ v- e- \* o    MultiAdjListNetworkArc<WeightType>* p;
    " F/ n, [% Y* V+ o
      l. o$ n& |1 m. G  W4 l. Y* ^7 R* x    for (int u = 0; u < vexNum; u++)% S  c$ {. e# j4 C' y: Z' ]
        {  t) y$ c4 B. Y2 y3 X1 e( a
            p = copy.vexTable.firstarc;  C! [. {% W8 v
            while (p != NULL)
    ) M7 A/ f, g4 w' W        {! k5 O, z. T: b* W
                InsertArc(p->adjVex1, p->adjVex2, p->weight);0 ?! H: @1 E/ t4 n$ U
                p=NextArc(u,p);4 y2 }- |& J5 f3 ^
            }
    $ p# o4 g' E7 X6 d( J) n! Y    }
    ! A$ w! {; J: Y}- |0 X: B$ j4 }" b9 Z
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    * W1 |! n# t) X" JMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy). C  \" e5 S5 {4 j& t# j4 ]" W9 o
    {9 Q* m7 P' t# v5 |$ N
        if (this == &copy) return *this;
    7 G8 d' }6 |9 ?- n    Clear();
    / X0 S, I* {& _    vexMaxNum = copy.vexMaxNum;% w  q* P0 L& g8 B$ S
        vexNum = copy.vexNum;' {7 ?4 x' U& u
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    0 P. Y" F4 z* f2 i. r* k    arcNum = 0;7 `: u3 f3 z4 c! o' F& y
        infinity = copy.infinity;
    $ O- u2 H/ y. Y) b7 W3 B    tag = new int[vexMaxNum];
    % w" H* m- _4 E0 j1 H
    6 |2 y4 J) ]/ m9 {# u; }/ ~    for (int v = 0; v < vexNum; v++)
    : P; c) v6 G# K+ w" y; d    {3 ~; g1 Q% A, |! l2 C/ {
            tag[v] = 0;9 p  |0 g8 F$ n3 P
            vexTable[v].data = copy.vexTable[v].data;" @* |9 _1 Q1 j/ s+ E
            vexTable[v].firstarc = NULL;6 r& [5 [0 D" h$ r( m
        }
    / X- d6 n  l5 }; Z    MultiAdjListNetworkArc<WeightType>* p;
    9 y/ \7 J# T9 U" x! B
    ( c1 W/ R, {( a! S; J- p; D2 l    for (int u = 0; u < vexNum; u++)
    1 v! J; z; H1 u9 c. J    {! ^; g  t% J1 X
            p = copy.vexTable.firstarc;
    8 W1 x5 |' U5 K4 K/ d        while (p != NULL)
    $ |, y$ Q& v1 r2 d        {$ F6 r1 m' {" R# z* M% Q1 I
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    * q. r- t4 a( L* c4 T; W+ G            p=NextArc(u,p);$ ~/ `. V2 w' o1 r- u8 h" a
            }7 G* g, @! `, F% R, @3 `" S  D
        }
    " V4 [4 H5 T1 i' H    return *this;
    # u  H4 d6 s7 K% B}
    9 u% w( v) H  Z! y3 w* v# ltemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*) U) A( b8 Z& |9 t3 c  [" a- Q& J
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const- S3 X! u9 v4 b5 n
    {$ H/ {; `+ s6 ^3 G" `1 N1 ?
        if(p==NULL) return NULL;
    9 E! X. N/ h4 l$ H    if(p->adjVex1==v1)% Y4 \& E0 Z5 _$ G% U
            return p->nextarc1;
    " G1 f* A7 X8 I  g3 a) i    else
    & s" ^0 L+ i& h: t5 ^        return p->nextarc2;
    4 M% N' _* r* o# b- ]+ G& ^5 P}
      b% u% |* c$ R! w+ Vtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    6 D; ~) A! P, X' BMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    # Q; j; T9 i2 |, k% y{8 @8 x* T: z: I  U% j4 |) f0 X
        if(p==NULL)return NULL;% ~6 f* N% ^" U/ X2 _
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;8 ?, d, |- i7 q$ e1 d- O
        if(q==p)
    ' A8 q3 X5 ~0 K  a# ]8 `" {4 A        return NULL;
    1 Q/ `( m7 u" N    while(q)
    8 [; w* h7 o% N    {! ?+ M$ x! z) n* u0 M6 T: H& G6 R
            if(q->nextarc1==p ||q->nextarc2==p)
    3 z2 D* e1 X: l$ h            break;
    & Y) ?7 L; Q# d8 V6 h$ C        q=NextArc(v1,q);( W; M8 E2 J0 n& [* q
        }6 s3 n/ a- o8 U7 s
        return q;6 a3 x. I4 B' h9 Q) Q
    }
    6 i! ?. \% z! p" x6 T1 Q  H+ utemplate<class ElemType, class WeightType>
    , K8 g  u3 r2 F2 A5 ^. y$ x3 Rvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)/ q! h" y, A. v, }# \& k% x. [
    {
    1 t9 ^/ q) R) V0 @" N) x) P) h. |    if (vexNum == vexMaxNum)% V2 C/ m% t7 p; M! M
            throw Error("图的顶点数不能超过允许的最大数!");
    % ?9 g' W5 u5 T. o! w5 n    vexTable[vexNum].data = d;
    - k4 v/ h! R! b  ]% W    vexTable[vexNum].firstarc = NULL;; O5 T" I3 ~" B) F* V
        tag[vexNum] = 0;
    - L$ ], F; ^) D1 J' R    vexNum++;1 \; b- h% Y4 f3 ^' u" p
    }4 m$ h; T5 C4 c6 k0 }( s  Y
    template<class ElemType, class WeightType>, m0 e9 ~5 Z/ g! N" }
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)6 d' r* l* S: U! Z5 U% {
    {
    0 o( |5 H$ S: I9 r6 O" o! [' c    MultiAdjListNetworkArc<WeightType>* p,*q;
    1 [6 _+ {& _6 _( b    if (v1 < 0 || v1 >= vexNum)+ G, S' ]; Y% S0 W
            throw Error("v1不合法!");
    * [$ N3 }: Q2 n/ @; s    if (v2 < 0 || v2 >= vexNum)
    7 @% q# u& U; |! b. l! G        throw Error("v2不合法!");* P9 s" Z% y# L7 H5 t& i
        if (v1 == v2)
    ) }6 Q- f) n) w9 W1 g; I; E        throw Error("v1不能等于v2!");
    * {3 J/ e% f2 S* X/ e/ h    if (w == infinity)- H" w- U9 A( q! D( U  L2 C
            throw Error("w不能为无穷大!");
    % K& m; A% u- A# u
    5 N) @7 r! P8 z- X) S: y. j4 z# c, ^9 K( ~3 f- e
        p = vexTable[v1].firstarc;( f# Y( X$ ?: y8 U# l6 F
        while(p)
    & F, H1 a" |  \- I  j    {
    & e1 w+ D6 d4 ~5 o- T3 }+ t        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    % u. s4 f6 \( I& `0 L/ [+ I        {1 ]- q9 j; E" I$ c7 N' W
                if(p->weight!=w)0 \9 z* {% m+ ?. u5 L
                    p->weight=w;5 Z2 @7 Z) N, K% h
                return;
    0 {  }; ^# |3 `        }' l$ |4 H/ o; _4 s, ~
    $ t3 o: Z7 t4 v( ^  Q
            p=NextArc(v1,p);/ S4 n4 j9 g" w1 `$ `
        }
    , i8 c$ J1 X3 ^$ y; I6 \4 M    p = vexTable[v1].firstarc;5 l$ w4 m4 Z; Q* l
        q = vexTable[v2].firstarc;# E% \' \1 }3 A* R& p
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法! ^) E+ J6 @) G* A2 W- W
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    # H: X# C3 C. L% L: {5 F' G% N+ V    arcNum++;# w: n- _& s% ]
    }2 ?9 j( n: s! h' L% ~# W

    . a% H: o* q6 X8 b+ Atemplate<class ElemType, class WeightType>
    & i) q  M" m+ Z# W# X; ?void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    / p6 x7 }: y, b0 M{6 o- r& q( r2 F7 P5 S2 L; }

    . u0 D5 S2 ]4 G9 c9 z: V    MultiAdjListNetworkArc<WeightType>* p, * q,*r;; _6 d7 B# `' a8 i
        if (v1 < 0 || v1 >= vexNum)
    6 C1 Y$ U, V+ ~( M        throw Error("v1不合法!");# v4 c( f4 T5 X
        if (v2 < 0 || v2 >= vexNum)* n3 r- _: }7 m. ?8 d" b- J6 z
            throw Error("v2不合法!");0 I. ~4 P- b8 l- h5 x. R
        if (v1 == v2)+ `: J7 O2 z, |, h
            throw Error("v1不能等于v2!");
    3 n& B0 a% h# s- h) v4 d+ A
    , N8 L& h; C; m+ g    p = vexTable[v1].firstarc;
    1 ?2 B5 }8 n6 s' p7 }& @5 X    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)- q; L* E' [/ f; @
        {4 y; R) R, V' Y; F
            q = p;: N4 y/ q' T$ T4 q2 Y) K
            p = NextArc(v1,p);
    * `: p5 j; c: I2 m" O# K    }//找到要删除的边结点p及其前一结点q0 B( f- B: B: M1 i* s+ h% q7 n6 C

    * K  D! u" h; W# J    if (p != NULL)//找到v1-v2的边
    " w+ M! x! T% @* J8 ?    {! A% \- ~2 A' h; o+ M; i) l
            r=LastArc(v2,p);
    & S' I8 ^* ^' _* {3 o        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL& h9 A9 \4 L0 |- ^
                if(p->adjVex2==v2)( @9 R9 O( T* s+ W* C# B, o- Q
                    vexTable[v1].firstarc = p->nextarc1;9 e1 D" Z" t4 b9 F: |0 a
                else vexTable[v1].firstarc=p->nextarc2;
      R9 \$ r, I3 X        else//不是第一条边3 P! {6 K# H6 g# S
            {
    * L  g1 U/ [  a# p            if(q->adjVex1==v1)( T! U+ r8 L8 |& U" b9 L
                    q->nextarc1 = NextArc(v1,p);
    / X5 a3 w2 P; H; T# ^0 U3 a( G8 K; J8 d            else, u3 l! k1 }( g
                    q->nextarc2=NextArc(v1,p);
    $ [" e& f( i; I4 q( Q
    - o7 k1 N. V/ R4 c9 Q5 Z/ ^        }% c$ l" Z/ I" T, z' h! |
            if(r==NULL)
    $ N. Y8 ~" F  \+ D: A8 E' C            if(p->adjVex2==v2)
    6 o5 X8 B9 Q7 m) T: z( r" o9 a% |                vexTable[v2].firstarc = p->nextarc2;
    1 R/ L9 X9 |5 p  x6 `8 e* D3 \            else vexTable[v2].firstarc=p->nextarc1;
    3 A3 k6 m% l: Q4 }; Q( D2 X# v/ q        else
    - ^0 K& \( E% _& `5 J        {
    $ w0 G: H  X* y$ r            if(r->adjVex2==v2)# t0 R, x% F3 l" S* |) E
                    r->nextarc2 = NextArc(v2,p);
    3 p/ D& J( l! A: F! ~8 j* C            else
    ; b% J0 ^% G4 Y$ s! {* a8 ]' o5 F                r->nextarc1=NextArc(v2,p);
    # K1 Z1 U8 @  n. |$ k        }
    2 o: ^) a- C: u  d        delete p;  S/ A& S7 Z. r" |
            arcNum--;
    * c' Z' g* l# S    }8 g2 j1 G! z+ @/ g

    ; S$ y: n7 X' I; n% i# [' m! x( u}$ {& X& \8 P+ n1 h) [2 k. F8 `% p+ V
    template<class ElemType, class WeightType> void! J2 ]+ J. S' E( X2 t
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    . Q9 W' ]$ [  }8 n4 |/ k: K% ]{
    # \6 }! h' E0 U    int v;+ g+ x7 y: B5 q  K9 W' x3 c
        MultiAdjListNetworkArc<WeightType>* p;; A, ^9 I. D- H5 w
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    : z' O8 B2 g1 O+ O        if (vexTable[v].data == d)5 }& [, E. J: h# a, O% L* [4 Y5 |5 f
                break;
    : Y3 M7 i7 H- |8 W: [7 v    if(v==vexNum)
    ; m' m( d3 e, h- }: M5 c) X. I# T        throw Error("图中不存在要删除的顶点!");
    . n' v( t' A8 |
    # d  @; A: S- R  g  G) S    for (int u = 0; u < vexNum; u++)//删除与d相连的边
    ! e1 [, o! C% ~, C+ k: n+ F0 V, I        if (u != v)
    : Y3 W7 U+ `$ e* y$ O) o3 L. @        {
    ) J& Z9 D1 U' x) H" G% N8 c" k            DeleteArc(u, v);
    & s5 ?! f3 ^2 z+ }9 \        }. |2 i8 v8 _+ P3 L9 [. ?5 i
        vexTable[v].firstarc=NULL;
    9 ^- A* w( b: ?1 _1 q7 ]
      x+ o1 h8 g. b9 d    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    7 R1 R+ o4 D' j$ H    vexTable[v].data = vexTable[vexNum].data;
    - o, I) E9 m' j; a. X    vexTable[v].firstarc = vexTable[vexNum].firstarc;! E! C% q3 Z; I9 _/ P# Q; i  Z
        vexTable[vexNum].firstarc = NULL;
    1 e- {3 r8 D8 l    tag[v] = tag[vexNum];
    ( C- b) Z1 x* D) Z    //原来与最后一个顶点相连的边改为与v相连
    8 Y, v5 I. ?# z; K- X' U* K8 Z: ]- O    for (int u = 0; u < vexNum; u++)
      [: {' b2 j4 @- p7 C, Y    {% o. r. `& W( |
            if (u != v)' Q1 w& j, a+ U( _* X. H) Q
            {
    * b9 w6 S$ {* L' g% C0 p3 k' X            p = vexTable.firstarc;
    5 s9 t9 Q- ]- M  _1 a. y            while (p)
    3 E( C2 v3 m: p' }/ y/ ~            {
    9 [& C" C) }* x4 o; f! ~                if (p->adjVex1==vexNum)
    8 |) n, g, G6 K3 z- \. K& U                    p->adjVex1= v;
    9 J! f% S4 r( N0 k% H) I                else if(p->adjVex2==vexNum)( j- n$ X: M; Y
                        p->adjVex2=v;
    2 x! \" e6 |$ }" B7 }                p = NextArc(u,p);0 p; }- s# J7 _9 f7 P: E
                }
    ! d9 q# {7 [9 B9 O; r        }
      l" ~, a8 J& s7 F1 D( x    }# q7 ~, @% R/ \* r3 S* |& j
    }. z; |, `5 u: t( V  l
    ///深度优先遍历
    # B# d& H. e* N- R% Ztemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    + L8 e1 p* L) d& ]. N6 c{* C& ]$ e7 n8 ]
        tag[v]=1;) Z% ]& N6 D) |" b  b
        cout<<setw(3)<<vexTable[v].data;& ?4 J0 q3 ^1 D  O
        MultiAdjListNetworkArc<WeightType> *p;$ p$ H. P* }. Q" p8 r
        p=vexTable[v].firstarc;3 @# g, Y( q. K# h2 v, r
        while(p)& H  x2 P+ C, i" d3 u
        {3 T' d; H* \; w, J. `# @. E
            if(tag[p->adjVex1]==0)4 `( ?7 u7 ^( i* w6 K) i! V
                DFS1(p->adjVex1);
    0 l  N) n/ l  e4 m        else if(tag[p->adjVex2]==0)8 }& Y. V! ?8 X  p  j
                DFS1(p->adjVex2);
    0 o  k$ A$ t4 u" h        p=NextArc(v,p);1 [0 `; {, _: b8 @/ Q* ^. v' R4 s
        }4 ?- e& a& P& Q
    }) j  Y$ Y6 M/ v7 O
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()4 T+ O: s, z" K9 r7 ]0 Y
    {
    5 g, @4 v5 ~2 [- u- K    for(int i=0; i<vexNum; i++)
    4 a2 L" ?, [$ D4 L. F. y        tag=0;
    $ T" f* A1 I- H/ g    for(int v=0; v<vexNum; v++)
    : c* S) N) ?, d. C8 e0 [    {
    5 s4 C" e# |- Z# B        if(tag[v]==0)1 m" H% R) e& s- ?8 G$ y5 D
                DFS1(v);
    ) ~. c, C- M9 }# U+ n8 z    }  |: m8 [/ }0 Q; x4 R+ X% Y+ y7 h% @
    }
      }4 E* n2 a' mtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    8 N2 A" X6 J6 b% h& C' K{: L2 L) e/ S8 E8 _2 _: u; ^
        stack<int> s;: ^/ y! ]4 }/ `
        int tmp;& u( D2 F% W% b# E; |! N# U1 _
        MultiAdjListNetworkArc<WeightType> *p,*q;" d0 l8 }- D9 u9 B  o8 M, w
        for(int i=0; i<vexNum; i++)
    & V( Y! v; [0 y" T  A        tag=0;
    3 T' O) E0 R+ G, Y3 [* r3 y    for(int i=0; i<vexNum; i++)
    ' K1 m0 H8 V% Y" {) r    {% O( [+ F: b8 p3 t2 R
            tmp=i;
    ) X0 G9 ^6 I' f( E+ D$ ^" \, ?  M% [        while(tag[tmp]==0||!s.empty())5 i: j- V7 b5 j, F1 n
            {
    . R) a6 A4 W4 _3 T! ^: l1 s" E            p=vexTable[tmp].firstarc;4 R: d4 ^; h! i% Y+ V8 e3 B. T
                while(tag[tmp]==0)1 d, Y% g" n  Z1 ]0 o' U: s7 `
                {$ N4 Q4 f8 ^' ?! u
                    s.push(tmp);) k) ]1 c( T! h$ a+ Y8 A- Z" c8 X
                    cout<<setw(3)<<vexTable[tmp].data;6 K: S0 L  V& q: I+ Y  |5 B9 z7 q0 V) l
                    tag[tmp]=1;
    " y+ U/ M! K, e# r                p=vexTable[tmp].firstarc;
    0 g/ E; W0 ~0 j) N: F/ v. Y                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for! f4 ?; o# v2 ]" _/ n
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);  U0 U: \5 ?, P+ f
                    //cout<<" 1st     tmp="<<tmp<<endl;
    0 k$ E4 R# e7 V+ z5 Z2 w            }
    ) B" W5 z/ F( t- l" S) r; ]            if(!s.empty())6 H, I: O% H! F) E2 b9 K' @
                {
    $ G5 i) N0 _5 Y, _$ K8 y  R                tmp=s.top();
    & O  ~7 k8 o& K% `                s.pop();
    8 `& @0 Z6 K4 L- @: S2 i                q=vexTable[tmp].firstarc;
    8 G) p- @& l9 {! z7 d                int t=tmp;3 ]/ _1 A& C" z' p, f1 h
                    while(q&&tag[tmp]!=0)
    + y) R# ?9 M* O: ~                {9 {$ @) f$ }3 W. J" H" S
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);# d1 v4 Q  E, Q5 F8 L
                        //cout<<" 2nd     tmp="<<tmp<<endl;" ^; }; a, E! w) }. e$ M" r5 r
                        q=NextArc(t,q);, q" V3 L" _  e: u/ u
                    }
    ' ^+ }; z( D, G                if(tag[tmp]==0)1 P+ c2 y( }; m1 i6 n" i8 |
                        s.push(t);  t) T: n0 u4 w6 a8 ^) v. \# R
                    ///1、对应上面连通分支只有1个点的情况! t5 C$ `( K5 k
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈8 }) v$ \- L" i0 ~+ G3 F* o' _/ P
                    ///tmp要么等于找到的第一个未访问节点,, G5 C& r9 ]% R1 K; j/ _* R3 ~3 j
                    ///要么等于与t相连最后一个点(已被访问过)% Y2 e- S, j( W1 c% h* P) U  F
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    * q6 Y. h2 y1 X6 I* r$ w            }- I8 R' @: M  f5 N6 @( {
            }
    1 h& X% `# S+ K' C7 a# Y+ a; Q    }; W# K0 c9 F# ]: j
    }# K1 U, L- M3 m# v4 h. s
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-16 w: f6 a/ a# P, ?
    template<class ElemType, class WeightType> int6 b1 A& I& e, h, R' _3 ~
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    - v6 ~5 f" \: O; i+ u! W0 \{
    * p" |# C* x) s    if(head==pre)8 X, T4 i/ ?: `$ w( A$ e
            return -1;  j+ k+ `/ k4 G4 `

    # H  Z2 v6 Z/ F6 U) U5 x    MultiAdjListNetworkArc<WeightType> *p;* a$ l9 X" k% s2 h7 u' e$ l' i
        p=vexTable[head].firstarc;8 f. `( e7 G  k5 k6 L9 Q
        if(pre==-1&&p!=NULL)1 k) i8 b. T/ E! H: {
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    # ?+ i  i4 Z8 J3 U7 V    //pre!=-1&&p!=NULL- I* [7 ~) G. H7 I3 G
        while(p!=NULL): O! `% X+ h; F  H
        {
    # R( m( b+ G/ r8 b        if(p->adjVex1==head && p->adjVex2!=pre), ~8 A" _7 B8 [: {( W) @
                p=p->nextarc1;7 O3 e" {4 [; K& i9 g
            else if(p->adjVex2==head && p->adjVex1!=pre)
    ! s- [  t7 L) Q/ `4 ^: c            p=p->nextarc2;$ V. I$ F/ k1 G4 f$ |! A2 {2 d2 B
            else if(p->adjVex1==head && p->adjVex2==pre)
    % {/ T  D- |+ f: W' o& @2 A. }+ G9 n        {
    6 F- o6 {4 K4 q            p=p->nextarc1;; l/ d% \; Z" V) ?; C' m- x3 P
                break;
    9 @# h. j! ^6 k; C+ @        }6 J9 x: G9 S/ ]3 P8 |9 u* {
            else if(p->adjVex2==head && p->adjVex1==pre)
    ' s3 W9 v# f: |, `  [        {& K, _4 |4 s, L2 p
                p=p->nextarc2;
    ) w: h& b, N% |; t, I! A            break;. X$ g, Z1 `. z# f4 u4 D# o: R
            }9 T+ n; f4 \* h, }! n( J
        }
    : G0 |4 z: ?  a/ u$ \    if(p!=NULL)
    9 x' r  b. {2 W5 ~* T    {
    3 a: @' c. A# ]9 {7 H/ X$ K        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    ! h- y6 p* \0 S- C! S+ C' n    }
    " |; B& s( j& ^6 R+ [/ R  k$ C1 t    else% H5 e  g' f. l
            return -1;
    + @- n4 P; g7 n6 Y}
    ; ~( |: ~& J, a0 n- e: M# \
    0 Z# |- @8 M9 S+ y" X/ r/ }% f& \, }, M; Q
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    ( p7 q# G  a) l5 @5 s{
    % H! w: A7 O$ \: ]1 D! j  U7 X    stack<int> s;1 d0 A" H. c* C5 {* Y8 {% N
        int p,cur,pre;
    / v& S+ O; x% c% ^! F( Q6 R+ A- v    //MultiAdjListNetworkArc<WeightType> *p,*q;
    7 ]/ l, J. }, g$ n; J5 N6 }- R    for(int i=0; i<vexNum; i++) tag=0;//初始化
    1 m7 M! z( o$ c, ^
    5 ~9 e* f  Y' ]    for(int i=0; i<vexNum; i++)
    % C. n3 h1 d5 @" s    {
    : b2 l! {( T! t9 ], k& |- ^5 Z! B* r( j        cur=i;pre=-1;0 }- j5 X! f$ @: F' @: I  j
            while(tag[cur]==0||!s.empty())# d" }4 |! i+ s( Q6 \
            {
      h- c# T/ \' b            while(tag[cur]==0), A& z# |7 [8 \) T
                {
    3 a! F. o$ k  l3 J3 ~2 a                cout<<vexTable[cur].data<<"  ";
    / }5 W- w7 O2 d4 n- g' J# A                s.push(cur);
    # G5 d; L2 S6 }1 z5 M9 n1 g                tag[cur]=1;
    7 z8 ]+ M7 P% V" S/ S& f               //初次访问,标记入栈
    9 O5 t: z4 `' J2 H; L: X: Q) ~* ^( x
    : O( ]) u7 d* t* }, r: w* m               p=GetAdjVex(cur,pre);//p是cur的连通顶点
    0 ^; j; J$ e) x, ~  @: l- t+ N               if(p==-1)# h4 F2 u$ [/ o0 F4 ]2 \
                   {. D, V, v# r" M( o
                       pre=cur;s.pop();
    7 U9 P1 b1 C+ L                   break;
    - F7 u0 g. b! w7 V9 T- k+ R               }" T7 D* ?3 ^* J, ^) S7 q
                   else# y- h" }+ n" d8 L
                   {. d$ s: M1 B6 E
                       pre=cur;' C2 N. k  w; H: T
                       cur=p;* s' a( O1 f: n9 V& u2 f. [. [
                   }
    ) n8 [) }+ O" Y, s- ^. j! s) `- f) A' U6 p
                }
    ) }9 c8 G4 M; i% a' ]            while(!s.empty())8 N- L  P. F& I/ p
                {
    ' }* @& [7 H+ h3 A% a' U                cur=s.top();/ U# f( _4 c% H9 }
                    p=GetAdjVex(cur,pre);7 Y5 t5 o1 `  B2 c* S9 i5 P* {
                    if(tag[p]==0)
    5 |! e+ y# h( I" t4 ~                {* d9 ]8 W9 n, `
                        pre=cur;7 R, }4 E/ W7 g/ x
                        cur=p;
    # I  }  i+ u8 J" c6 i; `                    break;
    + G8 b8 i; {. L" g1 ~1 ~                }
    # i& D# ?: t( E1 r$ f, S                else
    ! |2 c- m4 f3 y2 i1 a: H                {
    0 \5 B2 h) o( g                    pre=s.top();
    8 E! N7 e* F' [& s6 F                    s.pop();
    - G- s( {, @0 F                }8 m% h, [' T% f5 F* R+ K
    ( s) E. E$ [; f9 a, K( {; i& p
                }
    ; p6 Z' q" X  @) @( I! J. t
    5 D* z" |, t! k; m. G        }
    $ c9 X- Q2 ^) h+ _9 S    }- \% I5 }4 Q/ D7 @4 B
    }
    # ]9 c& I  P( X2 L9 m. g+ }template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    & Z" i. ~# q+ J8 [0 ?2 K8 I{
      K8 D' C  A" C. X& C/ J0 a    for(int i=0; i<vexNum; i++)# T5 U: m2 @, j/ F! D+ @9 g
            tag=0;
    7 Z2 d% m) p& K: g    queue<int> q;; J, Z2 N- H% q: e" h( F8 f! |
        int tmp,t;
    1 Z2 f2 y8 h! V! \  i  u5 {$ x1 C    MultiAdjListNetworkArc<WeightType> *p;  G# k3 b$ f0 a' q6 G. V/ t$ g7 U
        for(int i=0; i<vexNum; i++)
    7 E, U: r6 d5 i1 L1 e4 a" W    {1 t# i$ [; Z/ R1 e1 B1 c
            if(tag==0); V4 x& }3 f- G4 p/ c: T7 z
            {7 `* Q7 `9 f! J- {5 S2 M; v( r
                tag=1;
    1 Z9 b- Z$ x  p# B5 g$ r4 ?# ~            q.push(i);
    ; \8 w- ~  _9 \/ W$ L            cout<<setw(3)<<vexTable.data;
    & L6 J$ Q8 ~. E- Q        }
    , R. H8 \2 V- a% O) D. W        while(!q.empty())
    ( C" _/ e) ]/ `6 v8 _6 k. U        {  t. m8 J# a/ R, F- G% ]% K
                tmp=q.front();
    + A7 d8 e  E; X: y8 [& B+ K            q.pop();
    - f" n+ ?* m, p3 k6 F  S            p=vexTable[tmp].firstarc;; x1 Y+ T" L: t( h  \
                while(p!=NULL)  p4 F5 A, n& S1 a5 E3 M# W" c
                {
    0 w# s6 a; m0 L8 H4 L                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    8 C  K3 y0 a9 E+ F, v5 b                if(tag[t]==0)
    5 D7 M' J8 t2 i; p9 k                {
    3 J3 X9 W% X( G) {: R5 q0 s+ A! U                    cout<<setw(3)<<vexTable[t].data;
    ' m* n8 D6 I3 i% {# k/ B6 f2 U                    tag[t]=1;
    % A+ y$ a+ Q1 M1 R) Q                    q.push(t);
    , E& S$ O* X3 s, l. L                }" ]0 }( w  i1 C' K
                    p=NextArc(tmp,p);( v  [2 P: ~. }7 r
                }
    : j* f5 `) p1 {3 M- S2 |0 y/ C        }
    % m6 i8 M* t# Y& A    }# ~8 d' Q' Q6 {
    }
    $ J# `2 z! u( W8 i% Ptemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    * n- y' O$ p" Z6 @& t2 M* O{3 R" }, _; i' y$ |
        MultiAdjListNetworkArc<WeightType> *p;
      Y6 B$ A% ^: Q' q9 ?; n0 J    cout << "无向图有" << vexNum << "个点,分别为:";
    9 B% p, k1 V0 c    for (int i = 0; i < vexNum; i++)
    7 a' e" I( E" ^8 q: m/ e; C        cout << vexTable.data << " ";' S3 ~9 A0 l: S! K! q3 M* ~: h
        cout << endl;! u% _/ o1 Z& K7 ]' y3 a/ _# c
        cout << "无向图有" << arcNum << "条边"<<endl;
    . e! B' \$ e% ?    for (int i = 0; i < vexNum; i++)
    ) H# ?3 q8 z6 ]    {
    3 ^) V1 Q" U6 ~8 k1 Y4 W        cout<<"和" << vexTable.data << "有关的边:";
    ) U. C% Z4 E* M" V# C' V# g  Z7 K        p = vexTable.firstarc;
    ' O$ @2 i% W& X& v$ x        while (p != NULL)# y4 {. ?6 h# T4 h$ |: r4 N# k
            {
    6 @  p' g) q2 J3 D6 a            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";  |; a! q& o2 n+ u
                p=NextArc(i,p);
    + p1 B+ q" Y$ _8 ~* ?        }! K3 g* K: b3 ^5 Z" q3 j
            cout << endl;; M$ I- }) d4 Z2 P3 \
        }" P( P4 O  C( _
    }
    % R8 Z: e% Y7 u) e& F; n
    & }9 {( Y2 W; X  b1 n; d" A- o& _
    0 W8 X# p& @! X) j( K. I# l% v邻接多重表与邻接表的对比
      b( o& D# b9 f/ K5 j4 Y  o' \- {& A; B( [7 B+ q
    邻接表链接
    1 f6 X, B) ^* z( p6 P在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    - _$ P, W! a8 Y0 `; o! K1 v在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    / l' x! `0 a; J' R9 c; [9 M9 @为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    9 ?# z9 {% u! |, L# U————————————————
    ( Y* L- d/ a* ^; Q) l% D% }版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。% O* D6 y3 |2 J3 N
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    7 v2 K# `' u" \$ G
    - N1 d9 H7 N2 D& ^, H/ `3 H4 ]7 l, C

    6 Z8 v  K9 ]0 V' F' \/ i/ s7 c4 S* f6 @! c8 Y5 b
    ————————————————
    6 F: z! e' q& f! Y版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。% B) r2 |8 `5 n" _9 h1 t  U- m0 X
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958# X0 g, e. X  U" @) ]

    7 k' V8 r9 J# [' @1 c& h, m
    : W; j: P$ q! d, ^5 r  v
    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-12-13 03:00 , Processed in 0.747987 second(s), 53 queries .

    回顶部