QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1622|回复: 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
    3 x" q. C' M3 B! r" Y1 v- m
    图的存储结构——邻接多重表(多重邻接表)的实现
    $ Y" p1 ]1 l+ w7 W! G7.2 图的存储结构
    , V* V2 a' g& l+ P4 p
    * P+ p& f- N3 ~0 D/ U4 w' |7.2.3 邻接多重表(多重邻接表)Adjacency Multilist( |' x% h  t( }8 C* B
    邻接多重表的类定义2 Z) {) y$ ?% ]# ^/ z) j
    邻接多重表的顶点结点类模板
    3 |* B# k- d) B% ^6 }/ r4 C; B# @邻接多重表的边结点类模板: H3 s" R: X; X
    邻接多重表的类模板$ f* x* Y3 ]2 I& \
    邻接多重表与邻接表的对比
    " J2 H$ M( A; S% T7 k+ }3 a7.2.3 邻接多重表(多重邻接表)Adjacency Multilist6 s# \5 _  f1 H2 l, `

    7 {' Y: v8 Q4 ~; h9 Z$ a在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    8 U0 Y/ I; z+ E/ T1 r& }在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    ; R; c) ]( Y* y% v$ Y4 l) m/ m4 ^# S) Y$ E
    邻接多重表的类定义
    % G& }0 ]% ]5 V 1.png
    $ [/ S' i7 ~( c8 p. J9 X邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:+ E& K; G) Y' X0 Q4 L$ ^; I
    data域存储有关顶点的信息;; z. z) H' E1 s% I# U% E
    firstarc域是链接指针,指向第一条依附于该顶点的边。
    ; o; d! J* f' R8 g- h3 m" e5 ?所有的顶点结点组成一个顺序表。

    8 I. L9 R( B! V& I0 ?4 B

    ! V( ]0 y0 W# E6 w* Q$ ]template <class ElemType ,class WeightType>
    ' C* h  a* j6 T5 b$ Vclass MultiAdjListNetworkVex
    9 `& z; }' i  M: W5 v$ v7 h' L{9 M3 Y; Y) z3 R5 x) a' f  b
    public:
    % ^# C% S6 N+ V" `2 e        ElemType data;
    ) w. T' k) U5 r        MultiAdjListNetworkArc<WeightType> *firstarc;
    0 A2 w, J' {  V+ _- [9 G8 }
    + K9 w, z' J3 U- b1 Q1 T3 X& J+ x        MultiAdjListNetworkVex()' j8 H2 }  `2 D
            {5 O' t* k" @% ]& y
                    firstarc = NULL;" ^  g) `% v+ l' Z) E; t& ~& }" B# H% ]
            }
    ( M, _9 ~# y3 F  [3 g- J% Y        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)9 G* _9 c7 O  Q9 R& |6 a- q/ |2 F
            {
    6 A1 S: _  M, v3 z* `, m' z- A; J                data = val;- f4 y& Z+ V  s
                    firstarc = adj;1 G7 Z; B5 Q  f* t& G0 y
            }
    ( y3 U* i& l' _};3 f  B6 H0 R# Z: v  h! Q) S
    9 x& [+ g" O3 A$ C1 D  a. F5 \
    邻接多重表的边结点类模板
    9 G; ?8 [# ~( ]* a
    ( C5 r2 V) x/ [: g+ c6 o在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    ! X. l2 K% @2 k3 u9 vtag是标记域,标记该边是否被处理或被搜索过;
    5 i  W+ s8 A" pweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;4 X, ?% }/ P% g6 I5 ~4 Q
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;  }$ T% z  x9 E6 `
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。, Q7 D# p& ]6 f6 L" ^0 Y. {9 [

    . t: d$ l- v6 e% S1 d3 ^ 2.png
    ) c0 `' f! E& R8 e! mtemplate <class WeightType>- }& Z+ _- H' t$ R, l( I
    class MultiAdjListNetworkArc. E; F" z! w6 H6 Y9 s
    {2 r+ }# H5 G0 p: m2 h) V* E% r
    public:
    5 W% N, K: \5 M4 i$ T  O7 D    int mark;                                       //标记该边是否被搜索或处理过
    + P+ U$ ~- ^8 d1 v6 H. Q) n        WeightType weight;                              //边的权重& R2 w- C. l4 E3 A2 [- p# @% I
            int adjVex1;                                    //边的一个顶点5 H5 h8 L/ Q, a$ w5 Q$ z
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    . h, G3 M, f' C$ e( e, D        int adjVex2;% _' k* S, O# `) g% |$ x2 J+ `
            MultiAdjListNetworkArc<WeightType>* nextarc2;
    , s4 E0 \; ]+ t+ B* E  m. O. J
    $ _: R1 x! r( v0 ]7 {        MultiAdjListNetworkArc()
    ; V% z% t7 t5 g  I: N5 C; M- v% o  S        {" _1 z# e* E( `4 w. j
                    adjVex1= -1;; H6 f% |$ M# m
                    adjVex2= -1;& U; y2 R7 t  `
            }. g0 o( H; A9 [$ I7 y5 A
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL). f8 f' Y$ _$ W2 ~6 s+ U# j
            {
    - k% ?. J+ {8 a' k                adjVex1 = v1;       adjVex2 = v2;
    & ^9 `# M' J: z6 |, e                weight = w;
    / ]. x$ {- G4 @                nextarc1 = next1;   nextarc2=next2;- S7 J9 Z7 I6 p- X2 O" b& Y! S
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    9 C$ S$ i7 |# O0 K        }
    / i. Q! ?  r3 O/ K) d- z
      ^+ Q2 @0 {5 r7 t1 t" k邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>7 g2 I" @: E; ^1 s9 |3 b
    class MultiAdjListNetwork& i+ o8 r+ e$ D! y7 p2 N
    {
    * u- V! i: Z. ^# i! qprotected:% z3 y8 p% G. t
        int vexNum, vexMaxNum, arcNum;' e/ y' f  r; c+ W0 }# _
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    , M! j# f" P, @3 [0 l' r9 L    int* tag;
    . ^; n9 m! |0 T    WeightType infinity;" p1 ]+ Y8 k" _) G/ ]
    & Y# Y) M- `7 u' C4 r% _5 `6 Q% ?
    public:
    ' v' h0 x5 v0 ]    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);( D$ P3 z2 W+ H0 T$ X- n- O6 g3 [

    4 d. U7 j7 c4 ^! L- h    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    9 C7 {9 o: K& _2 @. T) ^
    5 {& r  L% U+ Q3 H) [6 F# ?    void Clear();" L3 m0 B/ ?# u% o# f+ D% U
        bool IsEmpty()
    # t9 m+ S( t+ [$ k. `+ X9 I    {
    $ a3 [' l# {( b, A4 q5 I$ T        return vexNum == 0;; Q+ b. E; |( C) R: ~
        }( J: g& U& f7 _% Q* G) b  s7 y' W
        int GetArcNum()const( U0 Y5 ]5 J" {6 ]! M
        {
    . H$ r! A- H4 e        return arcNum;  e6 \3 x, Z: @, g$ s/ S, m
        }* ?3 z! ^7 L4 p, _# t' `3 I
        int GetvexNum()const5 I- W* f! v( O9 M
        {1 _5 y; L' A% V! o
            return vexNum;
    % ~2 F6 n! K8 ~    }6 x* n( ~8 u3 F0 Z$ y5 }9 @; [
    $ s% `5 r- \/ f+ Y' v$ y* K- [

    ! ]4 w% U. @% X$ [6 g* d: ~    int FirstAdjVex(int v)const;# @' \5 X; `$ O3 Q; `
        int NextAdjVex(int v1, int v2)const;; j( `* m6 N. S; j2 F* X
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;# F6 {5 J, `, K' u' v7 p
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    7 q9 w6 \+ w5 R! ~. q- d7 l* |. w
    ) K* T5 C! Q' L% ?    void InsertVex(const ElemType& d);
    " o% [2 ^# K# u* _) ]! |- e: A5 o    void InsertArc(int v1, int v2, WeightType w);
    : J  h! ~$ L; g: b5 J! A% H; v
    : z7 ]4 R" X! ?2 I    void DeleteVex(const ElemType& d);
    * {7 p$ j6 Q8 X2 ^    void DeleteArc(int v1, int v2);
    $ E" b) b) l4 c' @$ X
    ' q# i: n$ V5 L! I9 {    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);" K) F  O/ I* o$ d
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);) s8 {. Y$ R5 P& j" D

    ' _5 S2 f% p+ x5 @  p# S  R    ///深度优先遍历* {9 {2 V; o4 o( i0 B9 j
        void DFS1(const int v);
    ( }( h4 x/ \3 ~  C- f% @    void DFS1Traverse();/ F" X5 F$ P( D/ r
        void DFS2();
    8 y$ \, A- I- I5 n8 S" n* c# Z7 L5 \2 ~& A4 v" e
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    # z; G0 C5 @5 l5 R) U7 [( C* I    void DFS3();
    1 e8 ?3 u; C, T: _- D1 r5 G
      h- M( r- }2 l# i# ]    void BFS();
    ; t) O+ i$ @' X' g! t: q+ M( x    void Show();
    - c6 v+ g2 J$ e: T7 d, X$ s};
    0 O, X' x4 [, T, ~( ]; Z+ F0 `0 W. A6 z
    2.函数的实现
    7 U. ~: C- y) y. w/ ]- A5 e! b  K' H研讨题,能够运行,但是代码不一定是最优的。8 ?8 M& T/ P. l3 a. u7 x
    ( ?7 l- H0 O2 j. c' c- J
    #include <stack>
    $ I( m4 I5 e7 v7 A5 G#include <queue>9 n0 M) m! J! x1 Z$ Z
    - K6 o* y. L* f$ `) L1 m3 N( s# m
    template <class ElemType,class WeightType>6 N' m3 U- C: |& p  b
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)8 b; p0 {" t3 C* V% k  ]% F" \/ A5 T
    {
    9 K5 X5 y4 e8 ^* q# I4 L    if(vertexMaxNum < 0)
    2 p- K; ]; w: F( m7 ^: C        throw Error("允许的顶点最大数目不能为负!");
    $ ~7 w4 l$ [( A+ K0 E& y    if (vertexMaxNum < vertexNum)7 B8 n% G0 X5 j& ]
            throw Error("顶点数目不能大于允许的顶点最大数目!");  i  j5 |  f  a3 r
        vexNum = vertexNum;4 u0 O9 C! T* t# S- E! V
        vexMaxNum = vertexMaxNum;
    , G1 D1 c0 j7 d# O* y    arcNum = 0;" b2 t7 M+ R/ |5 t  E* r& u
        infinity = infinit;/ Y7 b1 q& E7 j& y
        tag = new int[vexMaxNum];
    ( j- e* L* K# M& d1 c6 d    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    # u, _7 |5 Z; W0 O* o& ?; V; L, a2 M    for (int v = 0; v < vexNum; v++)
    2 O/ i- V/ u$ X1 B* O0 G9 e    {* m$ n- d) x& s5 T( @
            tag[v] = 0;6 T3 K, T7 B" E( L( o
            vexTable[v].data = es[v];* L9 Z+ ~; ]; P' M
            vexTable[v].firstarc = NULL;, X8 b, N/ X* I8 T' u/ Z& z. N
        }9 s8 O( t3 W# I% r9 L
    }% \- `0 g# ~. [8 M& n: B9 ?  C! C
    template <class ElemType,class WeightType>
    * f2 u* ^" h, \. XMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)7 l; V4 d$ h; f
    {% L' m. Z2 T$ ~7 n/ M: _* a4 y  L
        if (vertexMaxNum < 0)
    % Q, I/ W) u' @$ M+ z        throw Error("允许的顶点最大数目不能为负!");
    ' d! \; Z* n' `- S) V7 p; O    vexNum = 0;
    7 e7 h& j8 o1 N. o  X) ^5 r7 P' G    vexMaxNum = vertexMaxNum;6 _! ^9 c2 `' Y
        arcNum = 0;/ `$ k3 x) z; m9 H
        infinity = infinit;* o0 P3 L4 n) L2 B' g( Z  J3 C0 r
        tag = new int[vexMaxNum];
    . E- E& a9 d8 m0 S! N5 N    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];, v2 ?( A/ L+ ~! Z9 O3 b. ]
    }# o; c9 Q2 L5 g( @, T6 b
    template<class ElemType, class WeightType>
    . C$ }5 E3 o; Y5 ~int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const# B0 L6 V" E8 p
    {. S2 t2 i/ ]0 ~7 M! X  z" h& J
        if (v < 0 || v >= vexNum)
    3 m. P; V: }1 F        throw Error("v不合法!");
    & |9 |$ j, j2 P( O  S5 U* A2 r8 d    if (vexTable[v].firstarc == NULL)
    . u$ B" p7 X$ d" i/ T        return -1;/ }# K2 o" e! K! d
        else0 N. Y, V) F0 B& v) x. b- K
            return vexTable[v].firstarc->adjVex1;
    8 g8 I! N6 k% R& l}$ K& c1 ]' `6 m5 a
    ' f  u" P+ m' j1 y* f- m
    template<class ElemType, class WeightType>
    ( G3 @' q! [, O( ^4 `& eint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    ! t) N6 d* X$ s/ @{! _# Z) M  V) k& ]) }3 h) [
        MultiAdjListNetworkArc<WeightType>* p;
    9 W' H& g1 u/ R9 r+ `, z    if (v1 < 0 || v1 >= vexNum)
    ' X" h6 k3 ~: t        throw Error("v1不合法!");
    : @# B. h6 W' B; m7 {    if (v2 < 0 || v2 >= vexNum)
    8 r# [. |! [4 R/ _' ]1 X9 b( K5 |8 _8 ~( l        throw Error("v2不合法!");3 \& }0 W  y, ^5 [. b1 T
        if (v1 == v2)5 @- d' U' k' {  p6 N: A
            throw Error("v1不能等于v2!");0 y6 u) v3 ^% m# F, ]+ ?; `% \
        p = vexTable[v1].firstarc;8 ]1 m, E! V: @; Z, }
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    ! e/ G, H( W0 {! o! M2 p+ A5 L! z+ u4 F        p = p->nextarc;( n/ J, [* M* f+ z9 s& x$ J: \
        if (p == NULL || p->nextarc == NULL)
    & E, z' ~5 z: `" E+ S$ ~        return -1;  //不存在下一个邻接点/ B# P- ~; M: V2 Q3 o
        else if(p->adjVex1==v2)  C( [, u) Q. o! a4 r- v
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);- J0 b& P" ~8 u  q1 S
        else
    1 N: D) C1 n3 y        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);1 D* \- \1 h  S4 L1 F
    }
    4 T, t  k+ Q! t& M( W2 {7 wtemplate<class ElemType, class WeightType>9 K8 z9 D& z. v( ]3 j7 ^
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()
    4 f/ y- I, R: V( u/ D  k{
    * O" e3 v3 t0 V1 R* {& y    if (IsEmpty()) return;
    $ t% R6 O. k+ U3 x. o1 K    int n = vexNum;! u# ?& v* j) m  t8 C0 {# H3 G7 r
        for (int u = 0; u < n ; u++)
    " z( w+ C0 v/ ]$ w- K& B7 Z        DeleteVex(vexTable[0].data);- K7 p2 ~' g& I9 }' `) m
        return;
    " M7 S! `7 U; j3 H3 B}
    & @" u/ [: D$ P' ~  Ttemplate<class ElemType, class WeightType>9 j) a2 q4 b6 S. V
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()" p& \' r: r- W
    {
    & [, u, C8 ~. H( l    Clear();( v6 `5 ~0 A4 O
    }
    ( s$ n" |7 C# p9 ktemplate<class ElemType, class WeightType>) _7 _$ A  T0 b, V
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)( l' e0 E& x& \3 u; o) P/ G
    {% L& |' V3 F& ?3 u& Y
        vexMaxNum = copy.vexMaxNum;
    ! c3 [0 }* j2 k! c" ~    vexNum = copy.vexNum;
    ; g  Z3 n( x% F& [1 V    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    0 z6 y5 D% W# c3 Y2 I7 _, Y' w    arcNum = 0;! v5 t1 F, W9 ~$ c4 u
        infinity = copy.infinity;6 C) H6 D% C: w6 S0 T: v
        tag = new int[vexMaxNum];# r9 ]. q( d# q
    2 N' F1 N( t$ E
        for (int v = 0; v < vexNum; v++)
    , ]7 H2 D* k* i/ x( q% U    {
    0 D! ], u* O/ v5 d9 ~+ A2 s" X        tag[v] = 0;
    ! ?3 O2 Z, q0 f- T' d        vexTable[v].data = copy.vexTable[v].data;
    - [0 I! p% V% f! @9 |4 w! x# @        vexTable[v].firstarc = NULL;3 `3 S, x0 f" f% ?: Q  }' _
        }7 q' m5 t% v7 Y& u- z' `
        MultiAdjListNetworkArc<WeightType>* p;& @9 f# z2 R, o* n' D

    # m" a0 T) s0 G    for (int u = 0; u < vexNum; u++)5 P# d" t0 s  V* A$ [+ v) Y& c
        {, @* w( G1 L' ]1 f- \
            p = copy.vexTable.firstarc;
    % E5 @, w8 d5 b! L8 Z& R( b5 u        while (p != NULL)
    5 z( \4 D% f1 ^5 f9 A! u0 n8 G9 d        {
    & K% @: k0 [2 B9 O$ J$ ]' D            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    3 Y6 o. \# y; }- s4 C            p=NextArc(u,p);# Q& t4 o! Q, t- Q) X# ~) f# S
            }
    & @; d6 W6 q3 ]1 N    }+ {9 n0 e6 I" f9 Z/ b  q: [
    }( I: W3 W# T0 m3 I8 ^* \
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    1 i$ U9 M+ m* t* M& ?2 G9 eMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
      u% C  J( ?2 X6 A, n, \{- i0 f% M$ Q. [" c
        if (this == &copy) return *this;
    , M1 o, w; z( m2 W: O9 W7 J. O    Clear();
    2 @! m% q: l4 b    vexMaxNum = copy.vexMaxNum;; d9 i9 J$ J" k5 y# D, \' R" i
        vexNum = copy.vexNum;6 N1 S2 u# S' |0 j: F
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];% x3 [) x; L/ b4 w: G7 p6 ^- `' [
        arcNum = 0;
    # z( L( h3 [) H) M) b    infinity = copy.infinity;
    6 F7 j2 v, p5 s+ {" q+ Z! |    tag = new int[vexMaxNum];
      t5 O) d% }0 I4 s- S" [9 q+ |7 f. l6 F. s$ A
        for (int v = 0; v < vexNum; v++); g: _8 K# S" p( I8 ], g
        {
    0 N  w* l9 ^5 o0 O5 D        tag[v] = 0;; a4 }' u2 H/ n% |; \& u) W
            vexTable[v].data = copy.vexTable[v].data;1 C+ s( t- o# O! k  `( R+ d: f
            vexTable[v].firstarc = NULL;
      Q6 w3 K5 ^' z9 N( O( U    }  M& O' \/ O" O  l0 f; ]
        MultiAdjListNetworkArc<WeightType>* p;# G; D  Z/ t) Z5 J" H( {! [! X

    ! f  c4 b0 f5 ^) h  l    for (int u = 0; u < vexNum; u++)/ l) z+ B7 ~: H! d/ B0 `8 f
        {
    5 }0 n* P! l- d3 D: Z        p = copy.vexTable.firstarc;
    ) j# G' u: {- J! e% q5 |* ]        while (p != NULL)
    - L$ |- }: i+ m, W; K( v6 M        {5 ^2 [( P6 R5 h# }
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    2 [4 [  [2 d' Z& E- k            p=NextArc(u,p);+ x! z, F; o0 J$ i1 ?' F+ Y6 I2 J
            }
    # u/ J2 R" e' N% [% W9 t$ Z7 S    }
    2 {4 ?& ~" i% A4 K    return *this;$ K9 E: |* C# J& }9 q2 P) E% j
    }
    ) u) N5 I/ c5 r* stemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    2 i2 X$ ]- j8 B7 jMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    0 Y' s. ?: N) O( Y5 U% I{" Q) i- t! U9 l% C$ E! n
        if(p==NULL) return NULL;" ~0 j& y# `! k4 v5 E) M
        if(p->adjVex1==v1)
    / w% N3 V6 }- e/ A( |4 m        return p->nextarc1;; ~& z) i+ r/ H( \! x1 _3 G. W# L
        else
    ) X6 }' s3 U. A( t. F        return p->nextarc2;
    0 `, U4 i8 \/ m" A, K& O. v7 I5 m}. E8 v5 s2 Y, U
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*# C+ x! G5 u9 O, G3 R+ W
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const- K; Q6 w7 y9 H0 i
    {
    $ d' c" N3 t- T8 u) K$ \    if(p==NULL)return NULL;
    9 l( n5 C" z6 R7 m/ Q    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;6 j# K( W3 F& U! S- Z& @
        if(q==p)
    7 `1 W; b2 n& t1 B9 \4 q/ r) |        return NULL;9 r* S7 V3 a, ]  o2 r
        while(q)
    ( I2 V. ^9 `0 \5 n9 M" b1 [    {
    3 z! ^  E3 f% q        if(q->nextarc1==p ||q->nextarc2==p)2 |# b$ s+ W( ?/ ]
                break;5 s: H6 ^& ]% t+ N1 Y
            q=NextArc(v1,q);
    $ h" n/ P" j. P    }& I4 ?2 T5 W, k
        return q;. s7 ^+ m& G3 s# k; k0 R0 @
    }
    + ^* @5 B* r4 }! `4 o1 P; S8 Htemplate<class ElemType, class WeightType>
    ' {1 ?2 J4 L$ g2 A! F4 ]void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    ' _! `* o4 S; G( n. C{4 e% G+ _7 ]& Q- x! g
        if (vexNum == vexMaxNum)" ~' ]4 d- t5 R" e, n
            throw Error("图的顶点数不能超过允许的最大数!");
    4 Q; D  \& s% S, M    vexTable[vexNum].data = d;
      W+ s/ c' R# U; F; v0 k  G    vexTable[vexNum].firstarc = NULL;, q5 l8 C+ w. f1 x& U* o8 g
        tag[vexNum] = 0;4 t5 a; M+ U3 ^  h: \
        vexNum++;0 l( A4 |: z0 T) Z. R
    }2 a' s2 {3 g/ B2 t
    template<class ElemType, class WeightType>3 L, A% r& k( o8 t
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)4 d0 M( s. O$ h8 n
    {
    4 j! D, E( p7 m' Q  F    MultiAdjListNetworkArc<WeightType>* p,*q;7 w1 ^6 k6 U5 W$ v3 ~
        if (v1 < 0 || v1 >= vexNum): J7 Y2 S) B8 b. z
            throw Error("v1不合法!");% P' H# r6 K& U: S, k& K4 h) g
        if (v2 < 0 || v2 >= vexNum)
    / E  {* x% i! Y* ^2 V: l        throw Error("v2不合法!");
    : c1 ?$ C& T" c. [; j" ]* P3 W7 c    if (v1 == v2)
    5 W( `) f; a- t( l$ B        throw Error("v1不能等于v2!");# |, ~2 p! g) O7 J
        if (w == infinity)
    % w8 o3 U1 T& |; w( e; O7 N  b        throw Error("w不能为无穷大!");
    - m9 w3 K$ q( Z8 {0 B, L) |# j
    8 }' l5 a" {0 T; T4 ~5 l: J6 G; m0 B' I6 l. u
        p = vexTable[v1].firstarc;5 m+ K) S. H$ p& g& I' p
        while(p)7 p( Q/ M% p4 |$ d6 [
        {
    . X# y0 @  y2 a) N4 t7 B- C        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    ) ]" z) [5 a7 K, e! o4 K        {
    6 g! M7 Y* u* f, A% R, S& t            if(p->weight!=w)
    ; `- Y9 Z2 T* [8 G9 A9 Q) }                p->weight=w;; P$ h9 ^7 P3 U% X
                return;! V& U- ^' W) A% M
            }
    + l, V( {! o, \$ @3 V" Z. O+ f
    ! H5 r1 T/ F& Y        p=NextArc(v1,p);
    * `: Q" J/ a/ n5 A3 f8 }    }
    5 |" G6 |; ^) \" j: l/ |    p = vexTable[v1].firstarc;6 }: Y! C% V0 _: ^$ R% H5 g
        q = vexTable[v2].firstarc;
    . x/ O7 l' c5 J, F& F6 |* q1 E1 I) F4 T    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    ! q3 i5 L$ m' J) L9 h( I    vexTable[v2].firstarc =vexTable[v1].firstarc;
    - ~1 ?2 A. D7 K8 j* e. W    arcNum++;
    ( |" D) F; r; j; U: v! f}0 f' _" e) l6 n9 n# W" O' @5 r+ v2 \
    7 Z! y0 J) J6 g# X. X. U
    template<class ElemType, class WeightType>7 v  x% g5 M+ M4 f4 u4 @
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    2 o2 V3 R! z" D: A/ f5 s+ S{
    . _; W, A7 k6 t- h: f+ u$ R* i6 c! j! |" D5 y' A# \" p7 [
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    ' X( u7 c% }% q" |1 H    if (v1 < 0 || v1 >= vexNum)4 D3 f0 t( c: B# S6 V
            throw Error("v1不合法!");
    6 ^/ ^" t  R% R7 _0 K% l1 R    if (v2 < 0 || v2 >= vexNum)  K+ X5 q$ w, f6 Z
            throw Error("v2不合法!");
    . H7 T+ s; z& c# J1 I1 I    if (v1 == v2)0 R" b5 U5 Q: x4 A7 l5 b& z7 t$ [
            throw Error("v1不能等于v2!");
    ! w+ d% ]) _5 q4 A, t1 {
    $ ~' l! V, I2 C  H* |7 e9 W    p = vexTable[v1].firstarc;
    % d( K) ]" h" N! b" D' a( H    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    5 [. O  G( G! d7 v! |  S- k! }3 b    {( z) D. S6 g3 [; G) g
            q = p;! v4 b/ ?& Z) H8 Q' B: B/ j
            p = NextArc(v1,p);' \$ A/ J7 @! ^4 S( T& F
        }//找到要删除的边结点p及其前一结点q
    2 d2 O( w. t7 i5 O
    ( b( }( h  n8 p    if (p != NULL)//找到v1-v2的边
    6 w1 P. t5 O* F/ |" L0 G    {
    9 b6 B! \+ P. g# T. o        r=LastArc(v2,p);
    : y- J- G2 P# n. T0 g        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL" S0 p9 D/ k! Z( N, R
                if(p->adjVex2==v2). ]' ^5 C: _0 t& a& b
                    vexTable[v1].firstarc = p->nextarc1;
    6 O3 U2 k6 c1 d' X+ L! d4 _            else vexTable[v1].firstarc=p->nextarc2;8 x4 M1 n# u2 K$ ~6 k9 `
            else//不是第一条边3 w- y9 U/ l1 @- c
            {
    : i; r$ z; ^) G( c+ S            if(q->adjVex1==v1): D: E% [/ |- |  g+ H! k% c
                    q->nextarc1 = NextArc(v1,p);
    9 d5 C. s% d! S7 [0 M6 o5 c            else
    : F% m. y1 J7 s6 M) C* x  ^, x                q->nextarc2=NextArc(v1,p);
    : S# C% a8 O6 d, O  H
    1 C4 M+ d/ g* R, P+ P# p) W        }: C1 k5 O8 \& Y
            if(r==NULL)
    ! F' ~$ N( Q0 c, t9 K            if(p->adjVex2==v2)
    ( j0 v! J( q, p# ]. B2 z% q                vexTable[v2].firstarc = p->nextarc2;6 K6 ^$ u# u/ s9 e7 _
                else vexTable[v2].firstarc=p->nextarc1;% z2 A& H! T1 W& D3 t8 @, g
            else
    / g& r+ y& i5 k- p9 X+ D: `$ `        {
      K; M" F$ n5 H' \* X/ D            if(r->adjVex2==v2)
    ! F& M( m% M) b                r->nextarc2 = NextArc(v2,p);- s/ `) K/ \  p* i9 Y4 a3 v
                else, \8 d: g/ o0 I& `& }
                    r->nextarc1=NextArc(v2,p);* H7 V8 k1 @2 x: q- Z
            }- P1 n9 {, x( A  F- G& w! t3 @
            delete p;
    + }- R% H, y4 K' n6 Y  z0 R+ I        arcNum--;
    * r% j& F! M6 Z  @- W' t0 m    }
    ' h& g, s$ B# T# r. M. n9 V; b+ v+ }0 j% D: O
    }
    : n. W% ~; o4 C8 J# Vtemplate<class ElemType, class WeightType> void( E) [8 O4 p" @
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    6 O+ k& P" N! B: p! X% p9 I* X{4 g( T  v8 `6 X4 S! B: e* p1 H
        int v;( N7 b1 E! V9 U% n7 m" A
        MultiAdjListNetworkArc<WeightType>* p;
    , V5 [! j2 {3 @  G    for (v = 0; v < vexNum; v++)//找到d对应顶点
    ! U& t) S3 a* W4 Q* D) q8 c        if (vexTable[v].data == d)5 }: H9 |7 E* g6 i0 M1 Z
                break;
    * n6 F9 V( M" s- _    if(v==vexNum), h0 }+ z5 o1 F3 @$ y; [. I
            throw Error("图中不存在要删除的顶点!");
    ) N3 w" [- X, J0 C& p* P
    " h# ?2 t6 Y& J% D+ k' g    for (int u = 0; u < vexNum; u++)//删除与d相连的边: O6 J8 S9 ~8 H7 L  t$ o
            if (u != v)
    / }' d( q; g, n( X5 P        {
    " x$ H9 j- X6 Z# C" w: r, E" V            DeleteArc(u, v);
    4 K% e9 D/ A5 L, g5 k; V4 `, o        }
    ; ]5 n# R7 Q3 G3 ~( o* d  V    vexTable[v].firstarc=NULL;! z2 d/ m" z8 A, r. a( n7 d
    ; `/ A5 B7 d# P+ Y
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置8 h+ {3 q( V9 x5 x3 k
        vexTable[v].data = vexTable[vexNum].data;
    / X1 \, @8 n/ {* P8 _! ^    vexTable[v].firstarc = vexTable[vexNum].firstarc;
    ! m9 k  B5 x; `8 Q    vexTable[vexNum].firstarc = NULL;1 O2 a8 H, h2 h; Z" m5 Y% F
        tag[v] = tag[vexNum];
    $ V$ G/ S  @9 ]2 d    //原来与最后一个顶点相连的边改为与v相连
    + t* B; ?% E, N9 J8 N/ s! e    for (int u = 0; u < vexNum; u++)
    3 X1 j! a# {: ~, B$ Y5 n    {
    3 U( H- R" }  m5 K, J4 Q. L% Z        if (u != v)
    / U. Q/ w; k9 l/ C; C        {
    8 m* W4 b( u$ f9 {* O            p = vexTable.firstarc;2 Z8 x& r7 w  c' d% f
                while (p)# |3 K5 q' U6 E/ `# \. v4 X) n
                {& A" _2 }0 \, r+ S1 X
                    if (p->adjVex1==vexNum)% q$ P; [  R. {$ H7 H
                        p->adjVex1= v;9 j3 H2 m' p" Y3 t: g' L& I1 y5 d  O$ f
                    else if(p->adjVex2==vexNum)/ L6 R: e2 \6 }! w
                        p->adjVex2=v;
    ; a, a# H- b0 D) ~. P                p = NextArc(u,p);5 u& s9 }7 H8 d" P* `0 n: V
                }
    4 M" t2 z7 a& {( @1 i' k1 A        }. I& H/ ?' B0 g" r7 {" h/ P, M# S
        }& P8 P8 i0 c3 u/ l& ^' ?7 i/ Y" c
    }
    1 ~! i1 Z  |( \; e$ @4 q% t///深度优先遍历
    ! a" s4 _& t. l) B5 Jtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)5 H' H8 ?- B6 l9 r, B' U
    {) K1 }2 F& V7 M8 u8 n# o) d
        tag[v]=1;* @& z; l- L6 y2 F. g" k3 @5 |
        cout<<setw(3)<<vexTable[v].data;
    ' M5 U! [" |8 n" x4 H/ p    MultiAdjListNetworkArc<WeightType> *p;/ X( j. P" p" S% ]$ A7 I$ [
        p=vexTable[v].firstarc;
    : T. c7 e2 i( \, m; F    while(p)
    1 O3 @9 X% y' p4 z" C  [    {; n/ n$ K  ?$ [, _
            if(tag[p->adjVex1]==0)( g. p4 M( ?, |
                DFS1(p->adjVex1);
    / v3 x  X/ w/ A7 ~7 p7 {        else if(tag[p->adjVex2]==0)+ Z' w9 m3 N! f  N. o3 C. C  Q
                DFS1(p->adjVex2);& ?7 ^, f) Q9 n7 U0 w9 T
            p=NextArc(v,p);9 z5 ~( q$ F6 b
        }4 Z1 s/ N. |' M% j  C' v6 G
    }
    ; M% Z9 }+ X  d# r: F/ {template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()" O$ K. o, p  W( I, n0 f7 r9 J8 N! K
    {
    . [% p, K& Z! i8 A# t    for(int i=0; i<vexNum; i++)! S5 l- W# G: p' m6 E) n) y' y
            tag=0;/ I9 ^" C$ t) i- h
        for(int v=0; v<vexNum; v++)
    5 F( i; W5 p) J5 o6 {( ]    {
    6 X/ j9 y. P* f9 v        if(tag[v]==0)
    + t9 i/ L/ v- o; ], q            DFS1(v);) x: G4 Q) n( s# I
        }0 m6 g, C! ]1 h4 e( A* G$ Z+ K
    }& L; V9 n4 }% }. T3 K
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()3 g* U4 E& }3 }6 ~- X, f- R- p
    {
    + C2 ]' w$ P' k4 P( b+ \    stack<int> s;7 M3 T# n4 M- `' X: X
        int tmp;
    4 W7 H. Y( Q: C6 C, P6 {    MultiAdjListNetworkArc<WeightType> *p,*q;" Y; x% j3 L* Y+ L% }
        for(int i=0; i<vexNum; i++)
    # l* c2 x( W  f- o7 z- i+ r0 R        tag=0;. d  T* {: U% B* S) ~/ V
        for(int i=0; i<vexNum; i++)! K( [1 s' i) X) b+ `4 o
        {# t* S3 l7 X0 {1 {* u% j% K$ L
            tmp=i;- C+ p0 h! u, ]: Z
            while(tag[tmp]==0||!s.empty())
      }& o) R" @; X) A4 a5 `9 a        {3 g) P6 o5 q/ Z9 w7 {
                p=vexTable[tmp].firstarc;
    5 H2 I! v7 }9 B0 }& T. B            while(tag[tmp]==0)
    3 T( ]; ^6 C. ^  L2 I+ [; q, u1 c  }4 I1 _            {
    , a6 B, ^( J1 U$ k) T/ g- I                s.push(tmp);- K( e5 B* k6 q" h0 d  }" u
                    cout<<setw(3)<<vexTable[tmp].data;8 c, }. Y1 U( i' W6 W
                    tag[tmp]=1;$ F$ d- ~- Q4 f1 S! R
                    p=vexTable[tmp].firstarc;2 U7 f  I! g8 J9 ~  ^
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    - q* }' b; h  E/ ^; S  m/ ]                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);7 {* E: k+ k) Z, y6 e, k& F
                    //cout<<" 1st     tmp="<<tmp<<endl;- ~) b# e! D2 m- O; s5 c
                }+ H; u& q' E2 D8 v, E8 k+ ]
                if(!s.empty())
    ( b  z& ]7 Q# O& Y            {
    * O( ]0 w" g. I/ {, Y% C% E8 \% c                tmp=s.top();
    ) x3 V- z0 o0 Q4 |% ?. g                s.pop();% Z( b  m9 U0 k+ N- B' ~
                    q=vexTable[tmp].firstarc;+ A  m/ O1 L, d! S+ p( s* j- q
                    int t=tmp;8 r1 [* p' V- {
                    while(q&&tag[tmp]!=0)
    4 I% W1 L0 ]* {( d+ L5 J# B                {4 M: u0 X7 G. s
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);/ ?) \9 E* t9 |
                        //cout<<" 2nd     tmp="<<tmp<<endl;* d4 b+ n- p* j8 P3 N
                        q=NextArc(t,q);" }1 y5 s* N* F/ {' \  g$ E' l4 H) }
                    }
    4 l8 V  h* L+ a0 Z5 x- i2 r8 F' ^4 W                if(tag[tmp]==0)# A; H8 M6 d$ ?0 H  b- P( h
                        s.push(t);1 D5 ]$ a4 C+ c) k
                    ///1、对应上面连通分支只有1个点的情况9 {; t1 e4 G/ w7 z
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈" b, C8 V1 R$ F" L
                    ///tmp要么等于找到的第一个未访问节点,
    % R6 a) Q1 C, ?& y                ///要么等于与t相连最后一个点(已被访问过)
    5 F6 `" t2 p$ N5 [                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    + X  R1 w: A1 T4 G, y            }
    - Y6 [( k4 n6 a0 h6 }) }, V2 D        }
    5 |$ Q  V) G8 |1 d; a; E    }. y. Z( O1 e% {( W2 e( w
    }
    * ~( h" E$ \! Z2 H  y( [! h//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-12 s' @: G1 U# ~* V% b, M; t
    template<class ElemType, class WeightType> int: ^5 p/ \( X3 M7 }! J5 U& b6 j
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    2 K. S3 o( r2 h8 Q: r{
      y5 m  |4 i5 v    if(head==pre), A$ r# O6 R4 e( m& |
            return -1;& f  x, `- W% s

    ' L: b% @* i, f    MultiAdjListNetworkArc<WeightType> *p;
    4 H  Y4 ?  L: B. c% ?3 L% V    p=vexTable[head].firstarc;
    ' V. l+ b. Z( S    if(pre==-1&&p!=NULL)
      R! t! E+ I9 Q        return p->adjVex1==head?p->adjVex2:p->adjVex1;2 {6 A0 l: F/ c
        //pre!=-1&&p!=NULL
    / x! n5 H5 V- N  k" ]5 v    while(p!=NULL)3 e' ?" C0 O  N7 ]. o# ^& X
        {
    3 I4 V7 R+ y3 e, ]  F: J        if(p->adjVex1==head && p->adjVex2!=pre)" X$ K; b8 y; m6 H+ P
                p=p->nextarc1;) H& J1 z7 ~# a* y4 Z& B
            else if(p->adjVex2==head && p->adjVex1!=pre)
    , b$ U2 A  R& a. `: u9 i6 Q1 u, s* w            p=p->nextarc2;  s; `2 ]0 w8 ~; X5 g# M2 x
            else if(p->adjVex1==head && p->adjVex2==pre)/ r2 w! E/ K% R2 g
            {2 u: l- m3 @& L5 q$ n3 b- G4 @
                p=p->nextarc1;
    6 M' u; Z8 ]2 X) j1 x  f            break;7 e7 C+ u# M3 u7 r3 w: F7 i- N* C
            }
    / w) S4 ^" o- u        else if(p->adjVex2==head && p->adjVex1==pre)
    4 O5 R0 B: m' {/ d7 S9 K6 q7 i! ^        {
    1 y  R0 }/ A7 t) ]9 ]8 l            p=p->nextarc2;9 P0 b3 N$ ]( {3 i
                break;# `' O. j) x5 P& Q# Z
            }8 n; Q& C7 t% D. T; k
        }9 T* h0 ~8 R, q) ~
        if(p!=NULL): d/ V4 [" _! `( c* N
        {
    . r+ e, R+ r2 t& Z        return p->adjVex1==head?p->adjVex2:p->adjVex1;  c+ C3 H4 R5 f/ E  G. f8 O8 e& b7 d2 ]
        }+ Q8 u6 |8 J7 t$ p: [2 x1 K
        else0 \0 |* n, B9 D3 t' y
            return -1;3 T0 T* Z9 b0 t$ \9 P
    }
    # X0 i& ]0 s0 C- y+ [( b- V* I: x- A
    . F2 I; c: e" c. M( Z8 \7 |0 o9 o! E$ C, z( U
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()! ~$ f4 p1 c+ k! G5 H2 U2 y
    {" L: Z& w7 N% P5 x# o# }0 p
        stack<int> s;$ M8 l8 U, e% r1 R8 q2 w+ `
        int p,cur,pre;
    ( g% M$ U- M, L8 Q1 }' ?+ T* ~    //MultiAdjListNetworkArc<WeightType> *p,*q;
    : y, K' t9 {, F: f9 {( w    for(int i=0; i<vexNum; i++) tag=0;//初始化
    , {( r! Z+ _) Z4 w: V2 V. p- g: n
        for(int i=0; i<vexNum; i++)% [# c6 e  e* i. F$ Q7 p- ~
        {
    * q" @7 I* `8 T) A2 I6 a0 a- U        cur=i;pre=-1;9 d/ S& R5 r# t. J2 [" P
            while(tag[cur]==0||!s.empty())
    9 g- `6 l9 y9 E% Z: e        {: g+ m+ O" [6 r/ O0 e
                while(tag[cur]==0)
    2 a- p# q7 f; E9 P/ m1 f  F; D8 H- o$ Y0 j            {+ q; i) |7 a: |7 f+ n5 `1 c
                    cout<<vexTable[cur].data<<"  ";
    * ~! ]9 b  m7 E+ P) s( z' \1 i                s.push(cur);! c1 x2 p  l0 f" U' T: w0 n! r; e5 i
                    tag[cur]=1;
    . i0 [# x# M2 ?9 R! y( ~               //初次访问,标记入栈# |; K- _8 B& v$ W

    ! i0 C! T3 R2 Z3 n               p=GetAdjVex(cur,pre);//p是cur的连通顶点/ b" R% X" O) m4 x& d
                   if(p==-1)
    2 V' y- R' ^1 d               {
    3 M: _9 Z, ^& K3 F2 m! f1 O8 a. N6 y                   pre=cur;s.pop();& q. o  D' [9 W: H; I
                       break;1 a( l$ Z4 g9 T1 X, ~( A0 m1 T
                   }
    # b$ U$ L- `+ J" [+ y- I$ C               else5 {5 @0 ]* ]- K0 n; t
                   {
    ' v& D# U6 z0 Q; q( \' m                   pre=cur;9 K% L) h3 S" Q5 a
                       cur=p;
      d% ^4 ~$ }- R9 X2 f6 N               }) g# q9 o7 S) u9 ~1 I. I& \, D
    $ O& J! K  p$ Y
                }
    7 v! u- O! |; B$ c% E! @            while(!s.empty())+ n7 I3 b4 l1 X3 W1 E
                {
    , }2 ?: U: F1 C; G& X: X                cur=s.top();& Q: j( m0 V% J
                    p=GetAdjVex(cur,pre);5 u* Z  F* X/ a$ Z
                    if(tag[p]==0)
    " F4 w: C; X' ?2 ]                {
    7 J7 \8 ]; E0 w# x8 G) ]                    pre=cur;
    ) N3 z9 G6 S& e9 R2 s$ h0 o                    cur=p;9 v) \( L, q2 K8 ]3 s! \" C- g, t
                        break;/ l' ]4 l- Q( e; j3 Q9 S! S
                    }
    : `& [, c. U: a, c( q: x; B                else
    0 U# ?8 s$ C$ j( t. z+ F! S- e                {- }  O5 U1 j) r7 x
                        pre=s.top();
    - j6 a% w# L  A* Q* G/ ?                    s.pop();
    2 g  y3 C3 s) K6 H' C6 D  ?' o                }9 ?: s/ `2 r7 y/ U
    1 ?+ {2 ~# d* I! w& o6 B
                }
    : [. s  L3 _! @* e( T8 M; O9 W9 ~9 l1 h7 f5 h5 |' @1 R3 D6 \8 T
            }+ A; N+ S9 U- w/ T: t# |3 W1 _
        }
    1 `- D1 R( Y8 {, o" W}# p' \: I& `& u
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS(); ?! T+ c; E! ~; o- Y/ f- q+ W
    {
    2 t; q9 G# E/ c2 P5 R2 [    for(int i=0; i<vexNum; i++)
    9 G2 v$ v5 i) E, e        tag=0;( r( a) G4 f' \' N
        queue<int> q;
    - W9 z8 j# w' E& p    int tmp,t;" W0 W8 R- D8 I- F/ A- ^
        MultiAdjListNetworkArc<WeightType> *p;/ X7 X2 o  E8 q# d& ?  m  q
        for(int i=0; i<vexNum; i++)
    : D9 G# C) M1 l: i1 v6 H0 R    {2 e! t. s& A1 c
            if(tag==0)' Z% c! E  n+ w# o# o5 ?
            {( V/ N% l/ Z. D5 q1 z6 n0 t
                tag=1;
    6 D  W3 O: E& e  M            q.push(i);
    ' y" q+ r$ F, r- n: u5 I            cout<<setw(3)<<vexTable.data;
    2 j) ^* q% P, L8 t        }0 t/ i( H$ g" I& u1 z+ ?" L
            while(!q.empty())
    0 j+ n8 n3 z) y        {
    " r3 y1 W, I# Y+ N, i            tmp=q.front();
    , ~5 w- p( ?- v! g            q.pop();' T) L' \$ O) @, M" R3 t# m
                p=vexTable[tmp].firstarc;
    6 \  Z. J( }6 l: A+ @- y* F            while(p!=NULL)' u0 @8 D6 g* v9 J$ ?
                {
    7 u$ ^: g) J# E2 t% h+ _2 i7 G9 @/ [6 I                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    + e7 c( B& b1 i  ]3 r% ]' g, f                if(tag[t]==0)3 Q. i" ~  p* L8 m' `
                    {
    , t5 k* e8 j% U% t& t                    cout<<setw(3)<<vexTable[t].data;
    + K' D: J, ~3 Y( J& D                    tag[t]=1;
    ; l& t8 t* v5 Z  @                    q.push(t);  P+ z1 \/ C$ Q, ]
                    }
    " F! }* s5 E& D8 c1 T$ v) k( v                p=NextArc(tmp,p);2 h+ b- \8 W' h# j. L+ \$ {
                }2 u3 V- |0 i1 k! z8 V5 Q$ S
            }
    4 Q) {" c  y# t  c, L    }5 D" L! v+ V  e  b! T& I9 z
    }
    " e. ]) i0 u( y: @# L( G; R0 H4 xtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    7 C( t- [/ n% `, Q{
    ) D1 g0 i2 n/ g4 N    MultiAdjListNetworkArc<WeightType> *p;
    ; e) R! t( n  P7 ]* c8 ^; h4 F% N: n    cout << "无向图有" << vexNum << "个点,分别为:";
    ( v; B* m+ y5 c3 v+ F: F0 @5 ?    for (int i = 0; i < vexNum; i++)
    # `# B4 U) P0 u  P# d; U* F  z5 x        cout << vexTable.data << " ";  G0 H8 ]4 h3 |3 O' l9 _# Q7 v
        cout << endl;) B" n) u+ r9 _% O% m5 D- }
        cout << "无向图有" << arcNum << "条边"<<endl;
    - q; @: Y' h/ K    for (int i = 0; i < vexNum; i++)
    0 T" f: v! t& W6 B    {
    ) T3 A8 K8 z! F2 Y        cout<<"和" << vexTable.data << "有关的边:";# i* T5 I9 t& L
            p = vexTable.firstarc;
    ; q; I% F5 ~( b4 x6 K  `- J; p        while (p != NULL)
    4 a0 R7 a" f: M' l- A        {: E; b) i5 w& k8 h
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    0 f1 i4 v8 u4 ~: L( O7 }            p=NextArc(i,p);
    ; L, M) W" J) w  Q        }$ C2 k/ {$ D# q/ V( k% \' H2 H
            cout << endl;2 C$ P# V; R6 a( D0 l7 g
        }, K- R! h* h3 x7 b0 c. D
    }  v9 `6 @8 p; N. ^( G" Z
    6 G# ?% z: `: N# x+ }; r1 i

    6 Y( @6 {3 J  t% ^' @邻接多重表与邻接表的对比
    1 Z2 z( l+ [  I) B/ @
    5 {9 @" o& G! Z1 o$ l邻接表链接- t( M) X7 F$ }7 q7 s* k) g7 l
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。! E5 R, \/ D* ^" g
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。& m# W8 p: ?* e" R5 p/ f+ I
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    . v2 {0 s  L* e  J3 b( @————————————————6 [8 z% o" E. Z4 q; G$ R& V7 Q
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    % C& f, E: G# v- \- B: O原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958& T  {: l9 K5 m% X! s

    ( j/ ?! c3 o& {
    7 g2 X  I3 m" u
    $ s# i: [0 N8 M' h& A4 Z: M& e6 d' r  i! _  \3 F6 |& D# t# L. `
    ————————————————1 m+ N( I2 ~3 j  r) {0 H4 e
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    , z) d3 s! @0 g# a  {& F原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958- ]! a: P; d$ u

    , n9 r. \& z: E) n6 i! t6 ~0 n8 y  n! k! m+ q# n& ^& z- p
    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:50 , Processed in 0.406830 second(s), 53 queries .

    回顶部