QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1619|回复: 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
    7 q% a; p" }& b* g- K, M
    图的存储结构——邻接多重表(多重邻接表)的实现0 m2 f% J- }+ K5 S2 d; ]
    7.2 图的存储结构5 L, w, t- L) B. f6 ]

    ( J( u% H- a% X0 V( l7.2.3 邻接多重表(多重邻接表)Adjacency Multilist9 l0 D- z" i& L4 a6 L
    邻接多重表的类定义0 ~- S( Q) V  T, |. T) z
    邻接多重表的顶点结点类模板
    8 g; g: }# n6 N( z邻接多重表的边结点类模板0 K3 i7 ~( F+ \2 B) R# X
    邻接多重表的类模板  A  B6 i) L1 E* [6 y3 ]
    邻接多重表与邻接表的对比  a. O3 D. q: G/ g  v. N
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    3 X8 [" H( P3 t1 a0 ~4 X; R, S2 H/ s# c# F
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。3 K9 o5 ~1 b' v+ N0 [
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。$ s3 U" m  y" ?0 C9 n8 i
    3 k" d/ N2 |5 E
    邻接多重表的类定义$ t2 C% y# c: K
    1.png
    8 w- q' W  }7 ?4 Z& t邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    6 t+ }& W' Z) S9 a2 t% A) D5 Hdata域存储有关顶点的信息;
    # K3 P* N8 l, x7 I/ S+ }+ b* Vfirstarc域是链接指针,指向第一条依附于该顶点的边。
    8 v  q8 t% s2 k5 U  u- \/ m所有的顶点结点组成一个顺序表。


      v# t; b' O6 ]: O
    ' q3 p, p* m6 N, b. P: w. ~- ztemplate <class ElemType ,class WeightType>! r: p2 }  |2 z
    class MultiAdjListNetworkVex
    7 ~8 |, U9 r( a3 J{( l5 T- T8 w8 b7 J
    public:2 Z3 |0 s/ P) M# `* F: O0 c" m, w
            ElemType data;7 Z# e# g# b$ u6 u, V+ D) ?
            MultiAdjListNetworkArc<WeightType> *firstarc;, A5 i) Y+ w% U# O$ @
    8 j; o, f8 Q* u9 G# _3 `
            MultiAdjListNetworkVex()1 {, S: J4 g" a. U: M. b
            {
    ! L8 `& D5 L# j; Y. @* Q                firstarc = NULL;
    0 [) I3 f! l( w. H- ^8 \        }
    % L( U, T: R/ _/ c        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)8 a0 ?& j2 T. u# Q
            {
    9 F- g. S. B, g4 H; w4 d                data = val;
    0 f& J* I1 ~: `; i1 r, Q. B2 M                firstarc = adj;
    4 f1 M$ R/ {; G, v/ k9 u6 {7 }        }( \+ F5 M1 D- N8 }) S6 T, y
    };
    - a* ]* Z, n% ]2 t/ o
    " d% @% C+ O- i, w: S! A邻接多重表的边结点类模板% r, R1 t! G6 @1 c" e

    6 z9 D% j' l9 P1 O$ w4 b, j1 o在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:1 y, J  `+ u* X: w, ]
    tag是标记域,标记该边是否被处理或被搜索过;% X8 X7 @4 H) U$ W- B3 l
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;2 w' d+ O1 }6 G  p( |/ r1 ]
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    : T0 j) E% H6 y0 m" Z+ ?. n" I1 lnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    7 Y$ g- _7 r/ D  ^- s2 X1 \
    ' _7 D  {; |1 ~, v4 D% C 2.png
    ! Q% G. w/ w0 W! n. Stemplate <class WeightType>4 B6 B8 o' s5 T, ]: I
    class MultiAdjListNetworkArc6 L7 Q% d; L* S3 c/ v
    {, @* e: |* }2 o( i
    public:
    ' \- V. f" B' o/ _; R: G* I    int mark;                                       //标记该边是否被搜索或处理过
    6 ?; w$ j/ H7 f+ x7 F$ c3 S2 p        WeightType weight;                              //边的权重
    9 w  x1 l  w: y# z1 I  r        int adjVex1;                                    //边的一个顶点6 Q" r6 k4 }+ X' F
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    * V9 p0 x: \- t7 f2 V        int adjVex2;
    0 l+ o. Y6 B  n% l8 A. ?        MultiAdjListNetworkArc<WeightType>* nextarc2;
    2 W4 L- y4 }; R$ O$ U$ V
    3 v, y/ h& t! s7 ^) ~+ j        MultiAdjListNetworkArc()( U6 ~2 [# E' L$ h
            {! G, e/ ^, R, U4 @
                    adjVex1= -1;
    & o: k2 q. }. g) m" ~5 k                adjVex2= -1;
    + l9 M( L/ ?  i$ U7 y! y* s        }
    ! Y/ M6 c1 y7 B) r8 i. ]        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)/ I# Z9 g# i! i1 ^" z- E3 y
            {" o8 `+ {3 O1 @1 i" n( U8 W
                    adjVex1 = v1;       adjVex2 = v2;5 O) v: \4 P2 D1 s9 v- d( D
                    weight = w;! }1 ]' M9 |8 ?* E3 Y
                    nextarc1 = next1;   nextarc2=next2;; b) B5 ^! V1 W7 l" k# X" K
                    mark = 0;           //0表示未被搜索,1表示被搜索过6 y3 f) E5 i, p6 {( Q# e$ J* v6 s
            }+ l+ r1 S  T+ z. z( y# h. {

    8 [; c, T: ^; `1 s( I邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>) Y$ I/ t& U5 E
    class MultiAdjListNetwork
    7 A( i2 K/ W+ _( P; E3 d0 j0 e9 F{
    9 E( g5 ~3 d' gprotected:
    ' _* z6 p5 |& W6 b. b    int vexNum, vexMaxNum, arcNum;
    4 b0 C" H; ~* [& l2 n8 p& _    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;. [, C1 K1 y* R4 I- E
        int* tag;
    3 S2 l# w/ M. _/ n; E( ~2 o3 H/ B    WeightType infinity;
    7 f3 W  J7 W" [+ J, }. X( [( j5 d4 V3 ^$ Y
    public:
    % u" {8 J0 C+ L    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);# U1 V7 t- `! q$ ]* ?$ E- _
    " \1 J/ w2 f- N0 n: U& |
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);$ y) x! @' {5 T  U+ Y
    * x4 ]2 [) c" S* d7 _2 E
        void Clear();' {) l1 ]% p$ y
        bool IsEmpty()
    8 J. {. a2 {. a+ ?9 T  I; E    {
    & V9 l5 U7 _* Q        return vexNum == 0;2 i) V4 N# h: b9 Z
        }
    4 P2 k: f* N, q2 `; A. w- P    int GetArcNum()const
    : f* S7 X4 O  `* {( C8 x    {' J) t# e  e* m6 C* v% x) h. n
            return arcNum;3 j3 u9 K) `" L( ~, Z) G' f5 H' Q6 Z
        }$ R) j  D2 R! d
        int GetvexNum()const: s2 _$ b" x" z0 d8 `
        {8 T3 }5 L$ x8 [- k# H' l0 r
            return vexNum;6 F7 ^- d; X1 F: w( `: e
        }
    8 x6 M2 v+ g& ~" d/ V; }
    0 H7 ]: W* K' y* P0 f
    5 f0 {& F* t6 d( I    int FirstAdjVex(int v)const;4 {5 Z/ a5 c* F9 b- d
        int NextAdjVex(int v1, int v2)const;
    . r' x/ u! X/ V5 `7 P6 X8 {# q% g    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    + K( V' r$ o- p  N4 v, ]    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;" F( ], e. a5 I& ?

    ( F; Y" K$ Z$ U+ @    void InsertVex(const ElemType& d);
    9 c* q& w( b* \# h    void InsertArc(int v1, int v2, WeightType w);" u4 h. i- g) i5 p/ j

    3 C5 W+ r( f, \3 [    void DeleteVex(const ElemType& d);9 u( f1 u  N) W) D
        void DeleteArc(int v1, int v2);9 G8 l& k+ n) ~! H3 V

    . _1 V  d) a' S" k+ Y* \* T% }    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    ) X5 m, y+ e7 D0 L    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);9 C7 R' Q  O4 n9 b
    . a7 ~, ^6 t, B6 f% ~  w) l: l* F
        ///深度优先遍历
    ) a$ ]/ u" r* c4 P# y* {    void DFS1(const int v);/ ~0 q' O( ~' Z
        void DFS1Traverse();
    3 ?7 H) B+ L& d" |5 J& G. x    void DFS2();  K; x, z" x- t

    8 T, t8 X7 T5 o  f3 \/ y8 r1 ~. D    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    , H2 a5 J- M% \2 n    void DFS3();( D3 m0 `: K; [( T- U& F

    & a" b( y+ \% Z+ }: a    void BFS();$ U: t/ Y, p: |+ x4 L) @
        void Show();
    ; F; |/ I; l% g0 y1 z0 d4 R4 \" D};4 K$ \+ ]5 H! X" c& W% a

    # E; _- n" n- Y: v2.函数的实现
    3 y4 s0 D. h3 n6 a1 B; G* i; s研讨题,能够运行,但是代码不一定是最优的。* ?* g% ~6 j9 v3 z+ i8 I: D
    # t- P$ G7 o9 @! b/ C* L; i
    #include <stack>
    6 u- z& i  t/ Y8 o! {. w  T#include <queue>8 H% N; i- t6 K0 a; `" s6 N0 O$ _4 z

    , M6 _" ]% h6 _8 Z* E1 itemplate <class ElemType,class WeightType>$ J0 W+ w; p+ }+ M6 m2 F
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    " a+ A# [# \$ @4 q2 T3 a! Z5 r; j{
    8 \, @6 l- N5 R7 h7 I0 z: Z    if(vertexMaxNum < 0)* g# _1 O0 {! v5 I
            throw Error("允许的顶点最大数目不能为负!");9 A3 u% Q) l) h$ r6 A' t
        if (vertexMaxNum < vertexNum)
    " @4 Y2 z" ?4 q+ m" ?  e5 z        throw Error("顶点数目不能大于允许的顶点最大数目!");$ E$ b- j; O/ O! q+ y
        vexNum = vertexNum;+ k) g" R9 u6 W* C. N
        vexMaxNum = vertexMaxNum;
    $ R9 |3 Y( O+ }: E: ?& C+ I    arcNum = 0;1 R; k" Y) E5 [2 [5 F
        infinity = infinit;
    ' i8 V8 E& }1 }& \    tag = new int[vexMaxNum];" c. U/ V, k  r% C( g' i
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];( y: j. e) U% ]9 e0 f  ^6 f
        for (int v = 0; v < vexNum; v++)
    - q# z% c: |( m/ t    {3 F/ z. q8 D) j( g+ Y
            tag[v] = 0;
    + `! z7 Q6 o6 [$ u0 I0 k        vexTable[v].data = es[v];1 {; N/ G5 ~3 `9 ~1 ~  N" [. p7 U
            vexTable[v].firstarc = NULL;
    4 _$ e* h: B" j4 m4 X* x& u    }. M% l; R- ?3 f7 y6 M2 }8 T& P
    }
    * S( K  g2 ~% [6 H2 n9 b+ Q- Etemplate <class ElemType,class WeightType>* m4 V( l) I, J7 U7 R$ E; S3 q) V2 G! ?
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    - w  p( i6 {, M{
    $ K2 M' J/ K" z: i    if (vertexMaxNum < 0); M1 Y  d: a; J9 d: _
            throw Error("允许的顶点最大数目不能为负!");2 r6 e, L8 }' F3 H  v
        vexNum = 0;2 p' s: T6 t1 k! z! ]8 u3 O& X4 P
        vexMaxNum = vertexMaxNum;
    0 P& S# r4 F. g1 P    arcNum = 0;
    1 i+ a0 |, H5 y- M4 q1 w5 Z, K    infinity = infinit;4 A( x1 e6 y1 u- e
        tag = new int[vexMaxNum];0 h% M' R' [  a; |' n4 ]( k" U
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    ! e7 [6 T0 G& g4 i7 |7 Q7 Z4 ?}
      L1 ]$ h6 i# o* u; i+ Y4 h" r1 wtemplate<class ElemType, class WeightType>
    ; z$ \( v, \  g% ~$ Fint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const( o  M3 D, q6 {
    {4 {. e1 l! t" v* H- b; K0 X' |
        if (v < 0 || v >= vexNum)/ L# \& |9 n/ c" z4 a
            throw Error("v不合法!");
    ) D. z) \# B( g1 m    if (vexTable[v].firstarc == NULL)
    % T4 Y2 D* U! Y' I6 O        return -1;; m5 B6 ^) W- C! Y
        else: K. F& V, Z( m  d& y4 \7 U6 w
            return vexTable[v].firstarc->adjVex1;( O8 a/ M. ~8 M9 Z
    }/ a9 w; \, h% T, W- ^, w

    6 `1 e. ~( F# V  p6 e  dtemplate<class ElemType, class WeightType>
    + z6 n+ f0 \8 F( G( k; Wint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    6 @8 z  V2 o% c- ]7 i{* G! J3 O. _# a2 R$ y' K  M
        MultiAdjListNetworkArc<WeightType>* p;
    8 c0 g: c7 [# i    if (v1 < 0 || v1 >= vexNum)
    ; ^/ p( w5 s- [7 C        throw Error("v1不合法!");
    * j* y3 e% ^8 W% M) E; b8 d    if (v2 < 0 || v2 >= vexNum)/ a9 M' d+ ~4 @, V" i# M/ k
            throw Error("v2不合法!");
    4 A9 i; |7 d7 d7 v& s' Z* D5 U    if (v1 == v2)( Y/ i+ @- `( \5 C
            throw Error("v1不能等于v2!");
    + L; x9 F, V: y- f    p = vexTable[v1].firstarc;. i; f( p; p- V, P6 W! A
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    1 @* s% R6 L3 K5 x        p = p->nextarc;
    ( L% a# l+ Z1 D" f7 t+ a5 l    if (p == NULL || p->nextarc == NULL)$ {9 ]8 B1 t2 M1 C3 I
            return -1;  //不存在下一个邻接点
    " F) y- @0 o4 J    else if(p->adjVex1==v2)& M, |) j: Q. u7 B+ {* [6 S7 Y* L
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    ! N! V1 k- _  U: j    else
    ( N6 z+ @- S) g0 a9 M; n* \        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);3 t/ M7 g( U; r: s/ S; ]
    }* _4 q$ k! p% w/ F
    template<class ElemType, class WeightType>
    ( T4 f) g) l1 B  g3 p% z$ @; w! ^5 [void MultiAdjListNetwork<ElemType, WeightType>::Clear()+ \: z) \# q! G9 N2 W
    {, C) j0 j8 Y6 a7 V
        if (IsEmpty()) return;  g# C6 j3 Z- f/ z
        int n = vexNum;, a3 R, E2 U" _9 f, X9 t
        for (int u = 0; u < n ; u++)7 P0 I8 a) I* V, D: Z  S
            DeleteVex(vexTable[0].data);" s) B/ x/ h8 T' C" N2 C7 o
        return;
    2 Y% K- _# z- n7 t$ I1 H}' h- t% p+ T/ P. H* t1 F. Z* O. S& B
    template<class ElemType, class WeightType>  e( q" q" M; C5 X9 v6 c" \. G2 W
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()$ r3 F7 l& Y* E7 o
    {
    % D- g+ {& ]1 V+ n& \" V6 M2 m. Y7 `    Clear();
    6 @; X) T/ L9 D6 R& V' F}: l4 L4 J, u& {
    template<class ElemType, class WeightType>4 r, p% ~3 P8 X; Z1 m1 U) I+ S2 ^7 ?
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    + P3 r& X* @; h+ ?* N{
    8 _# c. U5 w2 [5 e( V    vexMaxNum = copy.vexMaxNum;: E4 T* X8 T3 N! E; }9 U
        vexNum = copy.vexNum;) X8 }0 x, O$ J# J! i6 f; _+ _
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    - q0 ^' z# Y8 o( k& e" ~# {* Q    arcNum = 0;# y. d3 u. O* m) _* A$ H% k
        infinity = copy.infinity;
    6 l# H4 K+ s- Z9 c  v. S% Q6 x# ]" T    tag = new int[vexMaxNum];
    0 P  g. K, h# p% L
    9 u" j- |. a% k* x) Q    for (int v = 0; v < vexNum; v++). q# a+ J5 T! v: _7 M" e6 N
        {, }+ q" x( ~$ U) A( N8 E0 O# Y
            tag[v] = 0;
    % K+ V5 S) P2 h5 I- a3 H' f        vexTable[v].data = copy.vexTable[v].data;; Y' p' t) {8 p1 g
            vexTable[v].firstarc = NULL;8 I0 z: L$ ^1 {$ @) K
        }
    2 R- t. Y* x. ~    MultiAdjListNetworkArc<WeightType>* p;/ P8 y: f- J" L  P' u6 G
    5 @# I- B: Q5 D* C. p1 r# F
        for (int u = 0; u < vexNum; u++)
    & D- G: @, G& q  j+ N1 ]    {+ G" i7 Q# {: m# s
            p = copy.vexTable.firstarc;
    ( j3 a9 ?' h; Y5 @; Y  @        while (p != NULL)
    # D9 h1 E+ H2 j8 d        {
    $ \1 v# G1 a& C, x8 _            InsertArc(p->adjVex1, p->adjVex2, p->weight);$ V2 K, D& L* i- m3 R2 P( [% u
                p=NextArc(u,p);2 E$ b6 R: Y# ^
            }2 A2 N+ k4 L$ z' j6 Y
        }2 H& {# i1 T  {. u/ G
    }6 ]! g. g9 d7 ^3 t% T
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    * m0 R$ E. i! s0 K7 CMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    $ t% F' B9 g7 h5 j+ O{* Y% K  v1 ]! R: Z4 D# E; v) G  S+ V$ l
        if (this == &copy) return *this;9 w" T% Z" l$ y# g
        Clear();& H: ]8 k; N9 |7 I% w
        vexMaxNum = copy.vexMaxNum;
    : D: j/ ^5 L1 @+ T    vexNum = copy.vexNum;
    & Z) ]2 n- I2 v+ J  t6 a    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];5 u8 R7 e$ q/ q
        arcNum = 0;& v' `# [# ]/ f
        infinity = copy.infinity;
    $ g$ n. K, q1 R3 P    tag = new int[vexMaxNum];8 T5 i" L5 D9 _2 l! k" g1 t5 \; A

    ) S* H  n8 {+ S3 {0 J) O    for (int v = 0; v < vexNum; v++)" T: z; H) J& r9 a! K
        {% P) y4 @, K9 H! t. u; A# H* g- ^$ y
            tag[v] = 0;3 K% J9 ]" E3 j' v- w1 \
            vexTable[v].data = copy.vexTable[v].data;
    2 g* P8 p6 t) M2 u) J% x        vexTable[v].firstarc = NULL;: I' K2 Q- `5 ^* a
        }
    & [2 c& Y% o* `# p0 C) X2 y    MultiAdjListNetworkArc<WeightType>* p;
    5 @4 y6 ]2 ~6 ^" K
      X5 ]- S! F5 \- S    for (int u = 0; u < vexNum; u++)
    + L$ T9 [- x; Y5 V' ?7 h* _    {& `0 |1 X) M" K! i8 Y) t+ J: [. E9 C
            p = copy.vexTable.firstarc;) S7 S# k4 \9 z3 q& A; w
            while (p != NULL)
    3 y8 Z* I9 h) B( i5 h( S" N, V        {
    0 q& o: O( T4 k            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    + ^2 z3 G  u* p4 u4 O9 z% j            p=NextArc(u,p);/ y, t, I0 u' Y" C2 v
            }
    6 m1 N6 K8 b& P    }) h* n! k7 P, _6 ]# e1 V$ T
        return *this;7 [  l" M2 {( b! b. Z
    }
    ! g' ]/ \: E* t1 v1 g+ atemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    6 U  ]1 l5 W2 S9 d; o* s3 H8 @1 UMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const4 _- F* A4 J9 _4 l1 E2 r. P6 X
    {( G3 \' T: f! |) \- z% N) p
        if(p==NULL) return NULL;
    / b  k4 X  _% H7 M$ C    if(p->adjVex1==v1)  O. _  a# j6 i5 m7 P
            return p->nextarc1;1 K$ L: D2 t& D7 A5 }- W! ~
        else2 w& p7 ^6 \5 ^
            return p->nextarc2;( M$ V" {3 D8 ?! t7 }3 g
    }
    * @: S4 `* `5 f% B% u/ e; R" G4 Ktemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*! Y( j# a) w: Y, Y
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    2 G+ w0 M0 {" t: w4 o{; R6 C$ U" Z7 z" \4 v
        if(p==NULL)return NULL;
    . T6 o( c- x$ |( U3 V' G    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    - b6 e* R0 o1 k" [/ \0 W    if(q==p)- c! D$ r* f/ Y/ ^& L. [, p
            return NULL;# D- i4 e  K  V4 B! n+ d/ l
        while(q)' r" w% |! }# z  ]% O* J& m) A; L
        {
    8 r7 a8 T) @8 _- o* d        if(q->nextarc1==p ||q->nextarc2==p)8 f, V- L- Z3 ]2 b# e1 L3 C
                break;
    0 P5 c) I, c& G8 ~! Y) K        q=NextArc(v1,q);
    6 L) E0 W9 T- @1 S5 M. R8 w. x    }& E9 P4 V8 l. n- h" s9 \
        return q;) K8 [$ }1 ~! {0 m4 i
    }
    7 [7 a9 x# y; T' otemplate<class ElemType, class WeightType>; r* j! Y3 i2 V4 N" E! y
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d): P! t" t- |4 _6 @: X# s- T
    {" `/ G: }$ m# S: t$ [( ~) u7 P
        if (vexNum == vexMaxNum)0 }, w( H+ a9 [3 Q: m2 n& ^
            throw Error("图的顶点数不能超过允许的最大数!");" t$ j% ^: \. \7 s
        vexTable[vexNum].data = d;
    5 v6 f' `) G: Y  m+ g( A$ S" G    vexTable[vexNum].firstarc = NULL;
    6 E' P+ m6 V3 X' k/ I7 E    tag[vexNum] = 0;
    , G$ e+ M! ]5 Y! H8 `    vexNum++;9 D) t6 Z% L# [' |
    }' P- K; N" K7 w: e7 ?5 n
    template<class ElemType, class WeightType>
    - p8 H4 K5 g; _7 f2 g% M1 u# |void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    $ a; S9 T4 }5 I- g9 c6 [{
    9 ~  T# e: P1 ?- W. k( f$ p8 w    MultiAdjListNetworkArc<WeightType>* p,*q;
    / @  D) ?/ o1 N    if (v1 < 0 || v1 >= vexNum)- `! w+ F; h- j( f/ r4 K
            throw Error("v1不合法!");
    $ G) A5 @( A9 l: }# T/ K    if (v2 < 0 || v2 >= vexNum)' j0 S! e: y( j6 F: G, v
            throw Error("v2不合法!");' C, Q+ H8 z( {. |$ w+ W) p
        if (v1 == v2)0 q3 U' O8 u" }& L/ j6 c4 W
            throw Error("v1不能等于v2!");
    & Z# Y. y. h3 x+ g9 A' h    if (w == infinity)
    3 m% s" C5 F6 J8 v        throw Error("w不能为无穷大!");
    % R; i3 C8 J9 }, {/ u% G8 C7 k9 k# v" {# B2 e
    ! h4 Z6 X0 J$ |, S7 q
        p = vexTable[v1].firstarc;) q7 f8 V! Q$ C+ [
        while(p)5 s0 ~9 b; C) z# a
        {- U% b0 e1 ]& Q1 x8 u
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中3 H, r' H; G# ?# P# r9 i
            {$ W% Z. h& I. w  h9 O+ v0 W1 ]7 ^! h
                if(p->weight!=w)
      W3 w* F. n8 `& B- X8 P9 J2 _. I# R                p->weight=w;
    6 V! x! v. q4 s* ^+ ^            return;; {  V- T. d* ?  ]; K( x* D' n
            }
    0 \( X9 }; \+ ^/ T  I' J4 \5 _1 E2 z1 U2 W
            p=NextArc(v1,p);
    5 s% U! r' h# A1 ^! T5 ]    }. `; J. q5 x6 }) y" O% r' }
        p = vexTable[v1].firstarc;
    : x7 \: x7 R8 A' W. ~    q = vexTable[v2].firstarc;
    8 O0 D9 o9 b5 x1 C    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法" B, J( D9 W! u+ k; f9 j; [' o; b
        vexTable[v2].firstarc =vexTable[v1].firstarc;, U; h- ^0 ?6 S+ i7 {# k$ T
        arcNum++;( V* H: ]+ ^  W* {+ ]3 C5 V
    }$ j9 b) Z. _  k4 k% G

    + W$ \# ]9 o. Z# W( P( ktemplate<class ElemType, class WeightType>  U) V: t' ^4 P( \) |0 `. y/ z
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2); \* b9 p9 @4 `) K- a1 N4 M$ R
    {5 ~# Z3 B2 D) e# a7 k0 y+ Z

    " ~$ q9 A# Q. P# K, A! r0 S6 }7 y    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    4 C& A" m6 b8 v! K    if (v1 < 0 || v1 >= vexNum)
    5 t( v* R9 {# H2 g8 Y        throw Error("v1不合法!");
    ) [  X$ o. p3 V1 i- Y$ u    if (v2 < 0 || v2 >= vexNum)
    " v/ h6 Z5 A. l5 s' v: c- V        throw Error("v2不合法!");# w0 j" F+ Y3 `: }9 N  S
        if (v1 == v2)( \+ k# v4 w  z+ ~/ }: T. Y
            throw Error("v1不能等于v2!");
    ) N( i& K2 a" ^& S2 H# Q6 ~7 g8 T  g. ]+ s7 [
        p = vexTable[v1].firstarc;+ a* w% V0 q1 `" c; _
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    + z* u  j( r8 i/ j) M3 Y    {; |' d8 f+ p$ w% m$ W3 w6 T5 Y1 I! Y
            q = p;
    2 }& a9 U1 h5 y        p = NextArc(v1,p);* B/ G1 t: V3 ]: c
        }//找到要删除的边结点p及其前一结点q7 v1 q0 J, p' ~6 d3 z

    9 T# h) ^1 o4 W# D) l    if (p != NULL)//找到v1-v2的边3 |6 @- K0 i$ @: z9 n9 s
        {( i3 c+ J) M# \6 Q  J# n
            r=LastArc(v2,p);
    ; m  V! M3 e+ `4 h  L) ^        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL$ k$ s" F2 y) T; [% G* k
                if(p->adjVex2==v2)
    / q+ N( l3 Y" i( s4 N' b                vexTable[v1].firstarc = p->nextarc1;
    - k; s" D3 f# |7 f% x4 n; m% ]            else vexTable[v1].firstarc=p->nextarc2;
    6 U. y1 v' V: W        else//不是第一条边; Y2 b. I3 o9 f) _
            {
    . ~- R0 m- a, f9 ~& K1 V3 O) \4 g            if(q->adjVex1==v1)
    + T( Y; z9 z; z7 f, E                q->nextarc1 = NextArc(v1,p);
    % M5 a+ s* [0 N  F            else+ ^: X+ Y+ U6 w- x% f' a$ O
                    q->nextarc2=NextArc(v1,p);
    % V/ ^+ X+ L3 W9 b& e! \' O6 I) \3 {. z
            }7 X/ y+ B6 \& M0 {3 l5 h8 u! `
            if(r==NULL)9 H4 G* s6 s& v; |% H
                if(p->adjVex2==v2)
    * b7 b  |. h6 I                vexTable[v2].firstarc = p->nextarc2;. B7 g6 y; V- p" ^! D( y- V& g
                else vexTable[v2].firstarc=p->nextarc1;
    ! F+ g; t9 n+ W. v1 k        else
      j- h6 _  T! |        {2 [' N9 C/ E" J
                if(r->adjVex2==v2)
    : [0 Y( s* I# ?8 n7 }                r->nextarc2 = NextArc(v2,p);/ Y8 G. n8 C+ ~4 w, b4 Z
                else
    ! n" N& |6 c; t1 F: \+ Z8 Z$ v                r->nextarc1=NextArc(v2,p);* y! ~# q: ?  U( l
            }  J- L8 {: Y) ]
            delete p;6 ]2 Y; @% ~% M# Z  g7 |3 c8 l* I
            arcNum--;) ~. A* @3 L* q  V6 f
        }5 `3 A& c# S% ?+ T* F9 }0 Y0 i9 y

    # W1 Q2 J. X6 F0 t6 ]3 w  T& S}
    & E2 K5 s3 I# b* a8 v; gtemplate<class ElemType, class WeightType> void4 B2 W2 U. m4 z
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)9 |$ }2 [, C# x0 u3 C
    {- @) M4 e% l+ K: M1 \/ v7 l1 N
        int v;4 o9 D) \& u# a
        MultiAdjListNetworkArc<WeightType>* p;1 ^; S. i# H( ~- `
        for (v = 0; v < vexNum; v++)//找到d对应顶点; @+ j3 \; t3 z& y+ l, k
            if (vexTable[v].data == d)
    ( H' S0 j/ r. \% B2 M0 x) K            break;
    - p( {  Y& P# Y: o2 @: n    if(v==vexNum)3 l" G" N6 c  G* o/ |0 U
            throw Error("图中不存在要删除的顶点!");7 K! ?, T7 `! d, y; D/ P; ?- \
    8 ?5 m! P; B7 N! B! L- v7 _
        for (int u = 0; u < vexNum; u++)//删除与d相连的边
    7 i$ x" ?+ p/ C        if (u != v)3 ^: T9 E2 G  l- n6 d$ y& ^& [/ g5 \% ?
            {2 L7 x1 S# ^9 }2 B5 Q9 o/ ^
                DeleteArc(u, v);
    # p. G; C% m% H. D6 K        }
    ' T3 A- f: g$ f' p# ^    vexTable[v].firstarc=NULL;' Q- K4 i5 K) D7 S3 K; _
    3 U' O" g$ b" s9 F6 Q9 ]: h
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    * I& p3 u' f/ m    vexTable[v].data = vexTable[vexNum].data;( ^" n; a% ?: l* C
        vexTable[v].firstarc = vexTable[vexNum].firstarc;
    2 u, t5 T$ J/ f! D1 T7 Y7 F    vexTable[vexNum].firstarc = NULL;7 m- `& ]) v8 l6 m
        tag[v] = tag[vexNum];. u8 a+ ?. b6 A! }/ g6 V3 k
        //原来与最后一个顶点相连的边改为与v相连1 k+ z: J, m/ w7 |5 z) y
        for (int u = 0; u < vexNum; u++)/ v" e; y6 F3 x+ ?) i; D
        {  g8 V9 W5 b1 U4 p0 V- p
            if (u != v)
    ! I; Z* b4 K4 }3 t$ h3 j        {  \" `/ e! ]. w% C0 r  M
                p = vexTable.firstarc;# Y3 j7 A, `/ P' J- y
                while (p)6 D9 f# |- u" ^% }4 _5 m! ^
                {6 m* g7 ^$ K' O% a6 }
                    if (p->adjVex1==vexNum)8 a3 E$ M+ M/ x
                        p->adjVex1= v;+ v2 P4 K/ l2 z/ w' _  P
                    else if(p->adjVex2==vexNum)& c+ I! t6 }2 O3 {
                        p->adjVex2=v;
    / y* D2 g; |% D( q7 e9 ^                p = NextArc(u,p);
    2 W* }. F; J- R, q& ]0 y7 [5 d, ]+ E6 P            }
    * d$ W; b9 z  A, J& D9 u7 e        }) [% r- Y* U% K8 J$ D7 _' S8 c. T+ S
        }
    " u/ x/ R! L& Y, D}
    # ]8 j2 N/ u& `! d1 T( b///深度优先遍历
    # o9 x7 t! u  f4 `template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)' @4 \4 [4 E. @) e
    {# T; }% B" M2 d
        tag[v]=1;
    - L2 A3 t. H2 J2 Y% S9 W    cout<<setw(3)<<vexTable[v].data;
    ) O7 h  v6 h3 b6 D: u+ @3 M2 F    MultiAdjListNetworkArc<WeightType> *p;3 o1 b% H. N. Y# G2 a
        p=vexTable[v].firstarc;; {( p  f4 _7 i3 ^% K
        while(p)
    ( Q) I% M/ i, U, l( H- S    {% r3 c3 H4 @) C8 L
            if(tag[p->adjVex1]==0)' F, i! G3 u* M  @
                DFS1(p->adjVex1);7 a9 \0 I! D8 P
            else if(tag[p->adjVex2]==0)
    1 K* f1 z; S  n) c2 |/ S9 \            DFS1(p->adjVex2);
    5 T7 ]  v) R, }        p=NextArc(v,p);" a2 o) @+ m( R/ R
        }
    7 c$ q: f+ }* m! p5 _: D: E- A}
    ( Q0 ]- E# M0 r4 F0 ptemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()( W! b2 q! r" I4 a: i
    {  D% H8 R" K7 j# {8 u1 }
        for(int i=0; i<vexNum; i++)
    6 M7 H4 S! n! Z+ ^        tag=0;0 V& m( S& r: a# A. y* j- a
        for(int v=0; v<vexNum; v++)) a: e+ G& L$ {6 E$ j4 |" ^
        {7 g9 m- Y( r3 @4 k" b3 X  W- p
            if(tag[v]==0)/ R3 `* _5 }4 G7 j' B1 f- T% k  M+ a
                DFS1(v);& b$ g# r/ P/ G* k( h' Z/ P
        }7 w. n& t7 J4 v, c! {
    }
    / w! V/ W) Y/ @' Q! P/ B: xtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    & X. V$ X1 y  v4 ?7 V; |{
    7 T3 Q' [2 x! K    stack<int> s;
    * x$ \3 p: X6 g* ]    int tmp;
    . R4 K! {& B1 G0 `" _" e2 v% d    MultiAdjListNetworkArc<WeightType> *p,*q;
    & y( [3 o/ B/ t. b3 L# B    for(int i=0; i<vexNum; i++)
    . Q0 J& R' w2 S5 O) U2 ?6 Q        tag=0;
    + H$ p6 I+ s  _" D. c    for(int i=0; i<vexNum; i++)
    $ x  N0 O+ [- w: [- C# L6 U    {5 P9 x' m' x! O% W! k
            tmp=i;$ R  r0 o3 ?1 k3 X
            while(tag[tmp]==0||!s.empty())1 E3 R' @7 s! H/ U, p
            {
    ; k  B: f  p; e9 C& v* t# Q* x            p=vexTable[tmp].firstarc;
    $ r8 m5 h& Q9 T2 v            while(tag[tmp]==0)4 \' g; _6 q. s3 b$ Y' r3 {
                {
    , m( o+ l& ]+ |) x( B2 h                s.push(tmp);) M0 _9 K4 y$ s" g# O
                    cout<<setw(3)<<vexTable[tmp].data;* B  h. D, J% N  \8 t
                    tag[tmp]=1;
    2 {" k6 \) W- a( H- a+ C( d7 t                p=vexTable[tmp].firstarc;" P( r# H* T8 y% a4 D! U: I
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for6 V8 v  }. P' g
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);3 \* [; a- B# ]  ]) Z/ \% I: r9 a
                    //cout<<" 1st     tmp="<<tmp<<endl;
    8 _; [0 x# k+ {. i& y4 P            }
    " F' e1 ]  T! Z; k% G+ P            if(!s.empty())
    2 `" R% i4 U& \4 P  ~. D( w' D            {
    / f" a# B8 w: ^( G( p                tmp=s.top();; l5 Q- y7 t( _8 y
                    s.pop();
    4 d( p# q1 u  N4 s                q=vexTable[tmp].firstarc;
    % M" y% ~; S7 z% F; H$ X                int t=tmp;3 j8 r2 ~  o2 I$ ?6 D( y" q( ?  P
                    while(q&&tag[tmp]!=0)
      k9 ~: J3 T+ @9 }$ W                {; |% m" D$ ?& b" _( k5 w
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    4 T. S0 w* K2 A                    //cout<<" 2nd     tmp="<<tmp<<endl;
    ' p  r& Q7 h, f8 X: Y0 C1 Q. Y9 \                    q=NextArc(t,q);* a# s; [) F9 @+ i9 l; `
                    }
      g( _6 u) w* _                if(tag[tmp]==0)" S, n# i2 S' C4 b  Z0 {5 f' E
                        s.push(t);
      t  T) e8 q& S# w( I                ///1、对应上面连通分支只有1个点的情况/ M& d  G; k2 _1 l5 {( r, T
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    1 {; q5 W# d+ D' s: c) n                ///tmp要么等于找到的第一个未访问节点,
    6 o4 n& L# j$ w6 z* S( t% ~                ///要么等于与t相连最后一个点(已被访问过)
    + S) Z( `8 \. R% c                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点. k6 x1 d/ y# d: d4 {7 F7 o
                }
    % m" n5 K  l" k& J  p: t/ N        }, S! r9 O- c$ Q* v0 `' {
        }
    * p9 N; U& h) ~" Z$ V. N9 K2 S) W7 l' l}5 @- v9 E7 F# d5 Y! M
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    2 }& d5 _. i: q  r1 E9 g& u8 W4 m: _template<class ElemType, class WeightType> int+ H" f! ]+ G/ ]& y& E- n
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)8 i7 N$ d7 G0 n$ b  Z) I0 f
    {
    ( a. O5 Q4 a# W2 d+ K* @: c    if(head==pre)- {) I9 p: ^3 N6 d/ `- D9 y9 W
            return -1;  x7 J% p6 t' H; N

    8 D1 I8 f) V' j# e    MultiAdjListNetworkArc<WeightType> *p;9 U9 p( B1 ~7 d+ E0 m
        p=vexTable[head].firstarc;; ]+ r, v( R' a  {
        if(pre==-1&&p!=NULL)+ i( E0 h6 e+ l5 J4 e
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    $ S& q- o; H1 `; {    //pre!=-1&&p!=NULL' U: X9 D5 V  A9 V- H: D' b
        while(p!=NULL)
    9 J6 U3 v5 Z- ]/ i, O% e/ ^    {
    3 L9 G- [; R- }+ ^$ p        if(p->adjVex1==head && p->adjVex2!=pre)
    1 K2 n& h/ F7 d0 C, J            p=p->nextarc1;
    + x4 w7 W6 D8 V$ r$ H        else if(p->adjVex2==head && p->adjVex1!=pre)
    " c: y( n' F0 I5 A! o8 z% h' X            p=p->nextarc2;
    ; e0 R5 W: ^, I  s        else if(p->adjVex1==head && p->adjVex2==pre)
    % L- b# e+ T/ C/ I4 {/ H        {
    . d6 R) P6 {$ a7 ?            p=p->nextarc1;& ~& q9 _+ E, [
                break;. M* @* ^1 N1 N6 ~- ~: U
            }
    " h/ ?$ s- G- r6 }: g        else if(p->adjVex2==head && p->adjVex1==pre)
    3 ]/ N& u/ U8 i% E1 H$ d4 I        {
    ! N9 }1 M& q1 X0 L. ?1 y            p=p->nextarc2;
    7 `1 A# w' A. ~9 w8 X            break;
    # ^& D5 H8 E5 ~& n, y0 e, H        }
    * f( M3 B0 ~' J7 w/ u* F    }
    2 |: i) f+ N. E  H! h9 o2 U    if(p!=NULL)* g9 K2 D: b. ^& R) d
        {! m# t4 f% S) G1 P3 v. e3 j4 J' ~) Z
            return p->adjVex1==head?p->adjVex2:p->adjVex1;1 V, r$ F9 B( E/ a) z
        }( s( \! ?" }+ M; a9 T2 b+ s8 E
        else
    * Q- H3 l! l: _. H# x8 a6 }- E' d        return -1;, l1 A( D/ \( k" K& _: W$ C
    }4 h0 Q; J8 Q: |! q3 g

    : R9 e# }( C+ l, N% D5 l! [
    8 j% Z* `5 y( B% _# b( ^, Qtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()9 C8 I8 M% l) c
    {5 g3 s# Y/ ]* t$ `. c) o
        stack<int> s;. G6 p  F8 i/ `' n# f
        int p,cur,pre;) g- U! [7 L, s2 h/ M: r) g9 ?
        //MultiAdjListNetworkArc<WeightType> *p,*q;
    2 l9 b; S  V( M    for(int i=0; i<vexNum; i++) tag=0;//初始化( o) D  U# u$ S3 T9 O( |
    2 [0 l$ D3 U9 @. H* y
        for(int i=0; i<vexNum; i++)
    8 v, p# z6 w5 x+ N# K    {
      Q1 k8 Q5 y7 s7 n3 C( D. m5 G        cur=i;pre=-1;
    # z. D  E. H# Y! w9 `. P, x        while(tag[cur]==0||!s.empty())
    6 G: W, K8 Y: p+ P        {" L* t+ R3 I: k1 \% V
                while(tag[cur]==0)
    . T" o6 I( {  M: F+ x8 @1 Z. @8 \2 v7 e, O            {8 W4 c: N! l1 v: N5 ]& _: Q5 v$ P; c, s
                    cout<<vexTable[cur].data<<"  ";7 L+ U5 ~8 G3 f+ _3 m
                    s.push(cur);
    , E, \; }0 A, v* e" W                tag[cur]=1;
    ( N) x7 n( N0 p0 z+ t8 n3 I( E               //初次访问,标记入栈1 X0 j6 X8 d: O) T$ u& y
    - d3 {9 z; n. p, ]6 _
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点
    / a1 F  R0 V+ W; i* f: e) T               if(p==-1)
    ! O4 O- G$ k; d* w               {
    6 g% I: Z5 X9 F2 `# R                   pre=cur;s.pop();1 \8 [+ p0 I& M: \
                       break;
    / N* {1 X) M* z9 w4 X/ a               }
    ; j$ c+ `8 W, z$ s4 U- U               else
    7 @4 I( L9 c9 r" h               {
    9 o3 ]- Z' O0 m! Z4 i6 n                   pre=cur;/ P* n9 J; z: d" N
                       cur=p;9 h4 N( ^  D* ~5 q" F9 f
                   }+ G+ S5 [- W4 E' t! k# G

      c% y) w) \1 o7 O' `3 S0 C            }) p, J; F/ }" d, A* F8 }4 u' f
                while(!s.empty())1 l; ?8 Y5 a) Q0 W' B& X; T9 O
                {. x* u* T: Q6 o
                    cur=s.top();
    $ ]6 ^5 D8 K. s                p=GetAdjVex(cur,pre);
    & r3 U# t& e8 D0 w  k% S3 }                if(tag[p]==0)+ M, |: X# k6 D4 j& N1 o
                    {4 v% R/ a; d, b3 {2 f# x
                        pre=cur;
    $ q* n5 D9 w3 S1 {                    cur=p;
    . T* c3 l' ?9 h) V: a* ^8 o                    break;
    . f9 p! F7 n% h- V, ]0 i                }( c7 G# q* Q3 {! E( O% n" p6 G( z
                    else
    ! ?/ B  V; f) f. G  ^: f7 e; p# `                {
    5 s6 R0 m: _- m" V                    pre=s.top();: O% K+ A, y$ ?) ^8 W7 t
                        s.pop();% a; |6 v1 f5 m, Q. g
                    }
    ; N8 ?) W( q' u' m. E4 i$ y4 g0 d' m/ `1 z- w1 o- R7 C
                }) M" h2 I( M: X& k( e

    2 I, T' r% q4 k        }
    0 K2 O0 Z& I1 c' O2 R0 \    }
    + a* o$ F+ ]) t5 K6 m, c4 U4 Q! V}
    . ^- \5 k+ H2 M# t* g: gtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    % n6 m* @$ J  w" n9 Y. m3 o{( ~$ C9 N$ Y4 i3 P& e# `+ D+ U1 F
        for(int i=0; i<vexNum; i++)3 j/ n5 |0 Q  m; O' ~
            tag=0;" F: ~% n2 c! l4 A! r
        queue<int> q;  p0 _  P/ ]3 N; e. Q$ q5 Z& m
        int tmp,t;
    , Y  ^7 H( {, X) ~' ~1 A8 o$ ], O    MultiAdjListNetworkArc<WeightType> *p;7 P' J# T; r3 x
        for(int i=0; i<vexNum; i++)
    8 N* A$ @. }9 f, g, x; o3 `- u    {7 I& [# _( S) d0 _, A
            if(tag==0)
      r+ X: t. @+ J! E( ~/ y        {$ Z! m- Q0 X/ O+ W; \" N: Q
                tag=1;
    - g4 R- k* C; l7 P2 t            q.push(i);
    6 O5 R' d4 Y4 U6 U            cout<<setw(3)<<vexTable.data;
    - u) y' ~- v% y, r- G        }
    % J% H3 e" i3 P# |        while(!q.empty())- K2 d$ C  m6 Q5 Y# s! A
            {0 G  Z% S  W, E9 v. Q8 j
                tmp=q.front();# F& d7 M) q# |8 W! S0 }& z3 Z: |7 Q
                q.pop();9 I0 t0 N  x# n% q, l* C7 d
                p=vexTable[tmp].firstarc;
      r( }0 D" L4 g  d. |+ Q/ y' v9 G            while(p!=NULL)
    % x$ N: W% x8 ?  e6 N/ y4 ]            {
    " p  ]5 m3 B, K3 E! ]- Y" Y                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    $ c& ]7 |6 Y5 P5 t: r                if(tag[t]==0)
    ! h, V% n1 U, [3 O' y* U9 ?8 H! h                {9 C0 [. x* |4 a1 @% l  \
                        cout<<setw(3)<<vexTable[t].data;" Z: z; }$ E$ [* A. G  Y, \) w
                        tag[t]=1;
    : X- b2 i" }8 G4 N0 k9 F                    q.push(t);% w, @6 ?7 A5 ?9 `
                    }3 w0 s2 [: X6 D8 j' @% b: @
                    p=NextArc(tmp,p);
    , l2 h' D" M/ R, L            }
    ! C( t2 T* y' G  H+ M, e        }
    % [& k" C* K  j8 E+ I    }
    ; t. M7 a3 Z$ F}4 e5 b' ?( F2 x, {* x4 d+ N, r! X
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()$ ]# a0 Q; A5 a) C5 \# Z
    {: k8 k* W4 q% L0 v
        MultiAdjListNetworkArc<WeightType> *p;2 X$ F  C2 H' I1 R1 i2 u2 G- T8 i
        cout << "无向图有" << vexNum << "个点,分别为:";
    % N) b& W; _* w; r6 Y    for (int i = 0; i < vexNum; i++)- B- b; B, l1 a. a
            cout << vexTable.data << " ";
    & P% ~  m% e: n+ W    cout << endl;
    1 E1 {7 j, g7 z: o    cout << "无向图有" << arcNum << "条边"<<endl;
    ; m0 f+ l  o& B, B* A% a    for (int i = 0; i < vexNum; i++)! l/ g/ ^& O# a" u/ ^6 y
        {
    2 z( M4 l* j& N- J        cout<<"和" << vexTable.data << "有关的边:";
    . c2 K' `6 U, z! I9 P0 N        p = vexTable.firstarc;2 B3 |+ y" Q" n  e
            while (p != NULL)4 B+ V* H" B5 g" i7 z1 s
            {
    3 x+ e* I7 H7 N* s/ y' W6 `            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";- N9 R; \! {! V) R
                p=NextArc(i,p);
    * [( G. u3 k( a4 G        }
    . I3 f" h! O2 P' C1 d        cout << endl;
    ; ?: c, F9 Q; f% J% F1 ~    }9 X: L; ]! v# S$ R
    }
    # B; h7 I' Z' W  a
    4 l1 V( r/ @# V- b6 N: ]. t4 H
    % [0 T+ x, E) e邻接多重表与邻接表的对比
    / G! d" `+ G  d
    . _( y; P9 I( W2 ~邻接表链接
    9 q& A# y' M! D/ C在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    / ^9 W3 [/ Q$ x( O0 L在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。" G. p6 e2 d  R% M  f' F3 a# U
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    - _$ l) k# G- \  ]) W————————————————4 I" M/ O- A% o
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    # E" a* E% v0 L3 N% w# X2 ^原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    , `+ V# r5 {/ j# F! b/ I% u2 e. j7 D; Y
    % T2 k) p, z; E6 l

    $ b; ^0 i% G2 N$ p% t' K
      F% [& J: h  I+ l: O————————————————
    2 ]0 f) D$ m, o5 X版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。- M' Q% y+ r8 v  a
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958) `$ [' {, G9 N) C! J( S
    5 J/ e# f2 r8 x+ s4 y

    ( p1 Z5 M% T* \: j5 r9 y
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-6-9 11:53 , Processed in 1.963994 second(s), 54 queries .

    回顶部