QQ登录

只需要一步,快速开始

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

    . D/ }( N- m4 P0 X: x1 S* {0 X图的存储结构——邻接多重表(多重邻接表)的实现0 o8 P; }* ~$ a- @) W4 R: D2 Z
    7.2 图的存储结构' _% m1 j4 o% E  P! y0 C8 A

    . Y: I4 {; d0 x7.2.3 邻接多重表(多重邻接表)Adjacency Multilist8 j% d0 t) l- _9 Y& Z% i1 v
    邻接多重表的类定义% ^+ p0 U- M' s
    邻接多重表的顶点结点类模板. g8 P( L$ D- w. S2 v/ t. Y* l
    邻接多重表的边结点类模板
    , d5 R6 C( K, `: u8 W邻接多重表的类模板1 q- t  C/ j8 j* k7 \8 T% N
    邻接多重表与邻接表的对比) H4 ]& p7 P+ i
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist% P1 E" G' x5 w6 |* C  ^6 m; f

    ; V% v* q2 h! Q% d8 b/ g  N2 w( h! @- T* q在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。# p. J8 B( @' \( F8 K
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。( @' P- S* q8 M4 g* u
    * e/ E; c2 ?! I) F
    邻接多重表的类定义
    0 w6 }, v+ K% e" v7 u8 E 1.png
    0 R% G6 R9 P3 n邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:' P: s  F, L7 Z9 B% k7 F
    data域存储有关顶点的信息;
    : N. T# U: L0 q) tfirstarc域是链接指针,指向第一条依附于该顶点的边。
    7 O3 U% |$ ~( [, w所有的顶点结点组成一个顺序表。

    - {8 F# N7 Q2 [. |* u8 m

    ! z" E* l8 x" o3 b6 m, u1 E; Etemplate <class ElemType ,class WeightType>
    5 z3 [" R# R7 \+ ^1 o" ]class MultiAdjListNetworkVex6 \+ B8 a) q3 ~# i2 n' L$ |
    {5 G# B. `$ E# R1 L  _( w5 `
    public:3 }2 a( E  T2 j0 r4 F* Q
            ElemType data;
    , f4 C, h; Y; T$ j        MultiAdjListNetworkArc<WeightType> *firstarc;) c# M% ?; b. o/ c  ^5 L

    0 |) X: m& B* d3 R% K0 S% N$ o        MultiAdjListNetworkVex()
    1 y+ o; M7 S' O- H" K1 c! A        {( j/ V, F! M' P' u! m: u
                    firstarc = NULL;8 J' B) y5 o$ Z& E
            }
    $ H( m6 v4 w6 t3 N4 f' b$ g9 y, }        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    0 G- Y; {$ j4 C8 b6 n        {. F& S2 R7 o- `8 ]5 y( K8 S! m; \
                    data = val;; X" O" h/ A5 ^1 F! d
                    firstarc = adj;
    7 j2 N4 j3 H; c# o3 ^        }
    6 Y8 G# n3 U( {  l6 I2 K};
    : C9 n8 b  e0 |( E+ r% q) G" R9 V. Q: {6 a! k
    邻接多重表的边结点类模板* G& K2 |( S7 ~
    + h! s: s8 `. Y
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    . u7 Z/ @) G5 D9 i) dtag是标记域,标记该边是否被处理或被搜索过;- x; Z4 ^! D! \) ~6 c
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    * d; T3 G6 ~+ w+ d7 S% V+ vnextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    % o' W/ E' m( A9 \) qnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    + C' G* @( z0 f6 o/ D; h* T# Z4 A: ?9 g1 f# r) t+ g6 X% w
    2.png 6 P1 J0 O. p% s7 D( a& v5 {- V% O
    template <class WeightType>+ U: o$ B; Z) t8 s5 r' w" X
    class MultiAdjListNetworkArc
    * }: g* Y& s+ ?" o{6 @' B; T$ S; U; p7 J
    public:: F* _" b7 c! Q8 A! l7 k
        int mark;                                       //标记该边是否被搜索或处理过
    ' H& E' |/ Z4 k$ [- j2 x. [* R        WeightType weight;                              //边的权重
    6 u* f6 b2 G. y- O  t        int adjVex1;                                    //边的一个顶点; t2 W' {% @2 L/ y4 p+ `3 \9 V
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    - C: R5 I, F' t# R3 y  n) M        int adjVex2;2 Z0 x3 z1 j: \& N1 W2 i- j8 E+ c
            MultiAdjListNetworkArc<WeightType>* nextarc2;' B$ ?& ^# ?# ?& [" l. a

    5 i5 ^5 B" s1 F7 U' z+ u( @        MultiAdjListNetworkArc()
    - z5 _: c3 r6 ]8 F" e6 V        {
    - h7 {7 M# k1 }5 K( s$ p3 a- z+ E0 O                adjVex1= -1;
    3 t6 J. f& B$ r2 a" {) o, [                adjVex2= -1;, H4 t) [: s# i1 G3 B# n
            }  B9 b$ M  p: y* u
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    - t" D, i& |) p( `& d- ~        {" v1 n& q  a9 B# R+ ]4 `
                    adjVex1 = v1;       adjVex2 = v2;
      J* q0 t4 Z# ?( d& f                weight = w;- D8 G/ x6 k# I% v( c
                    nextarc1 = next1;   nextarc2=next2;- c# v" |0 ?2 d, E" @- N- V
                    mark = 0;           //0表示未被搜索,1表示被搜索过: X& e1 A6 |9 G2 J" H
            }
    ( ?- r8 y: f( X% o4 l* |  Q
    ( X; ]; K) a5 Q$ l# H. O# n5 @邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>$ y2 E) q% ~; @1 a
    class MultiAdjListNetwork! g8 S5 D8 h2 y
    {
    ' D# t& w$ D: [protected:0 z# o* o: ]$ \# q
        int vexNum, vexMaxNum, arcNum;
    , A9 ]& [5 }9 W, z9 u  B% u    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    0 G! d, Q# f8 x+ L3 `) O; q6 R    int* tag;8 N! g6 m" \& ?& _4 }  X7 D
        WeightType infinity;
    7 N6 p3 [$ {/ f- g. t# v2 h6 L* q8 y
    public:
    * L2 n) F; ^9 E    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    1 t9 P9 f5 E+ z7 V
    * D& z% d8 w' l  x( ?  n    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);1 R' t; H6 E, J( m" v* _* w# w& Q
    6 E3 j. j4 f: X- e5 A( J5 _5 B3 S
        void Clear();: z) e$ i9 K1 Y+ _! i0 d) o
        bool IsEmpty()  S' p3 @% K0 i8 `4 O3 i
        {* L$ [0 d* b, Z/ K( P
            return vexNum == 0;
    # d# W( B! b' C, S& o    }/ k6 v4 m  l6 \5 J4 y6 i3 y
        int GetArcNum()const' Y1 E- y& U% i6 G9 p4 Q
        {
    / }5 J( d' Q# @0 @% M; f$ u: _        return arcNum;
    8 M7 q. l) c3 i, P    }
    & R/ d' y, w' z: Z6 I    int GetvexNum()const
      X( h) `& H; V, a* ]! J    {( v# s2 b7 y. [, K
            return vexNum;
    6 D4 U9 L) s; _    }) A8 H  O; |+ J( W
    % K/ b1 E" N& t+ B; c
    % p7 U, |$ n. }3 J3 u/ i# p8 \5 ]
        int FirstAdjVex(int v)const;# m( X6 r( h* y# W- D8 Y9 O
        int NextAdjVex(int v1, int v2)const;" Z3 V, c; [4 c' E, |3 I* g" |) S
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    0 Z% n  g& U+ I2 s+ s- p    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;8 K0 W% k& K" k' Q
    : g8 L; ?/ W! y1 U, c0 B4 s
        void InsertVex(const ElemType& d);. {; h: I. d8 K0 M& t5 y  _' v2 h
        void InsertArc(int v1, int v2, WeightType w);: t) o6 \. r3 M1 j2 L2 }

    ; w7 n( _7 C) ]" X    void DeleteVex(const ElemType& d);
    + ^6 b) r9 H9 d. R. j9 v+ Q0 j    void DeleteArc(int v1, int v2);
    9 |+ I1 W/ t( {: F
    + G8 ^3 ?4 K1 W$ |! }4 W( @    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    $ h1 M' k! P; j  w" k    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);8 D% f0 R8 d3 l  e1 M/ J# K8 J
    % J% Z$ Y; M, N1 _. P4 H: }
        ///深度优先遍历
    : t4 G8 D9 L2 K- a+ d    void DFS1(const int v);
    / @8 N; z* v+ K8 y" k3 N  u    void DFS1Traverse();
    * W% R, w$ O9 S; ]    void DFS2();
    9 G# v; {1 f8 e1 I( @
    0 e' ^, h0 ^- H4 p9 ?/ c4 v    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    6 u6 x( `" l, [9 r' B, ~5 G# k3 |    void DFS3();0 F) M4 W4 T) j

    # g! @' P: p; p: y% |8 U    void BFS();3 m, `& y6 W8 H+ U9 k. s
        void Show();
    6 S3 B: d- w; d- L" B: ^};
      |' O7 [- F( g/ l8 H) m+ s" J3 s" ~% {/ [) n7 Z( O
    2.函数的实现
    5 r/ D& z, U5 _# ^* |/ z+ {0 D1 @研讨题,能够运行,但是代码不一定是最优的。7 s4 y" g7 b1 [+ S! ^9 A6 {8 ^
    # T3 F& c) R5 z7 y- W$ l. J
    #include <stack>1 V9 B7 g" c# R5 X
    #include <queue>$ V- U$ O' W$ {* s( A; I+ G
    ! T: X& K% U: Q% @- v
    template <class ElemType,class WeightType>" c( t( |" g* m# z
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)6 o5 z& m9 E' X& A9 e+ F
    {) |+ ^( Q) N5 @1 R. h  u
        if(vertexMaxNum < 0)
    / q# P8 r0 s2 V7 M( k7 m5 `/ m        throw Error("允许的顶点最大数目不能为负!");0 T/ @* K  l/ q) P- I) e
        if (vertexMaxNum < vertexNum)
    * L8 D: v3 R/ z$ P% v: p: t        throw Error("顶点数目不能大于允许的顶点最大数目!");" H6 d- x( V# C6 w- a& j4 t
        vexNum = vertexNum;1 q: }3 h* P. n; z. f" x) H
        vexMaxNum = vertexMaxNum;
      ]" h" i5 c% }5 ^  \1 n    arcNum = 0;% @( y* H# J, v2 l) P4 ?1 P' e) V$ L
        infinity = infinit;: |* F) k3 s9 e& q4 I6 |
        tag = new int[vexMaxNum];
    ! }: d# j6 \& L2 B" H! R2 x# {. W    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];# H9 L7 d+ V% W# u+ J3 E2 ^
        for (int v = 0; v < vexNum; v++)2 r5 v, O* m/ F" h
        {" b5 H: h& D6 d1 a; f  v& s
            tag[v] = 0;
    ' m4 B# R$ L! Y! [        vexTable[v].data = es[v];  R6 Y( R  @. F: k
            vexTable[v].firstarc = NULL;
      X; H# {$ g9 l6 ~5 H    }
    + {" T' l/ [8 ^5 C}& p/ v' C; \* M' p. V
    template <class ElemType,class WeightType>
    + C; K6 D  u8 SMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    ; [1 i, V9 I: A9 M0 \7 ?1 K: i{1 O: K- d1 N! K) D  ]$ g
        if (vertexMaxNum < 0)
    ' s) i: Q- U5 V4 J$ i        throw Error("允许的顶点最大数目不能为负!");. J* }5 a; L" g8 T: x& ~2 Q; i
        vexNum = 0;1 ^/ g% _1 _7 ^( n8 S
        vexMaxNum = vertexMaxNum;* m" N4 }8 N. S! X& J
        arcNum = 0;4 N7 x8 a' w; ?0 X  ?
        infinity = infinit;
    8 U* F+ J; O9 G! s- Q+ }# Z    tag = new int[vexMaxNum];
    ' L4 U2 i6 F) w' k9 |" y4 N: v    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];: J8 v8 a( g( f! t# l# d% ?- S! i0 e
    }
    ( O( G9 Z' C# @/ D# I: \8 x* ]9 K2 gtemplate<class ElemType, class WeightType>
    " R* G8 Y. |' s3 ^6 Wint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    0 K+ w$ A1 k: c2 _) K( e2 H{
    / d7 m* P3 ?/ H% T& C7 i    if (v < 0 || v >= vexNum)
    / T# l6 T; R+ k7 W9 J5 L: B        throw Error("v不合法!");8 |2 x5 }9 D2 i8 ]4 F
        if (vexTable[v].firstarc == NULL)& H' p2 g4 }* A
            return -1;  q3 n+ j* E; ]. @' b& d$ p# `
        else
    $ R$ G/ d/ ^+ `. b7 k        return vexTable[v].firstarc->adjVex1;
    7 B1 \! W3 Y; g4 [) Z4 k- `}
    7 Q' `! z% E( {, \9 X+ S/ C& G
    template<class ElemType, class WeightType>
    & @# ~9 @: S) F, F! p# Lint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    2 W* f$ t' ^4 H+ i/ d{
    0 s+ a) g% U1 s    MultiAdjListNetworkArc<WeightType>* p;
    & i* v3 @) o2 m$ c5 a    if (v1 < 0 || v1 >= vexNum)
    & W0 q1 F! [6 x2 p& q( f        throw Error("v1不合法!");: `* b$ \( ]8 x/ N+ q" I
        if (v2 < 0 || v2 >= vexNum)
    7 h% @* e1 k1 V/ B        throw Error("v2不合法!");
    / ?$ K0 L6 B/ D! I: G    if (v1 == v2)
    % e  a! o" {* [/ e7 _/ U% l2 e        throw Error("v1不能等于v2!");
    6 Z6 I% f5 j0 C6 x" X/ j    p = vexTable[v1].firstarc;
    # `" @5 q& V2 {    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)8 r  t9 D5 a* f5 U% ^5 U- ^4 z
            p = p->nextarc;, h& Z  v4 x  T- Q- U, r6 c- ~# I* L
        if (p == NULL || p->nextarc == NULL)
    , d& D; _% D3 d3 U4 |6 E        return -1;  //不存在下一个邻接点
    7 q0 H/ h9 A8 `    else if(p->adjVex1==v2)
    2 R7 z% R! }4 q7 k+ i$ D+ C        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    ) ~2 l2 C) A3 T2 Q0 W    else5 L: R' S! I. Y0 c
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);5 n7 L0 J- O2 ^" @7 U
    }
    $ H( f" |: D& S- wtemplate<class ElemType, class WeightType>6 _4 F1 A' k0 q; G0 u
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()# P( E0 K; h' U7 F
    {
    1 {- A+ \+ K/ J9 c    if (IsEmpty()) return;5 R. }3 F; R- \' L' G
        int n = vexNum;$ o' |& T" g6 b; l# R! D$ J
        for (int u = 0; u < n ; u++)" }; y6 N! P+ K/ O
            DeleteVex(vexTable[0].data);
    + B, o7 x; f$ C0 `0 r- e7 P    return;
    & c& P+ E' Z' e8 R1 ]5 f}
    8 d, N# f" U1 Y3 ]8 _3 s/ ]) ytemplate<class ElemType, class WeightType>
    * d4 j% N: H/ L6 s: iMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    ) C! d5 Q& F* K5 {4 r# I{
    " A- z0 I2 {( t1 l    Clear();
    " G! E/ p- Z. D0 F}. z9 S. s) N: l" d7 X4 ?/ Z8 a
    template<class ElemType, class WeightType>- a7 o7 n5 K1 z4 W, f7 m
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)5 N. h4 W4 i% B8 I4 Z
    {
    8 N9 K. _! L2 e; C3 m" |; \5 w    vexMaxNum = copy.vexMaxNum;
    ! g% g* g' k( P9 [6 V" m    vexNum = copy.vexNum;
    % M% P3 g2 V# Q    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];4 C9 d  b# c+ j. S
        arcNum = 0;: e0 s* a, |# |, n9 h) f. E
        infinity = copy.infinity;5 j3 i/ C: V" [" ]
        tag = new int[vexMaxNum];
    ) S  B6 C4 I6 O+ W' [2 @- l% w
    / W$ Q: U( P$ N    for (int v = 0; v < vexNum; v++)
    & h# m, ?  d" @8 e5 ^  k    {
    ' j# Z2 i4 w8 A        tag[v] = 0;
    7 n2 i7 G* M& l- v( c        vexTable[v].data = copy.vexTable[v].data;
    8 f  {8 y* o5 Q8 `/ _% Y' D        vexTable[v].firstarc = NULL;
    ' L* a2 {8 j$ A' H6 Y8 E    }0 O7 p( \! I/ ?* I
        MultiAdjListNetworkArc<WeightType>* p;8 X; I6 C7 D& {, ]4 L

    ! @: n) C) K% l. M6 Y3 B    for (int u = 0; u < vexNum; u++)+ y' V. i5 o1 t2 a6 m) A9 F
        {
    & r' X1 R# b. B- ?2 M        p = copy.vexTable.firstarc;: a2 R; D8 j$ |* [; ~
            while (p != NULL)
    0 t$ _- p5 h/ j; L/ l/ s4 b        {  A. e$ [0 N. p
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    8 C& a6 o9 k% B$ s8 Q            p=NextArc(u,p);
    7 `; v' L* U; V2 n$ h9 R        }2 w% h3 b, ~2 K2 t' r* ]
        }
    # a/ o) C% e; U1 b" X}5 a0 p/ z6 B1 F2 q1 Q8 Z% J
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&1 m' }6 H$ ]  `/ B6 _+ g- K
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    7 x) S$ Y' i( i0 v/ Z{  t( r; j) Y  W
        if (this == &copy) return *this;# N" o) Q/ ?- D! d+ ^, R* M1 d
        Clear();2 Z9 U$ x- }' e) O! |  I
        vexMaxNum = copy.vexMaxNum;
    2 v* a' U+ f  i/ t* I6 O* A' W! ^$ ]    vexNum = copy.vexNum;  `0 P" z% a" _# M3 e4 Y
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];0 [( _1 {# T3 ~4 [! v/ j
        arcNum = 0;
    * q8 l  p0 e! O/ j& Z    infinity = copy.infinity;( U. Y1 w3 }( j# I# l/ Q* P+ f3 Q, x
        tag = new int[vexMaxNum];1 }$ E# k" s5 J: C) f- [
    $ P, ^  W% Z' V0 p0 v% \! l
        for (int v = 0; v < vexNum; v++)8 C2 u; f$ q. B6 c5 h9 j
        {
    / `# X- O$ a4 w+ U  n7 e! T9 W; O        tag[v] = 0;
    ! w. }! m3 T2 s, e' r  m        vexTable[v].data = copy.vexTable[v].data;
    * |! b( v9 d( Q/ F* _# S        vexTable[v].firstarc = NULL;
    / n# p/ d/ t/ V/ X# c2 x5 b- M$ b    }
    $ m: Q. Z, a" G/ n: F7 v9 D+ [    MultiAdjListNetworkArc<WeightType>* p;7 B- x- f0 d) D
    6 Y& m' t; y& O8 p* T
        for (int u = 0; u < vexNum; u++)
    9 H2 O5 q/ n; E    {% N) k& _/ g, }" ^$ F, x
            p = copy.vexTable.firstarc;
    : d7 S3 U2 P8 ?        while (p != NULL)
    $ S+ e6 Z9 w, z; U' M, O. F( y& g6 C        {; S2 `/ Z9 x6 p, ^8 x1 U1 y
                InsertArc(p->adjVex1, p->adjVex2, p->weight);0 d" y4 q# ~! D" M8 |
                p=NextArc(u,p);- ^7 r7 N( ?% G5 b! x
            }* ^: n- r# R1 f, H+ q% ]; f  P1 r
        }) Q3 `- ^8 u( H* T
        return *this;
    # Q* d/ s; Q# S. p}
    2 `7 N$ Z) B2 Y1 v: J- U, [template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*) @# v& H4 ]2 z" M
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const% A' B' {% N4 ?
    {3 y1 c# g, B. w
        if(p==NULL) return NULL;
    ) q1 d, V+ N) ~" x5 Y' z    if(p->adjVex1==v1)
    * T- n2 O/ [. e( O& }' T. c7 K        return p->nextarc1;4 u! R6 j, K1 A! J3 G
        else
    ) R$ a# X8 Y7 K" ?' A2 F" q7 E# W        return p->nextarc2;  h' N8 a/ W, @9 }0 @  h
    }
    % J7 ]: g: K( Y3 K( f; g: mtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*: c% b; V) E2 t; a# i$ ]0 w7 g
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    ) P. X4 O/ m) U/ i7 \4 X. G4 C{6 i2 f8 k8 U8 O) `! G. E
        if(p==NULL)return NULL;
    # v- z; R' B1 T; `  T    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    . ^5 ~' M6 ^9 I1 L) T# m4 q" g4 ?    if(q==p)3 `) S4 h& p) `* @# p
            return NULL;
    # l! h. h4 l2 @' `* r    while(q)2 K- u( J, u  H; c1 z
        {1 q! S. X# Y9 k% W* T$ }
            if(q->nextarc1==p ||q->nextarc2==p)
      k8 g& n. y+ v- C$ h6 S  A            break;# d6 U1 g' S9 U' `
            q=NextArc(v1,q);
    / o: C+ ^1 o! M4 h    }
    # j, h( z& S% [4 q    return q;, [9 K- r/ X! O, }# R* I: L& t
    }9 T8 ^0 z% o7 X/ I" ~
    template<class ElemType, class WeightType>) S4 {' h0 y: M2 i" R* L7 J! z
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    6 a# p* ~& r8 O& }{: o  U# M* Q# U4 d8 T$ ~
        if (vexNum == vexMaxNum)
    ) Y$ f2 ~! k$ Y! @. b+ E) [        throw Error("图的顶点数不能超过允许的最大数!");
    9 x% u0 N9 j/ I' H    vexTable[vexNum].data = d;
    3 n+ A; r3 q2 v) I( F9 C, \$ y( P0 g    vexTable[vexNum].firstarc = NULL;4 y5 q2 m* Y' R2 z
        tag[vexNum] = 0;) B$ I2 I4 Q, i
        vexNum++;5 B6 {/ }! v; e
    }- N/ l' \8 @8 D4 F9 ]
    template<class ElemType, class WeightType>2 I7 T6 q0 t3 Q9 e
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    5 T+ B9 o+ ?! y8 T  U2 k2 w{
    , E0 c% ^' Q8 ?! G! }5 G" [6 ]    MultiAdjListNetworkArc<WeightType>* p,*q;( k  ?+ ]7 c2 i) L$ Z4 w
        if (v1 < 0 || v1 >= vexNum)5 p1 \6 n  I3 y  ~! J
            throw Error("v1不合法!");* P* A" @" S* R5 _; n
        if (v2 < 0 || v2 >= vexNum)' _+ A8 C0 o) Z. |/ Q$ w+ Q, v& k  ?
            throw Error("v2不合法!");. e1 J5 d/ [4 J- _1 `. k
        if (v1 == v2)
    & [2 r5 c) d9 c3 \$ z        throw Error("v1不能等于v2!");
    % d# k" ?- C& Q9 {# l    if (w == infinity)- L' c9 J( u9 X, w8 I3 n2 |- o
            throw Error("w不能为无穷大!");2 _: m5 Z0 X, d. q6 L1 M
    7 |- ?3 C  [( c' ^# O
    & x  o/ A5 |7 D( _( ^" s8 N8 v
        p = vexTable[v1].firstarc;$ H% `1 p+ c/ ?% p" X9 w
        while(p)
    & N2 U% T4 \& ~$ N* h8 z    {
    # c" m* P) d2 }3 q3 z' L) k        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中+ d7 E- I, }1 S  y1 A
            {
    3 k1 E0 q4 v$ s            if(p->weight!=w)/ e: w7 U5 D$ y3 J! e7 @/ C& t  D
                    p->weight=w;9 v" A$ \" q9 R4 z
                return;, h' [6 e) F& S; o! r
            }0 i. a, h3 K. |4 s4 a
    # S/ R2 m' s  i  o8 [7 I: J
            p=NextArc(v1,p);" h2 ]9 h) z4 R" L
        }
    # v9 o" J& h, k' R" r: M2 u    p = vexTable[v1].firstarc;
    6 g. ]. U' w+ i6 v/ w! v7 U    q = vexTable[v2].firstarc;/ N& `( y/ ?2 o3 ]; [- @, s4 ]; ^+ I
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    : y- p+ j- Y& H9 R# o    vexTable[v2].firstarc =vexTable[v1].firstarc;9 c* x  N; y' h" _: O, a; [$ N
        arcNum++;; p/ G  f  b# a2 f6 d; c
    }+ h' _! _% w( U. {3 p
    " @4 [2 ]6 E# W% h
    template<class ElemType, class WeightType>
    5 N: B1 `7 Y6 Y' i+ Evoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    ( ?: C3 w& n2 L$ w% z{
      Z" n9 |: `( P& Y
    1 t$ n% T5 b! Y4 L& Z; l! d    MultiAdjListNetworkArc<WeightType>* p, * q,*r;7 s% D4 I+ j0 u8 ^- L
        if (v1 < 0 || v1 >= vexNum)6 r0 b2 P7 Y0 L$ `# }
            throw Error("v1不合法!");
    " j; W- J% F% z    if (v2 < 0 || v2 >= vexNum)
    0 C& Q* a9 P  q/ O( u+ D2 `        throw Error("v2不合法!");
      D  a0 K- h' m7 t7 J# T    if (v1 == v2)
    3 _5 H' ?/ l' j$ F6 t& Y+ }, h" u        throw Error("v1不能等于v2!");6 ^/ w! I+ q8 y: |
    3 l5 G$ m% ?" }" [2 a
        p = vexTable[v1].firstarc;
    8 U/ C1 R% o2 A8 T3 V1 ~    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)0 n" m9 n  O- N8 V  M, h$ k
        {; J. W; m# f; w1 w
            q = p;
    0 k  _0 X8 a. Y  m% E        p = NextArc(v1,p);
    + G; M% a  {. D; c    }//找到要删除的边结点p及其前一结点q
    5 e* Z* A- n3 ^% g' }) Y
    & B! Y$ o3 Z  ?3 b. p- L- ]    if (p != NULL)//找到v1-v2的边
    0 l! f/ c5 m+ Y9 H" N8 w) ]    {
    % d( j8 j9 q. P        r=LastArc(v2,p);
      b' I8 A6 i3 s9 U% ?        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL, |% n! S" C8 D: B- z
                if(p->adjVex2==v2)- F- A# u* Q( g1 U1 d3 d. m. N# _
                    vexTable[v1].firstarc = p->nextarc1;, B/ x: }3 n% f, k4 }/ R  l5 N
                else vexTable[v1].firstarc=p->nextarc2;
    ; g  e- o' z: p7 @, M        else//不是第一条边3 s7 v# R; |3 K
            {  U& B3 T* h* ~
                if(q->adjVex1==v1). U+ Y! a$ a0 g# T
                    q->nextarc1 = NextArc(v1,p);
    - y6 b/ c  c( }7 J, x. H            else
    ; c$ e8 Y4 C+ ~6 a5 I4 K                q->nextarc2=NextArc(v1,p);
    . [# d& Q* Z! G8 I9 H, ^4 \: Q" D% n
    ; \9 U0 c7 x! @        }
      v' S& M7 }$ T" m" B' P( g        if(r==NULL)
    " d2 i. K1 x/ r            if(p->adjVex2==v2)4 Y3 R! R6 f) |1 @
                    vexTable[v2].firstarc = p->nextarc2;) f) @. o; G" K! }2 ]4 `
                else vexTable[v2].firstarc=p->nextarc1;
    3 q. [6 l- v* K3 `2 K4 N        else, J: w4 Y3 \+ }% m+ z" l! [1 ]
            {
    & I! \" v/ s4 Y- d1 d            if(r->adjVex2==v2)
    % I% a+ d4 t" l( s                r->nextarc2 = NextArc(v2,p);
    & t0 r5 R+ T' f4 g6 ]            else
    3 s+ k6 Q4 U7 q* |" P9 e% J' ]                r->nextarc1=NextArc(v2,p);
    ! \4 Q" p1 v+ F( I  a8 @% B        }- e/ c! c4 \& D
            delete p;9 F3 `, V8 P0 T5 O9 O
            arcNum--;( r; a6 `5 b' A7 B- L; p2 A% A
        }
    3 B9 S8 O8 w6 c4 d/ j
    2 O; _" Q( `: V}& E; m( Y2 e  i
    template<class ElemType, class WeightType> void
    ; C1 m0 U! ?$ q( `5 O4 s  wMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    2 A' N" y" A) I{
    ! n" q1 T+ |% e8 ^( J+ [& Y    int v;
    - z7 x+ E7 t: U: H) w    MultiAdjListNetworkArc<WeightType>* p;7 `* L% G+ k: F0 l) v
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    9 L* S& J; l* L8 C4 ^' C) e/ f% g9 u        if (vexTable[v].data == d)
    5 I  ^9 @- @4 E; k% J! T            break;& f% U9 G0 D( E: Q1 Q
        if(v==vexNum)& n( C- ^; v- k1 z
            throw Error("图中不存在要删除的顶点!");
    8 O: S5 w/ _  I7 d) B
    9 ?1 `1 P/ w$ E+ E    for (int u = 0; u < vexNum; u++)//删除与d相连的边
    2 E4 i4 c$ r$ t        if (u != v)% F0 y/ l5 f; F
            {
    3 S/ b8 \) |/ m/ d& j+ t8 T            DeleteArc(u, v);$ D; ]' }$ E2 J/ b* E' U% Q
            }
    5 N* S: Y! O- B; n8 ?) E$ g% W( b    vexTable[v].firstarc=NULL;
    ; T$ r4 w9 T) X: Y" C2 b/ Q* n/ i1 H  j- E4 g
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置" v3 v0 A. \4 q/ }1 o& c) R  n0 ~
        vexTable[v].data = vexTable[vexNum].data;5 u7 F7 |) R6 R+ Q7 C
        vexTable[v].firstarc = vexTable[vexNum].firstarc;
    ! Q% B4 c& ?3 N6 j! T    vexTable[vexNum].firstarc = NULL;
    4 R7 G6 c# a1 P# c. P/ z    tag[v] = tag[vexNum];( ~/ Y6 b( a) S  Y8 C3 E
        //原来与最后一个顶点相连的边改为与v相连
      k. A2 M7 \' Q9 |4 V    for (int u = 0; u < vexNum; u++)
    2 R* e6 Z3 }2 K' L; T( U    {
    0 L3 z9 q' ]$ d$ V7 G% B/ s+ B5 e        if (u != v)! k# p1 R6 i9 h
            {" U+ A+ i3 Z# @5 I
                p = vexTable.firstarc;" s# F. [0 H  J% {3 a9 P2 w
                while (p)( x& F. J4 }0 U3 \- C
                {
    # H- j" i" p7 o# g  h, Q3 S  Q4 l                if (p->adjVex1==vexNum). ^* P8 L4 f2 U: |
                        p->adjVex1= v;6 \1 G1 O5 t$ Y" N
                    else if(p->adjVex2==vexNum)6 c% p- Q3 G% R; n1 T$ Z
                        p->adjVex2=v;
    + Y4 C! D$ K4 l8 @4 ?. X$ t                p = NextArc(u,p);
    * Z0 P4 h5 f7 ]% p9 ~( H            }
    3 z/ T  Z/ @/ |8 ]' s6 ~        }. _$ O7 P3 K7 G1 w+ T2 Q) D
        }, l+ V, |2 H  K% C9 Q3 q# w& B6 T
    }
    2 n% [, T" [7 u, m* ]; m" }2 E///深度优先遍历6 I# n9 J. v1 N/ D2 z! J- L9 x8 b
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)! ^! Y% y8 F- f8 l. ?. \1 m: ]
    {/ C2 D9 T- @* S
        tag[v]=1;
      m. l* V7 z* ^6 G4 B    cout<<setw(3)<<vexTable[v].data;) Z( b: e) M. C9 Z" c% ^
        MultiAdjListNetworkArc<WeightType> *p;
    ' s8 I/ C% h1 \( E+ t$ i5 L    p=vexTable[v].firstarc;5 b. G3 h+ E$ ~: f$ @0 B9 Z
        while(p)
    - y" l- O- o6 @% T    {7 o4 z7 d. l! q# F2 J" h
            if(tag[p->adjVex1]==0)) a) {8 k: b! x  ^6 K
                DFS1(p->adjVex1);$ t" T; K6 J* _! j* s& Q% ^
            else if(tag[p->adjVex2]==0)/ v* ~. E: ~: A) @, E
                DFS1(p->adjVex2);  U* x/ g( N1 j
            p=NextArc(v,p);
    1 [. Z$ P- m* I9 K- G    }8 B7 a  u, \$ D: i
    }7 z. R" e3 Z* F6 v) i
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    9 H1 U' I" G  y% ~* M{# R4 [/ N! [! n" t0 E- g2 C; p! ^
        for(int i=0; i<vexNum; i++); k# C& X9 c0 l
            tag=0;1 F+ |/ P7 t, {' Z$ @3 `& H
        for(int v=0; v<vexNum; v++)
    8 g7 M0 L- U) z3 Y& M& m    {
    ( k' L& f, i4 c) m( Y0 c        if(tag[v]==0)
    0 `) C, |6 t8 D/ c            DFS1(v);5 n& q! |7 V& b# Q
        }/ h+ {5 o# d: H& G" D$ c5 Z# l. K
    }( m# W8 A, |( c5 x. ^) S
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    ' G/ G, w: b5 L( i/ G& z! b& k{2 v/ U" @. c! p3 c6 x, Q
        stack<int> s;3 L4 ^! ?& L7 A+ e  p8 T* X
        int tmp;3 ^5 @1 q5 [9 I: F! w" l/ y3 p
        MultiAdjListNetworkArc<WeightType> *p,*q;
    ! v$ G$ a. P5 k4 {. s    for(int i=0; i<vexNum; i++)/ m( ~  C6 k0 V( M7 a9 h+ G7 w
            tag=0;, {) k; ]1 C5 r$ H; y+ F
        for(int i=0; i<vexNum; i++)/ h, J/ g$ \7 F& \( l) m
        {5 x/ M+ s5 V9 `
            tmp=i;
    ! ?% w5 E) s; G* j1 G2 j( h        while(tag[tmp]==0||!s.empty())
    2 q7 S) d% a" `* P, ]. s' K& L        {- x1 I  Q+ t$ j/ }' F
                p=vexTable[tmp].firstarc;( ^' W7 @' c) f5 _) E
                while(tag[tmp]==0)
    6 I* n& g4 x6 ~% [$ G            {
    8 r! R. P" F5 G, H                s.push(tmp);- f6 y* U/ H/ o7 h: k% w' R! v: x
                    cout<<setw(3)<<vexTable[tmp].data;
    % e7 ?: x4 M$ ^8 L- s                tag[tmp]=1;$ }5 V3 H' v% Y! f( \, t: D! ]
                    p=vexTable[tmp].firstarc;8 o# r- y: u/ E) |& H
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    # f* t8 W9 J3 D                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    ( h6 a* T! C- F  E: g                //cout<<" 1st     tmp="<<tmp<<endl;! e; a/ i: S0 l$ }4 M
                }
    " x( G, {, T1 _            if(!s.empty())) c8 l( L. C, P  B
                {6 ]3 e  r+ y8 R( z9 N8 d, [
                    tmp=s.top();. k5 a4 H- u$ a" j3 \7 h; Z
                    s.pop();- D+ p8 b2 R. f9 ]. C# e
                    q=vexTable[tmp].firstarc;$ V  x8 G1 s" s0 N
                    int t=tmp;
    6 `& G! e: d0 d  b. K$ f8 W0 _                while(q&&tag[tmp]!=0)
    ) l8 u; q+ ^1 H: Z$ B! o                {* }5 h+ V2 \( X& i2 |9 P; Q
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    , P' k; y5 ?! E# F) n                    //cout<<" 2nd     tmp="<<tmp<<endl;
    6 j) f6 W$ o" R; i. N                    q=NextArc(t,q);
      T2 _+ e6 f9 p                }; Z3 ?" b1 L- _* Y6 l
                    if(tag[tmp]==0)
    4 j  a( O7 v0 |- h2 V                    s.push(t);
    ( d* A# O% B( E  _2 B3 Q# s8 O1 o                ///1、对应上面连通分支只有1个点的情况) @) J  B, l9 V5 ?3 H/ u+ u. e
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    # |& J. F0 F/ V; C; l# Q- _8 ]2 R0 j, W                ///tmp要么等于找到的第一个未访问节点,# A- ^8 y. E: e
                    ///要么等于与t相连最后一个点(已被访问过)
    % t. P, W% E& |, b6 G! @                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点' ^+ [$ E( [0 l) s  M) {* V
                }+ }7 h& z, {' P5 q: T6 O
            }
    7 }  ]2 [% x5 @  F    }
    9 t" _) u/ `0 a0 x}9 e2 G2 \7 v& d, v1 l. o% \
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    $ m+ v# G7 \0 w& q! _9 Jtemplate<class ElemType, class WeightType> int
    . d( j4 t" u- kMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)+ W5 ~. b  N% @2 `  o7 [; ^4 s
    {& _6 i  Q  u: |/ W
        if(head==pre)
    3 b, R9 k1 a4 d9 g$ H3 ^        return -1;: q8 v4 o7 q9 `* Y5 U
    : z' K# Z9 E. g; ^7 `$ y* I- `
        MultiAdjListNetworkArc<WeightType> *p;' z( G) [/ R$ O- [1 ]9 |
        p=vexTable[head].firstarc;
    0 r1 t) d3 C% k! i" |    if(pre==-1&&p!=NULL)
    . |5 C" n. r0 n7 b! s- n        return p->adjVex1==head?p->adjVex2:p->adjVex1;+ T  H6 Q6 R+ G8 c6 E  ]
        //pre!=-1&&p!=NULL, f; T, k/ m) Z2 ~
        while(p!=NULL)
    , x# n1 K; u$ S7 E    {2 G% `/ g4 S, L9 j1 i9 D+ x! e
            if(p->adjVex1==head && p->adjVex2!=pre): U# r; L, p! k6 j3 w/ L
                p=p->nextarc1;# X; {; C2 X7 Y3 I* G
            else if(p->adjVex2==head && p->adjVex1!=pre)
    ; ]( H1 D8 ~% }, q" C            p=p->nextarc2;
    & |6 {4 ], \' E; V$ \        else if(p->adjVex1==head && p->adjVex2==pre)/ ^/ c4 S$ I  L; b: u
            {. M$ W5 w6 C" W6 x) o# Y3 W3 S
                p=p->nextarc1;) k0 W  p  J0 \' @: b" J
                break;: E. `/ Q% M- U9 X
            }$ L  j$ }8 ?) q- f. B: o) d( J2 S
            else if(p->adjVex2==head && p->adjVex1==pre)
    6 A* {# }/ n% n        {; Q" ~6 K0 }1 j8 M, t4 Y+ r
                p=p->nextarc2;
    . U4 i7 C0 ]. D7 w# j4 S            break;
    . }1 m& V! _. H& N, t5 S        }
    # n8 m# n" B5 J5 O    }
    # G9 b' W) g4 Y/ p1 D  `: p: }    if(p!=NULL)7 {# L+ O8 C6 g% E
        {# g8 L- O% t6 f6 Y( n- n3 P6 L
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    ! p5 ^8 U3 c; g: q4 U+ c$ T( S    }
    # X. a& O- I/ b5 z7 D* d4 o# x    else
    1 A, s: ?! B% x! x9 b        return -1;6 ?: o) u! e4 _* k. s
    }% d9 {* W1 B3 v2 V! x+ c; J
    ! r: d7 K) ~5 S: p& D: ]) u
    ) ]3 E+ Z6 }- H2 M# ?0 I9 K
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    ! ^+ ?/ ^/ ?  v$ l$ H; w, W{
    + z0 f" v! X6 W$ G* {1 O% @    stack<int> s;
      O* I- E9 x# c/ O# `) x    int p,cur,pre;# k, R* `- O' O
        //MultiAdjListNetworkArc<WeightType> *p,*q;
    0 w7 F8 t' ~9 L    for(int i=0; i<vexNum; i++) tag=0;//初始化: s6 i+ h0 y; u9 P

    4 N1 I) q- e- e    for(int i=0; i<vexNum; i++)
    3 J6 b4 b$ T. g& S3 f    {
    9 y* w- D3 n( z: p* K        cur=i;pre=-1;
    * t9 D2 g% i! ~) ]9 n; J5 Q: K5 Z; W        while(tag[cur]==0||!s.empty())6 J) B, Z. F- i" M6 _
            {
    1 d& o) L# n5 S- ~            while(tag[cur]==0)
    ) P% F$ g7 O3 Y- L4 p            {; G0 g! m8 V' }: c# B- S; H
                    cout<<vexTable[cur].data<<"  ";
    5 I" ]2 t; C% R) C, U* |                s.push(cur);
    * R- V" U, P# Y* u' m3 o                tag[cur]=1;
    + F5 y% x1 j/ A" \! D               //初次访问,标记入栈" Z6 Q. E3 {) U% ~, m" f
    ; n* f  W) I8 t
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点& v9 c* q+ W3 |  n0 T
                   if(p==-1)
    ; a0 ]0 |8 m1 s: C+ [6 P6 \               {$ E: D" B: {, |0 ?* r
                       pre=cur;s.pop();
    1 M7 j* ?- ]8 U8 r: H; S, Q0 U2 J                   break;$ \# H9 v0 P1 P# T$ h% j, L6 i
                   }
    ) Z8 E% e/ }9 |( Z               else
    9 _" f/ K/ o) o6 s7 u' [! A1 i+ N. u               {& p  f! v& N, F! Z6 a/ }. ?
                       pre=cur;( S: [1 J4 f0 L( }' v* z/ q
                       cur=p;
    % M  U7 |4 n+ q  V& I               }
    ; ?, L$ k) D# O) x
    $ A8 V" @5 N; L2 r! S/ }; X+ O/ n            }: x" Q; u7 }4 P2 ?+ b
                while(!s.empty())
    + @3 {& W# h0 @3 v            {
    0 n4 y5 v! z( O: v" F4 y6 N; w/ l                cur=s.top();7 u! Q. X5 I% O4 R
                    p=GetAdjVex(cur,pre);3 N* }0 z5 i% d' D& @( K- @
                    if(tag[p]==0)
    $ u( Y4 d. K0 u' G5 T/ g                {7 s  v$ B0 U! j& |8 ~
                        pre=cur;$ z6 N) I- P0 x5 S, v
                        cur=p;2 j. W( ~* M/ F+ Z! W0 k* o0 e
                        break;
    2 a1 Y: x6 l: N  {: O                }; P. s/ N6 S% i- E. c. A9 J: V
                    else
    $ @4 ~/ E4 x+ Y! C! K# y                {
    0 v7 S5 |# B; d! v% x  X% F% s                    pre=s.top();
      B4 J1 V4 s& w) C0 T                    s.pop();
    5 R6 q( L. d$ h6 M6 v3 `$ ^                }
    6 F) w0 u2 @% }2 H& r' v* c: @
    6 i9 y' e3 ?; {            }
    1 t1 [6 Q8 i  r0 L3 k$ z1 A. |# S8 f/ p2 ?" a& x) h
            }0 p5 E; N8 c. V* d8 ]( v
        }+ }+ _, A, {4 A# z3 R  P
    }
    7 v3 P- E" H9 H  I/ |- j( Ztemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()# }+ g! `7 J9 ?1 }" ~% m! w6 R
    {
    3 m( n) P, I, m    for(int i=0; i<vexNum; i++)
    & ]) o$ O" K- c  x        tag=0;# y. z5 [3 B. g
        queue<int> q;
    - s+ t6 U+ ]! @( R% Z4 |    int tmp,t;
    - H! y$ G' T5 Z    MultiAdjListNetworkArc<WeightType> *p;* U- f& g; z# y! p" B
        for(int i=0; i<vexNum; i++)
    4 w1 A# _8 \0 i) S2 M' I    {
    ! e5 }: `9 `9 _% H* s& ~        if(tag==0)
    : a! E+ J" Y! A$ R( ?        {
    3 S* K8 h3 U. O& y7 F            tag=1;; F% M- a4 r8 _& e" y
                q.push(i);
    / b3 i0 N; M+ r! e- T            cout<<setw(3)<<vexTable.data;3 Q3 X5 @! w; Y0 e
            }
    / W; ?3 X) O# O8 }& v9 o1 F* a2 ]        while(!q.empty())0 P, |+ ^3 }: ?: U4 ~- a4 `( ~
            {  L6 r: d; l) t3 G- x
                tmp=q.front();3 w5 j  }7 k$ r$ R1 D6 o
                q.pop();
    ! x& \8 M- D* V- w            p=vexTable[tmp].firstarc;
    6 u7 I2 q/ l1 a            while(p!=NULL)9 ~& |* |- m, g) N0 N* E7 ]
                {
    - I" W% E2 {- N. z0 \                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);: _' x  n) }. r0 X2 y7 E& C* S  M
                    if(tag[t]==0)2 Q! B5 v4 T' ^) c9 l
                    {5 \& ?9 @" {( k  Y# ~1 N( s7 X
                        cout<<setw(3)<<vexTable[t].data;* V2 d# A; P' @% G! F7 c5 k) ]
                        tag[t]=1;  q$ {- {+ D: c
                        q.push(t);9 I) s3 U& s5 E, ^
                    }7 W6 f. w& y+ d5 Z
                    p=NextArc(tmp,p);3 z" i2 l& _1 F
                }  n0 H! y  ]- M0 G: |
            }2 E. X9 y( T* r) y
        }
    ' F; r7 Q( y3 n" c}
    ; [/ \+ p* H9 f2 }template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    7 c% P% b5 M( }3 p+ ^8 G7 O6 K{# j8 T; Y5 k1 I7 f* l. ]/ I& c
        MultiAdjListNetworkArc<WeightType> *p;7 r0 O  w- b5 N- d- b" [
        cout << "无向图有" << vexNum << "个点,分别为:";5 I; J; r/ @- N3 n+ p5 ?
        for (int i = 0; i < vexNum; i++)1 Q& d, p" r* d# L! d+ s: e
            cout << vexTable.data << " ";
    ' t) l$ X+ u& \) }5 s2 ~, j3 ^    cout << endl;. k: J' h3 |* ]
        cout << "无向图有" << arcNum << "条边"<<endl;' h; v+ \& F* `& x# o* ~' f
        for (int i = 0; i < vexNum; i++)
    ( n# I9 R6 L3 [/ |% H    {4 [( [4 S& C5 u9 d
            cout<<"和" << vexTable.data << "有关的边:";
    . M4 y, `  c4 c9 S+ m7 e0 o+ O" E        p = vexTable.firstarc;
    5 R  S, ?+ O- w# u/ o" H. d8 _0 }        while (p != NULL). b; Z6 j: O& O& N# E; ~- e3 c" y
            {+ A- u+ ?9 h# B
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";" c9 A8 Q$ p: g/ H4 Q
                p=NextArc(i,p);! l! ~6 K8 \# Y/ F! o
            }
    9 _- Q+ ]' z4 N# \0 S- U        cout << endl;# x* B6 e! d8 I$ c$ }" q4 |
        }3 W7 V$ G$ @3 h8 w; G# l, Z6 I5 S
    }' z* j4 Z" P* H% K# f+ B6 V" s" n

    : `" |6 o  A! W( }) B" K& g6 J( k9 A6 c# }4 h/ n9 ~8 Q9 j5 j1 K9 W
    邻接多重表与邻接表的对比/ ], F; s, I& S' H
    ' U0 G# o; f5 c7 I) i) D
    邻接表链接; t! N+ l6 t( K! r+ _. x! p
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。  T! J3 x% _) L+ I* x9 a( C3 o" Y0 j# d
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    1 q# K2 T7 p& w" U为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    . k9 A! B2 R2 b5 r————————————————
    2 ^! Y  r; S0 V4 [$ R版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    9 g) h* L. h9 r4 u  z原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    ! U) c/ q  y3 t2 G2 D/ R/ j
    1 B5 g( Z9 n+ S+ m) r; j" L3 p9 b9 C/ [& q6 _. \; M2 f
    + a% v: O( G4 l& C! {! P
    / g. s  m  R' F4 z. m
    ————————————————
    ( z5 S0 f- Z& w# b# Q版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。9 j. m) K, R* a8 Z& Q' y
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    ) C/ Z" E$ B7 k) m6 q; f) k8 U' B8 U8 W7 K& @/ R
    " L/ c0 U. r; i# `' [7 G, ^: R% w
    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 18:56 , Processed in 0.445356 second(s), 53 queries .

    回顶部