QQ登录

只需要一步,快速开始

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

    + ]/ O! l% i. z$ o图的存储结构——邻接多重表(多重邻接表)的实现
    2 t8 V6 n* Z* E) ?6 @6 t- r7.2 图的存储结构
    " q( b. r# O. \' b4 Z1 X
    , r! z0 Y% b$ j) }! c3 t7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    ! v2 P" N7 O5 j; q. D( S; j邻接多重表的类定义
    # H3 X" n  ^1 T. t: h+ e4 N邻接多重表的顶点结点类模板
      g8 _5 T6 t" r9 d- s) O+ O# O邻接多重表的边结点类模板
    - K% Z1 Y  O' d* c2 u5 R邻接多重表的类模板( c9 ~9 }/ ]1 H7 H% e: m
    邻接多重表与邻接表的对比
    " K" A/ d- I1 o1 T$ ]8 D; Q7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    - c' M/ a  F) X! E+ Y3 h+ t! j8 K% y! ], P' k
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    ( f6 W/ T, i% R! n+ b在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    % Q. V/ Y4 A# C2 e  B! W5 s) p! J/ ~* O0 A1 J9 ?4 J1 I% i
    邻接多重表的类定义
    % ~2 L+ g8 Z* O3 S8 h9 y3 Y! Y 1.png
    7 E# ~8 T; i; Z! _邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:! `' l. s7 i, ]0 I
    data域存储有关顶点的信息;
    ! R' D( A0 z* F, A7 bfirstarc域是链接指针,指向第一条依附于该顶点的边。/ ~) T( I$ A9 l
    所有的顶点结点组成一个顺序表。

    - t. {/ v! O) V0 C+ p9 L
    1 _2 P9 D, v, y9 b. r" F- d
    template <class ElemType ,class WeightType>. z6 t) A6 D) r$ H6 `8 [
    class MultiAdjListNetworkVex% \4 o. O9 e% h2 h4 y! {
    {2 _7 ^' ]; w$ m( C1 k5 g
    public:6 {1 i% n+ l# g$ ]( _# R& j
            ElemType data;* ]6 [+ b% y2 K9 N: n  }/ H
            MultiAdjListNetworkArc<WeightType> *firstarc;* n1 p5 N" o* G$ q& y0 o9 i

    + E; z; o( F& l. k* W) @6 v        MultiAdjListNetworkVex()
    ; [: Q& a. r/ r# E9 k/ y        {
    & ~, g# j% \; ^' [$ d                firstarc = NULL;1 k5 P# [4 i6 Z$ s: ^5 R( Y/ J/ R
            }
    ' r6 ~7 L) L# O  l        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    & ~1 z3 S/ G5 C) n        {
    ' q" K0 J% ^' [5 _+ W1 Y- X                data = val;
    + l7 A! {3 Q/ `* o/ i                firstarc = adj;6 f3 }/ k2 z$ ]) ^% z
            }' g6 P" e$ A, V4 V& n) Y+ D
    };' A# N$ P1 e# L9 p6 f, d4 p6 k! _

    8 U( R! ^' R. k8 |0 j邻接多重表的边结点类模板: L& `5 e3 O8 R+ _" x) F1 v

    $ S" i& H* L& p! m: C- D在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    $ m( G; `( ~! i& I$ ?& |9 z4 [tag是标记域,标记该边是否被处理或被搜索过;
    1 C$ O- m" x) V8 |! [weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
      R4 {! v, e' [( z4 {# l6 `' k2 Z0 ^3 Bnextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    " x8 Z3 N' v' R3 ~5 a2 {nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    - {8 N6 n# W" q! C( h( j
    : S0 E# g/ Z; b  l9 F- i2 @# B 2.png ' P) U% x: w. P' _
    template <class WeightType>
    ( _, ?% S2 }& Z( vclass MultiAdjListNetworkArc0 u2 j4 C/ w, |- C" O! r! M
    {+ x8 F; [5 t1 R7 M& V) M5 h+ o
    public:+ _! W0 _' z, D5 |7 m" e8 B- C! }( J3 r
        int mark;                                       //标记该边是否被搜索或处理过* R8 N' Y0 v2 q% s/ w. |, d2 y# G
            WeightType weight;                              //边的权重
    $ Z1 M  E: v8 Q7 i        int adjVex1;                                    //边的一个顶点$ S; A; Q% o% s
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1  T7 g8 Q% ~# v% m+ w
            int adjVex2;* p3 N( `  ^0 m% O4 D1 _( m( a& v
            MultiAdjListNetworkArc<WeightType>* nextarc2;
    1 \: D0 g( a* f& ~- d2 b1 H; b: c* ^9 b) ]( g5 k" A6 |" c  y  H8 n
            MultiAdjListNetworkArc()
    2 s/ I' Q! z" w8 Q% E) R        {2 k$ u! l/ [) c1 o
                    adjVex1= -1;
    2 b0 L- \& a1 h  |/ I6 e                adjVex2= -1;
    ) w# |. o) y5 C% F        }
    ( b( ^" R7 V8 S  p( Y( Q5 W- u        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)! ?/ V0 y! o" b# O
            {
    ' s* w6 Y2 q# F8 d. ^. W                adjVex1 = v1;       adjVex2 = v2;
    , J+ r; `8 C! t! s                weight = w;( g# b. T" m. |$ k0 X$ _6 @
                    nextarc1 = next1;   nextarc2=next2;! i/ ]* o) ~7 i. A/ ?6 L
                    mark = 0;           //0表示未被搜索,1表示被搜索过8 d! V( S' @- _" r
            }
    1 J6 h1 o, v" w1 d0 F. O" O( d; ]4 s& m. I" a& n9 s2 O" d
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>5 i6 a) a1 J* {' P( g. f
    class MultiAdjListNetwork
    , g$ @* f$ v8 c! q' k$ {: i  z' g{
    ( H4 ]8 B4 M, k) U$ @protected:
    4 s/ M4 @$ p5 F4 |, h    int vexNum, vexMaxNum, arcNum;
    4 O# E8 f7 i8 ?: c+ U    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;2 a% U( F3 }* ?% f* p8 F' i
        int* tag;
    1 v7 f9 A. s$ ?5 R0 n* `5 H    WeightType infinity;+ P* I1 i. c9 g0 ]2 Q) \
    7 i$ ]' x3 ^  E; Y3 H; o1 P! H
    public:+ w7 j) r/ b5 R, W+ X* H
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    3 e# p; T: c: ~, x. ?2 }2 n2 O8 P2 c
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
      I8 `$ h- @" k& u  u0 _6 A9 k' d6 k  s# e/ D3 {) D% E
        void Clear();+ n8 e6 n! N& H8 b( V( ^" {
        bool IsEmpty()7 F- _9 Y$ ?; A* U# Y
        {
    8 n* ^6 }: t7 M3 i5 y# _        return vexNum == 0;
    : i% k9 O7 F6 F; g' y    }
    : _- [0 M( \9 o) w6 c; L  q    int GetArcNum()const
    % q' |  L* S6 I    {% }) r  Q2 i0 }; U! H$ M
            return arcNum;2 s( R# }8 y7 b5 o; x& n0 F* G
        }" ]- w8 z' T# \5 M" }
        int GetvexNum()const" U+ S0 F% l0 b/ H, R# S
        {
    ) b; A# b/ F/ F3 \, x/ W4 ]" k6 X        return vexNum;1 u$ p% E1 `( z1 [4 i  z
        }- u& X( ]' j; o4 J, U% H. i2 c
    0 e1 h- R1 J/ d& I( m( Q3 b; m

    # ?* \. ]/ R9 V0 q% ~    int FirstAdjVex(int v)const;5 |# K7 v3 ^; H3 F) ~
        int NextAdjVex(int v1, int v2)const;
    + |4 X$ s/ i. x  R/ u% \- T    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    ! N) y) {+ O. F5 @1 C( o/ M3 m    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    ) o( V# ~% |( B) \& N  J+ H0 L. ]/ ?
        void InsertVex(const ElemType& d);
    + F9 H+ q  X' X2 C    void InsertArc(int v1, int v2, WeightType w);
    2 y/ L: _- Q( G# s) Y. E, `: K/ O  K( D2 `
        void DeleteVex(const ElemType& d);8 I+ m) R! z2 O. A* C* U4 x
        void DeleteArc(int v1, int v2);: v! {- @# k! R# N# G! K! I8 I

    , t* B( e) A5 j% h2 ^0 P    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    ( _. J  P0 e. u9 k5 Q    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);; R+ p; y  G$ Z: h+ w; A

    ; |6 ^. \4 D% |% ~' [    ///深度优先遍历  v5 c- Z4 w$ d5 V
        void DFS1(const int v);
    3 e/ A2 R: r% ^7 {* s  {    void DFS1Traverse();7 K% Y/ O5 T7 Z' l6 r. e8 |
        void DFS2();3 G0 |; V; X% p. E% v/ c

    9 e2 J) ^; I$ `) E    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    7 {8 ~! x# H1 r" M    void DFS3();
    8 p0 z+ K: z! M7 Z, T1 a& C4 y
    ) s) L" ^& n/ T- z+ O    void BFS();4 Y* g" l* u4 k* Z( k' S$ E
        void Show();
    2 ]+ `7 {9 u" \};4 ?* C" a/ m' t& K3 }. m6 F
    # G+ X* Y6 y* t
    2.函数的实现& H9 }4 y+ F/ k# t4 q
    研讨题,能够运行,但是代码不一定是最优的。; B9 I% C: W4 }: }$ f  ?% Z
    5 |% s8 x6 h; p% f- w  p
    #include <stack>
    0 x$ N9 ?- }5 s5 X5 r# u2 }#include <queue>
    / n& {8 y( {, v" ?  I3 Z
      B: A  c" r3 A( a/ s% r' M; ztemplate <class ElemType,class WeightType>9 f" m9 T0 ]1 f) J9 N3 [( C
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)3 U& z" _" ~( K& T* [/ e
    {
    0 ~% j3 t: Z1 M: ~  j; o7 a7 O    if(vertexMaxNum < 0)7 V6 z; `! A3 R0 s" @) m" {
            throw Error("允许的顶点最大数目不能为负!");
    ( s* r# T% x" I) A/ ^    if (vertexMaxNum < vertexNum)
    ; v  H6 G0 H7 ]. q% O$ Z5 o        throw Error("顶点数目不能大于允许的顶点最大数目!");  }. f- G8 d7 b
        vexNum = vertexNum;
    " a/ _% M% e$ W7 x: w& w    vexMaxNum = vertexMaxNum;
    - {  Y8 I0 b& H8 V    arcNum = 0;
    # G! r8 f# K1 U# O    infinity = infinit;4 f: A2 J* X  j% |' B
        tag = new int[vexMaxNum];
    9 A- F& `# c3 t/ w( v    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    . ~/ C! K! J$ A" a; V& f/ p3 g6 Z    for (int v = 0; v < vexNum; v++)1 F0 Z) u+ d$ x, E$ S7 X
        {; u0 t% g$ u% g. H
            tag[v] = 0;: i% O. e: R: a( ]2 v
            vexTable[v].data = es[v];
    3 a* A* x2 ^# R8 J8 j$ L        vexTable[v].firstarc = NULL;3 k0 i. B3 G9 \0 X% `- I( }9 ^/ O
        }
    ; j. w! H2 R# o, ^$ S, ~: I$ I7 i}
    - c* @3 _( q& Q: _0 ntemplate <class ElemType,class WeightType>1 C- M4 N# R) ]7 d8 O
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)# s1 E0 m* C  t, @  t3 y+ O9 C5 U
    {
    3 B+ J2 l$ I% J    if (vertexMaxNum < 0)
    2 |$ Y& ?+ q( Z* r; z        throw Error("允许的顶点最大数目不能为负!");
    8 ?, M) n7 `. x' x; R: E    vexNum = 0;( L4 s. I! i/ G5 T8 d9 t' S( w; [3 x
        vexMaxNum = vertexMaxNum;
    5 S" N3 ~( I7 S5 ?6 K1 d! E    arcNum = 0;& T! Y& H, s. f3 \# |5 U' H
        infinity = infinit;
    * T6 l6 g1 x# n1 f9 }    tag = new int[vexMaxNum];
    " c1 o3 z7 O3 x2 V3 h    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    0 Y" q" k5 Q$ L9 o3 s}
    - r8 I# Z0 d' O0 g" P1 X9 Q" Btemplate<class ElemType, class WeightType>
    " ]1 \4 {, c& U! f) }' {8 uint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const+ a6 D! J$ o, p' @- {/ ]
    {
    4 \% E( X; [/ T/ V( p8 b+ m    if (v < 0 || v >= vexNum)
    3 l# H9 a/ c# j- c2 J        throw Error("v不合法!");6 {  y- s& ~: o' o
        if (vexTable[v].firstarc == NULL)9 E7 V4 m/ s9 A3 s
            return -1;
    9 e$ m, [1 _+ X( @7 K& ]$ ^4 W    else
    ) b" W) r* j( P0 i7 e2 @  P4 E        return vexTable[v].firstarc->adjVex1;6 x9 o0 d% E+ z
    }
    / d" E  R: u0 N/ m) [0 j8 e. {& }8 @- R3 \/ \2 w
    template<class ElemType, class WeightType>9 i0 T! T6 M: K' n/ p1 k% S
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const7 i7 O6 g5 g3 S5 U3 B5 W
    {
    5 F. f# n5 t8 U- x0 A    MultiAdjListNetworkArc<WeightType>* p;
    . N. Q9 j. l. i1 e    if (v1 < 0 || v1 >= vexNum)8 q& g5 O3 u+ A) g( i! f9 R( P
            throw Error("v1不合法!");
    ' I$ R) V# k+ w0 ^' v3 q    if (v2 < 0 || v2 >= vexNum)5 s) x5 R$ j% `8 l
            throw Error("v2不合法!");
    ! ~( [5 [% s9 T& X; h    if (v1 == v2): h. }/ X4 D2 }3 Y+ k
            throw Error("v1不能等于v2!");
    & t7 X+ Q6 j; f, G. Z    p = vexTable[v1].firstarc;* G+ y( l# B) Q  v3 [, w8 T! u
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    9 Y5 E, ~, a  z4 F* r: X& r        p = p->nextarc;# i0 d* t+ ]  _' O$ ~7 b! }
        if (p == NULL || p->nextarc == NULL)
    - Z4 s( r, s5 u" w        return -1;  //不存在下一个邻接点
    ! p7 D; ~+ P5 x    else if(p->adjVex1==v2)
    & G( ?/ T4 H6 i( m: D        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    ! `% m. i6 [" a$ R/ r; y    else+ [* D% z# e! }; Y! ]3 P0 m" F1 o
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);, w* e+ a: L5 A) `5 p: ]- G; r
    }. T6 a, ]% b5 m/ [
    template<class ElemType, class WeightType>2 h. y: K, n/ h# B
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()
    * Q4 Y5 N+ y# X7 w1 \! a6 k{2 ^# R$ j% {. F
        if (IsEmpty()) return;7 c7 O" w- N1 J* N/ Z. D
        int n = vexNum;
    # ?) z0 B3 |* W1 E% S6 q0 v    for (int u = 0; u < n ; u++)
    7 u* ]$ e# P8 t- r1 y! u! X        DeleteVex(vexTable[0].data);
    7 Z' \' `* @9 S8 l, G# }1 B    return;$ Q4 b3 D- d9 C' h+ L
    }
    4 C3 o( e; l5 J' {' u3 Y- ztemplate<class ElemType, class WeightType>
    * I$ J& k  T$ R- k: A) GMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()+ d1 A) v; H3 M4 B  s
    {
    ; _2 K' r$ v; C* W  [9 S    Clear();
    ! l1 b: i  Z2 s0 e}+ R  Y0 N* C% L
    template<class ElemType, class WeightType>; x( z4 m5 K; `7 F5 p6 g% c
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    % P) r( h" m3 I( K+ K6 O* v{
    3 N& M9 o9 q9 e* z- a/ [    vexMaxNum = copy.vexMaxNum;
    7 |" \! G. b3 F# U: R5 n2 q    vexNum = copy.vexNum;$ a8 M; r2 h6 @( w' k  _
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];4 {- |+ U9 X( o  Z9 ~" |
        arcNum = 0;3 X0 A; G6 x1 w& k, P* o
        infinity = copy.infinity;
    : ^+ M3 _8 \9 q; P$ `6 C    tag = new int[vexMaxNum];7 J0 B$ ]. T% P9 ]

    + H# y& I5 u) K$ K& s% K2 }    for (int v = 0; v < vexNum; v++)
    1 G! Z. t9 S6 e* E    {+ W* l+ v# \) }% T' Z
            tag[v] = 0;8 h; J2 ^, ^4 _# m5 \4 Z
            vexTable[v].data = copy.vexTable[v].data;5 T, p4 e) j8 e" T; ^
            vexTable[v].firstarc = NULL;
    , U9 j7 k% d, r    }; s$ V( t2 k1 |5 p
        MultiAdjListNetworkArc<WeightType>* p;  ^* n+ W( g, Z! b: V+ D
      @  I3 [5 \1 b$ f
        for (int u = 0; u < vexNum; u++)
    7 e' l/ ?0 W5 i0 i6 h- D3 l    {) W2 y) }. B$ T* E; I3 D9 p
            p = copy.vexTable.firstarc;' V$ F( w' b1 j- _  v" G( C  W/ Y
            while (p != NULL)
    ) u+ X" d8 D, n3 |4 ?9 ^9 f        {% B' C7 O1 i( |! \
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    . P7 \! z/ \& E5 o            p=NextArc(u,p);. y0 C5 @2 O5 @
            }
    2 X; q: g; X: r% X7 V" P" W, V  u" p    }8 S1 [7 F/ V2 m  @' r
    }; p2 w5 M$ d, g. \* t: H/ j
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    7 G; X& }' Q. V3 }- j+ R& DMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
      }* g+ x! R% }" I1 S9 X8 D{
    ) T- @4 p+ B1 x5 o1 E! ~) q    if (this == &copy) return *this;) [& P9 b( C' P, ^' }
        Clear();4 d2 ?! ^/ M4 X2 R- F/ U5 i
        vexMaxNum = copy.vexMaxNum;* p1 v3 T. J% @- Y, D
        vexNum = copy.vexNum;
    4 a: _& t9 S: h1 U    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    6 Y5 C) G$ ]1 G& L5 H( X* ]% }    arcNum = 0;. v7 _6 l0 t* s" E' I7 x1 t% [
        infinity = copy.infinity;
    9 B2 t. B# z& r+ @# X# m: H    tag = new int[vexMaxNum];
    / y5 q7 E+ y/ ?" P
    * w9 ^/ Q, s0 f4 L0 v$ l( T    for (int v = 0; v < vexNum; v++)
    - z; w; \1 ~8 t! p8 g6 T    {
    7 v8 H% q0 @/ e        tag[v] = 0;  D5 B4 I2 K& s) I
            vexTable[v].data = copy.vexTable[v].data;
    2 J8 g2 u6 j  u9 j( [' U$ M        vexTable[v].firstarc = NULL;
    3 w+ t- z# ~3 o- Z  F/ N    }, J7 A# I! H+ d, G7 p& j
        MultiAdjListNetworkArc<WeightType>* p;
    2 M: [- |& k3 z
    ' n2 l/ Y  O9 `- ]: Y7 O    for (int u = 0; u < vexNum; u++)
    5 h% W8 a8 Y" X    {: R8 V1 W2 u: r) V
            p = copy.vexTable.firstarc;
      h' A6 _3 Z# a        while (p != NULL)
    1 ]: `6 D" P- O$ t4 ~4 `        {
    . |& n) q, T# [            InsertArc(p->adjVex1, p->adjVex2, p->weight);+ A+ ^7 }4 c7 |4 O* o8 [
                p=NextArc(u,p);" t1 j+ C1 X9 x0 e9 }/ z! t
            }$ Z' r9 F+ e8 ?$ h! G) R
        }
    4 z3 Y- e- n+ \# F) ^7 K& a# W( `    return *this;
    - u: }3 i# W" J  L5 F! P}
    * n  O1 Z. d. K6 U, Wtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    " d9 [% I% Y' C6 P. J& xMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const/ e% b- U/ d1 s3 d7 G
    {
    $ {, D  j" c7 O    if(p==NULL) return NULL;: h) |$ r  Y* [6 |' ^' B
        if(p->adjVex1==v1)
      n* }9 P; M: q( {        return p->nextarc1;2 E) C, H# p- g4 N3 B8 [7 @* C3 t: }
        else
    ( B/ L: `5 P* k4 j2 `4 l1 O        return p->nextarc2;' |1 i, Y& j) u/ g5 X" A
    }* N1 o3 {3 X" F, c! j+ ^
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    , P% j0 i$ E0 V* j5 E% Z. BMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const! S, i, ?' W0 J2 t
    {
    " E( n5 F1 g) s: @+ [    if(p==NULL)return NULL;
    , a1 b# j, @% ~' i" Z    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;# M5 t3 p8 u8 w0 E
        if(q==p)
    & g# X* i  r8 M6 s* c4 q, j        return NULL;
    8 I0 J# W: }6 @5 @8 u$ j4 E/ b# O$ I    while(q)1 Q) _" ]) B  m- G: V5 ]! k1 Z
        {
    5 C$ U9 _3 J: T+ e        if(q->nextarc1==p ||q->nextarc2==p); }5 T& `* ~: R' Z
                break;3 L1 M4 p+ g6 K: E+ i+ |. M
            q=NextArc(v1,q);
    6 g1 D* A" M4 Q/ @4 t    }7 X; o( w; \8 g1 J% V% b
        return q;
    $ I. S0 ^" M. }: |% n% L}( E% s1 l; X5 [/ D, \5 ?
    template<class ElemType, class WeightType>
    . [/ d# \- |0 M" o; Dvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)  f3 w/ |- y  _, ^1 t
    {
    - t7 [$ g: m: e) {    if (vexNum == vexMaxNum)
    6 B. B4 S0 W/ [        throw Error("图的顶点数不能超过允许的最大数!");/ H' D( [5 T& R& u/ ~; h  u/ Z! ~) M
        vexTable[vexNum].data = d;1 i* d% H" ~* p  [5 I" ^
        vexTable[vexNum].firstarc = NULL;& h5 k% K* Y$ [! A& B
        tag[vexNum] = 0;
    9 [- q# p4 j6 a. G5 e    vexNum++;4 a, O& r6 l# l! ~' q" V( m* l$ }
    }
    " A; l  T# V6 y# Itemplate<class ElemType, class WeightType>; v0 O* ?/ `/ p% }+ k
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)& B% [  z" Y- ]: g$ U
    {. {8 V6 z* j' f4 y4 F3 s
        MultiAdjListNetworkArc<WeightType>* p,*q;! g; X$ M) t2 o8 l
        if (v1 < 0 || v1 >= vexNum)+ c; {/ A( P2 q( Q0 ^0 Y
            throw Error("v1不合法!");
    ( \: r+ p* A& u/ |" I' O" a    if (v2 < 0 || v2 >= vexNum)
    # {( ]9 _! g7 `* O; u% |+ F        throw Error("v2不合法!");6 }7 {# F: y2 p, J% ~
        if (v1 == v2)0 B- q1 ?2 ?  D  G3 ]# R# h/ F" Y
            throw Error("v1不能等于v2!");
    * e7 ~- P6 M8 v0 I    if (w == infinity)! A. n/ Z% R2 i
            throw Error("w不能为无穷大!");
    " i; d* f8 n9 N2 V$ W2 @
    ) L5 _) Y' ?5 M% ]$ |! j
    $ M' c0 ?% H9 A% K    p = vexTable[v1].firstarc;1 N* d5 {" B( x$ L! H7 U* N
        while(p)) C9 L) k9 _# M5 e  \5 p, S
        {
    " |& y& d% V. g9 I6 I6 `0 ]4 \        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中8 D5 N+ I3 D  |* O7 ~* b) M
            {/ @1 b9 m, Y$ u, X) Y' R- x  f
                if(p->weight!=w)
    . T9 q. i7 e% d1 P8 H+ `* Y# b/ @                p->weight=w;
    % E* w+ m, L6 A; A, F; W/ j+ ]( G7 z            return;
    . @) L4 w0 S+ x9 J4 t3 ]        }
    - @. H- `2 R3 @3 l( Y
    0 Q; k* ~2 f4 A        p=NextArc(v1,p);3 E6 u3 h" J: q3 k* Z+ {$ G
        }: s# h$ Z( _9 T4 ~
        p = vexTable[v1].firstarc;
    # I& w0 q8 Q) e3 y1 w  y. Y/ ?& S    q = vexTable[v2].firstarc;; l1 `4 {" k) U  t- r
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法1 `' Q/ k8 c0 g
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    ) p! S5 s( N6 }) z: T    arcNum++;
    + K' b! u" e+ y7 f0 ?5 Z}
    , o- U* x/ I9 j6 |" L
    " F: m9 h; x5 V1 u( Jtemplate<class ElemType, class WeightType>1 j5 e' y* f2 `7 D! U
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)$ R" ~, O( P3 P) `# J
    {0 E, x. `- b! O: T1 z& t3 i

    - p/ W4 J, n( R    MultiAdjListNetworkArc<WeightType>* p, * q,*r;; S4 l3 v1 c1 E9 k8 Y
        if (v1 < 0 || v1 >= vexNum). F6 R- `7 u; E
            throw Error("v1不合法!");+ }6 E. K1 l$ _2 t2 l7 d" U5 O) _
        if (v2 < 0 || v2 >= vexNum)' V. Z* C; _; F! R: D  v" T; m" w
            throw Error("v2不合法!");
    ' _( p: e9 G2 p$ b4 g% v; [% o% n    if (v1 == v2)0 M5 I8 W% B& Y& T) T
            throw Error("v1不能等于v2!");
    % C( Z* B: o; {# B
    ' m) R/ {; c( s    p = vexTable[v1].firstarc;- F; D$ K1 Z. x4 Q
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)( N* P' b2 }' M% g
        {
    . ?  X9 s0 m: _% U1 i0 n) [/ F        q = p;
    9 ?: C$ ^: U8 J1 `        p = NextArc(v1,p);# \# W! z- ?" q- F9 C
        }//找到要删除的边结点p及其前一结点q4 y7 ?4 V: o! k; p

    ! j3 q" `* `* |6 K    if (p != NULL)//找到v1-v2的边% |; K7 l. ^. n8 o
        {
    4 v! w! h; e1 a! [        r=LastArc(v2,p);
    . T9 F# d) K- \, g        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    " N$ a# a) T( [7 p2 m            if(p->adjVex2==v2)
    9 \: r8 j' X+ j                vexTable[v1].firstarc = p->nextarc1;5 h# G. k0 n/ p
                else vexTable[v1].firstarc=p->nextarc2;
    , a# m% A2 L/ H2 o        else//不是第一条边3 C4 J3 T3 C! P; q/ S9 H
            {: k4 f) W. u' v$ x
                if(q->adjVex1==v1)
    ) ?2 v. ~: ^3 F+ h, p! l9 D* g9 x                q->nextarc1 = NextArc(v1,p);
    / w9 j, @& y+ O, \            else
    ) A$ Z* C6 H: s                q->nextarc2=NextArc(v1,p);5 g. l) d8 w3 _; ?( O8 `% b
    , Z3 ]% h" W8 A! x( v2 Y0 N
            }
    . q: Z, Y, G% s5 o& J( Q, R        if(r==NULL)
    , C8 ~) F5 ^+ ^! t, U) c            if(p->adjVex2==v2): B) h( D( z* l
                    vexTable[v2].firstarc = p->nextarc2;7 U+ F1 h* A+ o; ^0 K+ t3 a. q
                else vexTable[v2].firstarc=p->nextarc1;
    6 [/ l$ Y  {; M& D4 u3 ^3 O* R% N0 G        else& H3 u0 p, t/ W: c
            {
    4 @4 ^  v9 V+ m. \            if(r->adjVex2==v2)
    . V: S( j& U; h! K+ O                r->nextarc2 = NextArc(v2,p);! k  P/ o; ^3 Z/ V: B- s, z+ y8 Z
                else0 O9 |7 P9 P% H5 u% d7 B/ Z
                    r->nextarc1=NextArc(v2,p);# x! h1 z2 h& d
            }! D+ u. D5 z9 w7 I3 l: K
            delete p;
    & a# B+ P4 }5 Y8 d& k: a        arcNum--;
    7 }  m) X& a8 x, J    }
    4 _0 H3 u) m$ S# o& y
    ) i- F. Z+ ?1 q8 J- i5 X}
    $ k3 r5 D& i* q: E. ]8 z( J( Ftemplate<class ElemType, class WeightType> void+ N  t: Z! l, [8 Q
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    5 ?. [* j! a( `5 B5 i8 J  k& X# n{) e$ Y$ U) Q- a, H( g
        int v;
    . A+ _- K. |5 W& G" d, a7 {- t    MultiAdjListNetworkArc<WeightType>* p;% a9 u5 \: \& h% d5 ^+ p" q2 k
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    # [& W' D- N4 T' f$ y        if (vexTable[v].data == d)
    : L/ m1 z2 i. a8 M& V            break;  M! u) a% }6 N5 u1 J2 U
        if(v==vexNum)8 r0 j2 I$ P& Z* y+ T( n' Q
            throw Error("图中不存在要删除的顶点!");9 Z2 q6 c4 a; V! ?3 I
    9 G  s; s7 w; p! o3 f$ A
        for (int u = 0; u < vexNum; u++)//删除与d相连的边
    , c" g+ m/ z9 B/ T  n! ?        if (u != v)4 b. i1 J1 N! A+ F; t# K
            {
    ! \  l) {  p- c' ?, Y            DeleteArc(u, v);- H# g' f' s% I9 C
            }
    3 K. t4 h* E% O9 S9 X+ k8 t" _( y    vexTable[v].firstarc=NULL;; A2 @. l$ T; J, \

    4 R+ b- v! u) l( @# f    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置3 ^% V; f- r4 o* q- |0 g2 l
        vexTable[v].data = vexTable[vexNum].data;9 E$ G) a' Y9 r
        vexTable[v].firstarc = vexTable[vexNum].firstarc;8 D8 k6 e- l2 a. J" f# }" F$ L, T
        vexTable[vexNum].firstarc = NULL;
    ) B4 e+ b* i! v5 i9 V+ c/ q    tag[v] = tag[vexNum];! R9 ?0 k& u7 g7 s- ?
        //原来与最后一个顶点相连的边改为与v相连, G! F7 m& j5 |3 j! z2 Y  l; C
        for (int u = 0; u < vexNum; u++)
    ; ^' a! Q+ v) y+ ^( Y: X# Z    {1 J* R4 b: ?) m4 U0 A
            if (u != v)
    % ]* E: ?! @5 b7 k' y9 S        {2 R9 O: C/ U# F1 A9 D
                p = vexTable.firstarc;9 ?% j: }5 Y. d" M4 Y  C- m! A
                while (p)6 c8 P5 B- ^3 c, m
                {
    3 c! V6 s+ k6 L2 I7 Q" [' C                if (p->adjVex1==vexNum)- H0 ~! ?+ ], \3 s: z
                        p->adjVex1= v;, ~7 L6 |5 [$ w7 n5 O! O. x
                    else if(p->adjVex2==vexNum)" K: e" k$ n8 I
                        p->adjVex2=v;* j6 V, R* w" b
                    p = NextArc(u,p);
    8 M' l3 ?3 T( h5 k            }( P8 v0 J2 f6 J* K2 e. u
            }4 ]2 s4 m" y" L5 @" Z3 C! J! t
        }5 E5 }& z( g7 @: R
    }+ p, \8 o. W9 s0 j3 W* Q: R
    ///深度优先遍历1 }# G# i! U0 l
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    : H7 R; N+ Q& @- o{# L4 k9 s) y9 e* w
        tag[v]=1;$ w: x# A3 [4 V+ f( k
        cout<<setw(3)<<vexTable[v].data;' @5 W8 H( G- Q9 d) ~4 b- @* X
        MultiAdjListNetworkArc<WeightType> *p;
    0 T3 Q5 o- j) u/ H# S9 C% [    p=vexTable[v].firstarc;
    * P& Q1 i2 V! G! G    while(p)
    - [9 i: y" [# U5 G, a    {- V4 \7 M, }8 F) X, g$ H! R7 q, m
            if(tag[p->adjVex1]==0)# h% [2 d$ S- A8 B1 i, z
                DFS1(p->adjVex1);2 x7 g6 y- s$ P/ B6 E
            else if(tag[p->adjVex2]==0)
    # V2 {% `  m! e# g: v9 {            DFS1(p->adjVex2);( K1 m3 \4 S$ I0 u
            p=NextArc(v,p);( v1 Z( f5 V4 C+ ^, \3 Z, a' {, t
        }
    - b; l7 V, f3 Q}3 D3 v7 m6 N8 V2 H; {& H0 i( X. C$ l$ |
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()1 k. {4 U9 }; w( b+ Y* v3 R7 x1 ^
    {* B$ t/ r8 X: U& R- h4 j; E' R$ V4 I
        for(int i=0; i<vexNum; i++)
    ; N' p4 C6 @: g  t7 d5 t        tag=0;
    + j5 l( I6 `5 d1 d8 a1 \/ n    for(int v=0; v<vexNum; v++)" E# |' \; W: ?6 c# }
        {8 K; U% I& Y  o, U$ c: C9 ~9 p7 Q
            if(tag[v]==0)( I# H/ D( |. E. @+ o
                DFS1(v);
    3 q; n: \& E# w( J    }
    + q% o. G  X! l- w  |) b}; t0 R% j! [6 {5 |
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2(): U9 c  @# C" n* j$ B
    {+ q+ M/ m% D* x4 X6 h# ^
        stack<int> s;* C, x1 V4 S& @
        int tmp;* H4 [. ?) `. Q: c: f
        MultiAdjListNetworkArc<WeightType> *p,*q;$ W* B+ o, x! T7 Y# n1 f  y6 Z
        for(int i=0; i<vexNum; i++)) c5 D0 E1 {; @3 i
            tag=0;
    * r# U+ G) t% K  r8 e$ l    for(int i=0; i<vexNum; i++)
    3 p+ [3 L9 ^8 z6 @2 j- U, g    {
    - L2 E% {( f) s6 y) H. f# S        tmp=i;( Q* N* d6 M0 y& u) H& Y3 \
            while(tag[tmp]==0||!s.empty())
    % E) V* l0 o  Z5 @9 y" l        {
    ! W; }4 ]' e% M! n. K1 M            p=vexTable[tmp].firstarc;
    5 n, ?$ m) c1 \& ?5 ^            while(tag[tmp]==0)
    2 n2 i% U6 f( l) s3 J2 @* T            {8 j1 a) x) G) j" Y' _7 I
                    s.push(tmp);4 |" _- Q" Y* O; v4 a5 A: L
                    cout<<setw(3)<<vexTable[tmp].data;# v& z$ {0 q2 O1 d9 w
                    tag[tmp]=1;! x" m! C* O0 o# z* Z1 L
                    p=vexTable[tmp].firstarc;0 W2 D" f9 j( }# _4 @
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    ) f# H$ I. ]8 G0 G6 q' r) D" T                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    " N- F8 ]2 z0 W- H/ l                //cout<<" 1st     tmp="<<tmp<<endl;! w. W) }! \. l5 D- k( g, M
                }- m* c" q5 q- y0 X
                if(!s.empty())1 q: w1 x, N& L- h# L3 N
                {
    " J$ r$ d  X, s3 O6 D6 w- T0 |                tmp=s.top();
    7 ~, x& Q3 O6 f8 R! X% z' @7 [% C                s.pop();
    % [. r$ Z. i/ W, m4 U( e                q=vexTable[tmp].firstarc;
      D; U7 M! d6 I- f6 g7 r4 M                int t=tmp;0 [" l) g7 ?3 X. X' p3 g5 q- a
                    while(q&&tag[tmp]!=0)/ b5 C2 Y+ A9 k" z0 \3 p
                    {
    1 \" H; e6 _7 T. N& |' q                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    + ]/ n) I6 Q3 B9 F, f' W                    //cout<<" 2nd     tmp="<<tmp<<endl;# t- W; c6 @8 F* A
                        q=NextArc(t,q);
    $ P; t" u( V& W6 j                }
    . B2 D! p+ r. C# s" o" H0 s                if(tag[tmp]==0)) N: N% W+ B) y& r. w: q8 ]
                        s.push(t);
    5 Z+ A* k3 p& a$ |- v! x                ///1、对应上面连通分支只有1个点的情况- a/ [; D) u) i8 c$ V' P: b; a# V
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    0 s  u; F9 f' d% P4 _9 u                ///tmp要么等于找到的第一个未访问节点,
    : n  p" K" _, h5 ]9 z                ///要么等于与t相连最后一个点(已被访问过)6 N9 Z1 q  d& [
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点2 S2 Y. I) F0 p' S; Y+ e' ]
                }
    5 p6 t9 i( l9 L/ d7 t. \        }4 B1 ?1 l9 }( [! ~% f1 `3 q
        }: ?0 B8 K4 F/ g! A
    }" `' R6 M% w7 E+ S9 Q
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    & a6 m( W& p1 ~4 otemplate<class ElemType, class WeightType> int, @5 @6 A% a" E& c/ P
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)( j: x9 B! m$ y. p
    {4 ~+ }- q- n+ E* {& r8 a6 z
        if(head==pre)
    : g$ y2 n7 R! f' z        return -1;/ s! o( {: R3 S7 s
    & D9 J. Y4 [8 k3 `% W- B
        MultiAdjListNetworkArc<WeightType> *p;3 H7 f9 m1 i0 a8 K2 E) i
        p=vexTable[head].firstarc;) A- H' e. n0 y9 _' O8 ^
        if(pre==-1&&p!=NULL)
    - S( T( U1 G6 m, |        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    % r* g: d- O% D, o! X    //pre!=-1&&p!=NULL* I  L- w; A1 f5 A0 s
        while(p!=NULL)- V+ |5 |. q4 j; F% Z
        {; ~3 M! G0 I; @- H- U' H
            if(p->adjVex1==head && p->adjVex2!=pre)
    ; d! h2 O8 x% w2 O1 n  `* g            p=p->nextarc1;
    ( Y' {4 L/ _3 M. e/ ^% U        else if(p->adjVex2==head && p->adjVex1!=pre)
    # q! I! D0 c% u7 f; i% ~            p=p->nextarc2;
    - a, x6 {2 d  l2 o9 h- t# j        else if(p->adjVex1==head && p->adjVex2==pre)
    / X  H" ~/ d3 u! |8 R0 p( _- h        {
    2 X& P* S7 i+ V            p=p->nextarc1;' |( c! V, d, g
                break;
    ! d/ q& C" O% [7 \        }
    - G; n& x' V+ K: p. W- S+ D        else if(p->adjVex2==head && p->adjVex1==pre)
    % F4 v4 ]& S, h8 z: h" @        {$ W* N2 k0 X; d* [* l' C
                p=p->nextarc2;" q1 _8 P' e; R. g( m
                break;
    4 e6 j) J) }! y( D( r7 {8 H! E        }
      @0 I$ p- a6 H7 v4 p4 H    }
    2 Q& ?4 |; N8 s1 B( N    if(p!=NULL)' t  n% f2 h; F' }& V3 V+ O
        {- j2 N. s! w: Y5 K
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    - w9 M; V9 e. a5 Y( P1 k    }: {" f4 C( M0 J3 @4 G" Y* a5 t# q8 e
        else# k5 \1 }& B! ^/ A
            return -1;
    # J2 B  J- a1 P}
    * Z7 Z$ }2 s, [, O: o; U3 h: N+ b) v: u7 X- H  w" ~' G; I3 g
    & J8 |0 y% \5 X9 D+ v% f( ]
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    3 B$ l: B9 y. U% U6 W' n{2 e  d+ H" R  ?3 B" G: @
        stack<int> s;5 l  u# o' e: j+ Z
        int p,cur,pre;
    3 [) I  U3 a4 z1 n7 |( K; B    //MultiAdjListNetworkArc<WeightType> *p,*q;4 [* _4 l9 h  }8 D/ J8 X/ C+ T+ l
        for(int i=0; i<vexNum; i++) tag=0;//初始化
    4 e6 I, C7 q3 \" F! R# a; w9 p! A. m1 l
        for(int i=0; i<vexNum; i++)
    / K) ]6 ^2 R, |& P, r. C# I    {
    5 m6 f* U0 Q4 W# ?  B        cur=i;pre=-1;$ d1 S- P9 J) L% o9 O
            while(tag[cur]==0||!s.empty())
    5 h$ @7 @2 A. \1 Q4 p0 l5 @        {1 j1 Q1 R. m/ c; G$ k2 ]+ o- Y
                while(tag[cur]==0)% c0 `$ d/ g$ }6 n6 T# `: L
                {
    0 Q1 |7 o, D$ X$ h0 T3 ^                cout<<vexTable[cur].data<<"  ";
    0 x7 z* k' U% B. ]! b/ J' N* @                s.push(cur);
    , z. R2 Y/ Y2 u                tag[cur]=1;
    / `& ]  m& u, k0 b0 b- v               //初次访问,标记入栈
    0 W1 p" k8 f* o/ H& o9 K
    $ ^" f/ z% x8 I+ u. H& q) T9 _% Q               p=GetAdjVex(cur,pre);//p是cur的连通顶点
    & _- J9 o5 o$ P, L7 V9 t               if(p==-1)
    , a- l7 N3 c; a1 N" s- c7 ]$ m2 \& Q4 e- Q               {
    + i2 ]$ m/ ?& f& F* t4 t                   pre=cur;s.pop();, E: U+ W9 u" i* E
                       break;
    . F) }; T$ }7 [5 d  g; Q               }0 Z! R& [/ U+ @+ M
                   else
    ' S" J1 n2 M8 ~! f               {
    ( f3 y" n* M6 q7 E+ e                   pre=cur;
    " D! p( j3 r, T% V. F9 ]1 g                   cur=p;$ A0 ?( G' I: C
                   }
    3 \/ c- C) C) S4 `. D+ r  X8 m+ m% l# e8 `3 J% q  y" s# k. e) W
                }: z% @& v  d* r
                while(!s.empty())
    / u/ D5 U; ~& x! \            {
    " [7 i( E! E% F5 g; s# c                cur=s.top();7 `. C' z. y4 t7 _) n6 r
                    p=GetAdjVex(cur,pre);9 Q! L; [. {2 Z6 z( ^; A9 y* B
                    if(tag[p]==0)
    3 x  h, z4 q1 Y& b* R  I4 `; [                {
    . b1 p- @' R  j+ Z2 R& g: a                    pre=cur;
    0 S9 b6 B& E/ o- e+ v0 m3 P. v! ~* m  c                    cur=p;
    5 e9 V; y- W3 f' T: h                    break;' Z6 E2 c1 g3 Q" F" f+ ^
                    }3 Y% v! s  q* Q2 n. i
                    else
    7 R0 w! Y6 e4 o6 e                {5 m# n/ t( w" j& d5 X
                        pre=s.top();, i6 t# Q% B) B& e! q
                        s.pop();
    : i' Q: w! I5 ?) s3 K* {. v3 i2 z5 d                }
    6 [6 c) D& H9 O6 E. S9 T9 W  s  _5 a  y1 V
                }
      s+ |: H8 E$ L: U( B3 a% l! F3 c( Z. l- P# _5 a
            }2 S0 M  J; V+ [; _  h
        }
    ) d) O1 Q1 h% c6 j}( Z8 A9 V8 E+ e/ r! S4 \4 p! X
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    5 y. @# _( e( f- ?& P{
    5 Y$ c+ Q) f7 t# P' t: S    for(int i=0; i<vexNum; i++)
    & E% a8 }6 k" R! @( C$ O9 F/ J        tag=0;
    : [! F: l% m* l7 u& G    queue<int> q;
    4 x$ \1 ~0 a- y( a! `1 s    int tmp,t;
    # S" S" R' X! F& I* l3 @) ?) g    MultiAdjListNetworkArc<WeightType> *p;/ a' c6 ~( v5 k
        for(int i=0; i<vexNum; i++)
    9 P6 p! a0 G* ]% p1 u    {: G8 E2 E  P& s$ U) j" n6 G
            if(tag==0)
    , c" E' |1 Z# d& j6 R3 p        {
    + l; X% e, i9 Q0 d6 ]            tag=1;+ E! o$ k4 c( p
                q.push(i);) t. C1 O: j. I- |6 t) p& V# ]! L
                cout<<setw(3)<<vexTable.data;
    - P# l3 B/ D% p+ g# b! m        }  s6 ^. T5 ]4 P: g  p2 J
            while(!q.empty())% D" F# I8 l/ `! \9 n& g
            {
    $ S) r2 K: }* |* K4 X, B% Y            tmp=q.front();
    7 J/ t! t  X: j% w            q.pop();3 C# w$ L) F9 R2 Z6 ~
                p=vexTable[tmp].firstarc;- s4 O  h% p3 ^- U4 X9 R
                while(p!=NULL)
    ! k- N$ N6 V2 l! V9 |            {6 d# N% x! \$ g- v0 L
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    * W( [$ k7 M5 ~. k& q                if(tag[t]==0)( m. K8 r& N( u3 n* e+ Z
                    {
    + p/ J" @6 ]$ D; Q0 m$ T                    cout<<setw(3)<<vexTable[t].data;
    + V! m# _# P/ ~- [* x                    tag[t]=1;6 z2 P: v; ~9 ]6 E
                        q.push(t);
    9 S) L* X1 k: C7 L! b0 G5 R5 k                }
    ' o) \  l2 D# N                p=NextArc(tmp,p);" D5 Q' ?1 g% v% K7 |/ E
                }" u$ ?3 Y! {+ a) O6 M1 x
            }
    ( F% h4 g6 A: x; I0 b5 c    }
    * q, b) q3 {1 a+ @  ~1 \6 m! K}
    5 p2 l- x3 }% g8 a; y: q7 Y, ~5 jtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()% X3 H) O% T$ u3 O
    {# p1 i  G" ~6 Q  }- z% f- p0 @9 g% A1 A
        MultiAdjListNetworkArc<WeightType> *p;
    3 D: _/ J1 }" ^" g    cout << "无向图有" << vexNum << "个点,分别为:";$ w. l1 F( Y' A
        for (int i = 0; i < vexNum; i++)
    / ?1 t6 j  l2 X) \+ U  u- q        cout << vexTable.data << " ";
    * t6 n2 G4 V3 Q+ y/ R0 y    cout << endl;% E4 H; _0 m' }8 t. |3 w
        cout << "无向图有" << arcNum << "条边"<<endl;
    + _# \8 H9 P( f1 p/ C    for (int i = 0; i < vexNum; i++)/ J; V' z% i) r
        {
    1 }  q: i2 {; ]  \: O$ {8 Q$ R$ E        cout<<"和" << vexTable.data << "有关的边:";
    . x% ~# Y+ V$ Q  a        p = vexTable.firstarc;
    , g5 q5 p: v+ h        while (p != NULL)7 q& ?/ k% F+ i! Y+ D: F
            {
    9 p2 ^6 C/ S$ o$ B8 b            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    1 i! h1 p0 N. S# _5 r, r7 @! x            p=NextArc(i,p);
    0 p6 ~1 v3 f! l& w0 N5 G% A( H        }4 T* w# n+ R! m  R7 Y. ?3 S* `
            cout << endl;
    1 R( b9 I6 h( e8 v6 K* y! f    }
    - H0 d; _. M1 T$ \}
    / U  I! b( v9 K' x/ H- {$ ^, y0 p  J

    ' t4 C+ H( s- O$ j# X) {9 ]: N& Q" B邻接多重表与邻接表的对比8 c' d$ o9 _2 F. U4 ^. P8 \
    3 \. a6 H3 e1 O5 n: n: r5 W& v
    邻接表链接; {- O6 K$ ]5 _% k: M; P/ H) D
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。4 m5 ]8 G/ e) ?- r* @! O5 q9 o( @) a
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。& ?& f: U+ r/ ~4 B: O! J1 f
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。* r2 w9 I1 L/ b( c6 W- n; l8 E$ ?
    ————————————————9 s( j3 ?, n. P8 r: ]# f3 D
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。1 G# _: E& i  Q1 r0 P
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    , H2 d  W' C% h6 o4 x5 F# z6 t' L0 `9 _6 H0 m, Z4 F' ^$ ?+ b4 M1 U
    2 K6 B! \" n+ W  u
    9 c( L" O% p4 H, \3 d3 B" K- ?

    ) z. {3 R% W# Y) V) I3 A2 q$ a————————————————+ m; [9 {) C7 k9 \
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    / F' s# ^3 T4 w+ @# k0 b原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958& j1 r3 U' h5 ~! J. d! X9 A

    7 N; M; F8 k; P3 q& e) y- Z- Q
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    fastpost qq
    收缩
    • 电话咨询

    • 04714969085

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-11-1 08:57 , Processed in 0.330377 second(s), 53 queries .

    回顶部