QQ登录

只需要一步,快速开始

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

    4 G* `6 |+ N; j- A9 T! d图的存储结构——邻接多重表(多重邻接表)的实现4 Y# i* F0 ]$ x" R% n, c
    7.2 图的存储结构
    5 [( q1 |% T1 d  e/ e: s- j+ ^; j: s& s2 y% j# ?* `  U4 }% h3 l; p
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist: \1 v7 B( a1 n+ S
    邻接多重表的类定义  }' ~6 T" a7 W9 S5 k$ A* d, N* c. p2 z
    邻接多重表的顶点结点类模板8 a# y4 T9 V; i0 u
    邻接多重表的边结点类模板
    + \( o: |5 o; m0 L/ o  ]邻接多重表的类模板
    : O/ G4 V9 A0 l/ F邻接多重表与邻接表的对比( C+ y9 M  e* S- J% c% g' P
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    $ q5 l8 l, B& [( E4 L5 B0 n4 C! N/ z9 l5 ]. m
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    ! T0 n  X- S. `$ M0 D! R4 O: d在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。8 Q6 S8 d2 ]$ N, [8 _5 t8 W
    9 F9 s8 d# y% _1 P
    邻接多重表的类定义
    " N' U, t0 ^& X, j& H2 t 1.png 2 O# s& _$ x9 }+ K" W
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    ) l/ L- }1 n& j0 U$ G7 gdata域存储有关顶点的信息;
    2 s! r, Z% `! Q! E3 L6 kfirstarc域是链接指针,指向第一条依附于该顶点的边。3 ^1 b! \( H. X
    所有的顶点结点组成一个顺序表。

    : w# S% _& u- U; {& P/ f6 Y
    9 w% e! h8 \% ?% U
    template <class ElemType ,class WeightType>4 B" A- S; P" w$ s* m# m- h" P* u4 C
    class MultiAdjListNetworkVex: _  Y. C2 L  |% @! k
    {
      C$ _' k- R3 ]' e$ e$ ~5 `6 spublic:
    ) p9 j$ t# q& x" T6 D        ElemType data;% \* O( ?, B% x, `6 |
            MultiAdjListNetworkArc<WeightType> *firstarc;/ l5 V+ r. W9 K% C  `7 q
    ( M1 l1 |* z" a! e8 `
            MultiAdjListNetworkVex()6 h6 D0 d+ z- W2 c
            {
    3 {( H5 B7 S" ^' p5 P) d$ D                firstarc = NULL;/ I7 {5 J* F  E
            }0 {7 \/ g1 F5 g: S# g; P4 C
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)( `  J1 Y4 V: d4 r
            {( S2 s: M6 p; H$ H4 K( ]/ ^( @9 j% y
                    data = val;3 K" R5 ^0 J, r8 u
                    firstarc = adj;7 s1 P" q) X2 @5 x
            }
    - Z1 ~5 L6 g) p$ ^6 X; P};
    . t! }( H; s: s# G+ F+ P! b& v! c9 [2 G# U" G
    邻接多重表的边结点类模板
    0 L  f+ w7 V" p, ?! y: d; ]6 _4 O
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    " w9 z" L9 \# Z& {1 Itag是标记域,标记该边是否被处理或被搜索过;% U! e$ x7 R4 m3 H6 e6 u
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;9 q+ o# d$ b1 u2 V
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;1 x& l+ @1 o% }* H- B
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。; v& F1 R7 h; P0 g: p" |

    % w# m5 V) t& Z7 F8 Y: G 2.png : f* V- T6 ]0 I
    template <class WeightType>* N' o0 I; E; y  v6 w' B- v
    class MultiAdjListNetworkArc+ ]: W) l% x5 L  f1 F
    {
    4 K- C  I) ~1 s+ B: R, P, ^% S) Dpublic:& y! {4 w1 p4 y
        int mark;                                       //标记该边是否被搜索或处理过
    8 F* c0 {8 e3 s& n0 r& b0 ?. A        WeightType weight;                              //边的权重2 l" h4 Y1 S' O+ W
            int adjVex1;                                    //边的一个顶点
    ) Q9 J4 O6 l+ [        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    1 w* D/ U: Y! p' h& F2 b0 G4 I        int adjVex2;
    2 O$ ^7 R$ X" l5 g9 A        MultiAdjListNetworkArc<WeightType>* nextarc2;
    ! e- P2 [; M2 ~* E% n. `0 B" r3 w2 c! X; Y+ ]
            MultiAdjListNetworkArc()
    : h* ^5 y2 A0 a2 m2 x% B        {" x. j* d4 a% Q/ ]& F. d
                    adjVex1= -1;- ~- i6 L, t$ t7 Y/ ]* Z. D  u/ E" b+ q
                    adjVex2= -1;5 n# x& j) g/ K. j( {" j1 }5 N
            }. K& X! }( j, h4 z1 r; M5 G; d8 q
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)5 ^% c2 t3 _$ ?, a" f% T  u1 T
            {8 X' e$ E9 c. E+ t
                    adjVex1 = v1;       adjVex2 = v2;
    8 W8 L" b- Q5 L. N/ F# x$ W                weight = w;" u( Z) V1 j. }
                    nextarc1 = next1;   nextarc2=next2;5 G1 D* b! L" q$ _% f
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    : P& O$ O& F* ?( x* B" {        }, P; V( p3 D% F# H  K9 h* H

    0 z( {" T" y! n8 R0 {7 E邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    - {+ _( G5 y4 z4 Q! W/ ], s" `  bclass MultiAdjListNetwork
    5 a. E2 M) l+ p% ?/ O{  m' \7 N4 \) y4 e: A
    protected:: F! t& c7 J1 D: t6 T8 C' R
        int vexNum, vexMaxNum, arcNum;
    ' e/ y6 k4 A7 g, }# t    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;# Z- e4 X1 C0 o3 N' h3 V0 I) H
        int* tag;8 Z. q: j+ F, P/ w  s8 Q
        WeightType infinity;
    : j1 A) b3 R. m4 [* N' @
    5 t8 j8 [# P; Z8 ^6 Tpublic:
    # @/ n" v+ M4 o" h5 k    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);. r6 m1 Z: |3 S9 @

    + _0 v2 O: ?1 d" A& M    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);( d: K3 ?% S3 Q* k0 \

    ; e2 \" v" @9 Z3 r/ y  J. x    void Clear();9 X: |7 v; {5 W( K9 f: y$ J
        bool IsEmpty()
    ! D0 A: v2 ?" N: A4 r    {
    4 v: O, D3 J( b+ X1 V) y        return vexNum == 0;
    : q0 n/ v' L+ C. Q  {' h    }
    * F; e( Q. J1 E( L1 m2 t    int GetArcNum()const& Q0 h  ~" @! c. v
        {  L% T( _2 X; ]/ ?( U1 ]* h
            return arcNum;
    9 w" ^( Q5 G. G2 r    }# m; w, o+ R+ M6 b) x* n: `
        int GetvexNum()const
    & ~2 P6 Y" g. Y7 f% p' B    {
    6 E+ n7 }1 H) w  C! [2 Q3 f) x        return vexNum;
    ( S  S# w# z" ?  g    }: ~0 [0 Y# @- v/ F0 E3 C

    # X1 y4 T- ~# L# f- G) p; _+ M. }( R% Q0 G
        int FirstAdjVex(int v)const;
    : ?! [. U$ b& N2 u+ H# ~    int NextAdjVex(int v1, int v2)const;+ d. N& Y9 p/ l  Y" J# o
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;6 r/ Z  u1 o+ T8 y+ }
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    9 Y+ `  g' c: i$ D* ^! l! f! w: G# B1 C, x- n3 F
        void InsertVex(const ElemType& d);2 \# l+ J% N1 r/ ]5 A# E2 O9 n
        void InsertArc(int v1, int v2, WeightType w);' W' j- y; `) ?: [4 z. ?' C* R

    2 c4 d8 A/ S; y" I2 t# X: B    void DeleteVex(const ElemType& d);
    7 Y: l+ t0 {! N4 l" g7 C    void DeleteArc(int v1, int v2);
    ! r) h4 B% B0 W% O: o/ A5 u, C6 b. D! o5 V7 A9 ^# z
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);- ?- a. O$ X, P2 l' I
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);$ a1 K, O1 o8 {3 c
    + V. Q! m- D+ p% z8 m% v
        ///深度优先遍历  u7 h* h* @, P7 c3 R
        void DFS1(const int v);/ l: Y, j  h) f/ M; i% U5 Q4 f
        void DFS1Traverse();
    ' M8 [/ t) D8 e& G$ k    void DFS2();
    & Q; m  Z- F* v  [
    4 l& i* w9 C. @4 @' y5 X2 \7 B    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1! V7 D' T7 M: a; D4 F6 @/ I
        void DFS3();
    7 @2 ]1 b& J$ t3 T3 Y/ L
    ( s1 R6 B" @$ V, X5 i* f    void BFS();
    6 N) y! [' z  s; n( i    void Show();
    . n# r' g6 [4 d) A6 `9 Z};
    ( B8 t# h' |8 {0 Z4 N- M( b
    7 f+ V" N( C: a* K& K2.函数的实现0 K% Z8 M; }/ N$ z1 E* ?
    研讨题,能够运行,但是代码不一定是最优的。
    $ l6 `3 o0 F' p9 E- t3 e: l' c& ?) z( X$ z% R
    #include <stack>, g8 g2 t) X2 c- a* v
    #include <queue>) F, d& |) l2 f7 W

    $ L1 r( u. \, i/ I* O$ y! E; }template <class ElemType,class WeightType>
    % h; ]4 J. U0 RMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)7 o% d, q0 b; u% N" h/ b" p, J! n
    {5 O3 Q; ]( M* x2 Y) j8 r" k5 s2 v: d
        if(vertexMaxNum < 0)/ V7 c, q/ Y9 ]/ B
            throw Error("允许的顶点最大数目不能为负!");
    $ j% i1 h8 h* V% E    if (vertexMaxNum < vertexNum)5 o( j) P# `; `/ H2 R
            throw Error("顶点数目不能大于允许的顶点最大数目!");
    % v7 G- a' J. {" P- F    vexNum = vertexNum;: q' Z* o% i+ }- t4 k/ H
        vexMaxNum = vertexMaxNum;, X0 _2 r9 I, V4 e" c8 t
        arcNum = 0;$ O/ {* l  F  i' m. m' E
        infinity = infinit;
    3 v4 w- w0 j2 F( @' e    tag = new int[vexMaxNum];
    % N$ h/ Q4 O: ]9 h    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    ) y" S) b2 z: e% h! ]    for (int v = 0; v < vexNum; v++)
    & d; ~$ n& A8 m; T2 ?1 R, u. [9 p    {
    3 g/ e; Q( h$ S* ]/ h$ J        tag[v] = 0;
    1 B7 _$ _  |, P7 }3 m        vexTable[v].data = es[v];
    8 N- Q! w( X% a1 Y        vexTable[v].firstarc = NULL;$ @' L  ~8 b7 ~1 _
        }+ Y( ]* {/ l1 o0 \+ m$ u0 o* I
    }
    ' @4 ]  M7 L; [- ?# atemplate <class ElemType,class WeightType>1 u. }. R6 G$ @  C4 j
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)! I' D( W2 |( g  r* E1 E
    {
    1 F: N, q: t9 [& R5 O" ]( R    if (vertexMaxNum < 0)
    9 a! Y5 |5 {6 e" `+ a' r: U. R' c9 N0 K        throw Error("允许的顶点最大数目不能为负!");
    0 G( V* S5 I" o  p: `: z4 T    vexNum = 0;
    ' ?3 U! ^" C. l0 {6 [! g5 V    vexMaxNum = vertexMaxNum;7 m0 |# J! J" e: p
        arcNum = 0;2 s8 n! a' u' u0 h$ j5 A& ?
        infinity = infinit;
    & n; G+ q' L% D7 c8 w    tag = new int[vexMaxNum];
    3 l  ?4 G. u1 x2 i) i% o8 w5 `    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    5 A9 i/ E5 V5 K$ d' b}
    9 \/ U( Z7 j! v% @template<class ElemType, class WeightType>
      E( J" k$ G8 K8 N$ J( f  Jint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const+ v5 `. R! W+ j$ j: j
    {
    ' a' S! D2 v! \+ R( J8 |5 G: [/ r0 k    if (v < 0 || v >= vexNum)* p5 A0 a* ?: \
            throw Error("v不合法!");2 H& N; o. y! z& [  c$ E
        if (vexTable[v].firstarc == NULL)
    ( I9 p$ ^/ ^5 _) v% x+ ]) H        return -1;) m" L! l; E( L/ I
        else
    # U& X, ~; \4 b1 e        return vexTable[v].firstarc->adjVex1;
    ; v6 T, I3 W2 P) F1 [; _}
    % \/ l4 a# k3 v( f! `% S3 C4 r* ^
    9 s( b4 m8 ^+ |! Rtemplate<class ElemType, class WeightType>
    6 M* l+ f  P9 B, d# |% ]9 T% {% Nint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    & t/ F4 |0 q1 h4 o) L3 m{
    ! c; s# q( g% |7 j: R    MultiAdjListNetworkArc<WeightType>* p;
    + Q3 j2 E- J* _" }4 a    if (v1 < 0 || v1 >= vexNum)
    # r  G! D7 ^# A# p: f" \1 Q+ y, v        throw Error("v1不合法!");+ ?! \6 x0 X, x  V# G  H' R( F5 k
        if (v2 < 0 || v2 >= vexNum)/ A6 l- |4 _2 x$ F
            throw Error("v2不合法!");( e: m' A& d2 r3 q, E4 @: Y. H8 K
        if (v1 == v2)' o5 N6 f/ X) q6 W/ }0 h( X
            throw Error("v1不能等于v2!");
    ' S0 }. e9 R$ v  Z    p = vexTable[v1].firstarc;
    - A: D6 w9 m  @' g    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    ) h8 L+ \: A% \  P% z+ \7 V        p = p->nextarc;
    . U( _" @. o2 J9 U" Z) y. z5 Q    if (p == NULL || p->nextarc == NULL)
    8 G4 g& `: w+ I$ [        return -1;  //不存在下一个邻接点
    9 K4 B3 ]1 y5 D& U, I" T% t    else if(p->adjVex1==v2)
    * j  ~4 I* N  C: Z) N% y+ v4 s2 T; \        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);9 Z7 R9 B4 M% m0 |, I
        else, D2 T0 O- k  L, k( ?
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    # E+ b, O8 i4 x, c1 q$ _, x+ M}/ T# d( U, g5 U, O, s
    template<class ElemType, class WeightType>% ^. y' r" B5 {! k
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()
    1 N$ c1 T$ g5 j- V$ ]( ~9 x{+ w& J" f$ U& \( A; P
        if (IsEmpty()) return;
    3 s' V# h( u- ?, T4 w3 [    int n = vexNum;. N8 r$ K9 h! i7 z
        for (int u = 0; u < n ; u++)# ^6 x1 X- c% ?2 i& K
            DeleteVex(vexTable[0].data);
    + h" K2 P  ~  j    return;
    ! U+ ~) @7 t3 b4 W}+ }2 Q! x$ {* _2 z: L2 z8 E8 T
    template<class ElemType, class WeightType>
    " w( a1 }& H0 d8 |- PMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()1 B1 z0 z' _% L- z; j
    {
    3 {- Y" M1 f% s  o. P/ k& t    Clear();
    - i2 u  z% Y; b, @* A9 [: @1 d}
    . L3 t% ]1 G% s) T; y7 l1 S  v# ttemplate<class ElemType, class WeightType>
    , I8 U; l0 U# M8 t" e# FMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    ! T0 s# {! D/ b/ K{6 o( O) c; L$ ^
        vexMaxNum = copy.vexMaxNum;
    7 N5 A" |6 [" {+ a1 O5 w8 {    vexNum = copy.vexNum;( ?1 Z$ p/ N9 F6 ^- K4 z
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];" L3 a$ T4 m2 i" \
        arcNum = 0;
    3 h6 E  V+ j4 T% |6 E( b    infinity = copy.infinity;; t* D& i. M) X9 L2 ^0 D, {1 ]2 \6 V$ ?
        tag = new int[vexMaxNum];
    % Z' p6 N9 T7 Q" T' L% s& `3 z# \7 G  H2 @. Z; H0 O
        for (int v = 0; v < vexNum; v++)
    ) [9 ?  p( i6 a$ y& C# G- i    {
    # H" [1 S0 ^) N' [7 r; Z$ X        tag[v] = 0;
    - A4 p9 A: E0 a; Y        vexTable[v].data = copy.vexTable[v].data;& o1 W5 K: X% s- X
            vexTable[v].firstarc = NULL;& E4 Y! V( W  Z7 c, x% \
        }
    ; S) w3 W) p# l    MultiAdjListNetworkArc<WeightType>* p;  P0 y3 ~3 o, }7 T4 ^" U
    4 D; e4 _- U- y8 j/ B7 X. p( y9 @
        for (int u = 0; u < vexNum; u++)4 ]) x$ o% v8 S0 {$ T5 N
        {9 j; \1 H0 n" o+ y
            p = copy.vexTable.firstarc;
    : B& K" o  T; R% P* E* R2 ?# K1 z1 n! ]        while (p != NULL)% A  O8 O* U) N6 k# z5 E
            {
    $ O2 e: i1 _: f7 j) n/ R  C            InsertArc(p->adjVex1, p->adjVex2, p->weight);; g, ]+ V) \9 E, W
                p=NextArc(u,p);  ^2 {# o- A/ R: Y- f
            }% E  f# u5 p9 J0 v* C7 j
        }
    $ v" l' r0 t! y- z. H}! m  {9 A: H# ^, f" w' C  {$ a
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&' q' M; h' @" _) l! f' a
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    5 m7 l1 E$ {; h{$ n/ x, Q8 j9 b. I
        if (this == &copy) return *this;+ b* R1 Y% A+ y
        Clear();' {% c( v! C/ w( Y
        vexMaxNum = copy.vexMaxNum;$ V* w( u+ Q) ~- V7 ?/ c, @
        vexNum = copy.vexNum;8 y  {+ D. D8 Z5 p
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];" c( T" ]1 X: w0 _/ D! {9 N
        arcNum = 0;! o' a4 s3 f% b) P
        infinity = copy.infinity;$ Y* Y7 v* x# [/ p* t& }
        tag = new int[vexMaxNum];1 r  H7 v7 d# ]" b1 e0 i2 B; |% S% Z

    7 u& y5 a9 D+ Q2 k% Y* F5 g4 D    for (int v = 0; v < vexNum; v++)8 n' h7 M- e  L# X  T* S2 J0 X
        {
    3 a( X* x8 H4 P$ q8 P5 Z        tag[v] = 0;6 s5 v# W# S! u2 e" o" y4 v+ f
            vexTable[v].data = copy.vexTable[v].data;
    ; e3 k# r# |' Z+ o5 Y        vexTable[v].firstarc = NULL;% M% l! g; Q' r5 U2 d
        }
    1 B  I' k5 Q: P9 |, d8 M: Y    MultiAdjListNetworkArc<WeightType>* p;
    # h  v) a# r' a8 u; J/ w
    ' V4 Q2 p  j3 b  t    for (int u = 0; u < vexNum; u++)) X& z7 Z" j% \# [
        {
    1 ]! F: ?: e; J+ d! g: u$ }        p = copy.vexTable.firstarc;$ h2 I1 E3 S9 M! }3 Z& E2 h
            while (p != NULL)
    3 i6 N9 b8 y4 O) I) M+ H8 D        {9 s; w2 t' i$ `5 J9 H
                InsertArc(p->adjVex1, p->adjVex2, p->weight);, b  I; z! ]( q  ~( r7 d2 Y+ L
                p=NextArc(u,p);
    " G; h3 o/ e  ]$ R4 S  [! O        }- d1 {' _+ h' @5 |
        }
    3 d" t+ N. g! ]1 A9 Y! B6 X    return *this;
    1 s/ C  n9 T0 V' e- K}
    7 W  a! }! {' R6 v2 l. ytemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*/ H; m. c% e# `; m" ?* v4 I8 b
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const/ _9 X" H/ w' g: s9 b" D
    {
    / N9 N2 Z$ t4 _9 R  L- u, k    if(p==NULL) return NULL;- a7 \! ~' h, ]6 `+ V9 [! g
        if(p->adjVex1==v1)
    4 i) |" h) A2 R, J8 u# B        return p->nextarc1;# Y! R; W- B, V, E' k0 H  _
        else
    + N: r1 I6 l8 V7 q/ a        return p->nextarc2;
    ; K. I  w4 D1 [2 p, Z4 g' ?}
    : z( k5 H2 Z# b/ w" d& w& F  Ttemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    + X3 m+ Z% `& l/ @" F8 J3 lMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    5 q, |2 ]8 Z  _6 R4 R{
    ' A* B  H& ]/ p    if(p==NULL)return NULL;
    1 |2 H; q, {- f0 ?3 S- ~1 i, Y! R    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    1 ]$ u/ P9 n3 ?, ]4 I: z$ w' y2 ]    if(q==p)
    4 L' J1 V: @# P/ P/ x0 r# K        return NULL;6 Q0 [" }! d3 H* f) D9 M" h
        while(q)
    ; n2 E4 b: _9 _6 m    {3 y7 Y+ C# U  ^4 h8 g
            if(q->nextarc1==p ||q->nextarc2==p)
    ( P, \8 l: n) s! A( V/ w( f            break;6 z- n1 h1 [! J. B- i+ [
            q=NextArc(v1,q);
    * r3 k6 J( F! s2 e$ w    }+ [2 O. Y& F5 z1 {
        return q;
    9 I& k1 @$ k3 X4 f2 V, I6 z+ K; N}
    ' m# Y7 W6 R8 f1 i' j3 Jtemplate<class ElemType, class WeightType>
    0 K# w) n4 k/ O& qvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    " p$ D$ j( \5 r9 ?- X{8 T2 [2 q) q" o/ B. ]) i
        if (vexNum == vexMaxNum)
    7 t# \1 e6 w! {, U( T. C: }        throw Error("图的顶点数不能超过允许的最大数!");! N4 ?! o% h  }3 |
        vexTable[vexNum].data = d;. y& h9 Z4 T( O' F+ j) m
        vexTable[vexNum].firstarc = NULL;
    + ^2 F8 R0 Y7 ^+ k8 u8 J+ u! j    tag[vexNum] = 0;6 s3 f& s( C7 p
        vexNum++;7 F/ y7 i" B: H+ U1 i; B% r
    }' ~1 t8 A6 A$ n6 J  \' y
    template<class ElemType, class WeightType>
    , U. G; O9 n& N( i) X2 a. Yvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    5 `- d1 }5 J7 r) S2 [$ C# Z{' U& V- H! m' Y
        MultiAdjListNetworkArc<WeightType>* p,*q;
    + _5 D; X7 f: b0 [3 L    if (v1 < 0 || v1 >= vexNum)
    . F  A. c" `8 [  G6 U$ b6 K        throw Error("v1不合法!");
    ' V8 [  W* V/ F1 z6 L9 p    if (v2 < 0 || v2 >= vexNum)
    ; p# C9 B8 E6 d$ m* Z, ]        throw Error("v2不合法!");
    ; C) `4 |/ p" M8 G8 W  v8 L    if (v1 == v2)1 ?* {  S: N+ b; E& }
            throw Error("v1不能等于v2!");
    ( O. ~# S4 k6 d- `+ y0 [    if (w == infinity)- h; z% ~" B& E) J( d4 \# |
            throw Error("w不能为无穷大!");
    # B4 y7 J  X% V# A9 [8 |5 Z; |5 O; V  b

    - L% l5 c2 R+ @8 Y$ F/ g5 t    p = vexTable[v1].firstarc;, _) `+ |8 V1 ^
        while(p)
    . C9 O7 R+ n' V2 N4 q    {
      S5 x+ Z1 w8 h: q4 Q6 _5 j0 k7 Z( ]5 A        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    " [, P/ P1 p5 T( x7 S        {
    ' ^1 a0 y7 @# u/ w            if(p->weight!=w)% K1 U8 w0 E% N+ j3 c
                    p->weight=w;
    3 C5 r5 D/ w/ [            return;  I5 {  W  C3 @8 @, o
            }
    0 @6 q3 r$ }  S& i: K0 q7 N( p* ?) R- R9 k  C& N
            p=NextArc(v1,p);/ w: r5 ]/ ?7 |8 D
        }
    ( r% W! ~5 U+ z1 r# D1 H0 J( y    p = vexTable[v1].firstarc;) j5 k7 Z! e# y1 B: l
        q = vexTable[v2].firstarc;
    6 b( m  G7 W: P, C" S8 u    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    . o4 L  o0 Y5 z8 `3 C# X7 y6 I    vexTable[v2].firstarc =vexTable[v1].firstarc;  `! @4 K7 K' I1 S& r0 ]
        arcNum++;$ L1 I) P9 H0 h' E" g; h( ]
    }
    7 \2 V! v) @0 C' p4 ~! W: v* q8 i* |  `& `3 H$ L, q
    template<class ElemType, class WeightType>6 J9 X1 E  S2 |% B! d: z( i
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)- ]% o2 q# y( U. m) t3 d3 h0 I' o
    {
    5 X/ ~6 P, y) `& }6 T$ k4 W
    * s/ k( t; {& Q( L    MultiAdjListNetworkArc<WeightType>* p, * q,*r;9 P1 k% t* G+ r) [, ]
        if (v1 < 0 || v1 >= vexNum)
    1 ^7 a) ?9 y8 y: ?3 @5 X! O        throw Error("v1不合法!");$ O* S/ W8 l: V' {/ c* h% h
        if (v2 < 0 || v2 >= vexNum)1 A* u& l% D' s. x
            throw Error("v2不合法!");
    7 R, G7 L( _5 v% W! G6 ^    if (v1 == v2)+ }3 _' J2 {7 e0 z$ ~. ~9 D+ u& t- A
            throw Error("v1不能等于v2!");1 Q0 d) ?- s+ F# S3 w

    ' [( }' K& `7 H" o  R: \  r8 r( \    p = vexTable[v1].firstarc;, H9 b4 g7 M$ R4 t$ i' `
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)0 k0 y$ o1 a; v. [
        {
    ( a+ x4 b6 D5 W6 y        q = p;
    ' k8 s: m4 f1 J6 }% n$ g        p = NextArc(v1,p);
    3 i9 |9 `% G0 a" w& a/ o- O    }//找到要删除的边结点p及其前一结点q4 t, F/ R5 s# a2 I

    1 j. T6 t& N8 {# v2 A0 \    if (p != NULL)//找到v1-v2的边
    + Y: [% \. n, {    {6 O: e1 j, j5 a8 H/ H) [) N3 \
            r=LastArc(v2,p);
    : B& c" {6 W. h% ^' ^9 P        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL. Z0 v' g$ t/ e1 ~& f8 P4 A
                if(p->adjVex2==v2)
    2 x  m0 p( P/ }  ?% m/ G4 g                vexTable[v1].firstarc = p->nextarc1;
    ' y9 D! q3 i& x% D: A            else vexTable[v1].firstarc=p->nextarc2;* Z5 C6 ?. K1 v+ z* a3 J$ B. c1 d
            else//不是第一条边+ v2 j0 q2 w8 C9 e
            {
    5 ]* U4 f2 l9 S4 P; u$ @0 h            if(q->adjVex1==v1)4 g( v/ I3 i( E4 p6 q' v
                    q->nextarc1 = NextArc(v1,p);
    ) V# L+ y/ M9 ]' E' N            else7 U( d8 B5 X& W8 W; }
                    q->nextarc2=NextArc(v1,p);6 g9 V( {* t4 U. w

    ) J$ e& U, `; o# p% A/ t, P        }( z0 U( ]% A) m3 u# D
            if(r==NULL)# a2 o9 m" ~1 p" @) W& s/ f* f
                if(p->adjVex2==v2)
    " ^8 _2 M, U' }6 i3 T                vexTable[v2].firstarc = p->nextarc2;  t+ f) x  r* t$ k9 O
                else vexTable[v2].firstarc=p->nextarc1;/ a: `: k8 ^. [% K
            else" Z, q- [) u9 ~5 P  e" E8 y
            {
    4 f" i5 a4 ]* o: P: P            if(r->adjVex2==v2)
    % G9 N+ R; i* b8 I) J( H6 G- i                r->nextarc2 = NextArc(v2,p);0 G7 V& e6 I1 ~; A; o% W
                else% M) ~6 f3 e( j3 w7 e7 ?  ~( V" p
                    r->nextarc1=NextArc(v2,p);
    ; e$ f+ D% C% V        }
    6 [1 }- r( {) }* y6 g) D. U1 p        delete p;
      \" x* [/ [' \" J7 y        arcNum--;8 _  n& [1 f0 ?9 g6 s
        }2 h: F3 c: E# h  u( Z
    7 ^& ]$ c. k1 k' I. p
    }: L9 N0 J- R' L
    template<class ElemType, class WeightType> void
    ) P- ~5 k2 j3 {6 Z% _1 n( iMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)# w! s+ z  L( V6 X& ?0 Y. c2 x
    {& |0 q) c( F" h8 @/ J
        int v;1 @# f6 ^" U" W
        MultiAdjListNetworkArc<WeightType>* p;" F4 L4 u/ E! O1 ~2 |- ?0 ]
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    $ H. g! x  ]+ C( e; M( T6 F        if (vexTable[v].data == d)) j( r+ H* ?  |( r* v/ }' X
                break;: |" m; d7 c5 J: g' q" o
        if(v==vexNum)0 C4 o2 H9 `, T* A; t$ G. o, Z9 E% l
            throw Error("图中不存在要删除的顶点!");
    $ [0 Q; L% v7 o& N! ^0 H
    3 z( w* P( w) j2 T  {    for (int u = 0; u < vexNum; u++)//删除与d相连的边
    3 H) ^3 W4 \3 S& H+ q. E        if (u != v)" k7 ~: `6 v* n! M/ i( O2 V+ ]$ {
            {' [9 L" c2 ~( ]% j0 P4 W
                DeleteArc(u, v);
    6 Z9 N( T1 }. g$ M* N        }
    % e1 E" B( o' ^% o7 w9 ~    vexTable[v].firstarc=NULL;; G- A4 m/ n- t

    * t' J/ l  X8 [; L) N    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置: w( P4 s  e7 ]: i) @
        vexTable[v].data = vexTable[vexNum].data;
    2 K- k9 ~$ N' w2 y# i0 B/ r    vexTable[v].firstarc = vexTable[vexNum].firstarc;& x  z: W( g9 J$ Y5 ~1 n# v
        vexTable[vexNum].firstarc = NULL;
    ! g5 P$ r" ~: i2 ~( [! z$ e    tag[v] = tag[vexNum];
    ' i* P2 k( X- g6 f    //原来与最后一个顶点相连的边改为与v相连9 b& ]: {4 u9 A. |5 s% f; W8 k
        for (int u = 0; u < vexNum; u++)
    1 C% t- w+ b+ I8 U6 P: {9 s2 i    {9 f* b: Q6 [2 e0 F4 ]- H4 \
            if (u != v)4 @* K2 m! j8 I; i8 x( N; d% M) Y
            {* O) _5 q- X3 P3 r- [: x2 q
                p = vexTable.firstarc;( j8 m( B. c, r( e
                while (p)
    & v7 y$ A0 `6 J  |3 c$ U; u            {
    0 v6 y% B2 E3 d$ q4 i: H& a* r                if (p->adjVex1==vexNum)$ [% r# x7 S2 M" R, V) ~
                        p->adjVex1= v;1 k. \+ x& p/ d6 X& J/ H
                    else if(p->adjVex2==vexNum)
    0 ^6 P+ U9 }4 H3 ^1 g( e0 P# \" h                    p->adjVex2=v;. m6 N" J" [* N/ N
                    p = NextArc(u,p);' j' {9 N3 ~0 _; e9 P  P( T0 T
                }
    ) ]& o* D5 n$ }  Q+ s; ~        }" y( S& z. c" U* o2 K
        }3 }$ F+ C0 }/ ~
    }
    / n6 q" ]6 G1 S) n. q; ^8 m) D///深度优先遍历
    / d5 r" p7 q$ Wtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v): r$ F* r- m2 ?0 Z
    {2 {9 d: w& n. K/ c( G6 A# F% V
        tag[v]=1;
    " j( T0 {! K7 |0 o3 _, v" O    cout<<setw(3)<<vexTable[v].data;  v  W  D" ^! \
        MultiAdjListNetworkArc<WeightType> *p;) y2 G& `* T3 J- s' R3 f# \
        p=vexTable[v].firstarc;- I" {" G( B: ]7 h5 j2 N
        while(p)
    * A  v' U% e2 r4 _. u" x# e3 H& V    {: U9 U4 l" a+ P  x: Q
            if(tag[p->adjVex1]==0), ]4 F2 c, ^/ P- Y
                DFS1(p->adjVex1);4 G  I7 _# b# @  q4 O) S! K# a3 {* M
            else if(tag[p->adjVex2]==0)9 V4 M* Z; [3 W$ B' \8 ]
                DFS1(p->adjVex2);
    $ q, N! f  Z: f7 @  j        p=NextArc(v,p);1 K* ^4 a! X( R' T0 I9 F' X0 S5 o
        }
    * h" L; a0 J7 p" ~- \# b}# l  w# n# g7 M% B
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    7 l% O  g0 c* `% @{. ~8 |; r/ c3 e' n
        for(int i=0; i<vexNum; i++)
    ( ~* j9 T- k  m. Y        tag=0;
    - b! L7 }: W' G  U+ L! P4 ]) W  z' M    for(int v=0; v<vexNum; v++)
    . l* s- Y9 F2 G/ X3 A    {5 E% `5 Z+ q/ s9 W+ \( L
            if(tag[v]==0)0 k+ `4 Z9 z! ~- E
                DFS1(v);
    ) V/ l5 N( {1 w$ _. O) L6 o2 r    }
    % L+ t. P& ~9 P! E% n# b! {6 N4 j}
    : V' N, h& r0 b3 M4 B9 _template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()& ^9 L5 r5 L! H! z8 [7 `
    {/ N, c. Y3 k" O; x& ~6 i5 J
        stack<int> s;
    : a+ `' X6 J1 L+ U) u5 W    int tmp;
    4 O5 Y  v7 C* }/ l( h+ s, u    MultiAdjListNetworkArc<WeightType> *p,*q;
    ( \# q/ B1 b$ r1 C( Z% Z- n) V! @    for(int i=0; i<vexNum; i++)4 [8 e! X% J) V* B3 U# n
            tag=0;" L6 m1 z2 K# e7 w6 O) U: T
        for(int i=0; i<vexNum; i++)
    2 K" o' W, `% \9 E6 ]    {
    ! m4 Z( I1 Q) N: i% D/ [; P        tmp=i;0 p; x$ b# F* M5 Z  O! E
            while(tag[tmp]==0||!s.empty())" ]8 x1 V" p4 a3 j/ t, S4 f2 Q, X
            {4 l1 ^$ S4 z( u8 h5 ^" |5 K2 e
                p=vexTable[tmp].firstarc;
    9 q" g9 J8 X9 |$ R# x            while(tag[tmp]==0)7 z$ d$ ?$ d; N8 b
                {1 e" k5 D$ `6 \/ o# O
                    s.push(tmp);
    " s" t3 [! r0 h3 e                cout<<setw(3)<<vexTable[tmp].data;
    7 ~+ L7 f( n4 {                tag[tmp]=1;
    , R+ e5 n' A, k' s, r1 D                p=vexTable[tmp].firstarc;3 ]4 I1 S* I% F1 C6 f+ o. C
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    1 V) w# k2 d* P7 d& w5 B$ Y                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);) i) X* d: ?/ x& J* U: K& R
                    //cout<<" 1st     tmp="<<tmp<<endl;9 w% ~# q2 N2 R
                }
    1 c( o1 V+ O$ y$ x/ e2 L' O            if(!s.empty()), R0 i4 x8 n( j
                {0 L0 e7 {7 t6 V6 u
                    tmp=s.top();
    % n5 @; B' u3 v  W( X, v                s.pop();8 f1 P' O$ }+ J3 Q5 m- {5 _
                    q=vexTable[tmp].firstarc;
    ; M8 T( ^, C! U: l5 ^- u                int t=tmp;0 [" k0 v% t$ u6 F
                    while(q&&tag[tmp]!=0)
    / E: U9 Q! C( _                {
    4 A0 u2 g6 V  T# X                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    8 a: Y9 N( I# c7 j3 g; Z                    //cout<<" 2nd     tmp="<<tmp<<endl;8 }- B, u: {1 p
                        q=NextArc(t,q);# q" ^/ e' R9 \
                    }# w' U) C6 g* W) X3 {
                    if(tag[tmp]==0)
    $ d  C3 n0 x  _) h) v. l                    s.push(t);
    1 o2 f7 O& y* l6 T/ L  Z) I                ///1、对应上面连通分支只有1个点的情况9 Z) E# g. c1 f( a) S$ `
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈- K) ?; S, p* h  c% E3 H8 J8 p$ g
                    ///tmp要么等于找到的第一个未访问节点,
    # ]. q5 r( L1 m$ t* g$ \# y                ///要么等于与t相连最后一个点(已被访问过)" ~- W3 j+ \: F4 n. L
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    9 a' k  t2 P6 C: y, C3 _            }
    $ v) E! P+ J# ]' J3 X" G6 z" y! h        }3 l  O6 b" e* y! ?
        }
    8 E0 G$ w4 p  y! s}! n2 v# v7 N" P
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-11 H# _3 J/ p0 L7 H1 x3 D
    template<class ElemType, class WeightType> int
    - A$ |& e5 f+ C, x5 |, Y( mMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    1 V. Y' \4 {- N9 G& y/ F2 E* a{- _( _+ A, W* ^1 T! ?) r+ l7 _3 S
        if(head==pre)
    1 ~! V1 X/ M' u/ |        return -1;( b, o8 u& L5 W( ]4 x

    / ~# i* A5 v- ^    MultiAdjListNetworkArc<WeightType> *p;
    / E7 L0 L6 M5 Y6 y+ {    p=vexTable[head].firstarc;& `( }5 x  h2 M8 f# q
        if(pre==-1&&p!=NULL)- E2 z" L* b! j8 L8 s3 P! S
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    2 s* B! b8 W' g, h/ j, ?    //pre!=-1&&p!=NULL1 I! g8 T) x, j! V
        while(p!=NULL): l" n/ c2 M' n
        {
    6 k% ^# ~. d7 p$ [        if(p->adjVex1==head && p->adjVex2!=pre)
    . ^; G/ U* u7 X, A$ w1 I3 u            p=p->nextarc1;7 x1 s' m: ^! }1 L. r; n- Z
            else if(p->adjVex2==head && p->adjVex1!=pre)
    ) m/ W6 L, j. e3 Y& B            p=p->nextarc2;1 ^' n- A& G2 p8 Y9 @* ?# M  K; \
            else if(p->adjVex1==head && p->adjVex2==pre)) T' S) }5 M, y& V3 \7 x8 {7 x
            {& A0 M. H: u- j8 }2 T- X% _
                p=p->nextarc1;' Q  x  t' R% F# I9 q# B8 ?+ c
                break;4 i" `2 z/ ^. X1 j2 ^6 s
            }& T) M/ ]8 @; }, D; V3 C: X7 g
            else if(p->adjVex2==head && p->adjVex1==pre); h/ L* z# m' L3 k
            {
    , v$ A4 {2 S3 P. O            p=p->nextarc2;0 _. p0 B5 z; D4 H
                break;% L) \4 F" G; g. R6 j( E
            }
    5 j* B8 B3 K& e. J    }
    ( Y- h# ~2 z  ^9 i  V    if(p!=NULL)
    7 J! c0 n  M) C/ @1 ?% ~    {
    4 n* B5 C6 T2 K" t' h        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    * q2 I: R" F7 N! H4 \8 f+ q( \    }% }& f+ p7 }2 z/ v, K# \
        else
    " g* ~" U- T9 w- Z& d        return -1;9 S5 j  E2 }: b4 f9 O  I, [: T* J
    }' i! M8 A* {2 r4 R6 L

    # @. r1 ?: {7 O/ @( K/ O) H2 w, {3 c/ q" q6 h( i
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    2 ]8 w+ {' X% @1 C9 R8 G{
    - D& _) M3 h$ {! I( L; t1 i/ k    stack<int> s;
    ! p* X6 t+ Q7 \0 u% \' F) c; I    int p,cur,pre;
    & F7 f' r' j( x5 ~) j4 ?' K+ y    //MultiAdjListNetworkArc<WeightType> *p,*q;
    7 a+ A3 s3 o2 @; w    for(int i=0; i<vexNum; i++) tag=0;//初始化2 s, \, `6 y8 D; Z7 i2 j0 V
    " A9 b' h; A) F3 |1 h/ m* x
        for(int i=0; i<vexNum; i++)
    . a8 @" e) ^) b' \' J) B( V    {5 B# r2 l4 i$ K; k( H6 E5 c
            cur=i;pre=-1;+ Z0 Z4 W& w+ p' Q& _! s* P' v
            while(tag[cur]==0||!s.empty())/ ]! U8 f: q5 K1 J3 M
            {. w+ {$ H& u$ A
                while(tag[cur]==0)
    ) L. m$ A) t7 {# m; L$ c2 e            {, O: K- P2 u- ^$ G
                    cout<<vexTable[cur].data<<"  ";
    ) }) k  B# g9 f+ A# N" B                s.push(cur);1 ^3 C1 y, r; b  O
                    tag[cur]=1;
    " y, l" P# _* w) h( c               //初次访问,标记入栈
    # B* k: l, n8 ^* I$ R+ ]; Y3 P! `/ q# `" s" Q
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点5 U' M5 V; q- R% Q
                   if(p==-1)  l5 E  c( u& U& b/ t/ d$ `
                   {, B7 V3 n: R' H! _: X/ f- ]5 S
                       pre=cur;s.pop();! E; A1 y* _" D% j  ]9 I2 ]
                       break;. J! u: @% o/ M* w+ l1 f  n- l8 s
                   }* U# @, e# j* L
                   else; M3 L9 z5 F8 H
                   {
    3 p  p. a: z( X# K" g                   pre=cur;
    ) `5 n3 [. g5 M8 Q                   cur=p;8 R; q* r' k2 d
                   }. Y9 K' }6 u2 G; f2 A" |, T4 `
    1 p4 r1 S  M5 T
                }
    6 K. h0 y( ?" @! C" D9 d, N* x            while(!s.empty())% }% D' s" q' X' T+ g2 h  S  V
                {
    . e; ]' G+ t% B: U$ V8 o, D                cur=s.top();. H. o# m' l: w4 e7 X' I5 X: A
                    p=GetAdjVex(cur,pre);7 P& d& }) H3 `- t# A# e
                    if(tag[p]==0)
    3 F6 ^9 s- l, z6 d! V4 U                {
    6 ~' R/ @' a& m% X, m                    pre=cur;
    ! r% p3 c4 n+ I5 d4 @5 |5 |                    cur=p;6 w4 y6 B- K/ y0 p: e" u% w
                        break;( J, T5 Y3 X. S& X0 p3 r3 C8 P
                    }/ n0 [$ B( J. y  c. N2 w/ i
                    else+ L" I: ?" Z. H6 L5 J2 B" t
                    {
      ], F* w- n* |* f8 {+ p) M, i                    pre=s.top();
    ; A" R& s6 B0 i- A+ Q# Y                    s.pop();
    # x5 y- I( d9 Z2 o  l( J                }
    4 K' d: z, v& X6 Q5 n# N7 k$ B% c  o! k& p
                }8 Z9 f: X1 R8 M) X' E9 X

    ; ^+ P+ J) ^2 D$ R3 o        }
    , Z! e: T' M* m: W0 ?    }* q5 @( ^, V) P
    }. l, y5 y3 f: A0 M% ^
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()* a) h' g# ~4 [4 o# ~; [! k8 u$ b3 i8 Q8 z
    {
    # Y: H4 X4 _! p0 q+ O' n6 p$ x    for(int i=0; i<vexNum; i++)/ J! R$ G6 j+ A
            tag=0;' u# c- q% {" S2 u" P% s' k
        queue<int> q;
    $ E! r2 U6 r! ]' M    int tmp,t;
    + ]1 _/ [" P7 r' i    MultiAdjListNetworkArc<WeightType> *p;! @, a0 f1 V5 F% c$ W5 }+ H  F
        for(int i=0; i<vexNum; i++)
    % L! N8 P* \1 f! Z    {1 x- ]( s6 n: k) \
            if(tag==0)
    $ U5 |) b/ \6 \( U        {7 ]. E9 I9 f( d7 S
                tag=1;% J$ N) r6 x0 M/ l
                q.push(i);0 I0 x% t0 C0 D2 ?  a
                cout<<setw(3)<<vexTable.data;
    , C& d) @& @5 s% @8 ]        }3 i8 a, `1 r/ Y+ y- S, G5 b
            while(!q.empty())
    - X! m/ R# ^1 ?# f2 p        {; u* o1 r) m& T) W0 @; w* y. H
                tmp=q.front();/ N$ Q& n8 r$ @
                q.pop();7 S+ h3 M4 h: h% t
                p=vexTable[tmp].firstarc;
    0 `9 Y* m5 y# v            while(p!=NULL): L/ C9 f, ]7 T. n/ c
                {' K8 t2 f* Z& m2 s1 _6 {& U- }7 V
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);( U- P6 }& J8 x2 U
                    if(tag[t]==0)
    $ y. W( t. Z& R( e                {
    . v5 a! ~: N- N                    cout<<setw(3)<<vexTable[t].data;
    ; I; X- g, \4 D" l5 E                    tag[t]=1;+ S8 k0 n6 f9 t
                        q.push(t);; B) M3 z  [' n$ j: H+ M
                    }! M1 Z* J9 t8 Z7 \0 N
                    p=NextArc(tmp,p);
    : M& f5 U+ q: ^0 k            }3 ?; h" {2 Z- v' l6 J8 o- n( h0 i
            }
    5 H0 m/ ?' M& p6 z2 ~    }
    0 ?) A+ G2 c- Z}: v* T, Q" b3 k7 [
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()( K) r* c* E, M9 w5 G3 n7 _
    {
    ! w- i. V# ?, W! t9 g2 I. k    MultiAdjListNetworkArc<WeightType> *p;
    5 x* C  e6 S2 H    cout << "无向图有" << vexNum << "个点,分别为:";& t7 t4 ^2 ?, v: G' P
        for (int i = 0; i < vexNum; i++)
    / w8 E/ T4 X4 P4 k  f% w' v& J        cout << vexTable.data << " ";
      N8 D  I* H( `& d/ |" y# U    cout << endl;
    1 x0 A7 l" y( Z( m+ x    cout << "无向图有" << arcNum << "条边"<<endl;
    : x3 R1 @$ W. W+ ?' c    for (int i = 0; i < vexNum; i++)0 F. r! {, {# v; o( F- R8 e7 g
        {
      z2 j1 n3 [& I7 B- X/ P        cout<<"和" << vexTable.data << "有关的边:";
    1 N" ]6 f1 d4 |+ h: N& g2 Q; f        p = vexTable.firstarc;
    0 T' l' s# Q% \2 V/ \3 _        while (p != NULL)6 ]. b; W+ ?2 j/ T+ o% C8 g
            {
    ; }% e) M5 A9 F1 B' g6 X            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    8 u: r1 M" g' W6 _' d" ?            p=NextArc(i,p);
    ' `" y, P1 D5 a  b! r        }$ i) s0 b/ \% N: |
            cout << endl;7 @8 g) M& w" U& l, ?
        }. a: G6 c8 n. U
    }
    9 H3 y% O% R! b- U: I- ?( }$ z  P. S8 ^
    4 l9 h8 [4 f' f/ b3 M' w9 q
    邻接多重表与邻接表的对比
    9 w) x4 O  t$ x" ]5 H6 C4 H& [# R/ ]0 n% y( f
    邻接表链接. {( d- I4 Z8 m4 W. k( f) I8 V
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    ; o* L5 i% Y1 ^" f( O) g$ I在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。( N& M3 U* H7 l+ }" {! F! o, d
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。- E$ V8 c" H8 y9 s# ^
    ————————————————2 n! I% H9 F' Y- K
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    7 Q) E% [! z" E8 }原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    7 l* b- Z8 R* I) y# |* }: w" ?2 K$ s( c- F. l( z
      {* X9 O0 @2 ?$ O" ?/ x, C3 d
    3 }; B# f# w1 \; G+ d; q9 |. E
    2 }+ Z, \' `% @4 w
    ————————————————
    . v- ^  e* ~7 m" \版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    + T' z2 l( q/ p原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958! {, [* ?' A2 n: T* O0 [

    ) C9 ^9 `. D7 K3 e! W5 u0 q' p4 Z5 Y9 U
    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-10 02:39 , Processed in 0.514267 second(s), 53 queries .

    回顶部