QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1341|回复: 0
打印 上一主题 下一主题

图的存储结构——邻接多重表(多重邻接表)的实现

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2020-4-26 15:26 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    7 j' Y; i  L: ~$ G8 r
    图的存储结构——邻接多重表(多重邻接表)的实现
    ( P1 h8 d; o- C7.2 图的存储结构- Z1 U. B! _5 S: d

    - e2 [9 r- E- p7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    ' |- ^$ ~) A. Z4 t1 X邻接多重表的类定义
    . q" D. S. F, y3 J; n4 K邻接多重表的顶点结点类模板+ Y: ?* T. Y, P3 K3 U" Y
    邻接多重表的边结点类模板
    % g% a7 n$ m/ M) O  ]邻接多重表的类模板7 W5 p3 U" J1 j: s7 z9 P$ F
    邻接多重表与邻接表的对比
    ) A- C. F# `5 v  D" h: K7.2.3 邻接多重表(多重邻接表)Adjacency Multilist4 n) `' N* t8 u5 Q: R  s
    0 U% p/ {2 g6 y4 J. ~* y( E3 F- [
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    4 i4 o5 m  `5 l在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。/ s. h& t% b7 t0 j. b. P

    - m5 g" m# |) l" H/ k" ~3 Z邻接多重表的类定义
    " S' q  e" x' ]* C$ z: P 1.png
    ) `3 j$ z' b3 M$ [8 W# h' u6 w邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:1 U8 B/ F: w5 O' i! I
    data域存储有关顶点的信息;+ y+ Y8 F! q9 _1 _$ p
    firstarc域是链接指针,指向第一条依附于该顶点的边。/ {' K: X& u$ K$ y' X, z
    所有的顶点结点组成一个顺序表。


    - X' w/ n, z7 p, I/ c' c: ?+ |! w$ x8 T9 J) `
    template <class ElemType ,class WeightType>
    6 R7 i: z5 u+ rclass MultiAdjListNetworkVex) J" }6 {  ?7 ~) L9 V. a
    {: L; M$ H4 m& B9 H! ?* q  B
    public:
    * S. V1 ~' w' N1 l        ElemType data;$ W/ _9 V/ ^! I, \" W  d6 h
            MultiAdjListNetworkArc<WeightType> *firstarc;
    ! G( V/ i( d! q$ z+ x. U3 T. X0 h4 U! [* T) B! ~: y5 ^# c
            MultiAdjListNetworkVex()7 e1 Z, x: U3 G
            {8 r/ ^* @7 A) p1 \& j8 W
                    firstarc = NULL;; a, g7 k5 R2 l/ M0 y3 g+ K3 ]
            }) F& a8 O" c# J8 b( D7 }# n7 w
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    4 K% B$ P- U: G) {% }( `        {3 f) R6 J* b- G
                    data = val;
    ' F; |/ L! Q: E* ^5 D  a                firstarc = adj;
    7 ~2 U3 |& w7 E0 ~+ C7 K4 k        }/ X7 W. s3 ^0 \
    };
    , f9 x3 t! O, d. |; y7 Y( X- l" \; D( E9 c: J
    邻接多重表的边结点类模板
    4 ]3 G" ?) M2 Y0 K+ i) B  i3 D
    : ^# U& n" I& ?在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:! s" s- x2 ^  d
    tag是标记域,标记该边是否被处理或被搜索过;- Z! B# s2 y+ K: \" S
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;" {8 r7 r4 p) j6 S
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;! @- m6 _2 i; L
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    3 I! r' J% ?: g( D+ x' |) ~
    + z' P; [7 X- \- ]3 K: `# f; a 2.png 6 X. Q# H1 Y9 s7 B
    template <class WeightType>
    # j8 Y; C: l& Y2 X9 r1 [. _class MultiAdjListNetworkArc7 W( x# l- _" F  @) U! b1 i
    {9 |; d& }, L2 v9 P9 x
    public:" e2 \/ v& ^' K2 S  s- I5 N
        int mark;                                       //标记该边是否被搜索或处理过
    ' @6 k, q/ T: S  r        WeightType weight;                              //边的权重
    6 n5 e6 e; M8 o9 {        int adjVex1;                                    //边的一个顶点
    & X/ s% d' J" S* C* m% Z        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    ) V3 b8 |- }6 u4 C' R, b- l        int adjVex2;$ x1 `0 H9 j; }1 v; ?
            MultiAdjListNetworkArc<WeightType>* nextarc2;: q/ r6 h9 h7 I9 e- c* f) r4 @8 {
      m% E6 g. x- E9 j" O
            MultiAdjListNetworkArc()# X& z- p7 m1 L/ N$ U
            {
    + C1 d' b% R) n. k) c' H0 b; O; P                adjVex1= -1;# O7 ?# _- \' o4 h2 I/ r( k
                    adjVex2= -1;' R' \- b: e( P( P
            }' W* s5 r6 y  }+ ?% c4 @
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)5 W/ h( |( @0 Y2 L7 W! W
            {3 b' X/ |) E; z7 ]/ r
                    adjVex1 = v1;       adjVex2 = v2;
    + Y4 ^; S# z$ G( b0 h                weight = w;
    + n1 J4 B' W4 Y3 k% o/ D                nextarc1 = next1;   nextarc2=next2;# o& V/ [& ~# k3 r( B
                    mark = 0;           //0表示未被搜索,1表示被搜索过3 s0 P8 }$ F. c- j; u, X
            }0 t& [" j+ S8 v$ Q5 J2 d: K" |1 b

    1 N+ t7 d; n% T7 W邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>. E) H# b) y1 x' M
    class MultiAdjListNetwork/ V. f( n, G: k' }
    {
    : B5 y0 R8 B4 i9 x! ?# X4 `protected:8 g+ j. t" ]0 v$ n
        int vexNum, vexMaxNum, arcNum;5 R2 I+ }: H; \/ c) |( \
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    * z4 e! b  a& ^  \: ]    int* tag;- x" m; }8 {& T; e) E  }
        WeightType infinity;
    7 R3 L) l6 R' W3 g' [& K
    5 ]8 O) R3 L: h9 B: N2 U* H) Ypublic:
    ( I  Q5 s7 U2 Y    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    : N2 z0 }( G# V9 f) |
    4 r% h6 _1 i( U$ F5 H4 e, o3 X    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);# u  a6 x4 V0 n1 L' m
    5 B7 j1 Z' B' w. n3 C# t0 n
        void Clear();
    ; \3 i, N6 ?! Y& M    bool IsEmpty()
    / w9 y1 ^6 _* G7 J% l: f    {8 D3 D- X" R2 {' i; d0 s
            return vexNum == 0;3 ^6 V( y7 a# I' k
        }. ?" W; X& h3 M5 ~$ h
        int GetArcNum()const4 D$ {! d' w4 Q' X0 N0 d
        {5 \' R. z* @( \7 S/ A* s
            return arcNum;( A4 Z0 k, Y$ ?  o8 J9 C5 t
        }) `5 L! ^9 k. [5 V
        int GetvexNum()const' Z: ~) k4 o8 `" @
        {
    2 ?) c- t7 P- x. U9 w        return vexNum;9 a4 T# S9 y' G6 y, G3 ?' M0 ]
        }5 [1 u8 C8 m# X% i2 V1 X8 ?4 Z0 {

    * M4 u1 K9 E5 o1 Z) J& T
    $ M* \( `- Y; ?, l$ i5 `4 k5 \    int FirstAdjVex(int v)const;
    8 X4 d+ r$ m' b" m0 A( R, N    int NextAdjVex(int v1, int v2)const;2 ?* ?: e4 ]8 {- ?% |4 i% s: ?
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;% K: l- b% q$ l- N8 \* Q4 p
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;7 s. `( w1 I/ [( \1 f  N0 x
    2 ?$ t$ w3 d$ a/ a! U
        void InsertVex(const ElemType& d);: R8 E& Q; i$ ]4 D% ~& m
        void InsertArc(int v1, int v2, WeightType w);; C- T  s1 z" w; W" u. G7 r. E/ g
    " T# a6 e, B, Q4 X8 h! b. k
        void DeleteVex(const ElemType& d);
    1 h0 Z& M) ?2 e  P    void DeleteArc(int v1, int v2);
    7 ]" Y1 ]# [1 r. m
    . U3 j) f0 j* j" x9 G    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    + g. n" y" B; ^5 H    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);* z' a+ q( Y9 s9 |/ H4 T
    ( ~  ^# |! c/ k9 w
        ///深度优先遍历
    8 l5 a  t+ `1 U/ ^    void DFS1(const int v);+ e8 Z) b5 V) \- Z
        void DFS1Traverse();
    % ~) h; t7 J& D" k$ i8 X    void DFS2();
    ! f9 ~6 F" I8 r6 T, e- |8 }- e/ d0 @
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1! n+ b3 H  D4 T' @
        void DFS3();* {+ M. |& a( H- V
    ( O2 E' D# P& l* U
        void BFS();
      d" n: ^' [, X0 v% Q$ O# r    void Show();
    . m! j& U. X* |% _5 d1 ~: h1 E, A};
    6 k0 [" F- h1 \- _: F
    5 k  l) h, v) ^6 W+ ]3 c5 _4 M2.函数的实现2 F, {+ u3 H- C- ?% i3 f. h
    研讨题,能够运行,但是代码不一定是最优的。% ~+ S9 j4 t9 |5 _3 E
    ( j; A# t+ [6 m( y0 `
    #include <stack>3 `$ K+ o. {6 o$ t5 t) @; W: N
    #include <queue>
    6 [  \; M5 _: v) ~# R4 t
    ' }. h; _1 s& u7 ^/ qtemplate <class ElemType,class WeightType>
    ' F. Q4 m) ~' J# BMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
      h2 a* f) n5 g7 |9 U% ?0 j( d{  T$ n) Y. N- }1 X3 W
        if(vertexMaxNum < 0)
    : J  }: x% ?* L* o7 _/ |) o        throw Error("允许的顶点最大数目不能为负!");! V1 f# M, Q  g1 {
        if (vertexMaxNum < vertexNum)
      R' E1 R4 V3 k* `8 M. O9 M; G1 V        throw Error("顶点数目不能大于允许的顶点最大数目!");3 N$ L6 `! _" v8 c4 z9 S1 ]/ h
        vexNum = vertexNum;
    % J6 d) t9 {  G    vexMaxNum = vertexMaxNum;5 X. \. I" B0 M/ M
        arcNum = 0;
    & B9 Y: K% y8 V, b7 f    infinity = infinit;
    / A+ S( r( p1 m    tag = new int[vexMaxNum];+ E' g' L! i  ^( F0 y" b  e, t
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];) g4 m( E4 O3 v2 r" O5 F. s
        for (int v = 0; v < vexNum; v++)2 b/ s7 B; J* Q- V/ Y: W. L+ q
        {
    " y: H9 V, w$ p0 Z        tag[v] = 0;
    ' [1 H! e* q! C        vexTable[v].data = es[v];
    " Y2 k! p8 x, \( A- `        vexTable[v].firstarc = NULL;- q; ]+ }: X2 o0 m! [7 d& i
        }
    - ?5 v4 h' X5 P) |. `! @}& V% _8 \/ T9 ?- ^9 s
    template <class ElemType,class WeightType>
    & W$ m4 s% r& u' Y9 GMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)' Y: y% _6 y- L" r" Q1 E
    {) \; b9 \/ I  S5 O
        if (vertexMaxNum < 0), q4 d$ L, H5 K* N8 v
            throw Error("允许的顶点最大数目不能为负!");
    # h" ~8 i# S  J& t" N# S    vexNum = 0;% @% T) }, m& e8 O) N
        vexMaxNum = vertexMaxNum;
    . _& A: F& S/ K3 V7 ?0 C% q    arcNum = 0;
    ) Z1 n* ?6 K1 J  H& M0 N    infinity = infinit;
    9 R9 k* v4 U7 |( S1 l9 y) T( C! t    tag = new int[vexMaxNum];/ |5 l3 [9 u: h) c- c
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    , U4 }" T& t0 g2 `: `* C}
      Y0 K% A: c* ^7 V% jtemplate<class ElemType, class WeightType>, v5 F5 T2 {1 ]( {+ p- h0 r
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const6 g' a+ t5 q0 n  b3 Q: Z" V
    {; @% c1 @5 V8 f0 Y
        if (v < 0 || v >= vexNum)
    7 h8 i- R* O" q2 l* ?/ o& w        throw Error("v不合法!");
    0 Q. d* [6 `3 N" ]1 |" @5 n. k    if (vexTable[v].firstarc == NULL)2 Q( Q( V; |" t- u
            return -1;7 X( B3 [% G6 K2 D% R1 M
        else
    5 x& A: Z8 \( |6 D        return vexTable[v].firstarc->adjVex1;
    # v7 ^* ^9 Z3 _- f( G}  y: Y+ N( ~% I

    : [6 c4 n0 x" t8 h8 L& F+ |template<class ElemType, class WeightType>5 V( g# h* e1 P- N! [. [) D, I( e
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const7 Y4 Q0 r1 A6 R+ C) y" ^
    {
    * ?5 ~% S2 m% Z1 q  y" o7 {    MultiAdjListNetworkArc<WeightType>* p;  ?3 o  W, V5 ?# W- m
        if (v1 < 0 || v1 >= vexNum)
    ; r+ |8 y/ y  {* l: M- @) @5 s        throw Error("v1不合法!");5 y! Z! d! x( r( Y+ }4 J  A
        if (v2 < 0 || v2 >= vexNum)
    4 l9 [: P! Y' C% D0 ~& g& h        throw Error("v2不合法!");$ |9 R6 @% q0 G% n3 V
        if (v1 == v2)
      z. b% s6 d  q' L3 L. \- Q        throw Error("v1不能等于v2!");
    # {* h0 K: G: }    p = vexTable[v1].firstarc;
    % C5 ?; a1 |2 M) @    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)& M' x8 v. H6 X
            p = p->nextarc;
    , i) N9 l4 T+ V# D6 u* m    if (p == NULL || p->nextarc == NULL)
    $ P, A) O  Y, X4 I        return -1;  //不存在下一个邻接点' t* j' z2 g1 @
        else if(p->adjVex1==v2)
    - x9 Q. u: j. k+ q4 j        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    + i* X& u  d! Y$ |# p6 [    else
    . z' {+ }9 m  U! j; j8 G/ J  C        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    6 I. q9 i. ?, b/ ^8 e}
    ! {8 n$ e* ~0 K7 A: t# `7 Atemplate<class ElemType, class WeightType>5 U( z3 y0 Z0 ^& k6 R& p# @
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()
    + S7 m, i4 O2 M6 ~( l{
    9 j. m0 d! T& E0 ?+ x' |& @9 V    if (IsEmpty()) return;& B$ j( H2 F, R; ?: z
        int n = vexNum;! L9 V( b3 G7 E7 a8 Y. M5 x
        for (int u = 0; u < n ; u++)
    3 X) Z! R& G% D        DeleteVex(vexTable[0].data);
    + i* N3 z" ~6 g+ g% B7 }4 }  }4 U    return;
    3 \  D# o) T% O2 f% {: z}- m# K6 o1 Y! e( n) s
    template<class ElemType, class WeightType>
    * K* ~+ }' x# n" T" p( wMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()9 v9 _. i7 `* B  N. E
    {
    4 U. W& p/ h3 S. {5 a    Clear();
      m, P4 `8 Z3 P}0 J- K; Z0 J/ \4 `2 F
    template<class ElemType, class WeightType>
    4 {7 _$ o; z) MMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy). Y! L3 u4 B0 S
    {
    & W5 v6 I% L- V+ Q, J9 c    vexMaxNum = copy.vexMaxNum;0 U/ a. v/ B5 p0 }- B6 ^" d
        vexNum = copy.vexNum;
    4 v% w8 l+ U# U    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    0 J* w8 n, A+ Q; d    arcNum = 0;' K$ m/ q& I% T! P$ `3 A
        infinity = copy.infinity;
    6 D3 t( |4 c2 x4 d  S6 E6 x    tag = new int[vexMaxNum];
    ) R1 |. p- T$ m. x- B% {" L+ g
    " E0 [2 @. g; ]8 z0 I    for (int v = 0; v < vexNum; v++)
    " g- s+ K7 ]; O' A; ]. J    {2 Q/ w( `, C0 E0 [& p) W, L
            tag[v] = 0;3 Y* M. S/ e" ^3 Q9 h
            vexTable[v].data = copy.vexTable[v].data;
    ; j8 N% w! O: W1 S, _        vexTable[v].firstarc = NULL;6 c2 y+ G6 Q# I! M5 r
        }) J6 Y2 t: Q& \# o* V  t
        MultiAdjListNetworkArc<WeightType>* p;5 f+ x1 v5 B* P: U

    8 k- s& m7 F7 C4 U8 t. x* [$ }    for (int u = 0; u < vexNum; u++)* }" D! z* J9 ^, F6 m* }1 B8 q+ s
        {" V% @1 |( l+ S# q5 H
            p = copy.vexTable.firstarc;9 R' y8 I! H. C" a9 _
            while (p != NULL)4 Z9 ?$ a& N; M) B: ]
            {: @! G$ ^6 l6 f2 T5 e( U
                InsertArc(p->adjVex1, p->adjVex2, p->weight);7 u& f' i& i5 |* U. @
                p=NextArc(u,p);
    - o3 x, {- K% a2 W7 L        }
    " T5 G$ z# T- J, P    }
    2 b" ^5 ^) v9 j}
    / t5 g: {0 n+ F, ~7 itemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    # \1 v& \  g/ f* |2 V2 h) [MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    $ o. S) a6 G( P{" x: _! a9 k! R2 M, s5 |2 g
        if (this == &copy) return *this;4 o  p: B3 P* H
        Clear();, o* Y: ~" n" K& I+ f7 b
        vexMaxNum = copy.vexMaxNum;
    * \6 u; Y' U& v8 ^    vexNum = copy.vexNum;
    & c$ p5 ?, @5 C5 B    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];# q0 T3 f- J( a
        arcNum = 0;
    6 t" @! o! w1 m8 M    infinity = copy.infinity;9 S, R$ V) U" y5 V* g2 s
        tag = new int[vexMaxNum];
    ! a1 I6 r5 o2 E3 x. {  Z5 {( p/ [3 q9 t5 k
        for (int v = 0; v < vexNum; v++)" A  e; R4 @/ \
        {3 L  `* ^3 q/ W6 v) }$ N2 V: X5 p2 K
            tag[v] = 0;
    + o7 f2 n) b! Y3 R        vexTable[v].data = copy.vexTable[v].data;8 n4 Z/ d6 u# s2 u
            vexTable[v].firstarc = NULL;
    3 ~' e5 C5 }) K7 P* Q# }    }! F9 o& ^5 _$ w" K, d
        MultiAdjListNetworkArc<WeightType>* p;. \1 n! k* D8 `. e' `4 ~
    : Q0 u, u5 @+ L! ^' ~. X3 `- a* [7 V
        for (int u = 0; u < vexNum; u++)  g1 F0 e# A4 P0 q
        {& }1 n& w: ~/ B
            p = copy.vexTable.firstarc;
    . I. e  p- h5 ?) _0 I        while (p != NULL), L% m: Y8 [5 _
            {
    * L# R- W1 n/ \8 J1 X! z            InsertArc(p->adjVex1, p->adjVex2, p->weight);( {* b2 v/ j8 i, |# c0 ^2 B
                p=NextArc(u,p);
    ( x& F. M6 F( d3 S8 T& P( D        }3 Z8 G4 k# D. G
        }
    # Q# G  ?9 A6 D    return *this;6 Z4 y5 F9 E+ m
    }
    ! `. g0 E. T+ u  p. ^  I4 Ptemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*$ F) s# m* r" m1 M
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const+ w% H; {0 x, @( H& Y4 H
    {8 r: j4 M2 Z' l0 G9 h6 x
        if(p==NULL) return NULL;
    3 Y& k) X' P" u7 |2 i+ Z0 ~    if(p->adjVex1==v1)' L% Y) P8 w; i5 `. p
            return p->nextarc1;; v8 ?- P; D$ K- ^
        else1 ], m% S% y7 p, M, D/ l
            return p->nextarc2;
    1 P6 \0 t2 q5 q}
    - P( L9 [+ r3 C4 q+ k. Xtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    . B& a7 F0 o1 \MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    6 [; I! o( w' {6 q2 y{
    : {/ d0 n0 |. o$ k    if(p==NULL)return NULL;. E3 l4 x) C) S  R' b3 y
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    # y5 ^- D7 j  }; [3 r  [# r    if(q==p)7 d# g3 C& F1 ~; x8 U7 w
            return NULL;
    5 z) y! s" ^! N- J& f2 a0 d, s    while(q)
    ; @. x. s7 |8 _2 @    {/ K9 p7 F- s6 F& R6 q
            if(q->nextarc1==p ||q->nextarc2==p)$ C& l3 W; y# q$ }/ [8 W+ e2 X  ~  `
                break;
    $ q. [. i& d) i) x1 N/ k7 c        q=NextArc(v1,q);7 o3 C8 x* R: g- l
        }7 |' b4 r" K* x/ h
        return q;' F* e8 \: W5 m1 b/ S
    }! m9 v2 {4 h/ z! X! i
    template<class ElemType, class WeightType>( S; d1 ]+ T( v; S+ M6 e! D; B
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    % X! M% e0 j  [1 [/ m{" B8 @. [" u; f. \% s
        if (vexNum == vexMaxNum)6 O0 Q$ w5 U7 E) [
            throw Error("图的顶点数不能超过允许的最大数!");
    / d  J7 b7 c4 B" w1 t    vexTable[vexNum].data = d;; T/ a. @2 H1 O) ]& n
        vexTable[vexNum].firstarc = NULL;, {; U0 G- @5 }" n& Q) v
        tag[vexNum] = 0;8 X! O3 I) k. _# w3 X8 a
        vexNum++;9 u1 D& h# g% Q: C/ S1 }
    }
    ) S3 w3 E7 g' E% b( ntemplate<class ElemType, class WeightType>3 D( J( `6 `) q% ^/ Y" k% F
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)  b' p4 J! s/ b2 K) ^* K
    {+ @  t" u+ B4 e+ \4 x
        MultiAdjListNetworkArc<WeightType>* p,*q;- H) b1 }+ S/ M2 |
        if (v1 < 0 || v1 >= vexNum)$ |% {0 g5 P. R8 e7 Y/ b
            throw Error("v1不合法!");0 q0 ?' f: k+ N  Q
        if (v2 < 0 || v2 >= vexNum)
    + o3 j6 Z# a! @+ ?        throw Error("v2不合法!");
    " n# X' c) R; u5 }- Y* f1 A; g    if (v1 == v2)1 A  Z* R% S0 s' H0 K8 k
            throw Error("v1不能等于v2!");
    1 T- X$ N+ v7 B    if (w == infinity)
    9 b6 A. G+ v8 k& o# Y" C        throw Error("w不能为无穷大!");/ G) T7 I2 U1 [! \- a
    ' D1 S7 l& H. o% w4 K/ l$ S3 b

    6 Q9 V8 n$ n" W  G& a  q2 o! B" M* w    p = vexTable[v1].firstarc;
    - R+ w$ G3 S: A$ T( M    while(p)4 F6 z9 d9 p" [# G1 J  `$ Q# r8 j
        {
    / ~2 j1 d: T1 q/ m5 q  ^6 Y" P- Y  n        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    & F& x2 j# f# \) q0 V; w9 m        {
    1 F; p" @% }( |3 G, W            if(p->weight!=w)
      o, N* J+ y7 q: J7 f5 Z                p->weight=w;+ m+ M  p/ ^! C7 a5 s. o+ s
                return;
    4 i6 H" P' n* Q1 I+ H, G# N        }! P+ `) n  I7 R1 |6 b1 I, E

    ' B$ w2 O. ?( G6 u, r( \7 g. |        p=NextArc(v1,p);! W$ D4 R; M  c% a
        }. M5 V% V) R! D# u5 h# r" \+ u7 w  F
        p = vexTable[v1].firstarc;( {9 @" f, X! ~; Q4 J
        q = vexTable[v2].firstarc;
    0 }" C! N: _. m. _5 S/ {* o    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法  ]! Q2 F; E0 i! R% e% |
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    ! c+ i. l" ^# C& @0 @) s    arcNum++;
    7 q5 ~1 k' ?2 R' y4 Y! s+ {. x3 ~}$ R, b& n1 C1 K) @( {* i, ~1 [
    . u5 @6 M" j- K% U/ b4 d
    template<class ElemType, class WeightType>
    7 a1 [% Z# T2 H9 b5 L' bvoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    1 L4 P8 o* C, s. _, T7 Z{2 u* l8 W) @) k, {" |

    ) J& c8 S" @, \, m1 J    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    " l. K1 _1 V9 U    if (v1 < 0 || v1 >= vexNum)1 R0 J4 F& O1 _* t7 T% O
            throw Error("v1不合法!");
    4 m$ X* r: G) R    if (v2 < 0 || v2 >= vexNum)" H' R# D& V4 ^6 ~  \
            throw Error("v2不合法!");: B9 T0 A+ t/ y0 Y
        if (v1 == v2)
    - L6 |: m9 E) c' `" B        throw Error("v1不能等于v2!");
    " C0 Y0 C$ Y9 ?! R7 L! \' p, Y9 r- r5 w4 N$ o
        p = vexTable[v1].firstarc;; }# X1 P' h1 d; @2 Y- D# ]6 H/ G* D
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    3 K$ G5 k; Z1 S5 g% E2 r0 ~* O, J    {
    ' P0 G' b1 [" n7 @; c        q = p;" M( Y: \: R; p" a, @
            p = NextArc(v1,p);" N4 _* ], g* t9 i5 H# h% S
        }//找到要删除的边结点p及其前一结点q! p% ?  I8 A' k0 `
    6 R/ I# s0 [- Y7 d
        if (p != NULL)//找到v1-v2的边$ z/ V1 h( o" L1 ?% }
        {
    ) i& h& R' ^+ T& J! ?2 G        r=LastArc(v2,p);4 E; [+ ]' f; C  C' {# P+ V) ^
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    4 T# j2 W; P7 x: v            if(p->adjVex2==v2); K- M7 [$ O9 W/ L7 s
                    vexTable[v1].firstarc = p->nextarc1;. c" W+ {* t# i7 ?& A3 k
                else vexTable[v1].firstarc=p->nextarc2;
    ; j3 \, ^' {1 ^* a% u* T) ?  }        else//不是第一条边
    ' P# [9 J+ e: K2 B7 W# P        {
      P+ S9 Z. _3 s1 @            if(q->adjVex1==v1)3 }+ k% i: v: w+ {
                    q->nextarc1 = NextArc(v1,p);/ i# P+ E: m+ r8 O
                else
      M! g) X+ \6 h7 o$ t7 {) b                q->nextarc2=NextArc(v1,p);% X' \  V/ j8 ~2 D" A4 S( w& Y
    / C, _. V$ M$ w3 J' S
            }3 z+ I  u4 M- u: E1 g5 X4 e
            if(r==NULL)
    # u; Z" A7 H( r7 h4 ?            if(p->adjVex2==v2)
    . F' D7 f* @( x! r% B: \2 u                vexTable[v2].firstarc = p->nextarc2;( ^2 ]( g. M( T2 [5 Q
                else vexTable[v2].firstarc=p->nextarc1;4 {5 A) d4 S2 A( p  a$ Z  I: T/ b; r
            else
    " k6 c+ k) m* B8 _        {
    ! r  P. V% V! s            if(r->adjVex2==v2)
    7 l, b& d+ G: z                r->nextarc2 = NextArc(v2,p);
    5 g% s, @, X# P2 K            else
    4 Y% m% c; Z9 m4 G* n9 f                r->nextarc1=NextArc(v2,p);9 h0 e" H& F: V' I" h
            }8 x" d6 [5 e; u5 z4 @8 l' H6 U
            delete p;3 Y% _* o- g! B0 F
            arcNum--;
    # }; S3 E9 j$ M) s    }- O8 w$ U& |' Y+ V' q$ z. w
    : Y, h0 J! g9 x
    }7 A. l. ?* d1 d# g
    template<class ElemType, class WeightType> void
    - `6 @, l( M" j" R( {/ J# }+ QMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    ; _- u3 P2 f" Y; b{
    % w1 }0 h* q% G3 w9 V( ?    int v;
    * o( x6 J, e2 f) m) r    MultiAdjListNetworkArc<WeightType>* p;
    - c8 j- j+ f8 {! i3 g    for (v = 0; v < vexNum; v++)//找到d对应顶点
    8 `9 I/ }5 u" x1 ^) w7 D6 d        if (vexTable[v].data == d)
    ! f! P9 e  ]& u" I% z8 w, ?            break;( m# c3 {- K% X0 W* g
        if(v==vexNum)
    0 X+ ]( j+ e/ \$ S" r        throw Error("图中不存在要删除的顶点!");
    5 A: U7 a. Z$ H1 U, R
    ; l) J% H& G6 n; T8 w$ ?% W    for (int u = 0; u < vexNum; u++)//删除与d相连的边
    3 U$ Y0 k  I% [9 f8 \3 J        if (u != v)
    , d4 Y9 ]; M# s$ ]        {
    7 i, k  n0 }2 [9 s% a            DeleteArc(u, v);
    % u' I6 P9 k( a* P        }
    ! V% z1 s* |3 f$ y, n: P0 ?+ Z    vexTable[v].firstarc=NULL;
    8 b' D. N8 @6 s: K, Q' P  R  `$ R4 U, ~$ p* a" R5 V
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    * J. C/ Q8 W2 I; u, O    vexTable[v].data = vexTable[vexNum].data;
    ( M& x3 R# o  F+ O  [. Q    vexTable[v].firstarc = vexTable[vexNum].firstarc;4 b! N5 j" |* K# \0 |% T4 f* l
        vexTable[vexNum].firstarc = NULL;  I: [3 a1 I9 }4 o0 I
        tag[v] = tag[vexNum];
    " \1 D) |2 a$ }( W    //原来与最后一个顶点相连的边改为与v相连* G: f8 V% r: d6 ?; \
        for (int u = 0; u < vexNum; u++)9 e' ]) G4 f; `& z8 c) I8 B# m
        {
    5 N( F0 V, @/ F" A! R2 |. z        if (u != v)
    7 X8 _1 N' g  d        {9 w5 H" P3 ]2 N" P% }$ B
                p = vexTable.firstarc;
    . A( R+ z$ @$ v. i, [4 B( }8 w            while (p)! B* t" d" f4 L% x/ w4 R
                {/ `4 ~! J. l- a( L! s/ E, y$ x1 |3 _# ~
                    if (p->adjVex1==vexNum)
    $ B6 J2 N, F9 ]                    p->adjVex1= v;
    & L6 q  ~: F; w) M0 h( D                else if(p->adjVex2==vexNum)
    ) q3 d7 W) _6 A( @5 r                    p->adjVex2=v;% o. c1 }1 ]( i9 ^
                    p = NextArc(u,p);: A) s3 c0 E" h* s* b6 Q! d
                }1 e" u/ C* T7 y, g. J' J' N# W, E
            }  \8 H. E& ~7 o1 W) j3 }4 T
        }
    ! w  L( C; d) A1 T1 i}
    5 o/ ^4 }% Q1 x///深度优先遍历$ x1 ?- w: V% o
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    / p; Z' }% L+ k& @{
    3 Z: N. h: @" Z6 @( |9 V1 g    tag[v]=1;
    8 i, M# D6 `1 S+ W/ }+ v    cout<<setw(3)<<vexTable[v].data;
    0 Y" ]: V' ^% U! r% i! h    MultiAdjListNetworkArc<WeightType> *p;! M# s4 M' p: D+ W
        p=vexTable[v].firstarc;! F+ s% ^3 S" |6 a, @5 k- H: {
        while(p)0 K5 m* @  g& \* U+ K+ o; X. }3 n
        {
    # z; i) p3 Z3 b  e8 b        if(tag[p->adjVex1]==0)# C5 L- Q: {- u6 G1 b  i) O
                DFS1(p->adjVex1);2 b  F* v  I) v3 f0 O  l
            else if(tag[p->adjVex2]==0)
    ) i9 a0 E: y* Q- _4 z! @            DFS1(p->adjVex2);
    , ]* U& q) x5 P- f1 x* Y  J        p=NextArc(v,p);
    3 L5 I0 D# E* w7 ~$ ]( ?    }( b' X0 I; h! ~8 i6 f0 i8 I
    }; Q+ c4 i$ n" W5 N& n# ]: X; z; Z
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()) }6 ~: k; f" x0 @
    {& O, W% c5 V  z6 L2 G$ S
        for(int i=0; i<vexNum; i++)* K* E8 E; k- t/ |$ m
            tag=0;* S! a' P$ y% S1 X
        for(int v=0; v<vexNum; v++)9 j. D- i( i$ z$ m# `) k- {
        {
    : W$ N! z% |& t) j! x, k. c9 ]9 b! t        if(tag[v]==0)
    5 C; b! P" h# U0 }+ p! D: I7 }            DFS1(v);
    & N8 }1 q8 u# i( [: v6 }4 `+ R    }
    - V) S5 K" i, L* `! K) {}
    - }" G2 ?+ M2 [3 Q: }+ e4 L- Ftemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    * L; N* R* @; O1 n{
    / r2 g* j5 a' D  T    stack<int> s;- l1 ~( E/ O1 t; P$ ]0 G
        int tmp;
    # n, i- c/ h+ ~* {! K    MultiAdjListNetworkArc<WeightType> *p,*q;9 f3 A. C  d+ u0 O9 U
        for(int i=0; i<vexNum; i++)
    0 i6 r  `! n: i4 D& d) X        tag=0;1 @4 k2 P* j8 b. ~2 q: J
        for(int i=0; i<vexNum; i++)0 [% D% ?) v6 r! A
        {
    $ Y2 X4 k% S7 _( G- X4 r5 w$ f        tmp=i;
    ' `& c. Y1 V' R1 D        while(tag[tmp]==0||!s.empty())
    ( e! K: y% e% X5 c3 W1 b  k4 |        {% l  C2 H- C: p: A  u0 ?
                p=vexTable[tmp].firstarc;" {+ ]4 k" }! O6 v3 l9 r
                while(tag[tmp]==0), k1 ^( e& D9 z% e& F
                {
    + V5 R% |1 F& k2 b, H1 E                s.push(tmp);7 ]6 M9 U8 h( v- \
                    cout<<setw(3)<<vexTable[tmp].data;
    ' [  X9 O. ^; }: n% v5 ^& ?6 z1 U                tag[tmp]=1;9 m" v! c# E( y, u+ t' a
                    p=vexTable[tmp].firstarc;
    + t  G: C4 F- n9 u6 J, |6 t+ D1 _3 O                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for4 b+ d7 x# a2 A
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
      i% o2 A6 [( x3 ]; G: e  P                //cout<<" 1st     tmp="<<tmp<<endl;
    * k8 k5 V% Q: \1 ~% N            }
    1 H/ X2 W6 D+ A            if(!s.empty())
    3 I" n3 l3 [! K- K  @            {
    9 P1 b  U: s4 M, ~  ?                tmp=s.top();
    5 ]' M# _( b5 h. j) t' \% u+ F( Q5 W                s.pop();5 B/ ?+ E$ N$ q" y. A* W
                    q=vexTable[tmp].firstarc;
    / V7 v! e# I5 p6 r' H9 n                int t=tmp;: I7 U* _9 A% y
                    while(q&&tag[tmp]!=0)
      s0 J/ L5 ]: b8 X  s                {6 a4 F" j& z0 O
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);& C% V1 G- G/ F$ P- z! P# @
                        //cout<<" 2nd     tmp="<<tmp<<endl;
    ; j5 B9 v% v9 k                    q=NextArc(t,q);
    & g. P! r9 p& p                }
    ! [5 ]6 R+ h/ s8 T. q                if(tag[tmp]==0)
    3 @4 _; T5 e+ A+ ]: t9 W                    s.push(t);- j5 h$ v1 H  i& Z2 k2 s
                    ///1、对应上面连通分支只有1个点的情况
    + _4 Q  H5 a' ~' {, _6 `& l. `' r+ j# H                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    - u( ]6 I1 }6 n; t7 z1 H: F: w3 R                ///tmp要么等于找到的第一个未访问节点,
    $ b' [8 N6 W9 p8 z                ///要么等于与t相连最后一个点(已被访问过)
    ' q7 b; f+ z; _# B+ u                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    8 M/ g4 K# d& G- }) h8 A            }
    4 e( \3 H# i' F* Z, i        }1 |* E' k1 s1 G( i* ~& a2 r- p6 {
        }
    0 X5 \/ n3 g1 R2 Y* R& h}$ ^" c& q% {: Q- ~$ H7 e
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1  y' \( T' y5 e
    template<class ElemType, class WeightType> int
    % G0 V* Y9 A2 Q7 l' J# g8 qMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    0 A5 b8 B3 H2 Q. B{
    4 z+ O! l- ~3 Y7 H3 O/ ^    if(head==pre)
    $ Z0 s! I1 P* m4 s2 U3 w! k        return -1;
    + p& a6 u7 B" U0 R' [6 g  A; A/ p5 w( P/ x3 v8 ~
        MultiAdjListNetworkArc<WeightType> *p;
      B& h7 D  E  o9 N! K/ k    p=vexTable[head].firstarc;& ^* h4 {  H# w3 v2 g3 O
        if(pre==-1&&p!=NULL)
    , s' f" F- Q  x        return p->adjVex1==head?p->adjVex2:p->adjVex1;* I! c8 I$ g( b" Z( q- u
        //pre!=-1&&p!=NULL
    8 K/ i1 D9 k% T3 y% W    while(p!=NULL)9 G7 K0 C4 n3 w# @6 c% X
        {  z4 ]( z' G! V3 w
            if(p->adjVex1==head && p->adjVex2!=pre)
    $ z3 B0 Y+ Z) k" a            p=p->nextarc1;
    . j* a- a* `! i9 e  P9 U& m9 P        else if(p->adjVex2==head && p->adjVex1!=pre)4 [$ ~+ Z8 y9 v4 `$ K3 A' i; K
                p=p->nextarc2;' ^" ?, b* u6 b# c  O+ o. b
            else if(p->adjVex1==head && p->adjVex2==pre)
    5 Y. v+ c* S7 i8 D' \7 w1 e        {
    3 T9 T& u' A, l) E5 v5 ^# ~2 B# i$ R8 K            p=p->nextarc1;
    3 d3 K( v4 I  C+ A8 m            break;2 L2 H" T6 E) [2 V. F
            }
    3 a5 {- ~" U. T/ s        else if(p->adjVex2==head && p->adjVex1==pre), v' I3 {& V/ O, T. D9 v
            {' z4 g3 k5 _' n
                p=p->nextarc2;; u& X, _+ _/ P6 _# E
                break;
    ( |2 K: {5 w' o4 @, e        }
    % k7 h6 H# A  k3 z2 q    }
    ; l+ d' z9 o+ W' d* Y    if(p!=NULL)8 m1 t: s. {' p
        {& Y- V0 ?! ^( P5 Y
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    8 H4 B6 j. b$ y3 q# |+ y2 E' b  S    }" }/ V/ Y; \. [' ^% `1 G# a
        else+ z: T0 X3 }) \/ D/ q
            return -1;+ `  a% p- N) {' q9 h
    }
    2 j+ X! }& V& _$ g' B3 ]8 K' o* i  S( I4 ]4 n1 d

    0 D- X! L% ]& X! j% X* dtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    ( G6 q. P/ T# h7 r( I{
    9 T5 u, M8 j, y8 E0 Y    stack<int> s;
    9 b9 j  ^- @+ U    int p,cur,pre;
    , X3 B/ ?3 E8 A    //MultiAdjListNetworkArc<WeightType> *p,*q;
    2 x- f4 ~( [1 @  g) ~% f: \    for(int i=0; i<vexNum; i++) tag=0;//初始化6 u( L! ~4 Z4 r/ b
    " T  \' W3 T% x& d+ c6 H) m  u9 a( U
        for(int i=0; i<vexNum; i++)
    $ R" B- c5 u- F$ g    {2 |% E3 D2 v, W  S2 J3 M
            cur=i;pre=-1;6 Q8 V1 Z, T" K, _, p# D
            while(tag[cur]==0||!s.empty())
    # u# w) S1 G- I* u( r2 N: B        {
    * a3 |5 Z$ w$ P. v* ~; U. N& y            while(tag[cur]==0)
    / u) @. A; G; B1 U            {
    ) Y( {" {# Q4 P2 d2 J                cout<<vexTable[cur].data<<"  ";1 @; K6 b0 k' G' `; [* i
                    s.push(cur);& s% B0 O9 o- _% S( Y7 c; u
                    tag[cur]=1;) {* J+ I. Q% h  a, ~
                   //初次访问,标记入栈3 x& u7 R( P% P/ A* t
    8 x5 p8 }0 t  s& K* m
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点
    5 Q, u% U. P  n- ^7 `/ I! }; d               if(p==-1)2 i, k0 L" z7 q- n$ [+ f1 o
                   {7 d  r7 t1 H- [: c
                       pre=cur;s.pop();+ ^% l( v; i# Y
                       break;& \8 m) C6 F3 ?
                   }: {  c3 H9 F6 ~( i9 _1 O
                   else# w: `" x4 [: N
                   {0 X! e8 G) w% w: f8 a
                       pre=cur;
    6 k. O. ]5 f# s8 a* l                   cur=p;
    2 T  k7 L  k% _6 w               }
    1 z8 `; o# F! e+ K0 S. h8 v6 l" A: t
                }0 a# X! S4 }, r, [8 _
                while(!s.empty())
    ( B+ C- L$ }% Q  J+ k            {
    1 Z* y. s3 t0 m) f- ?                cur=s.top();
    % `6 Q% o0 M+ d4 X; A                p=GetAdjVex(cur,pre);
    3 l- v" ^  d# A' g2 t                if(tag[p]==0): ]$ E: h7 L1 v% v. ^5 _1 T
                    {  u6 _* d0 @6 |2 U
                        pre=cur;6 D! a* j. v# f7 ?9 K+ ]
                        cur=p;
    7 p3 J+ v3 h* T( w. E; T$ l! P                    break;
    + j0 ]% n0 `# r5 J" N# C8 P                }
    1 Z$ k) g; [+ a& h. g                else
    / ^9 ?# `( P5 z6 ]$ T$ f- R6 u  {8 m                {
    0 h" ?1 B5 i' l8 K6 w% S                    pre=s.top();
    : ?# \) X, S, _                    s.pop();% z+ \) w2 o# O* [
                    }
    - u: S! X2 K' d  r7 F7 c( ^! h# x  \) h( k' F* Q9 A* e
                }
    4 e# z' ^' a. s4 c: V4 b: `: X  r+ h, x: X1 F3 h9 J
            }1 Y- u2 e; l6 Q: S* w+ t6 p
        }8 y  e5 P+ B% {( j; @4 O; ~$ j6 ^
    }' a. y  c% r! Z3 U2 X
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    ! d7 o% X1 ~, L2 _6 @{" b1 @% T* g. `+ F8 s% N6 P
        for(int i=0; i<vexNum; i++)2 c3 L3 H% K0 ]8 K& e- {' D
            tag=0;( k: m$ ~1 P( j% D' D. B+ P& ?
        queue<int> q;1 p+ E6 `, j& }! x% Y( A# B
        int tmp,t;6 h. t* c: N, [  \
        MultiAdjListNetworkArc<WeightType> *p;
    : v0 r! M1 r9 ?  \% z9 n3 O, X    for(int i=0; i<vexNum; i++)
    # o8 i% o# i4 }9 k5 Z8 ^    {+ O2 r( L* t/ Z/ {# T
            if(tag==0)8 _) ?) ~5 J! g) x4 X* k4 g7 S
            {
    , @$ }+ x2 R8 j$ a% e            tag=1;
    - G2 O+ y, K: b0 K6 i8 P+ g            q.push(i);
    / W" N& o- {9 W: }4 T* K1 [6 o            cout<<setw(3)<<vexTable.data;
    3 Y6 }2 v! \; |( I2 G1 p        }
    $ o$ G, h- B/ G8 U* v        while(!q.empty()): n7 f/ S+ n0 _. B: x+ H' `' p' L" O
            {9 D3 J, A$ D0 c, Y' W
                tmp=q.front();
    * f3 J, r# K$ q            q.pop();4 J2 J+ w2 S# _) k7 G
                p=vexTable[tmp].firstarc;
    ; o0 n6 M1 z( F: T            while(p!=NULL)
      g1 F* ^: q' t) G  y1 I" D. m6 H7 }* p            {
    4 M  L' k% _3 r! o6 S                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);) C* N8 Y* {7 G) l# _8 a
                    if(tag[t]==0), P$ J) [; k2 f+ u% i
                    {. ?2 }: c" Q, j; n
                        cout<<setw(3)<<vexTable[t].data;9 K- f5 M/ O+ u1 i
                        tag[t]=1;9 b( C6 I/ ?8 a. v, m
                        q.push(t);
    8 [: x+ }" U4 ]0 j6 x: j                }+ C, R+ W# B* L0 ]& Y7 @
                    p=NextArc(tmp,p);* \) n4 N4 H$ C2 v( |
                }
    / d5 B* ^% l+ B% e. N$ }        }
    # X4 B6 r  H$ R' j6 Z, Q4 N$ s    }( R6 T. ^$ R8 A
    }0 w) ~& @* H5 i& b
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    8 J  Z0 }9 w( m{, N; @8 V6 R9 z4 z- F- J  V
        MultiAdjListNetworkArc<WeightType> *p;8 Z5 r% i) j" g1 l" H
        cout << "无向图有" << vexNum << "个点,分别为:";
    " E" S" K4 l& w, @6 S    for (int i = 0; i < vexNum; i++)
    ) h( S) f/ |! @  }7 j1 h        cout << vexTable.data << " ";% v5 h- j" n. q" i% O
        cout << endl;$ t& b* S7 X2 L; F
        cout << "无向图有" << arcNum << "条边"<<endl;
    ! E7 T. l" R. R* |3 d  t8 e) L9 k    for (int i = 0; i < vexNum; i++)
    ! B7 Y8 [, @' _7 E    {
    ; e% n. a1 W7 l8 p2 }8 K        cout<<"和" << vexTable.data << "有关的边:";
    # ~: X/ C' g, T9 I% N        p = vexTable.firstarc;
    2 s: b' L: [" F. _; u# H        while (p != NULL)
      T. B/ Z6 |/ S/ L; J% h# [9 f        {4 }  A/ D- ]4 e( _2 i
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";7 J, E- B# m& x/ J
                p=NextArc(i,p);9 o" f% J: O9 D& g7 {
            }
    ' t! e5 j! k: o5 Z9 M        cout << endl;$ @4 _5 G; E/ g4 `6 g/ J* e5 P
        }  `+ B; s, X3 J+ n$ L
    }+ J- g- T( q) Z; i: @) }+ U

    / d+ v, t3 E" k) y" c: H. V: I9 T
    - E5 w6 g& \2 M邻接多重表与邻接表的对比/ t2 N1 O7 V+ Q& j' M

    + o) Y5 k1 o5 A( ?- t  x0 c- q1 l8 ^邻接表链接
    4 j3 k$ }0 ^8 |2 n& J1 _在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    8 S6 X& J" |$ O' z9 A' h7 A0 I, ]在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    # B) r, h, j6 K为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    ; F& V; z8 z5 Q7 |: T————————————————
    % w) o! H& v+ D" p8 X% |版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    1 b# U/ k6 a- j$ e. b原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    / k* b" C) C2 x2 V: d- t' p7 |' @

    ( U( q0 u- v* G
    " ^% @, E9 u3 l+ N; B* x
    1 q; n: E7 r2 Q  u2 P————————————————
    ! F+ S2 p' i* ^( Y( s& E, A版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。* [* i9 O" I1 V
    原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669583 o" s& b. ]# ^5 Q, C
    ( v, J& j4 K, P  |

    ! G: h& K) {4 R( q/ L
    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, 2025-7-8 02:51 , Processed in 0.286509 second(s), 53 queries .

    回顶部