QQ登录

只需要一步,快速开始

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

    ' L$ k8 y8 }$ X' g+ d图的存储结构——邻接多重表(多重邻接表)的实现
    / @; g' ]( t+ G5 r# n- Z3 c7.2 图的存储结构' q7 b, n; E: \3 q# j

    . C1 f6 r' u! b- d" Q0 L7 w; j7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    3 \2 c3 g& q0 ?/ A' G0 I$ `4 o邻接多重表的类定义, z* }5 O4 h. O" I5 |3 n# F" E
    邻接多重表的顶点结点类模板/ m! |: f$ |8 _8 F9 g$ y  y' d/ Z
    邻接多重表的边结点类模板
    ' R: w) s; A! A4 v- H邻接多重表的类模板4 h- ?  V9 S% E* ]5 z
    邻接多重表与邻接表的对比
    ) U5 I) H* `, e! `7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    - v1 o7 N+ \' z9 L+ A3 {1 v9 h3 f/ U4 q5 c% J: o2 F2 V
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。3 N; {5 }: `8 B* D' O# F# O' B. G
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    4 j9 U! ~7 L2 e) i  v2 K$ t& S. {" [9 G! H* W% a7 n
    邻接多重表的类定义
    2 q, I. V3 j: S. Y. v 1.png
    ) p9 c8 ]0 I- u9 W+ _邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    ( n8 y) x( {! F9 R2 P5 \; V1 sdata域存储有关顶点的信息;
    6 U3 Z0 t& [) U( l+ A2 W) Sfirstarc域是链接指针,指向第一条依附于该顶点的边。
    ( a* ?0 @$ R4 u" \$ L; M所有的顶点结点组成一个顺序表。


    6 T7 l( O2 \' n; F' ?$ w* m# o( a* s
    template <class ElemType ,class WeightType>2 c; D+ b* F: u" h/ L4 ]8 t
    class MultiAdjListNetworkVex$ v( Q/ c) _1 n5 k% S+ Y- Z% Q3 W2 |
    {* {7 P7 Q. v9 |! T+ e
    public:
    + {& K; [! z3 y$ V, o' M        ElemType data;
    ' t3 P8 d6 `( M2 \( K  D& T        MultiAdjListNetworkArc<WeightType> *firstarc;# |$ ]8 Y% \9 \4 @, O, `5 [( s4 H+ `) B

      m1 D+ y5 O& T6 Z& _; }- K        MultiAdjListNetworkVex()/ I! k7 I9 Y! F& _
            {
    # S4 K. j  i/ I                firstarc = NULL;/ g  [% @# s6 }) d5 d& N
            }. l$ Z- P, t* y! X: K4 ~
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)6 {; R3 b+ b$ V! Z% C) ?- ^! r
            {  I7 I. P* X5 w. Q) h  B; m9 a; G
                    data = val;
    $ t' l; o# U8 F4 f                firstarc = adj;* _, O4 I/ ~  w( W
            }$ x% j4 ~0 |9 ^5 g* v! [& ~
    };7 [9 b& D" o) i' A( ~; b7 F& b
    ) e+ Z$ P  P5 K
    邻接多重表的边结点类模板
    / d- U: V0 Z8 @5 ^* V8 r: M3 M  ~5 W8 T
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:: k* @3 }7 N) v7 w' u3 w$ R/ Q8 ?; M
    tag是标记域,标记该边是否被处理或被搜索过;
    ( J4 x) R- w9 q* O$ z: jweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;+ c! n! k$ {' }; K) [2 F
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    ( h, C6 Z' \/ G2 S' _2 |( [nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。. s7 [4 a1 h3 m! \7 b3 o
    ; r2 Y1 M1 A3 Q. Z
    2.png " z2 h8 J! b* F) Q
    template <class WeightType>
    * A$ k, o, X/ }! B/ L. j0 B6 P% sclass MultiAdjListNetworkArc- d( ]( Z! v4 u
    {+ K, O( v9 j. m/ Z2 b- |
    public:3 x0 q3 Z$ K8 c  L( m; \
        int mark;                                       //标记该边是否被搜索或处理过& r. t7 y! h8 Q3 |2 i6 p, k
            WeightType weight;                              //边的权重
    ) s! w9 ^) e2 Z& e4 \5 R+ e- X        int adjVex1;                                    //边的一个顶点, O7 R& T8 P+ V, ]
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-17 R7 k& s8 S, [1 e5 I- I& W
            int adjVex2;8 _! ~5 \4 i# P2 r
            MultiAdjListNetworkArc<WeightType>* nextarc2;6 [& _6 a' [! e* P

    $ A) Q; J9 `. }# f$ d2 N        MultiAdjListNetworkArc()& l7 f5 h& s+ L  _! N
            {# {8 O0 `3 |3 a$ s5 r2 C
                    adjVex1= -1;" \/ y/ P# Q$ [/ G
                    adjVex2= -1;
      B6 S3 h) b: d$ l$ I        }' ?0 d3 U9 q# p3 c8 N+ Y
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    * }& y2 Z% q+ B  Q4 h' p        {: l, {! j: B4 M( Z
                    adjVex1 = v1;       adjVex2 = v2;$ H# v8 f/ N2 F+ u" _2 @7 v: G7 L
                    weight = w;& c# @' ]7 B) X/ j2 z  {# z
                    nextarc1 = next1;   nextarc2=next2;
    8 x6 s& G2 u6 j9 @% c: i! X+ h                mark = 0;           //0表示未被搜索,1表示被搜索过
    4 i$ K: X6 @7 t        }) J" ?0 N3 }) s
    * A2 _& }: o# w4 X/ u) g* ]4 M
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    $ l0 l5 U& R' v* Lclass MultiAdjListNetwork
    ) N1 z# w( }6 ^: r& s{8 Q# N7 U6 G& }$ m
    protected:3 L  t0 y  r; _
        int vexNum, vexMaxNum, arcNum;
    6 a3 w8 b* S* o" y' R! ^2 x2 D    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;, J. g* z* L( o8 C
        int* tag;6 e5 J0 O1 a" c* [2 c' }$ a
        WeightType infinity;
    . u2 ]% ]0 h8 x/ r5 n- V# \- e5 H6 q
    public:
    ! C9 @, f1 T+ d' W0 y8 ~7 i5 x    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    # U0 p) l2 |% R; t. m6 {* I" L
    ' z3 f8 Z& a- _" \    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);6 S9 _$ x4 B1 l& X2 `; T  P
    0 L4 B1 W* p& y! v* p
        void Clear();
    # J' B) Q" z, L$ [    bool IsEmpty()
    , o& V8 J) e6 W4 E# n    {
    , |: m6 y! c5 i/ R( L5 D! `3 O! @& j        return vexNum == 0;7 s% \! I$ t$ [& G; N) r, r
        }' _3 x) s; L; O* ]
        int GetArcNum()const
    ! k6 ?( R& {1 {! ]4 ^7 v5 T- K6 s# P    {: K2 F/ ~, T# x1 e
            return arcNum;
    2 h, p* W$ P4 E) p3 P2 o+ G8 a    }
    % M- ~, v5 S) X$ o( v5 m5 W    int GetvexNum()const
    . @* f+ A9 C' P1 e6 D" C    {& c5 z" g4 e" i
            return vexNum;
    4 o9 U, \% _0 ~+ W% I4 C% ]    }! ^- S$ {  R( _% e1 X' [) U
    3 k* J2 i! ^1 j- `, z
    % l$ D$ s% s( R
        int FirstAdjVex(int v)const;
    # e5 ?1 ~+ h$ b    int NextAdjVex(int v1, int v2)const;9 W5 |. \$ r2 \9 q1 [" Q
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    ! o5 R  a  q# |  Q3 C    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    3 Z: `0 C/ j6 M# v
    + B8 m3 X+ S% W: g. j4 p* E, Z    void InsertVex(const ElemType& d);
    7 H2 h( P* k4 K    void InsertArc(int v1, int v2, WeightType w);) Z( M+ W; [5 D" m* c3 y( S, s  l

    8 [$ @  _7 _9 ?2 D! o    void DeleteVex(const ElemType& d);3 r1 R6 H7 [. ?3 f
        void DeleteArc(int v1, int v2);5 h. d2 V# K  m2 D1 s/ d- \9 h

    / k1 g" o$ f% z. _& W    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);( m8 D& O- Z1 o; c# [2 X4 _" F: M
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    ( {' l/ O$ c9 T' u  X* O" s9 f+ X' i  x/ `
        ///深度优先遍历
    : @- Z, w7 K8 D; t4 z7 W    void DFS1(const int v);" x/ r$ _4 g- M4 o
        void DFS1Traverse();" o  U; `) n" M2 p
        void DFS2();
    " k7 [$ x( b0 m" M: S, E) ^1 {) d9 G/ h
    5 @, [# y/ f2 ^  R9 z7 Q    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    0 }# V# g) R1 N- x; D8 H+ h3 {    void DFS3();
    ! b8 Z- T- B5 g0 d8 Y
    $ a( b5 @( q& q+ i* R& p. x- R+ B    void BFS();8 i( K7 N/ q  W* i4 D+ i
        void Show();  Q6 d0 q. I3 }4 N" \8 H* j
    };
    8 h2 ~2 D. c, H3 ~6 b1 q. |! C1 V6 P9 N6 _7 Y* p8 L* A
    2.函数的实现
    . C# K- ]: _6 e. F' t/ v研讨题,能够运行,但是代码不一定是最优的。$ v9 |* z& D0 I. e

    ! F/ p+ Q6 X2 W+ B# t0 G. O) _1 x#include <stack>* \% `/ F% L8 O
    #include <queue>
      x- J  e/ ~' k; _. U: @8 J. G" M; V3 k$ B. m: A/ _
    template <class ElemType,class WeightType>
    ! G! J8 K8 S! O+ a( M% n% }MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)) \; z" g6 T) Y2 l. ], o/ Y8 r8 l
    {
    & v, L" J# S5 Y9 ?- r7 h    if(vertexMaxNum < 0)& C6 k: \1 s/ {+ H3 p' _
            throw Error("允许的顶点最大数目不能为负!");
    0 e- {2 t" T/ ]( a    if (vertexMaxNum < vertexNum)
      T6 B% }1 ]0 y8 N        throw Error("顶点数目不能大于允许的顶点最大数目!");
    ) m1 Q7 w; R# ~4 G2 H) u    vexNum = vertexNum;0 a  `  v+ T7 N2 ]
        vexMaxNum = vertexMaxNum;
    ! v0 K2 |, j+ a2 @    arcNum = 0;# l/ _. _5 z8 J9 W' r; M) ^, C
        infinity = infinit;; M; C! Z1 P. m. x- \; [
        tag = new int[vexMaxNum];7 D8 Q- F+ `" r5 X7 `/ o1 P. S
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    ) B6 C: S# L& N% o2 [/ U% j$ _    for (int v = 0; v < vexNum; v++)
    - e* C+ I) @8 v+ {3 F    {
    1 U/ X% p/ C0 `8 z6 e        tag[v] = 0;
    & ^) g) p: x% n- {; j, d        vexTable[v].data = es[v];5 X  X8 V0 g! o! b
            vexTable[v].firstarc = NULL;; _/ `1 |7 C% j" R7 Q5 q7 L
        }; p8 z! r* G( ~9 H. g, n
    }
    5 |5 [- t4 f. j; S- Qtemplate <class ElemType,class WeightType>- v# p4 B/ I* S$ D+ @( |
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    * L  w; x$ o* L0 p7 d4 l' @{: z6 W' I( Q8 D  J& _% X1 \
        if (vertexMaxNum < 0)) K9 q7 R1 Q2 A& g* h
            throw Error("允许的顶点最大数目不能为负!");
    % D5 H2 q9 W! Y# }    vexNum = 0;; j2 s. Y  ^4 V6 Y7 H
        vexMaxNum = vertexMaxNum;
    5 t3 g( c. e; d5 M    arcNum = 0;
    & R. m+ X) \7 d- D% ?    infinity = infinit;
    6 J7 }3 h9 f9 v+ v4 p    tag = new int[vexMaxNum];$ t9 D2 }) _5 S0 p8 P
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];6 o% o: Q: h& J
    }: @1 j1 J' U4 z( j$ G' y! X
    template<class ElemType, class WeightType>
    $ K9 T: d" x; b1 D& I; {( Eint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    * q' ]& V- R  X+ A1 d/ y" s' X{
    ; M. P# w: q2 S, c    if (v < 0 || v >= vexNum)
    2 B/ U. c; E- k8 G" M" a8 p        throw Error("v不合法!");" ]3 E1 |& ^; \' f' Z3 o
        if (vexTable[v].firstarc == NULL)
    7 i" s" X7 D% T, y2 T+ b2 e/ d  V        return -1;
    & F/ f; I) ]( H# t+ s3 C0 |  P& e$ U    else
    6 V' b: X; z6 v* J. `* v        return vexTable[v].firstarc->adjVex1;2 c$ S+ |1 p% |
    }
    / t/ e; p6 Z6 I: y! m# d
    ) u0 |' _+ J- u! J. d8 ztemplate<class ElemType, class WeightType>, _$ @5 W. x: k( s. b# O# X
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const! I) s. \7 X$ _8 B3 R3 b
    {
    3 Q$ V, x& {: ?; p    MultiAdjListNetworkArc<WeightType>* p;
    4 v0 n  |' V! i+ F2 h    if (v1 < 0 || v1 >= vexNum)! T% f+ d! H, d* z7 W( W) f
            throw Error("v1不合法!");
    - F" p' W" G! n* p& ^    if (v2 < 0 || v2 >= vexNum)
    - P) y" V; d3 o$ \7 S$ q- s        throw Error("v2不合法!");! z- k. Z. x& a1 W. Y7 F6 l/ K) Q
        if (v1 == v2)9 q/ g1 A. K! ?) ^9 L4 M8 t3 d
            throw Error("v1不能等于v2!");- L; F: X) z: @9 r
        p = vexTable[v1].firstarc;- |( p5 K& Y1 H" l# ]
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    5 F0 P8 [& q' x# o7 b' [: \& Y& P% P4 H        p = p->nextarc;6 v  f( {, H* Q6 X- ^
        if (p == NULL || p->nextarc == NULL). }  t8 b0 S. ?6 F; n' Q- y
            return -1;  //不存在下一个邻接点- G- `) f. k; S' i/ J- C1 f
        else if(p->adjVex1==v2)' ]5 h: d# w* S; Z: F, [- Q
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);% Z5 x; I7 x& z1 O, a) E! H
        else1 [: [# x% k5 a9 c& I5 b. @
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);8 t' z  C5 ^9 ?+ {2 M; w/ @9 J
    }
    $ A. m( v% e" W" |) h; Qtemplate<class ElemType, class WeightType>
    # E2 X: r9 n( q; t, Xvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()
    8 x4 n- X+ z# ^8 F2 V; H7 e{* L1 u  I: A7 L5 @
        if (IsEmpty()) return;# C$ Q9 j+ M: V& z
        int n = vexNum;( b( _& n  D# L1 V! q
        for (int u = 0; u < n ; u++)+ e9 |8 Z9 }$ b8 l+ o
            DeleteVex(vexTable[0].data);
    8 z+ O0 a0 Y, v3 {, [) C/ i    return;
    8 V* f  V% ^5 Y6 W% l8 ^}
    $ ?6 [8 E: [: {9 ^+ q( M! ptemplate<class ElemType, class WeightType>
    2 L4 u: A, q, {* s/ sMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    3 H* `+ W7 o9 C9 @1 q' o% o4 q' D{
    # ^5 d  x7 T; Q% U8 U    Clear();
    * n$ Q8 U1 i" N' n6 `5 v* q}
    % i- ^" t! P  P( P7 O; n7 m0 rtemplate<class ElemType, class WeightType>
    * j0 w3 M5 v: S6 U2 V2 jMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)5 V. V0 B- k  ^5 q$ {
    {6 a# f, \; H; M. m6 }2 \
        vexMaxNum = copy.vexMaxNum;- s, P8 b6 m4 Y9 H
        vexNum = copy.vexNum;
      S- A2 \& ]& p) i& B5 X9 {# T: c; I    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    % P" t0 V1 }0 W$ \    arcNum = 0;
    * ]7 V2 U5 {% B: S. K, h/ a    infinity = copy.infinity;+ W+ `2 T+ \1 b3 c
        tag = new int[vexMaxNum];0 @/ \4 n4 l" J4 q8 b6 e
    2 Y: S6 P' a) W- I, O! [7 d
        for (int v = 0; v < vexNum; v++)
    . R4 [3 k& t' B5 j0 X    {
    2 ]+ M7 N0 P6 {( s        tag[v] = 0;
    8 L: P. E( g7 e- C! G# [( T* H        vexTable[v].data = copy.vexTable[v].data;5 Q& F" `; y  j9 A4 g" r
            vexTable[v].firstarc = NULL;% S2 l3 M  |* p: W5 t# j2 b, \
        }
    " `/ @1 ^1 a9 e$ k    MultiAdjListNetworkArc<WeightType>* p;
    8 ]1 ]" g% L; C6 D8 u- b  i, q" B0 v, V4 u0 P6 c& W
        for (int u = 0; u < vexNum; u++). Q3 J- v5 h9 I1 B4 A
        {" V6 l4 I0 O" j* b0 Z
            p = copy.vexTable.firstarc;+ W8 ^- p. _7 K3 m
            while (p != NULL)
    : {' z4 Z3 E/ M6 j0 P! M1 U0 ^8 U        {
    + ]3 [& f& [* Q( S            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    1 D+ ?5 P  U/ S) b, s7 r  N            p=NextArc(u,p);  x1 P1 X/ B4 i7 X) b  E+ R9 _/ f
            }
    # }( u. m2 V0 t- K    }+ \  ~: L/ J! ]
    }$ v* k' h7 m2 n& S5 O: o
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    6 W2 d+ ^- o- D& ]MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)  @+ r( K/ n5 n9 A3 ~% E1 i, E
    {
    2 B  ^# s" N7 P    if (this == &copy) return *this;8 o+ u8 m5 T5 s+ C1 M7 ~/ ?  ?# g
        Clear();: X" m- F! m+ s% ]- P* T
        vexMaxNum = copy.vexMaxNum;! k5 U: k* O3 q( X
        vexNum = copy.vexNum;
    . y; n5 M* l1 r    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];) Q1 `+ {$ B4 z5 e
        arcNum = 0;
    $ E. B, J' ?. w7 n, j' u    infinity = copy.infinity;; U; l' S4 b, ]3 }, a6 c
        tag = new int[vexMaxNum];. Z& C8 J  H3 U. `( q
    ! q0 W7 p% H# k+ \7 k6 ~( Y
        for (int v = 0; v < vexNum; v++)7 @0 I4 ?: T  u
        {
    3 P$ Z% S- P  b" A        tag[v] = 0;
    ( Q" z% F  o3 v) V        vexTable[v].data = copy.vexTable[v].data;" f5 j1 s$ t) ?" |3 \7 b3 b
            vexTable[v].firstarc = NULL;9 I6 T$ ]; ?" f- h$ W) O  o5 l
        }4 j5 h, w* @6 c# Z2 ~( _
        MultiAdjListNetworkArc<WeightType>* p;
    - w+ `# a3 e1 Y- x
    ; c- c3 h' g/ A5 j& t    for (int u = 0; u < vexNum; u++). O( L! @9 h  }! m7 Y5 h+ z) R
        {) Z- p' n3 h' o8 e1 z
            p = copy.vexTable.firstarc;
    3 t) e0 B- B: O! q$ `6 g" K* j" \        while (p != NULL)
    " v  {3 L" }: X        {8 J! w# s8 g! T* Z0 j
                InsertArc(p->adjVex1, p->adjVex2, p->weight);/ v/ j+ @0 L* }# }5 W5 j
                p=NextArc(u,p);# D2 K" l6 i! Y4 s  t2 i3 V
            }5 r4 [8 J1 ~" P, C7 I- Z
        }
    4 g* w8 d9 d: G0 c1 z    return *this;
    - M$ e* H8 Z/ Y8 l2 `}
    " K  Y; Y2 N# b- x# I! Dtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    ( ~  I" v7 V9 i% x5 zMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const! O3 \$ _# ?% S: x* r) x
    {2 X0 J1 `6 a" m5 q0 J, N2 D# _! x
        if(p==NULL) return NULL;& d7 f, H# I# C) E" ~
        if(p->adjVex1==v1)! K: O, E; j. X9 F- E4 }; |
            return p->nextarc1;$ |! g' |# L0 D
        else" z9 n, s/ A. ~2 Y$ I2 O
            return p->nextarc2;/ G& d8 X" ^$ v5 {8 J% ?9 J  D# |+ i7 w
    }9 e# W+ K6 J5 Q+ H$ u
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    & U( u, E  N6 l% c7 mMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const/ Z9 X0 R% c- J4 d5 H
    {4 N# O8 A! u# b
        if(p==NULL)return NULL;0 n6 G# h9 o. j4 K/ \  N* b
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    8 ?% G& \" X; F" T0 Y4 q. c    if(q==p)4 i! N, ?( ?6 D  x- E# {! `* k
            return NULL;" f' I3 i2 N0 j# k" x3 A( J7 G# _
        while(q)) o7 Q% a5 ?5 Y8 z& }8 T1 T
        {2 e3 q$ \3 v9 G- q4 A/ t7 ^
            if(q->nextarc1==p ||q->nextarc2==p)
    % @! p% T5 X. j! h            break;
    2 Y' ^$ F" x' b7 d        q=NextArc(v1,q);; k# y8 B1 q5 V8 m3 W
        }. {! Y' Z* o; a/ A
        return q;% ~& S7 @' p# ]2 j0 q& x3 F5 s
    }/ _. h5 {5 T  r
    template<class ElemType, class WeightType>
    $ _  [; T0 \; \0 ?- [void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    ! Y$ G6 ~% e6 }8 g9 r% S' i{' X6 |1 k* p; P* _8 H1 Y
        if (vexNum == vexMaxNum)/ e- G8 S( {+ n
            throw Error("图的顶点数不能超过允许的最大数!");
    & _/ B: v3 r8 Y4 G0 z3 G( }5 J    vexTable[vexNum].data = d;. M7 @, U( ]1 K
        vexTable[vexNum].firstarc = NULL;( W" \) w" F+ H- u4 h
        tag[vexNum] = 0;
    - p  i& M% V; S' B; N0 _" Z! f    vexNum++;
    ( t, o" g7 v1 H2 f1 Z$ w0 I: I& A}% A6 Z2 B) X4 V/ G2 X% j3 H
    template<class ElemType, class WeightType>
      O4 r; r9 j8 ^. A# }- X3 M, w6 dvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)/ o* F! H( K, U/ V. R
    {
    : M; K7 u$ [  i2 |+ S+ l    MultiAdjListNetworkArc<WeightType>* p,*q;& q/ o9 Z- r- j3 j) n
        if (v1 < 0 || v1 >= vexNum)
    - C! Y2 W4 d) Y        throw Error("v1不合法!");! P( S/ P# n( }3 W% ~
        if (v2 < 0 || v2 >= vexNum)3 k2 X" A# O  X; _: F1 B
            throw Error("v2不合法!");
    6 P8 e) @2 s' b9 i    if (v1 == v2)
    & |; y$ L  [4 O        throw Error("v1不能等于v2!");
    / L( E% j+ d7 D+ x3 k    if (w == infinity)6 H# s0 V; @( f4 `6 w3 g8 I! i. A
            throw Error("w不能为无穷大!");
    5 q$ K& e( X# b7 p& d) }
      y( a4 n* B( u' d* V% Q) {( U1 R  r- b3 ^6 X4 |9 S6 h
        p = vexTable[v1].firstarc;' b, p! Q; z% v) J7 l( y
        while(p). l6 N+ E# d3 x# P. w
        {
    ) S; T% p- c; G' K! D        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    $ H& a0 L7 O+ |9 y" \. h, n2 ^        {6 _* L9 c! \9 l3 x5 E$ P! s
                if(p->weight!=w)9 N0 u0 t" W- U& `0 k, R) [
                    p->weight=w;
    . m, x% }9 r7 l) s' s            return;
    & ^6 y4 e$ S( q3 M) J        }9 W! g( D: ]. V7 I

    . u* U! M7 V# }. w  r1 O        p=NextArc(v1,p);
    / z4 L- O1 A; I0 Y9 P    }/ L" Z  S1 g7 ^  N. C6 T
        p = vexTable[v1].firstarc;: M  d1 Q* }8 y% i* L8 t1 x
        q = vexTable[v2].firstarc;
    ' o3 B$ W& M( y6 l4 Y) `5 ?    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    8 q+ M! A4 r4 v1 g    vexTable[v2].firstarc =vexTable[v1].firstarc;
    + U! A! o0 B& s0 X9 i    arcNum++;
    4 x/ ?1 L4 H, Y  o}( w/ S& R; h7 P$ z

    % q; B7 F4 n1 q) L( v' Wtemplate<class ElemType, class WeightType>8 ]: T7 Q% h/ P' m
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)* ^' F# C; {1 L
    {
    2 {% E& t! Y9 B2 ~& o0 m% [& Z3 g& G( W) W# b6 A' s9 P
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    8 Q( G2 {& ?4 H  w; k    if (v1 < 0 || v1 >= vexNum)8 f  ?: D( F% ?1 q! I3 o
            throw Error("v1不合法!");
    1 H' z8 Z0 t( z7 B8 \4 A! P# t1 Z    if (v2 < 0 || v2 >= vexNum)& G$ }) ^. q; G( y* r
            throw Error("v2不合法!");, y; o% `) [) I1 w% m4 }/ x
        if (v1 == v2)
      a, V7 |5 b/ `7 ]  }7 F0 Q: ~        throw Error("v1不能等于v2!");' M2 _2 Q3 t( Y, R) q8 @# b
    2 i; C. d* `( _: \7 f/ Y
        p = vexTable[v1].firstarc;& z& Z3 c0 k0 x* P, B" H
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    ) T3 f$ _6 U# L4 y& p    {) p  X& B+ K& n6 Y( I# n
            q = p;6 z4 n% p# f( N; N$ N& I  P
            p = NextArc(v1,p);
    , o+ o, k  _5 {    }//找到要删除的边结点p及其前一结点q" n6 K$ L0 f& E. P* p2 Q
    & g  S* i  O, e8 s$ L! c6 I
        if (p != NULL)//找到v1-v2的边
    3 u, t* ]2 x3 |! Y7 u    {
    1 K; a  ]! |2 \7 t6 k3 z5 \+ E        r=LastArc(v2,p);5 X& I3 F' O/ l! x8 {6 d3 u9 S
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL$ h, s$ l& U) R; r) P
                if(p->adjVex2==v2)
    " v1 M/ r& l2 ~6 [, Z& P# X$ d                vexTable[v1].firstarc = p->nextarc1;
    8 W+ ~( {* P3 ~" e/ |# w            else vexTable[v1].firstarc=p->nextarc2;! f" ^8 x% E" k
            else//不是第一条边
    0 f% ]. D6 R* U; I3 O) Q        {
    * B3 S- G* j4 \            if(q->adjVex1==v1)- ]6 Q  I1 V) [* V& T6 c1 S& }
                    q->nextarc1 = NextArc(v1,p);. k& X' W+ _" _& W  m' O; Z0 _+ [
                else
    7 t; h7 f- g8 o6 J8 O                q->nextarc2=NextArc(v1,p);- i# K5 G3 F: O& r1 u
    ; T7 j; o# Y7 q' a3 ]& m
            }
    " A$ @/ u, T6 G# I/ J        if(r==NULL)
    3 w1 x0 D  z1 r% U            if(p->adjVex2==v2)
    : P) Q6 Y0 r3 b7 I% v3 e4 h! n9 H                vexTable[v2].firstarc = p->nextarc2;
    7 p* I% M4 Y- K% c" Y            else vexTable[v2].firstarc=p->nextarc1;
    1 O, b. s1 N- n% R9 ~2 T        else7 {, q) Z6 a/ }. f. p& Y. r
            {# O9 O1 |$ h, i0 @2 Q# G' n3 z
                if(r->adjVex2==v2)
    0 M" e4 j5 _* s- }                r->nextarc2 = NextArc(v2,p);
    ' R% X" r4 i: x4 }$ k9 l! ^* H            else" T( \; j3 `/ n% R) h
                    r->nextarc1=NextArc(v2,p);+ r; F# s0 [! g6 C0 H4 s8 h
            }, [2 s- k9 Q, Z7 S
            delete p;
    ( b: I. i- a; E        arcNum--;8 }% g* x; Y: w5 w4 |  e* w
        }
    ( l+ ]6 K2 K7 N2 \- k/ M9 c& {' G: _) i+ A3 j  m: q
    }
    * e0 S; o4 F5 u) xtemplate<class ElemType, class WeightType> void+ P# A* |+ ^8 j# P7 m) n0 E9 e
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)) @5 v$ ?5 O3 d  r
    {! o7 E  j0 ^/ B2 h* O! x
        int v;
    & \3 C' I7 _7 p1 ~, c, H7 X7 l5 C    MultiAdjListNetworkArc<WeightType>* p;" `4 g( S% d# T+ @
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    # `# Y+ A2 z$ n        if (vexTable[v].data == d)
    & I* Y9 |4 ?5 Y# }: e; O$ k/ q" V            break;. @" k# S0 W* Y6 `# Q- u
        if(v==vexNum)
    4 O5 T" d! m8 @6 m) ~5 H) x        throw Error("图中不存在要删除的顶点!");
    7 M( w9 U: J# r0 n2 Q
      E* k, W; q! [, W/ o    for (int u = 0; u < vexNum; u++)//删除与d相连的边! L* x+ `8 I% w) T  f0 N8 O8 V
            if (u != v)6 z6 J7 X+ C5 O* ]/ V
            {; k( f& d; W) `# \8 Q
                DeleteArc(u, v);
    . A5 c) H8 x: P! U( D# c        }
    ) R; ^7 Y  H" R: V    vexTable[v].firstarc=NULL;6 K  w$ L# x* ~' {5 |" D" Y! f, a
    , q- m: l2 f. F5 ]3 L
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置3 Z! ~; G! y, K) C( v% j) f3 d
        vexTable[v].data = vexTable[vexNum].data;
    4 ^5 R7 b1 |, O. b% K    vexTable[v].firstarc = vexTable[vexNum].firstarc;
    ! K0 C9 \; b4 ^( U( V& Z* j' ^    vexTable[vexNum].firstarc = NULL;
    8 j. k) M4 R( l0 B& [6 {    tag[v] = tag[vexNum];. C9 R' t; L9 i
        //原来与最后一个顶点相连的边改为与v相连+ ^% [9 {' L$ r7 }( K
        for (int u = 0; u < vexNum; u++)
    1 Y- _2 ^7 F# |    {8 m$ V( k6 |2 A' Z% B5 l- ]; Q# i
            if (u != v)
    " y3 \+ [# T- Y6 v0 m+ O        {  K( c* z( P) q
                p = vexTable.firstarc;
    . y" A* P' {' e/ J& `3 ^            while (p)
    7 V" h$ W3 S3 K( |            {
    ( p: L) m( b6 [- O5 N" X9 t                if (p->adjVex1==vexNum)
    2 D8 [, N5 ]% N# e# f4 w                    p->adjVex1= v;
    1 |$ b) l, J, y- h9 w4 M                else if(p->adjVex2==vexNum)
      s$ {" z+ A( _  L8 u) T% c; U* |( a                    p->adjVex2=v;2 H* B: ^$ L% y. [4 z
                    p = NextArc(u,p);' D, k; r  c3 o7 Z# ?4 Z  w6 i- Y
                }
    3 l+ P2 U, {. J4 G  [        }
    , C; j8 i  d( z. _& @: R% _    }
    ! ~7 ~% U2 ^$ B2 J0 H8 X}
    3 w  Z5 c  @- e3 [/ u% q///深度优先遍历  ~1 k6 ^7 u; n% m9 z. U
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    - t4 D( x3 e) L5 V{% u) s" H9 E; Z9 l. `- i3 b, ?
        tag[v]=1;
    7 @; b) k7 D# e6 Z8 a    cout<<setw(3)<<vexTable[v].data;7 _/ _" r, I1 \4 H2 L
        MultiAdjListNetworkArc<WeightType> *p;. j1 I- N* u: Z4 `% ~" ]" L2 k+ q
        p=vexTable[v].firstarc;$ N. L+ z. B- {" b  H
        while(p)1 U# N2 P4 w  a7 R+ J+ ]/ H' E
        {3 C3 @* r$ Z5 W" G7 I* T  y; \
            if(tag[p->adjVex1]==0)/ h" u3 l3 @% T) |
                DFS1(p->adjVex1);
    0 b( [' _6 w1 p5 d) K        else if(tag[p->adjVex2]==0)& r/ _4 S  N$ b1 R9 L3 N7 Y
                DFS1(p->adjVex2);6 J! z: Y% K# t4 [( g. }8 }+ Z
            p=NextArc(v,p);1 r- M( n  Y: i
        }
      P: i3 J" W; H$ z6 A}
    7 T1 ~- G  n& H* R( Utemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()5 s: c& X# ~- q, U
    {
    + B2 _$ d! }! Z! y1 J8 c    for(int i=0; i<vexNum; i++)' T, i: B/ h! ^) |* O: g  A
            tag=0;' Q8 j: o. u' M: |/ N4 Q- y
        for(int v=0; v<vexNum; v++)1 a  g; b; a+ I& K/ c) K& r9 |  l
        {/ C+ B0 y) X! G2 T1 S$ \
            if(tag[v]==0)
    5 \& ^+ E: s, m. I6 X! r" p            DFS1(v);
    " x( p! N# J6 n, G) {, }    }( s3 E4 ^9 C; c& Y0 Y) {/ ?1 {0 p
    }0 T. a$ E/ R+ q
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()  {5 h7 }0 U2 N. |
    {6 j3 q* _/ A' ^; _! g* P
        stack<int> s;$ |3 V+ m' \+ X+ t+ r% A
        int tmp;
    - j, {3 P; M6 o' Y3 Q2 q) d, `    MultiAdjListNetworkArc<WeightType> *p,*q;
    3 y! L- b" E0 d% ~/ d& m5 e  W    for(int i=0; i<vexNum; i++)
    2 `/ u( @' }# p        tag=0;
    / ^  q7 n: f8 x/ Z$ Z    for(int i=0; i<vexNum; i++)8 t  q* F3 |/ V/ B' [0 B$ F, f
        {2 [! J' a( T2 J7 t
            tmp=i;
    + M. k9 }+ f3 R5 X- v7 z6 q        while(tag[tmp]==0||!s.empty())
    ) Y. A: G( p' T        {
    3 d8 a7 Z9 L. p/ u/ h            p=vexTable[tmp].firstarc;9 A5 Y2 Z: a9 e$ A' p
                while(tag[tmp]==0)
    : ~; X& b% |+ l; ?  ]0 w            {
    1 h! ]: ~. u. {  C                s.push(tmp);) S, c/ }- B* X$ D2 _- `6 g* F1 u
                    cout<<setw(3)<<vexTable[tmp].data;
    . J; N" P( v/ I0 \, E9 P3 y$ q5 K                tag[tmp]=1;
    ( P. u7 g5 m9 D/ F- [                p=vexTable[tmp].firstarc;
    3 h5 [4 \4 J& D4 |# E  e! ?                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    5 Q2 ?: ]5 K3 z+ G: \2 F                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    0 v1 U( d4 \( t+ E9 N1 g1 V                //cout<<" 1st     tmp="<<tmp<<endl;1 [' E/ V# \! \7 A: H# r
                }( I6 c$ K; s/ }8 z  x
                if(!s.empty())
    7 k7 Q, X# q$ Y6 f: K            {9 W+ D0 \* ]& J' j( V8 Y
                    tmp=s.top();
    ! r6 V) ]7 N2 o8 y' u                s.pop();( i8 V+ w% r" F' M
                    q=vexTable[tmp].firstarc;8 e$ g9 j4 o; b1 T; C( v* V* _  m
                    int t=tmp;
    9 B' M& J+ p; n& X                while(q&&tag[tmp]!=0)6 m- Q. D* l6 A0 ~' n9 f% \9 V( ^5 s
                    {
    , s) u2 l( |& X                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    - j( W' r) D$ f' H) Y1 L+ N                    //cout<<" 2nd     tmp="<<tmp<<endl;- ?" `+ M/ C; Q+ l8 f5 E
                        q=NextArc(t,q);
    8 H$ Q: q6 |2 I5 g3 ]                }  F; z: s: A$ ~+ }, @
                    if(tag[tmp]==0)
      X$ u" X; |6 W! ^                    s.push(t);
    " F! A$ B# c+ A" _. s: b                ///1、对应上面连通分支只有1个点的情况- Q$ e$ d  R; W% }" D* j/ Z
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    / p1 x, q" r/ p3 g5 u( E( ?6 i                ///tmp要么等于找到的第一个未访问节点,
    / D  T  C& ^# l/ \. _% d3 e                ///要么等于与t相连最后一个点(已被访问过)
    6 s7 r* [0 ?6 @5 s' C8 s+ r' [% L                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点0 d& h6 k( e% M* U
                }# M3 S; k- g0 @6 n( \) Z
            }
    4 \) Z) @4 g0 a- I    }
    & G% w7 o, I" U5 S5 B' N}2 o! p+ O& Q5 R- P2 n6 J+ B7 Z& S
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    . Y+ `! P8 s8 r8 Ktemplate<class ElemType, class WeightType> int
    1 h3 u( I! E8 g9 Q; r! k, zMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    " }* |1 a# z4 _6 _{
    , m6 X# P, e  i4 n$ Q7 t    if(head==pre)
    9 E  s- D; L8 l2 t        return -1;0 J1 E9 f& I- R0 F; E) q
    7 x, A% F) o/ J6 J
        MultiAdjListNetworkArc<WeightType> *p;  t, k& ^5 k, e, s5 V1 `  [& C
        p=vexTable[head].firstarc;
    : K1 V: q5 }( }7 O8 f4 z% W7 P    if(pre==-1&&p!=NULL)
    $ F# u2 a% F9 u& q7 q        return p->adjVex1==head?p->adjVex2:p->adjVex1;- @7 f$ w* {) {; T+ V% f/ a
        //pre!=-1&&p!=NULL* N0 U+ D! R9 n) \' Q# F: ~
        while(p!=NULL)# e2 q: ]$ V- z! K  e, f! b
        {' m1 c; s1 r5 e/ `5 s( t% v/ N! `
            if(p->adjVex1==head && p->adjVex2!=pre)
    % f6 f& e# p8 @: M6 Q1 A4 `            p=p->nextarc1;
    & m% X" `0 e0 q/ ?- J7 x! C' Q2 Y        else if(p->adjVex2==head && p->adjVex1!=pre)2 C* h- M9 L1 a3 x( \" |  E+ k5 m
                p=p->nextarc2;
    4 D+ R; w& i" V        else if(p->adjVex1==head && p->adjVex2==pre)
      ~3 i- U8 m# a) w        {
    : x% e7 @  e7 l- F' z            p=p->nextarc1;
    3 h8 g8 T) r& r- _6 v6 o            break;0 B$ U9 H& i2 K' E; v
            }/ y  e% j: Y: a( R, D7 O
            else if(p->adjVex2==head && p->adjVex1==pre)% D  Z1 C6 b! _; ]2 h' t
            {6 _; \7 p' q3 G+ d" U3 [& T
                p=p->nextarc2;2 }. C$ i2 s! j* m' r
                break;
    2 _- G* p6 S! |        }1 e% f, v$ |. b' o+ x5 c( j
        }
    . p9 G$ `# f! O! k+ l5 ?    if(p!=NULL)/ m! r- H, X  U1 V. @4 _  C% r
        {! z+ X9 s3 a$ J
            return p->adjVex1==head?p->adjVex2:p->adjVex1;$ X6 V" Y* t6 B; D! D& `
        }
    1 H$ _8 m* f- q9 ~8 H3 F    else7 E" L9 q, n6 a& a$ C
            return -1;
    # C  b+ Y- y+ P' f( Z}4 X. @0 Z6 f9 ~9 i- v8 r
    4 q5 V4 R% O! l! G

    4 F* Q! F1 O( [; j( F: h. K4 p6 \template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()0 \" I0 D$ ?+ o4 p7 T
    {
    " V. _6 A4 d4 M) ~    stack<int> s;
    4 x8 j, \) x3 E    int p,cur,pre;% g, Y: N) m+ c3 u1 h, \: {
        //MultiAdjListNetworkArc<WeightType> *p,*q;
    / Z" `  G2 ?+ n, d7 B. ?, y2 {: d    for(int i=0; i<vexNum; i++) tag=0;//初始化
    * C4 H( ?* i1 u* g! {8 \! J" W+ T8 B2 L
        for(int i=0; i<vexNum; i++)
    ! Z, p4 B# v& E/ k3 W5 @# q    {
    7 e5 T" Q/ S' {: Z" d. G: z/ ~        cur=i;pre=-1;
    9 m( x; g4 R( q, U# W        while(tag[cur]==0||!s.empty())! x0 `( f* o- k: F9 ?
            {# W: |# d0 u0 S3 [) }$ D
                while(tag[cur]==0)% g9 O1 W; z) Y* X* s; C! U- Q
                {
    $ O$ O! ]1 @6 E) e                cout<<vexTable[cur].data<<"  ";
    + M" N; w% R0 u0 e3 G: g                s.push(cur);) S- ?  F; n  r+ p. V. \7 `
                    tag[cur]=1;
    1 }! X" I. ^2 A! l2 G( G9 K  v               //初次访问,标记入栈
    ) j: F, y% U( a' u
    ' d9 o3 F3 D- N, m# d1 z2 `5 Y4 ?9 _               p=GetAdjVex(cur,pre);//p是cur的连通顶点' b2 B" \4 |5 j3 J( o* Y- N
                   if(p==-1), ^3 I7 Z$ F" z* P. r  x
                   {5 z) q3 H9 y* U6 @# v
                       pre=cur;s.pop();& i7 f; P& l5 f0 W8 j0 R
                       break;: e# n4 j3 h% d2 ?0 e8 u& U
                   }. N+ ?* z" j/ I6 f1 A* A, `
                   else
    1 a' r" @% @( n6 a               {
    / ?$ x$ z- ~: g8 t  ^/ K                   pre=cur;; H  \, g0 I7 I( {* Z
                       cur=p;
    4 M# Y; ~2 O. b9 f: O" F7 D               }
    6 ?8 T4 y; A* v6 \$ Y$ b' o* z+ o6 I9 i* F
                }5 Z. B3 L  q( Y1 }3 f
                while(!s.empty())
    ! Z5 z* B( x' V4 k: W: S            {& q- `& K& K! _4 d* o% w  o3 S8 n
                    cur=s.top();
    . `+ J8 \: ?6 m* L                p=GetAdjVex(cur,pre);' r/ `/ {0 H7 q: Q
                    if(tag[p]==0)5 h+ I: _$ X" b& O7 I4 t
                    {
    % h6 N- W" d/ M  e( n  p                    pre=cur;
    9 l+ s' }$ t7 I; h) Z% L                    cur=p;# R* Z# g. x+ D# r
                        break;
    ( w) b: ^+ @) }9 }' k4 p                }. U: y+ ~3 M" M" ?( M* F. r4 t; e; x
                    else
    6 H' v" J$ Q! q* [# e* Y                {
    ; D3 u$ M( j8 V" |, s                    pre=s.top();- }1 l2 l! {* t4 h2 w2 q" x5 T3 R/ v
                        s.pop();$ z  h7 }6 b. h# @& n! l
                    }2 m! \4 d$ T9 m" M# G

    4 `# p" P% d# q# s4 V            }: c8 W" g3 Y" Z3 Y( d

    ( b! S) O: n2 w        }
    ( E" V+ v' c! s! g3 @2 ]    }+ @; I- B. Q# V7 Y- `: b
    }
    4 D& }$ p1 }9 o/ btemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()2 Z! G! ^* g' L) d
    {
    5 R) ]$ V8 q1 ], k/ w( I* @    for(int i=0; i<vexNum; i++)
    " X7 o6 ?# \" {5 f        tag=0;* F$ C/ D4 U' f# R9 L
        queue<int> q;
    ' u: g! p+ L, T8 ?+ b+ k! U) h    int tmp,t;/ N3 \( Q! @9 M
        MultiAdjListNetworkArc<WeightType> *p;' e4 ^$ P' F; y; M6 w  W' X' ?
        for(int i=0; i<vexNum; i++)
    - E8 o& ]/ G$ u" Z/ }, k    {
    - w8 Q- N( x3 N( ^        if(tag==0)2 s9 r! B4 l& f. u
            {
    1 t* h+ E2 }" b4 B% |7 h4 Q            tag=1;
    - i  C: k2 ~; Q8 R" _4 X            q.push(i);! ]5 X+ k. C5 X- X
                cout<<setw(3)<<vexTable.data;) C' T7 z8 Y: Q1 r1 q0 r
            }
    ! M2 h8 Z  |9 s% }1 w        while(!q.empty()): T& D" A8 b2 T% r2 _
            {9 f+ y1 O% u, j. _
                tmp=q.front();
    ' l* M6 A/ X: @1 v# n' S            q.pop();
    5 D% V. V, ~. R- I' p            p=vexTable[tmp].firstarc;
    , q' ~' Z+ y* a0 [+ w# }            while(p!=NULL)
    # \% c0 I6 ?5 S            {3 W! e, h" d& y
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    # a5 w7 I9 y2 f                if(tag[t]==0)7 c3 d+ u! B; S2 x, n. e, B9 j) @
                    {
    # O4 m/ K) `* y' I                    cout<<setw(3)<<vexTable[t].data;
    $ e# [  K# v5 J" p                    tag[t]=1;
    , ?2 H  C  k9 l) w                    q.push(t);" U# U9 u' V, @+ C: z) W! Z) z
                    }) H9 W5 H& Z( {4 O7 ~4 i
                    p=NextArc(tmp,p);& J' o0 Y  W$ N% n2 R" q0 A: r& ~
                }9 ]  W& t7 W# C' {- |
            }/ N0 @9 q! t! m
        }9 b4 _: I* q' J# u
    }9 B9 C& A8 n1 y6 i" L# `& W; K
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    : j; Q* u9 n5 P{# u1 d3 _  G0 E: j7 w: M; q$ M
        MultiAdjListNetworkArc<WeightType> *p;
    ; q) v! U+ r3 _4 |    cout << "无向图有" << vexNum << "个点,分别为:";* F4 B, v, ]2 M, s6 {! d  Q, T8 y
        for (int i = 0; i < vexNum; i++)
    : n- M9 x3 O$ A$ L- b# W        cout << vexTable.data << " ";: q7 J  }9 }2 N  m2 e- B# A
        cout << endl;
    % x" q1 d4 }9 [$ M3 I( w    cout << "无向图有" << arcNum << "条边"<<endl;
    . ]6 l9 u; y- C9 P6 A    for (int i = 0; i < vexNum; i++)6 p/ r3 a1 C/ a
        {
    3 r3 }1 d( {2 l- r. ?6 H        cout<<"和" << vexTable.data << "有关的边:";
    0 B7 L/ k2 E! T5 m        p = vexTable.firstarc;1 V# M( I, l+ w" }' P7 K& E
            while (p != NULL)
    ! Q% R' K! {4 f- t/ |4 P" A% A) p        {
    / V% s8 h# `* ~# }; P            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";* B4 U% F( V7 ^+ A. T
                p=NextArc(i,p);
    2 u4 W" k! U4 v. D0 ?        }; G$ ~8 k1 p+ D& S$ Y7 p
            cout << endl;2 v% k$ w0 j9 Q) j
        }+ T7 q, I8 Q& ^8 q) k9 ]* }) ?- k
    }' ~$ ?0 o8 ?. |
    5 L: Z" B2 P( ^; u* F
    ' O, C, c8 \2 [. `" }# {
    邻接多重表与邻接表的对比* x' Z- @/ h: @8 M9 v
    4 T0 q: R$ b0 K% {! I; `3 V
    邻接表链接
    0 U+ j' [8 J; P4 m0 k3 ^# |在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。" l% ~; x# `' Z- p% [
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。# o; V2 r7 j8 ]0 d
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    / f  W+ W+ g- A) i2 o% ]& N————————————————
    + y- d; x/ L* z+ ?( ]1 g# Z8 M版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    + f* Y, @) c8 G% C原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    + g" A& W. x$ @1 p) g
    3 e! w# _! B! z+ E0 e6 O3 B7 D6 M
    - ?1 d2 Y: |4 V0 r9 f
    4 I0 H% r2 n6 V  R2 I+ G/ F
    , d- p, R1 p; h: O* o# ~6 s6 E: V$ c————————————————
    ! r1 R& c1 p) p- {' [版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。* j8 H: [2 p, Y# L  ^! D
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958- k- O0 V' Q' e( K2 d% y
    ! o. [5 l- O: L( T. H. O
    # p/ H" e0 F; L4 ~( {( w% b$ q
    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-11-26 15:31 , Processed in 0.410990 second(s), 54 queries .

    回顶部