QQ登录

只需要一步,快速开始

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

    # Y1 @- {+ Y, V* L/ J& g+ U图的存储结构——邻接多重表(多重邻接表)的实现% U/ c" L+ Q% x$ F. Z0 P& o# p
    7.2 图的存储结构8 g/ ^: {: ]7 g% u. j5 ~' u9 w. p

    8 A; }+ A4 l  Z4 n- A5 g# \* o7.2.3 邻接多重表(多重邻接表)Adjacency Multilist/ P( B: C4 W- j  ^
    邻接多重表的类定义
    ! Y. s7 }. r& ?邻接多重表的顶点结点类模板9 H( r% X5 b' v+ o: b
    邻接多重表的边结点类模板8 \& R- P. j( p" d" N# e6 E
    邻接多重表的类模板
    - W$ [# @$ L; K: `- W  v) I8 a9 J邻接多重表与邻接表的对比  A! w0 i' t( [) Z2 {/ U
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    1 I7 C6 Z: D" |+ x4 {; k, A) q6 l, B
    % q' J: h# S! a+ G! C在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    # j9 }, }  v. k0 l, V/ f5 B在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。- Y7 u$ U, z$ f

    ' a7 h4 l* r  D邻接多重表的类定义# J0 U  ^1 B5 M3 r2 S
    1.png : S$ K3 G+ y. Z% X$ B4 y
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:7 I( y. r! ?4 o$ T# S6 Q4 J" Q
    data域存储有关顶点的信息;
    $ M# O% i( `' P  jfirstarc域是链接指针,指向第一条依附于该顶点的边。
    , ^$ _( l  k4 S+ k% S( B; I所有的顶点结点组成一个顺序表。


    2 v. h1 E8 ?% r  s" _1 K8 {* v/ Z( V4 s& H" y) g
    template <class ElemType ,class WeightType>
    2 u; ?3 d/ u! S* @- E  U2 Z5 zclass MultiAdjListNetworkVex' y7 ~7 j4 n6 T
    {
    6 C! i* x5 S2 m1 r/ N6 I( T$ gpublic:
    - {9 @4 A! V6 r. S% C: m        ElemType data;4 S* ?- `3 N1 ^# c& A+ e
            MultiAdjListNetworkArc<WeightType> *firstarc;
    5 ]# z. G8 Z3 n3 d* B
    % h. Q4 c& e/ z( \, P        MultiAdjListNetworkVex()
    % y/ Y- D$ w3 m* \! S& l: n/ F        {
    , a1 Z% V! W, R+ _                firstarc = NULL;
    ! {$ r" ~1 w: y% b/ [        }
    $ N( Q: A1 }6 Q        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)- V* K' x2 n1 ?) W" w2 R
            {0 z; r+ G/ p* o  a
                    data = val;
    : i+ F4 k1 C7 l' W                firstarc = adj;* g) ]* M3 l; P7 V) ~
            }1 {! V1 \: P  `( I. T  H
    };
    4 a" w1 A: g/ F* h5 G
    % \( Z- G# n% o+ a* \邻接多重表的边结点类模板+ ~8 n3 c# }+ T; C# A

    + U9 G, l( r, h( E5 a/ l在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    ; i$ t4 j" b8 j' C& a# V1 Vtag是标记域,标记该边是否被处理或被搜索过;
    : y, t+ C3 U5 A; N9 \5 s" I- X" fweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    ' ^1 e5 _3 j5 u1 ~' Bnextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;- _, ?8 j" E9 ^# B
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    ; h# U2 b5 _, h* r: I( ~
    : r0 `2 S" H3 r% b6 Z) Y# i 2.png 8 b5 k3 g/ B) C
    template <class WeightType>4 g% y3 X7 p9 H) k9 Y! n1 d- o
    class MultiAdjListNetworkArc% U# d5 u1 a: I9 u* n
    {4 v7 ^) I+ A+ ?% E  y- s0 v. \
    public:4 P2 K& `7 c4 F  F3 H4 k7 e5 h- u
        int mark;                                       //标记该边是否被搜索或处理过$ ?5 Y  H. g2 w# C( m( Z2 a* e
            WeightType weight;                              //边的权重  ^4 @8 [" B8 ^+ ]7 @
            int adjVex1;                                    //边的一个顶点
    3 r" i, _) W$ P) y# n        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    9 m8 I" \4 u  x6 \5 W! l        int adjVex2;8 K  R3 m/ Z' y6 g* I. E' J
            MultiAdjListNetworkArc<WeightType>* nextarc2;
    % a, S) W9 E$ F' B$ B8 U3 m4 `: Q% K- |! w; m! T
            MultiAdjListNetworkArc()
      v+ u  g# i8 o8 E  p4 V        {
    # I3 D2 G$ v5 I' b' [3 }                adjVex1= -1;" ]0 v& h0 E. d# \+ p/ {8 M
                    adjVex2= -1;( s) O1 Y8 L2 S; T9 I" F
            }
    0 p! p% K6 J  [) c        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)0 _' l, c7 K! J
            {
    ' y$ ]( ~- K" T: ?, v1 x3 G                adjVex1 = v1;       adjVex2 = v2;
    8 e( q7 {: K' |8 W' b1 y* |                weight = w;
    $ z/ o- ]7 r3 o                nextarc1 = next1;   nextarc2=next2;
    4 M+ ~" G, I. |' }                mark = 0;           //0表示未被搜索,1表示被搜索过
    7 U5 O1 `4 d. G9 k+ U4 x        }
    8 e: I9 o/ f" S: N. H- H
    1 O2 I! d% n# v1 B3 t$ v7 }邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    & _) R* q  i& j  r: Fclass MultiAdjListNetwork! G4 G4 G' H# w* [
    {! E, c. L  |+ p0 ~% T/ t
    protected:
    0 x" i7 E' q+ {; v    int vexNum, vexMaxNum, arcNum;
    5 Y/ u+ s4 I! H0 y( y/ U    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    6 M5 N; n5 v' }0 S    int* tag;
    6 s* }& @0 c" Q/ g: Q8 U    WeightType infinity;
    , n0 n7 Q) i# W9 W; N7 r* ~/ c7 C+ k6 `: u, N" f
    public:. e0 ?) b3 v7 u& r. F0 y* {! P9 C
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);7 H  e1 e9 Y* P% b

    ) w% i; _& L! D! ?    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);( c9 f8 N' H7 |" n4 S$ p

    ( r5 D( B4 D& h3 y  _8 k1 n& i' U    void Clear();7 }/ I( i. p2 U) D! N( |
        bool IsEmpty()3 h) y3 P+ J) ?% @! ^+ l: J
        {
    % O/ Z& Z3 m6 g. K7 L* E4 n        return vexNum == 0;
    / @9 u" b6 b  C0 ]$ F9 f    }
    7 O( I9 ~: p& e' V) p* V! ^    int GetArcNum()const
    7 Q; v! q: z8 B0 X2 @    {' c# W9 J1 o% T8 E/ m
            return arcNum;# n. A! J! ~8 W4 S
        }) t! n+ C) J7 F+ S; ]/ u. e" g- X8 I
        int GetvexNum()const
    : Y9 u! Q/ X# @: v    {
    5 w- F* x- t; {9 k9 ^* e7 A        return vexNum;4 B* g' y8 U" T1 |0 G; B( P- O
        }
    7 u( C$ s7 W0 S- I; T2 P% ]7 @+ w; }# z+ M

    ) N( {4 Q. N- c3 W8 N" C    int FirstAdjVex(int v)const;
    : w. \" n4 X+ J' }' \) G    int NextAdjVex(int v1, int v2)const;
    $ H. r+ d/ \% A" v9 U/ h8 V    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    * {2 Q& z& a* r4 r: h" Q    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    1 m: n$ m5 T1 F% g3 _0 h) U: P# Z( D6 L
        void InsertVex(const ElemType& d);' ]* G4 s' f, h$ x; y. I
        void InsertArc(int v1, int v2, WeightType w);# O3 Z7 m; F9 A) ^6 R3 V

    7 ^6 B# @" u- F    void DeleteVex(const ElemType& d);
    $ v3 j) B- m0 `& h6 W) u9 H    void DeleteArc(int v1, int v2);1 H# v  M& o" \6 d. O

    * D. d( f0 F$ [    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    5 T9 }: F/ s$ ?    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);, Y8 T" E3 o! Y& p8 `9 w

    * r8 ?) b' h1 J3 ]7 O    ///深度优先遍历# h2 M% M. s+ d- B
        void DFS1(const int v);4 t% n# ~7 t% b# p+ y
        void DFS1Traverse();2 W" w: B& c# c3 r& b" O2 O: `7 R
        void DFS2();. u0 W0 p2 L1 d% h6 U. a4 S
    : S# |8 z  \: H3 X, {
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    ' \7 j3 W( g# w    void DFS3();' q5 H& J& E9 {
    4 t- [# ?& u; m& j, h
        void BFS();/ Q- [! g( K, z! O
        void Show();
    : g6 T* K% w6 |4 c1 t};
    ) S3 L6 c$ Z0 y* t& B& \% K. u3 w' b: k" ~. D1 y% x
    2.函数的实现
    & ]) t7 m* C$ }( X- j% n& m研讨题,能够运行,但是代码不一定是最优的。1 r" p9 |0 l+ Z2 B# I$ ?% n
    , z+ D. ^6 T" z% t" |
    #include <stack>  c5 P4 E$ l* I- H; i( S% x
    #include <queue>
    ' C7 g8 b+ M1 i! _2 |' Y4 W. o( Z- ~; a0 U
    template <class ElemType,class WeightType>
    ) P7 Z- D" o9 s3 a  H: uMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)4 ?; h+ G# Y: Q1 |
    {
    - ~& s5 @: \1 x8 t- i    if(vertexMaxNum < 0)
    4 }& v! y- j) T$ d0 o: m7 ^        throw Error("允许的顶点最大数目不能为负!");% I+ c2 c! e% B& R7 J. g- W
        if (vertexMaxNum < vertexNum)
    % u* P% M! {0 a. s7 e5 l2 \        throw Error("顶点数目不能大于允许的顶点最大数目!");
    ( y  _  ^. M, N9 A$ O8 o    vexNum = vertexNum;
    2 J$ x! ]- q4 M' f% Q) ]' K. ?    vexMaxNum = vertexMaxNum;
    ; V4 K* h3 [1 Z! g  M; N7 p; O! Z    arcNum = 0;
    % z, M+ j% `: \6 d% s5 p/ B    infinity = infinit;
    ( e& Q) r) J* O) n& Y8 l    tag = new int[vexMaxNum];9 {, D# n7 B4 P8 X1 \' s4 j
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];' g' f# V% d5 ?4 C+ }  [5 e
        for (int v = 0; v < vexNum; v++)
    - Y* g8 x+ j- P, q6 A3 z    {
    3 b7 |4 J+ S  N1 `        tag[v] = 0;
    : U$ \* G; I' [8 c! K$ p# p        vexTable[v].data = es[v];) j+ Y* d; n2 m' ?& ^
            vexTable[v].firstarc = NULL;, B3 d# }  M7 l/ E; }* |! e! y
        }; C0 c" D# h( |3 E* Z
    }% ]$ x6 e4 y5 V+ d6 i% P
    template <class ElemType,class WeightType>
    # |1 ^& B7 q$ p: ?, j6 hMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)" P/ j/ ^2 T/ l$ S2 P
    {
    ; X6 J! G7 s5 \, ?) }    if (vertexMaxNum < 0). r; |& O2 ~3 s
            throw Error("允许的顶点最大数目不能为负!");
    ; [6 [) W) B" h" Q    vexNum = 0;
    . A2 o! o4 c! |. n+ B# D    vexMaxNum = vertexMaxNum;
    / I4 Z2 |" G, ]9 n4 A6 q+ Y    arcNum = 0;
    " M* o) F7 A. Z    infinity = infinit;! E" ^/ ~% [( E4 \9 m6 y
        tag = new int[vexMaxNum];5 x! y  s( L( b
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];" U$ i7 X1 z' h/ Q
    }
    ( `3 ]9 g  L3 X" X! v, o7 e9 htemplate<class ElemType, class WeightType>8 l& L8 V: v  t
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const7 D# e) P+ }! u- E2 j- K& E
    {6 v% U6 s& x3 m: r3 Z% D5 F
        if (v < 0 || v >= vexNum)
    * b+ N5 f+ u3 c7 }; O        throw Error("v不合法!");
    " u0 U" H# o& W4 T7 i    if (vexTable[v].firstarc == NULL)
    * g" K' m  L1 |        return -1;( T' i% t- g8 b* Z
        else
    * |" P  Z* S2 U( ]8 |        return vexTable[v].firstarc->adjVex1;
    & Z. ]! C( E- s" ~& {. J}6 J  R" P4 t* t( g; }0 g" P
    ( p9 s0 W/ F( l) \! E0 L; e3 F. j" N
    template<class ElemType, class WeightType>2 ~% c" F) f( a+ }9 j
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const( ?$ W; s0 K3 F* U& r/ l
    {) u4 B# u7 o' ^( u
        MultiAdjListNetworkArc<WeightType>* p;9 I% A! u9 O/ Z* A
        if (v1 < 0 || v1 >= vexNum)
    ( G1 A  w5 B7 U0 @        throw Error("v1不合法!");3 s/ q- C2 F2 a7 Z/ T; E
        if (v2 < 0 || v2 >= vexNum)
    2 O# G; W8 C, m        throw Error("v2不合法!");
    * `8 \' f0 y* A: r. C    if (v1 == v2)+ e' k& S% l. ?; u( s
            throw Error("v1不能等于v2!");
    & z3 Z4 Z, m- i0 F2 A( k7 a( @    p = vexTable[v1].firstarc;5 F# |( d: K: p8 H
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)4 f  d  v# r2 c' e0 W
            p = p->nextarc;0 ^. N2 k' W/ ~( s! v, s
        if (p == NULL || p->nextarc == NULL)7 s$ [* t$ _' T8 j
            return -1;  //不存在下一个邻接点$ t: O) A0 W2 T8 M9 {3 a. W3 N
        else if(p->adjVex1==v2)6 u3 ?8 c" u1 U/ v6 X4 ?
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    / r0 R7 v. f; Z5 p# |# L4 E, A    else
    + ?3 u2 I5 l$ R, W; d( l        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
      l, ]% R& f" O$ d  N+ d0 C}- |9 K% X1 d2 L/ w
    template<class ElemType, class WeightType>
    7 f# y' y) r* }; F, Ivoid MultiAdjListNetwork<ElemType, WeightType>::Clear()
    $ U( M! ~8 U8 |$ f{
    0 Z6 w4 V5 F9 p) E" J    if (IsEmpty()) return;
    : _' h) r8 @) t4 o! s/ `' w    int n = vexNum;
      I# ^; B; N0 Z5 a2 B! `2 ^( W    for (int u = 0; u < n ; u++)
    ' s/ Y" T; C+ X5 ?# }  D        DeleteVex(vexTable[0].data);0 `# h8 W( @) o: j5 k8 {2 x
        return;5 Z/ F1 E  o) j3 T$ s" H
    }/ E# U" @' p5 R& l) J* Q
    template<class ElemType, class WeightType>( M3 {* e0 E, S3 N
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()/ I6 P* e  ^7 v1 M' p+ V3 {; `! J
    {9 R  B- H0 d3 D' M$ [' J
        Clear();
    ( U1 o# h  v; f, R8 Z: Y: H, x+ L6 f! f}3 l) H2 X8 X% Y% l
    template<class ElemType, class WeightType>) ]& ^9 R" u2 S. Z
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    2 z& e5 g. E8 P; v{
    3 Y1 T+ ]$ S# ~& F- w' q3 q0 m# o9 n9 N    vexMaxNum = copy.vexMaxNum;
    " R- Z. A( H3 |8 E) O- Q    vexNum = copy.vexNum;
    * K5 w6 k9 Q: t$ s# I    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    + d0 e8 J( c4 s5 g    arcNum = 0;. q  K* T  Z6 ?  j* a9 c. k( d% }
        infinity = copy.infinity;( J5 T9 {) i) H: @/ g# t' K
        tag = new int[vexMaxNum];* ^+ m8 C! G6 S! Q( U) h

    ( w6 x2 b! x1 B9 y: F    for (int v = 0; v < vexNum; v++)
    & e3 f/ _" }: ]. @6 ^9 B    {" Z6 b$ j2 {5 a3 G. v2 Q4 s8 r
            tag[v] = 0;" u" g' Q0 O6 W( X, \7 T1 x1 g& Q' H
            vexTable[v].data = copy.vexTable[v].data;1 W7 b. L* S5 i# `3 ]3 Q
            vexTable[v].firstarc = NULL;
    ( g) g' O7 g# o& T    }
    $ [- b1 z0 {3 W/ }' N; [    MultiAdjListNetworkArc<WeightType>* p;% m* t; I; ^1 j- E! }9 Q

    9 o& z4 U$ p  M( D+ k3 n0 b    for (int u = 0; u < vexNum; u++)
    - \+ p9 T) B5 [/ y0 ~    {5 H* W9 V' f4 S$ i$ W+ x5 V
            p = copy.vexTable.firstarc;
    1 @. |$ v' u* {3 m8 R        while (p != NULL)* g: h2 s9 D3 T) z7 g
            {$ w' q& n8 ^  S! D
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    0 ^4 b# z4 M! y* p+ W! a; r8 F            p=NextArc(u,p);
    : I* L8 g8 b0 M9 l        }6 q# l. j5 C9 q+ C9 H* W
        }# r4 Z, `# N4 w/ ?. i9 w, C( Y
    }
      Z8 p) c5 p/ a& B& x* Qtemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    0 h) i2 O9 M+ {+ VMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)( q5 G5 V$ z/ p; L: l) a
    {) ^: Q0 I! [8 m7 V/ E
        if (this == &copy) return *this;0 x6 L! z* l9 T) s6 [4 D
        Clear();: S, v. L, [) a/ E" x
        vexMaxNum = copy.vexMaxNum;. e+ T6 v  e' Z. r3 q
        vexNum = copy.vexNum;
    0 x& G$ o) x+ `+ X$ i0 d& o    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];' O9 z, t0 w7 _9 A
        arcNum = 0;% X/ q$ L7 N5 C. l9 A+ r  b) U# d
        infinity = copy.infinity;
    " b& u; V" `; y2 e$ K1 k3 b, S& M    tag = new int[vexMaxNum];
    1 }) g8 P" Q+ X# b/ n4 p! U, o- G; Q7 p3 R
        for (int v = 0; v < vexNum; v++)
    % b+ s% N4 p* [; z    {
    ! I) t- S7 T0 C& k1 K        tag[v] = 0;7 O& W6 c% ?* K2 x3 e# R
            vexTable[v].data = copy.vexTable[v].data;$ Z# ]5 L) \# T0 y+ U( c8 T
            vexTable[v].firstarc = NULL;: T! X4 Z% Z6 V2 y/ O/ P2 h
        }
    1 k& W5 D5 l! U) t: I" L& I* p3 G# U    MultiAdjListNetworkArc<WeightType>* p;! |7 z8 c2 l+ ?3 p3 _5 r: O
    8 q7 @  k8 y0 [
        for (int u = 0; u < vexNum; u++)
    % b& Q' R: k4 q9 O" D0 _. R3 a    {
    0 N6 {: R7 ]3 ]9 V& e        p = copy.vexTable.firstarc;. v/ m; ^! S" j2 i; z; Z
            while (p != NULL)
    5 n; ]3 c# e# e+ [) B! |& f        {8 L6 B8 B) J' d6 L5 ?
                InsertArc(p->adjVex1, p->adjVex2, p->weight);( G' s  [& E. C9 z& F8 c8 E' }
                p=NextArc(u,p);
    1 H8 e1 i# M' d8 O" v3 B        }8 Y7 [  p. N& _! x
        }
    5 F) z5 z) _# {) q    return *this;
    $ j6 j# j( M5 o, Q" n: v}
    * F  {8 }; m4 X  Ttemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*6 g1 J+ S# ?  q$ h2 x. S# R# u# ~4 c
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    ; I- A5 ~  B7 ~8 U& N{
    . g' Y4 ~) D3 {' v( Y" u, e    if(p==NULL) return NULL;
    $ w& r* g, j2 Q9 L# `" \2 |    if(p->adjVex1==v1)9 ]% \, w* b9 b+ @) |
            return p->nextarc1;( x$ u; q8 l9 I5 }  p- M! g
        else3 l0 M- n% B# v2 C$ |" ~" o' a
            return p->nextarc2;* {* R  k5 d- {
    }
    5 m1 z) M* P3 i0 ~; Rtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*  l1 D" A, v6 D* Z, b0 o: L0 [' T
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    * T0 Q9 J6 g" K( n. O" t+ q  x{/ ]* u/ k' v7 x: J. X) s- X0 F
        if(p==NULL)return NULL;( E" [1 Z; I: w! F) I1 L  }0 m; }4 L7 F
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    $ G% l! u" j  u( \9 j4 }    if(q==p)
    9 R" q/ m* i' C5 t( E        return NULL;
    2 ?9 f+ _# I* Q! ^' k0 A, Y' t, m; R    while(q)4 `  o6 i- S4 m4 |$ S
        {2 ^& I* P" v* a% J: a9 s
            if(q->nextarc1==p ||q->nextarc2==p)- v' d. |; _, j! v; O  U3 ]
                break;
    / g) [, E8 G2 K8 x        q=NextArc(v1,q);7 K# M3 w# U, J& V. R  r9 z
        }* F* c7 {7 p- ~# u5 E$ f% p
        return q;
    4 ?1 A5 G7 T2 m7 R/ y$ c}
    ' k4 e2 g+ H0 m" a+ @; Gtemplate<class ElemType, class WeightType>/ `0 q% m6 m4 F
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    7 o* T+ s% |2 U* Q$ f& s& |{
    1 C: [2 c/ C/ |    if (vexNum == vexMaxNum)
    , q5 \# P( c3 Z; e4 m1 N" d% k+ }        throw Error("图的顶点数不能超过允许的最大数!");
    7 ^; M% C. Z2 i  L& I    vexTable[vexNum].data = d;
    $ |9 T7 K6 l8 j0 e& o: x5 s9 p    vexTable[vexNum].firstarc = NULL;
    ; u2 N% `4 U1 u; n- ~    tag[vexNum] = 0;0 p6 c% u+ G5 l- a. a' X* V
        vexNum++;' l" y; t' a0 U& w% t# ?6 a
    }
    + @# d: o' U" M- Y2 |template<class ElemType, class WeightType>' q: A  N8 S5 t3 m6 B
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    6 V* I1 ^8 b9 Z. _( k8 G+ G9 X{* @' i% Y; u/ ^4 V2 s9 `8 T
        MultiAdjListNetworkArc<WeightType>* p,*q;
    3 A# X( N# Y  K, V0 W' z    if (v1 < 0 || v1 >= vexNum)# X# Z$ E- ?  h9 F
            throw Error("v1不合法!");
    1 L" [/ ~1 o/ r: ~' _8 Y    if (v2 < 0 || v2 >= vexNum)
    " }( Z, [: }; E$ S2 E* x        throw Error("v2不合法!");+ a. @/ k: Y2 T  D- G6 e
        if (v1 == v2)
    $ \( N$ {3 ^- x1 Y" f! ]) ?5 C" t4 H        throw Error("v1不能等于v2!");
    0 K# l+ \7 ]1 |    if (w == infinity)
    & u9 d7 p" \! Y9 @- p! s% X        throw Error("w不能为无穷大!");( F  L( Q( o5 i2 I4 }6 M7 M  M
    * p. {: \: L9 N# |1 L

    * g) M; O) {% Z% J2 B3 K    p = vexTable[v1].firstarc;) N" }3 u; J; I5 P
        while(p)* O5 |: q' U- U6 X* ~
        {0 U% |5 F/ j+ l6 D1 a
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中) T6 M. R9 j7 H# {; F. s+ M1 r; z
            {
    4 F3 F" p+ \# K/ h- M$ g3 Y/ f            if(p->weight!=w)( w8 X: B6 H! r7 Q3 [/ F
                    p->weight=w;
    / w2 }/ c9 ?# r  \) r  O* f            return;
    # g( I" e2 n9 h* e/ R& q        }
    ' d8 d: _$ y6 n$ ^9 t
    : X! J& g* e" \        p=NextArc(v1,p);/ b2 ^' ]- C( C% o& l4 q$ l5 l: j; t
        }. E. I2 ^+ o5 i% _
        p = vexTable[v1].firstarc;. G5 w) e* L( c4 i& i; J
        q = vexTable[v2].firstarc;1 q/ h8 M& q$ _( ~) ^. B- p& T. q
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    * B2 Z# c9 U: H2 Q    vexTable[v2].firstarc =vexTable[v1].firstarc;
    ! ]8 b! f4 m* i- x, R+ H' Z    arcNum++;) T- Q3 g* Z) k$ B8 s5 _! o1 o; P6 ?
    }2 L0 e# W5 c1 U

    % M% [% x( A; E$ U7 a3 Wtemplate<class ElemType, class WeightType>9 |% j3 g7 ~- m, N
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    + q: _' d: u, E: _; \{* Z- y  {, q3 c" H) o! o6 l+ a
    $ t" P; `) r! u& b* ^
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;' d4 J6 B( _+ y$ ^1 @, }4 I
        if (v1 < 0 || v1 >= vexNum)+ [) F5 J. r5 |; l5 h! j; J/ p( I" M
            throw Error("v1不合法!");
    8 E; }. }$ r2 m* ^# y4 U$ |    if (v2 < 0 || v2 >= vexNum)
    - g- I9 R6 o) d6 Z: K: p        throw Error("v2不合法!");
    ! @3 M! F" P( U, e5 M' A- r    if (v1 == v2)0 w" R6 Y0 n$ C. S7 W. T
            throw Error("v1不能等于v2!");
    2 L9 ^8 o  ?8 D9 ]9 b( _  L( Q9 N( J- d! J: D/ W3 j% _/ G# X
        p = vexTable[v1].firstarc;4 h. q6 h; Z' o" o, S9 ^
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)7 r( E5 O+ t, S3 {0 c$ u
        {
    4 A; G$ X: y* O, X$ N        q = p;+ I- s% ?& u! n' p
            p = NextArc(v1,p);, B0 S, S8 F" x7 a( K: o
        }//找到要删除的边结点p及其前一结点q
    3 U- Z+ d& A( J3 F1 h7 e: I+ B8 ^2 p+ |3 ~1 W
        if (p != NULL)//找到v1-v2的边. A& T3 F( M  r# A3 ?$ F" Z* f
        {
      B; }8 M; A% L. V        r=LastArc(v2,p);) D7 A: Q8 P5 s5 U/ W
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL* y1 X; _1 F2 }; \$ [
                if(p->adjVex2==v2); ?  A* w8 P" \9 s) \& u" {
                    vexTable[v1].firstarc = p->nextarc1;9 b- ^$ P: Y  c( B& E) M7 F
                else vexTable[v1].firstarc=p->nextarc2;8 X/ r+ E, Y; S" `" m6 T  x
            else//不是第一条边
    ; k2 c7 d/ B) y, X% Y        {9 x- m) F9 ?) h! p
                if(q->adjVex1==v1)
    , Y! p0 N/ J' |                q->nextarc1 = NextArc(v1,p);. y4 P8 E. k& E/ S- {+ I
                else
    & q4 C; r2 _  X                q->nextarc2=NextArc(v1,p);
    2 M/ k1 z3 e! j# c/ K: U6 D1 s' C5 @* {( I2 X' D6 K7 [( ^0 L
            }
    8 O' B' T" K% }6 L        if(r==NULL)
    . R+ \3 A* P1 G7 N: c! V            if(p->adjVex2==v2)
    0 C' M7 H& `  R" r  {# J8 s                vexTable[v2].firstarc = p->nextarc2;
    ) V: B) P2 B) Q+ s2 B            else vexTable[v2].firstarc=p->nextarc1;% H! y4 l% J9 Z% q  j- ^
            else
    + a5 k" j- G4 h        {- T; c% v6 M$ ~* M$ f
                if(r->adjVex2==v2)" N5 p8 ~) x) `  K5 n4 m
                    r->nextarc2 = NextArc(v2,p);0 q5 d  ~5 n3 s, Z4 ?) \! t% Z" i8 C+ g
                else. {) l& i6 a7 S5 T' q9 C% |
                    r->nextarc1=NextArc(v2,p);
    0 L5 `/ h+ {" L        }
    6 M) S7 c$ t0 J) ^8 o: ^/ F        delete p;
    ; G7 ?. s& ?8 G        arcNum--;
    6 ?% d* ]7 D+ u5 F- E    }/ K% f, _6 I! r5 j# t( g
    6 j$ _" v- e% F0 R
    }  Y; E* n- D4 _0 v1 q* z% H' N
    template<class ElemType, class WeightType> void8 t1 F. P! Y6 P0 U0 [
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    " j$ X$ l) L; H6 a5 H& _{( q' V$ O6 E5 f- O3 e
        int v;5 S% x; @& ]; r
        MultiAdjListNetworkArc<WeightType>* p;2 u2 O, N6 J1 @1 ]4 q9 _
        for (v = 0; v < vexNum; v++)//找到d对应顶点! z  u; l1 _! d9 C' m7 ?2 h
            if (vexTable[v].data == d)7 ]9 W: R8 D0 S- u8 W3 Q" o1 p0 a
                break;  b  Q+ O5 H/ G6 ^+ M
        if(v==vexNum)
    1 ~5 C: Y6 i2 L; P" Q8 k& G        throw Error("图中不存在要删除的顶点!");
    " l6 Q9 K2 o2 J7 }. R& R# d# L7 P4 s* j7 g8 o8 O
        for (int u = 0; u < vexNum; u++)//删除与d相连的边2 B4 d- b. Y! Q: O3 P& z0 g
            if (u != v)
    + r8 R7 z: l4 q* W/ U/ N        {
    8 w' \' O7 _/ q5 l            DeleteArc(u, v);0 q% n3 W! U2 l% H, t* I" [
            }* r/ E/ T$ z/ B" F$ h# a2 ^
        vexTable[v].firstarc=NULL;; d' E; d4 N0 y2 G
    " h' p8 G2 @$ @9 B" y, S% n
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    0 Q) u1 R3 Q! P+ i    vexTable[v].data = vexTable[vexNum].data;0 p' f$ U& h. R
        vexTable[v].firstarc = vexTable[vexNum].firstarc;7 S# `! F9 B# `- _
        vexTable[vexNum].firstarc = NULL;8 M5 K' J! e; f: ~8 d; E
        tag[v] = tag[vexNum];
    8 }9 n6 ?+ ?8 x  t$ _& q9 g    //原来与最后一个顶点相连的边改为与v相连% Q* p5 P9 ]8 Q
        for (int u = 0; u < vexNum; u++)
    ! g# Q) I9 u9 F8 v    {
    ! H" ]% J5 O9 F1 C        if (u != v): J) ~) t* n( D: J
            {5 C1 A& ~3 C  ?6 M( Y- B2 N- R
                p = vexTable.firstarc;
    % d) h3 \! v/ i5 \, e            while (p)+ t9 t, Z; k$ D3 k  ~% {/ U
                {
    8 g+ a- b: q4 R- M* M/ p# |# B& w  t                if (p->adjVex1==vexNum)7 Y+ P  i1 o& u0 ?& U! ~
                        p->adjVex1= v;
    " e4 d+ f& Q0 F/ p                else if(p->adjVex2==vexNum)
    ' v% n2 r: o. c6 k6 e9 J4 @) T                    p->adjVex2=v;
    9 [+ Q( m5 Q5 f9 O' z$ f2 p' g                p = NextArc(u,p);- D& [( v1 k/ `9 @, ]7 o' v' c
                }+ v& s5 W) S* ?$ X
            }
    ) l! p. S; c1 a. u% L0 S3 i. T    }1 i( O1 x4 n4 D% R: n
    }
    8 }4 A9 m1 Y6 J# B( E* W$ B///深度优先遍历
    ! `  r2 Q! b9 l) M8 }+ |! G5 r: z$ wtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v), u5 M6 D8 h  z# v) W
    {: a& {/ v) R2 V% o
        tag[v]=1;+ F' V1 \! j2 c- P( o; V# i
        cout<<setw(3)<<vexTable[v].data;
    & |: F% u5 |  l+ P    MultiAdjListNetworkArc<WeightType> *p;
    : `; l3 }" k+ p. V    p=vexTable[v].firstarc;0 m& G: x3 n& y6 \& j, d8 t$ b0 e
        while(p)4 ?. D: T6 h: R
        {
      ?, u" H* A4 v' `! J        if(tag[p->adjVex1]==0)
    $ D2 D5 ^5 d* u1 T. [            DFS1(p->adjVex1);& d' J% E* F7 _( }0 }' X6 D2 U- g2 F
            else if(tag[p->adjVex2]==0)+ O% h$ R1 f3 A$ @
                DFS1(p->adjVex2);
    0 j( V# Y- Y  S6 @. R7 q        p=NextArc(v,p);
    1 |; d: w7 v9 l/ |$ X% M# ?5 \4 G    }
    ) P2 a/ |+ W8 `& {}
    8 B+ w' f( w  m4 v- Etemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    ' m8 [1 y: z' f# G; j+ x; g, @{& I* t) D# p: V
        for(int i=0; i<vexNum; i++)
    , v4 q  C9 F2 O" x        tag=0;" T6 J) N* o: D7 u6 P% w$ u6 ?
        for(int v=0; v<vexNum; v++)
    " `$ G+ {; J% m; A7 k    {
    * v8 E4 d! Y- ~6 G1 {& Y  L        if(tag[v]==0)
    9 E# L9 @% r% m  e8 L- y  \7 l' i            DFS1(v);
    % K' z: k  k4 j/ T- b0 r- _    }$ M4 L7 @7 o7 ~# u+ R3 u  Q
    }5 Y$ f  \0 s4 _* e
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()! i* i- _+ K* P# j" Q9 O
    {4 ^* H7 d4 h9 V9 s- V7 A
        stack<int> s;
    ! W( P" ]1 E& {    int tmp;, N% A  M: Z+ D& _( W1 G2 Q
        MultiAdjListNetworkArc<WeightType> *p,*q;
    6 S& |6 m2 U( r3 }# V( V    for(int i=0; i<vexNum; i++)
    * y: g( s' O4 I8 G        tag=0;; x9 b4 L; I2 g. u7 N" {9 c$ f
        for(int i=0; i<vexNum; i++)( r* p8 r4 `, U: _2 S! u0 j1 Q* z, \
        {# j7 n5 ~" z# k
            tmp=i;
    # h) P- S: I/ i! G) Y        while(tag[tmp]==0||!s.empty())
    " _6 o: H8 m2 R2 v, u        {
    - s- a) q) r4 }7 I3 x  Q            p=vexTable[tmp].firstarc;
    / h% \! D0 V7 G; k            while(tag[tmp]==0)! G! p6 t; Q8 ?
                {
    7 D" D# d8 L0 {# t& {" }: w                s.push(tmp);% u" n6 b; z: \  |; v$ [
                    cout<<setw(3)<<vexTable[tmp].data;! A# ]& _3 V. \, w/ C8 W
                    tag[tmp]=1;
    4 ~4 G5 V% Z5 s( H                p=vexTable[tmp].firstarc;
    " _9 o, n* _% V& `& F                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    3 i6 `& I9 `" L9 o7 J                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);" R' `5 `7 z) T/ J/ E
                    //cout<<" 1st     tmp="<<tmp<<endl;& V! Q1 c: k3 N5 O" o0 ?
                }; m3 }6 N4 q, h  y8 V
                if(!s.empty())" V, c& ~; ]7 I' w- {! x
                {
    ; d: o% \8 h% p                tmp=s.top();
    0 K9 v9 ^2 n/ ?6 A6 v- G0 b& `" ~                s.pop();5 u+ `2 c8 G; C4 U, l  J& h
                    q=vexTable[tmp].firstarc;: J9 h$ P1 B& ?1 T5 X
                    int t=tmp;
    / i" E5 A+ S8 ?& K& N                while(q&&tag[tmp]!=0)9 J: t0 ]. @8 `/ j3 A" v- Q
                    {
    2 F' @* l: J8 N+ R! ^; {                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    9 X3 |3 z4 w: z+ A                    //cout<<" 2nd     tmp="<<tmp<<endl;7 r: H! _+ w- _% C7 a% ^
                        q=NextArc(t,q);. M. z3 g4 O# g9 \: M
                    }# \, W% R/ H, Y  `9 {7 h2 Y( L
                    if(tag[tmp]==0)' s5 T7 t& O: ?: D: L
                        s.push(t);
    9 {, \& l3 w4 t  \9 v5 X- L# S                ///1、对应上面连通分支只有1个点的情况/ M9 A6 u( |; L, O4 C/ y
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈0 q. W+ s& i% A5 V* O0 \
                    ///tmp要么等于找到的第一个未访问节点,! `- a4 p7 d; R" |" C' m6 k
                    ///要么等于与t相连最后一个点(已被访问过)' j8 ~) g; R  q
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    # d6 h. |, j9 |4 B9 X% v            }. F* x1 G# {# N# Q
            }. e9 S6 I( A; `& _2 f, g
        }% Z$ h: j3 o( X* W  ?1 R( l
    }
    ; B# h' X2 ^! Q; \3 g- _//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    + z3 p/ v" P3 d2 ^5 z, `" rtemplate<class ElemType, class WeightType> int
    2 X: J4 a! n; v) y2 ~# hMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    ) T2 o: ?5 k9 b, B( s{# U; ]5 b# p9 m/ e
        if(head==pre)
    ( I0 Q' c4 f" h( E+ r( u        return -1;! B: {$ K% o* T3 n

    4 R; |! W+ {# X1 }) ?    MultiAdjListNetworkArc<WeightType> *p;' }2 U. N+ F, J* |- p
        p=vexTable[head].firstarc;( y5 }5 {0 ]' {
        if(pre==-1&&p!=NULL)
    + T/ [7 A+ {  M. c        return p->adjVex1==head?p->adjVex2:p->adjVex1;+ M9 o6 R: L% Z/ C8 u% q4 k; n0 W
        //pre!=-1&&p!=NULL; E, D" }- {6 b* b1 b2 X1 V
        while(p!=NULL)3 C4 M3 E& X8 w' [4 r- q6 `* v, f
        {
    - q1 t( _- A' Q" ?        if(p->adjVex1==head && p->adjVex2!=pre)* u' W; G0 P* Y$ _) T# t* O2 _
                p=p->nextarc1;
    + Y; {7 H7 k4 f. f, d: F5 z; Z        else if(p->adjVex2==head && p->adjVex1!=pre)" S- m- b0 D0 I: O
                p=p->nextarc2;
    ; L2 o2 |* |/ O        else if(p->adjVex1==head && p->adjVex2==pre)
    5 P* C- a. f8 X! d" q6 ]0 J2 T1 X  p        {) l. k9 ~3 l$ a9 u
                p=p->nextarc1;
    , \5 N0 l  }6 l" C5 K+ J            break;
    % L4 Z& {  L5 r; i' t* e        }
    " m6 P) D2 i) N  o% ~+ Y0 O        else if(p->adjVex2==head && p->adjVex1==pre)
    8 M( S! f8 v7 r, M5 F        {
    6 ^! T) O& O6 E" V( G6 u( E            p=p->nextarc2;
    8 \! v: @. z4 }            break;- O# N4 A0 D. l% A" J1 V% H
            }
    3 @( C3 ?; X# s4 w1 h    }
    6 E) |" d/ M- M% d" j: X* ^    if(p!=NULL)3 I( c3 i+ g  Q6 B, k- I
        {
    % K* P( U! c% c5 T( b4 X# b        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    * o* h8 u) q5 J8 K    }
    4 ]% y: S" s8 x, U) l7 o% E- A    else
    # g3 D1 K! e0 \! B7 V        return -1;
    % q1 Q7 N. d4 I! x2 e3 q% }! D& i& L}
    4 }: Y# y' a  N8 l: s( J8 B; m# V+ F3 j; f

    " K* u9 `3 g1 K4 ~; ?template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    ( u* f: ?6 r  C{
    - K% \* i* x( E$ ~' d) l    stack<int> s;% L3 h) V5 \- J& b/ |
        int p,cur,pre;
    1 Z  B( N8 h6 m+ t% t) t    //MultiAdjListNetworkArc<WeightType> *p,*q;& k# \# M) e- c; {0 z& j  [
        for(int i=0; i<vexNum; i++) tag=0;//初始化
    . U6 y3 ~! w# ^
    ; e% J' F7 H  c' F" @$ I; U* W    for(int i=0; i<vexNum; i++)
    $ J2 J* ?9 g9 C5 Y    {- i# ~0 l% a- P9 t) ^) `4 l9 y
            cur=i;pre=-1;: s) A7 Q6 G" U; ~
            while(tag[cur]==0||!s.empty()); u8 n* r9 t% X+ {' G+ C
            {2 M% p. {& B5 ^. t. L$ @0 z3 L
                while(tag[cur]==0)2 h2 K+ ?3 i" [7 l- J  }
                {7 G0 f. G5 t+ p+ M+ n( c+ P
                    cout<<vexTable[cur].data<<"  ";
    7 `# J0 `% W* H' X1 U% e  I4 r                s.push(cur);" K5 \1 K6 K- k, [$ G# F" o
                    tag[cur]=1;
    ! Y& F6 ~$ t& E$ ^/ _               //初次访问,标记入栈# ?, l6 [" y- B

    9 ~) [3 W) S, e$ j% d               p=GetAdjVex(cur,pre);//p是cur的连通顶点, J( J6 B& I1 j8 q
                   if(p==-1)  e/ _+ v' u  c/ B1 q6 M  s" c
                   {
    1 X5 _1 _6 F6 L+ E  C! |                   pre=cur;s.pop();# ~& F7 y; l. v/ {' p
                       break;
    0 `2 I* y' U5 z- }" {               }
    9 B$ h5 z+ b! n1 c! z2 u" x               else/ b" L8 D' y0 l* }1 p1 z
                   {& L  g3 m) Z! W) @5 z; ^
                       pre=cur;
    " X6 N% F, H! k) ]/ n" y3 N                   cur=p;& m/ H# {9 d9 f. X
                   }
    3 r4 W# Q5 z+ p9 z7 Y' s8 {& h% K# e' d& ~+ t, P6 q
                }
    % z: {' v# ^1 b            while(!s.empty())
    3 H; B0 `% ?& [& d            {' j( f' G+ J! R9 E7 }2 \3 X
                    cur=s.top();7 h6 B) z$ U4 ~' |
                    p=GetAdjVex(cur,pre);
    / M1 G0 E: \- r, w. J8 w7 `# m                if(tag[p]==0), i& f6 I; y1 G; R( t, ^
                    {
    4 _' v% D/ G4 H8 f                    pre=cur;
    / y/ n4 e* x" ^; {/ w                    cur=p;/ c5 T' j4 x0 ]! K. l
                        break;  V/ [- L3 j6 t/ T
                    }0 g7 B9 d9 L0 O5 ~8 k& v( n
                    else4 _3 `" I) g+ D' b
                    {1 a0 A: x7 ~4 g6 _5 d4 H) [, X  x
                        pre=s.top();
    6 ~$ ]" C1 s2 S+ f% U6 h9 n; T! A                    s.pop();- I0 z: \& V; t. ^1 M$ `3 J
                    }
    * {2 T( d. f3 u! ~2 I4 J% G
    + M- p, e. t( K3 h& C            }$ K: A, f( S! v) c

    3 r$ X5 l* e/ v1 L        }4 d+ ^5 m9 p- l/ c7 H& |
        }
    . c# x4 W$ q( J: G3 ~  T}2 I9 v3 q% G: ~( N8 S. L; |* g
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    ( n9 f( Y  ?6 ]6 v' u* ^{
    " \! g) {3 W/ D- ?6 e' _# ^* z    for(int i=0; i<vexNum; i++)) D, V4 a; n5 L) Y
            tag=0;
    8 U" H) |# L8 O, f    queue<int> q;
    ! F4 u/ J- w+ T( q    int tmp,t;: f5 i3 {6 N0 X1 Y5 f* Z) u
        MultiAdjListNetworkArc<WeightType> *p;
    - A0 E. ^5 d" h. y' i( A8 j# e$ K6 P; Y" a    for(int i=0; i<vexNum; i++)
    8 N( @& [& H# @  s. L  Y3 f7 e7 R    {
    9 k8 `0 N& i* D; q/ T        if(tag==0)  W0 Z1 L$ K0 m( M- Q/ S
            {
    5 Y4 ~0 z4 A& E* x1 b: Y% h            tag=1;
    ' t* I7 P0 W; P# i            q.push(i);. G4 l" X, B4 j4 I6 h* i
                cout<<setw(3)<<vexTable.data;
      L$ x  a) A/ e) g& R5 H        }
    $ {, v/ q# }1 ~; W$ e) M: n        while(!q.empty())
    ) g1 P: }) B$ Y4 h$ D; o1 X        {6 J1 C# ?" I; n9 j! w
                tmp=q.front();( }$ ?' x: E: g1 H
                q.pop();
    3 _, U; F6 B+ W( j; z. g' n            p=vexTable[tmp].firstarc;; X* _( f  |5 v* a$ }  H+ }
                while(p!=NULL)
    * V9 i# v* |: F# M% R" ^            {
    6 I4 T0 e) C* m, h                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    ; t/ I1 K7 m$ \. s( o                if(tag[t]==0)
    , M' K7 Z0 I+ z                {
    2 ^/ z. l! ]/ Q, ]+ b, }8 ]                    cout<<setw(3)<<vexTable[t].data;5 w9 U$ m$ Y  o
                        tag[t]=1;
    ; Q  |! C% Y# ~' Q1 R% |                    q.push(t);
    & G2 I# l( Z* [$ T; M9 K                }' V- d- A) P0 @0 \
                    p=NextArc(tmp,p);
    5 T- V: r, ?- _  Q9 }+ y7 {. c3 n            }
    9 B  C$ g# b' v. B0 j: X0 \* t% S        }! |* y$ i9 s3 Q4 c" V' D. Z
        }2 t3 i: z% M4 c' ]) q$ ^& Q: G1 F
    }4 `9 e  ^. c! f/ ]: b# I
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()1 s0 ~# w. o; @5 e0 Y9 o8 ~; A% F3 I
    {( {/ [- A% R% L/ Z: \
        MultiAdjListNetworkArc<WeightType> *p;1 e9 V. J! z+ c* s+ G9 y% [3 V( V
        cout << "无向图有" << vexNum << "个点,分别为:";
    . T* \: N) f  w1 b0 c    for (int i = 0; i < vexNum; i++)4 x' ?3 Z' q' ~0 [2 [
            cout << vexTable.data << " ";5 f0 Y& d- b: Z2 }& \
        cout << endl;
    , f, r. t$ @1 t9 F; k    cout << "无向图有" << arcNum << "条边"<<endl;
    , f. Q9 T7 T1 P! g' y2 V    for (int i = 0; i < vexNum; i++)% [1 J7 x6 D4 l0 Q+ Y8 Q+ R- c
        {
    2 S. J( o6 @, Z' }        cout<<"和" << vexTable.data << "有关的边:";
    0 G( u% {1 k3 z* R7 ~3 u        p = vexTable.firstarc;9 d6 \" T0 x0 n. R
            while (p != NULL)/ F+ x3 |8 L. }% ]' _* R% M& Z
            {+ ~9 |7 F& L4 J5 }. K
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";# I  m' _  k; S! @- H9 V
                p=NextArc(i,p);1 n& ]' u) s' K' x: s% [
            }
    ) f- {5 [5 L1 m1 Q7 }+ D        cout << endl;3 k3 \/ M3 G! L$ C
        }
    & I, e, c( p$ C( ]}# O8 a( w: C1 ]' F

    & J9 d. O3 _$ g" o7 x
    7 A' X) s! t- m邻接多重表与邻接表的对比& i& D# ~8 a( S6 d- H9 M+ Z" i& c4 |
    6 {% h7 Y3 a- L
    邻接表链接' w6 l7 I) z  B- F5 b5 O' i% A! P
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。4 V# i' E+ @9 h: [
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。( E/ m8 B+ {: {. L: n$ F$ p
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。" v% H6 C  T$ r8 x5 i: M
    ————————————————
    6 v. S( {6 e1 R% }) m9 `( [版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ) d. Z" f  v) e: V' ?3 `0 Q原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958% p6 N! k& h# ?9 f4 ^% u$ z

    % j" I& T- J- L! K  Q& J& p, Z3 H  b

    * b* F4 }# ?4 c: q9 c; t' c  M8 G& X1 E5 V8 J/ N0 R. h
    ————————————————* A- B4 M# [% g4 c1 K1 D8 J
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。  {4 Y2 E3 |% ?  M4 x6 T
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    * x9 n' w. A+ [! t6 V7 O! B
    6 A& x; H2 e7 V4 s5 |, Q  D, t8 u0 C3 _1 L. R9 D" |8 b$ R
    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-4-20 14:00 , Processed in 2.921980 second(s), 54 queries .

    回顶部