QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1627|回复: 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
    ! p" O: }' y( r+ H. s9 z
    图的存储结构——邻接多重表(多重邻接表)的实现
    : ^% @) j2 u  D' k1 v. }7.2 图的存储结构
    0 X' r5 f# F) M  y, G$ X5 I1 V, @: f6 ^, B- q
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    ; q5 r4 q) J8 K. s$ [" n邻接多重表的类定义5 i. |' W% k# E+ }: e
    邻接多重表的顶点结点类模板: X7 C% M: N* ~$ Q4 H
    邻接多重表的边结点类模板
    ! `  g2 x7 K8 A# q1 f% e邻接多重表的类模板: P* N4 e/ n* O/ b( @" q
    邻接多重表与邻接表的对比2 x' y; j3 Y0 \
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    # U5 S. Q% m, s  h! \, }0 L' C$ _9 `0 V, k
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    6 E3 {! U! }5 q+ z在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。) M6 S6 _! B5 p

    ; r2 `) _: S/ E邻接多重表的类定义
    7 ^& e* C0 k8 h6 K+ x. U 1.png ' O/ k" c0 P4 k3 P: o
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:4 {% `( J0 H; j$ ?4 `! ]
    data域存储有关顶点的信息;
    * j& c  j& W, V5 H2 w, Z: b2 Afirstarc域是链接指针,指向第一条依附于该顶点的边。. l$ w+ e8 |2 X3 m" u& N$ C6 I
    所有的顶点结点组成一个顺序表。

    2 u# S0 I# A. [+ s: I8 R& J, ]* N
    ' f* w' f# L9 G8 Z6 t5 d& A
    template <class ElemType ,class WeightType>: ^: H4 Z& A. U4 P  {5 P1 G+ H
    class MultiAdjListNetworkVex. |2 j  U, `3 [3 ^( L7 K
    {4 ?4 Z9 m9 ^6 h
    public:7 ?) J7 t# u- d, S& N3 z
            ElemType data;
    - n8 L  {; p, Z3 \        MultiAdjListNetworkArc<WeightType> *firstarc;9 f' m) `( @( X; K& S# f2 h

    ( J  o; d, x. j( c        MultiAdjListNetworkVex()! P1 G* I. {" `! P+ T  k8 l4 l
            {
    " i" L, _7 g6 n+ y0 Z0 r                firstarc = NULL;
    ! T% G  f8 ?% h3 ]7 p        }
    * X8 c' Z8 X, n. z0 p7 q        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    * z! w) v4 M1 u3 O1 t) k        {
    8 d- F- T. C" E6 D" t5 y                data = val;
    2 S( y- J. i  }( }+ x                firstarc = adj;
    $ ]: v. X4 b' y/ |5 h" A        }
    ; Q8 D. c, N% A( e2 M0 K# n# I};. ^' ?9 n" B. o$ j! ?
    * ^( h- O" O* G, c2 Q6 k
    邻接多重表的边结点类模板* h7 i$ @+ Q" A' m+ M$ J
    : e% B) x6 q' |7 z/ ^
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:0 p- E: B, N0 z# {/ y
    tag是标记域,标记该边是否被处理或被搜索过;. H. X- s4 a2 i
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;' h7 G' [' m! J; j2 l9 C
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;; B+ j/ y. b* U+ a. c7 c3 ?
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    1 p. G- a4 D- i; @! k. p" t# d, R" I6 w/ }  s% T! z
    2.png # [, k6 P5 p  o0 s, h& t% @* h/ p
    template <class WeightType>9 \5 Z' Y. h3 j% A- V# c9 o
    class MultiAdjListNetworkArc
    4 n6 L# V7 R2 Z2 f' m% T! }{! J( e* W/ l/ [1 s1 {9 ^7 N" L* [
    public:/ f6 X& f+ g/ i
        int mark;                                       //标记该边是否被搜索或处理过
    + p" @8 z3 x" U! ^2 a, V        WeightType weight;                              //边的权重
    & b; \1 l' ?* ?9 J( p5 d        int adjVex1;                                    //边的一个顶点
    # @/ |/ b& C6 l" q8 {        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-11 r4 ]) P9 R. z+ A
            int adjVex2;
    0 `, ]* l/ S, @6 u; _1 D( Q        MultiAdjListNetworkArc<WeightType>* nextarc2;
    $ o5 {# t: A8 u/ p! ], E+ W
    & [& O0 U  S$ ?5 L, J( ^6 k        MultiAdjListNetworkArc()
    ! I5 o  W! p, K' x* G3 H        {9 x+ n$ ^+ b, a6 r5 r/ A- ]8 S
                    adjVex1= -1;$ T3 t/ }+ G* u- C% _
                    adjVex2= -1;
    : w% j: K, Y' j$ `; E- f. w2 k& U        }
    6 ^% t1 k' w  t  r# V        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    " ~" r6 v  V0 {! _        {! E0 [6 d5 x: U9 U% @
                    adjVex1 = v1;       adjVex2 = v2;' u5 U- N1 j7 @8 X
                    weight = w;! D/ p$ Y  V7 W; f
                    nextarc1 = next1;   nextarc2=next2;
    / R/ i0 N& Q! _                mark = 0;           //0表示未被搜索,1表示被搜索过  j! a3 O$ `9 k. b6 V
            }1 d2 G7 p" }& G9 D2 j2 ^' s6 I! N
    & k8 x- b8 K; ~% b5 L
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    - r* l1 H. I6 iclass MultiAdjListNetwork
    " L. p0 |- H" m/ d' E{8 H( F5 p4 F' g# j9 I1 @! K
    protected:
    5 I# {9 P& I, a2 ^    int vexNum, vexMaxNum, arcNum;. C- z9 x/ x$ {: `( ?
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    7 t' F4 u" q- b. b+ K- M( G    int* tag;
    0 }' _1 J! t0 B2 U- l+ i    WeightType infinity;
    9 m, @. v8 w+ c. o* ?
    ! T- w3 W$ d1 o4 S, Wpublic:" B& e: S2 K  g0 h
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    4 O- `9 Z" {( V$ s) W' R3 t# a
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);! _+ p& h3 ?2 B, w1 s

    ! o  n7 ]0 l+ G    void Clear();* K9 L  W" z2 @5 g
        bool IsEmpty()( B2 w% c; L/ e5 c/ [) X8 }
        {9 N7 `2 L0 H1 t& ~: }: n7 J
            return vexNum == 0;
    : g6 m* r8 Z: v. t    }8 U2 Q9 B% a, i& H2 `$ J7 Q8 w
        int GetArcNum()const
    ! Q9 h* C/ n/ b/ J    {
    2 t5 o6 _) w. n- c+ [# T6 o, n' n        return arcNum;4 }/ T" }. Y0 L  A, I
        }
    ' Q! _( ?  s3 w2 ]    int GetvexNum()const% j- a6 \  {; S$ L) o
        {
    . t* x1 r- k. `        return vexNum;
    ( A8 D) e" i1 R    }
    6 x8 b, \/ e6 |0 s& S4 q
    % ~" h9 C8 Z) x6 d6 J4 K$ I
    ! [3 [5 R- L& t. o% w    int FirstAdjVex(int v)const;
    . t- V4 B% I. M% t% ]4 l) W    int NextAdjVex(int v1, int v2)const;' x8 u. e/ b& Y; I
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;1 q  `- Z0 `' X  G6 d
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    " ]" B6 L4 y6 X
    9 u6 x6 T* Z2 D. y& V  e+ h    void InsertVex(const ElemType& d);
    , A* M6 s- e% @: M4 w/ k' h8 J4 [    void InsertArc(int v1, int v2, WeightType w);: L+ h5 s% C: }  X+ H
    * r5 C# Q8 L# q8 `# |# E! V7 u
        void DeleteVex(const ElemType& d);
    1 k" X& c7 k, W8 u, e    void DeleteArc(int v1, int v2);% s! O1 `9 _$ j2 ~$ n2 Q9 K8 X2 @
    6 K+ g0 l# L# o6 }/ r
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    ( o* A% ]7 b3 q& B1 J- |    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);4 e3 g+ w& M, ?" T  i0 w: x
    * u" F7 f. ]1 F
        ///深度优先遍历) O7 u7 L& ?# j% p) Q
        void DFS1(const int v);
    $ \* c6 a! r; P, J: ^  R1 J    void DFS1Traverse();; q" u4 I8 p1 }- d4 B' F
        void DFS2();
      M1 A  q' Z9 I, D2 T: o; H: C6 V  Y+ m8 H2 W8 S
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    % ^; H* y# X2 H( D5 d    void DFS3();( o' O5 R1 C7 `7 c; s& I

    , G4 X5 w, U) S+ h6 H( `: Y2 l    void BFS();3 h; Q" y+ H; k
        void Show();
    1 }" M7 q5 X% p* {$ [+ n7 M};
    4 p. @8 m& J( F' ^6 E9 Y( g" ?
    2.函数的实现2 O7 a, ?  P; e' y1 O$ [+ _
    研讨题,能够运行,但是代码不一定是最优的。
    + L* h, a' _# W8 B. Y! L) z# g1 g6 ^6 Z# t" \6 r5 ^" C4 I
    #include <stack>& L( e& l6 b% S/ b; Z1 b
    #include <queue>9 f4 L( Z$ V) ^, @3 m8 Y

    / ?; C+ d/ A8 L$ `. K7 d3 S9 l, Jtemplate <class ElemType,class WeightType>
    6 N* ^9 k4 Z5 o$ L& \4 l% M6 s* W3 }MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)$ R7 W$ O- q3 d2 K. }/ }7 i
    {
    9 \" a% t( q. w. {, e6 U7 D    if(vertexMaxNum < 0)' _( j' @/ W3 z
            throw Error("允许的顶点最大数目不能为负!");
    ; O+ p6 {  U# A    if (vertexMaxNum < vertexNum). A6 W: r6 W1 ?* {; L
            throw Error("顶点数目不能大于允许的顶点最大数目!");
    ( u5 M! J3 u# G, B9 |2 F. _- v0 M    vexNum = vertexNum;
    7 ?: X# ^% M' A3 k2 }9 @    vexMaxNum = vertexMaxNum;) F5 N- s* j& u- c
        arcNum = 0;
      v# ?' ~# l8 m/ p" P6 K7 n    infinity = infinit;
    1 ?2 t/ Y8 y8 c( ~- e, m. q: b7 E    tag = new int[vexMaxNum];7 ~* r1 O! n+ u* ^9 B
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];) }% ?4 }: r1 h5 w) y2 V; f
        for (int v = 0; v < vexNum; v++)% S' @% Y4 \! G* U
        {* [# n8 D3 i9 {6 l: q0 m
            tag[v] = 0;" B8 g8 S& B8 u
            vexTable[v].data = es[v];
    + ~4 P8 `( N7 u. Q/ S2 s2 ~- F- a        vexTable[v].firstarc = NULL;/ L+ n5 P: L7 u* g- m
        }4 H" X, j' C2 z6 O+ x- ?' F
    }
    5 V; |6 t  O8 Ntemplate <class ElemType,class WeightType>4 i. n0 c+ `$ D! O
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)2 E/ y6 m* q1 K9 c6 j
    {
    1 D3 j5 `: C) @2 g# ^* H8 n    if (vertexMaxNum < 0)
    3 T" P  u" V. h! L8 _' M        throw Error("允许的顶点最大数目不能为负!");
    ( y2 X8 S7 ~* l7 ]) {- Y( {9 h2 ?    vexNum = 0;( _( }  a2 G3 _8 o$ A" k0 D
        vexMaxNum = vertexMaxNum;
    , ?" s2 g+ C3 m7 Q    arcNum = 0;2 Q8 z* ?( I! A7 F0 v6 J5 G
        infinity = infinit;; H# E9 g6 n7 l+ c3 e1 T7 M" N0 i
        tag = new int[vexMaxNum];; O$ j* l8 _- Y6 k' @! N, s+ e
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];6 ~7 n  c% Z. D5 f
    }+ Q1 L0 [3 L! m0 S  O5 f! ]
    template<class ElemType, class WeightType>, ^* w5 B- p. g1 Q1 E) q7 T
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const: I% p$ u& k$ g3 n6 D
    {
    $ Y; P% [( t" ], w6 u5 v    if (v < 0 || v >= vexNum)
    & Z7 B# T' {+ {8 n6 K4 Q) l        throw Error("v不合法!");
    7 f6 m2 T" R. t: i1 P- |. f( ?# Q. g) I    if (vexTable[v].firstarc == NULL)1 x7 w+ X* `' D8 A& L. X9 {
            return -1;* j2 V5 D7 a0 q7 ^* e0 B/ W
        else
    : U2 a! A6 j$ _4 Z5 R2 U4 {; k        return vexTable[v].firstarc->adjVex1;
    " A# G; K) I' @# |9 a}
    1 u* r8 C( y( v' I# k3 q' W( h: f7 e  M
    template<class ElemType, class WeightType>
    & [$ `$ ~2 j7 I) u: R2 ^3 M0 h" rint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const  @2 y  o" ~7 l+ b5 e
    {
    % K& B9 Q( f; h) t# X. b! }    MultiAdjListNetworkArc<WeightType>* p;
    9 B" |' G$ d4 [3 T( |" J4 b  X    if (v1 < 0 || v1 >= vexNum); c; H& x! [7 S. a# v, o  e. a/ I
            throw Error("v1不合法!");
    . M( f3 m- y- ?    if (v2 < 0 || v2 >= vexNum): W  J# m5 `0 E, l( v1 s1 Z
            throw Error("v2不合法!");
    8 z+ X: |- A% c9 V: q    if (v1 == v2)
    6 {+ R$ g" i/ c/ d1 E" t        throw Error("v1不能等于v2!");
    / \1 E: K0 W+ F! }    p = vexTable[v1].firstarc;! `3 d7 L3 W' o% _: }5 w8 _7 h7 @8 A
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)0 ]0 n/ C, n3 u2 ?7 B
            p = p->nextarc;" K5 p, r2 f2 C* _- Y' T/ B7 }% Y
        if (p == NULL || p->nextarc == NULL)/ [; ^& b8 ~: n$ D2 G0 q4 V/ V, F
            return -1;  //不存在下一个邻接点
    & f) `% y; k! y    else if(p->adjVex1==v2)1 x; d/ l4 e) X1 W/ {  [" F
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    : X, d, W; {/ E; Z7 ]& `# O2 g    else
    1 C. q3 s/ s& q# b+ D: x3 {        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);. ?: I0 F4 Q4 K% M4 A) [
    }4 [# j6 X- a, W. N6 U  d5 y
    template<class ElemType, class WeightType>
      ]$ `) R1 x5 l! i% cvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()
    % |3 W' W7 Y* }$ `) a* j$ p; A# R{
    6 s" [+ c8 J% G, j" C    if (IsEmpty()) return;7 ^8 [8 [- x4 s
        int n = vexNum;/ A. V0 @7 X! L) ?0 c
        for (int u = 0; u < n ; u++)/ n& `! z, {7 ?- m; m0 g  U
            DeleteVex(vexTable[0].data);0 E6 e$ q6 C  B- f7 a/ u
        return;
    9 y/ o  p3 ?  P0 ?, q+ o}6 J! N/ C& _7 m& w& R
    template<class ElemType, class WeightType>
    $ v) N' c1 o7 Z, lMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    : I( v  \% G5 B1 E; n6 K' Z) B# }{; |3 F# }7 o$ K/ b: ^7 C& G
        Clear();
    - k# v/ q! ^  J2 Y4 T# p! a  N& v}
    5 @! n! q% O% h- Vtemplate<class ElemType, class WeightType>1 R7 J2 V; x0 t6 N
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)' f4 ^3 ^4 g- g0 U* [
    {
    6 b4 b. m: a! S5 [+ z% [* w    vexMaxNum = copy.vexMaxNum;
    ! l( e, p$ G7 R8 V    vexNum = copy.vexNum;
    & P- ]6 K7 t0 d+ r$ s; `    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    9 c2 c. ]/ W  _, Q% T/ Q2 x1 k    arcNum = 0;
    5 Q9 B# R7 j# y6 w    infinity = copy.infinity;1 C( y) @; r! h# F! c
        tag = new int[vexMaxNum];
    ) o+ Q; _' s0 k- z( l7 V1 J$ G2 p/ K9 t
    + O/ X& z% @+ m2 D7 v    for (int v = 0; v < vexNum; v++); w4 M( i7 }2 D
        {
    6 H$ B& z3 f. o: x3 D' ?  ^) l        tag[v] = 0;, A1 `; k3 d4 ^2 M! Z
            vexTable[v].data = copy.vexTable[v].data;6 `: w  H( {0 `0 j. I4 Q8 J
            vexTable[v].firstarc = NULL;
    3 t: K$ [% m8 I! f% B    }
    $ a! p/ g* B  _( A    MultiAdjListNetworkArc<WeightType>* p;
    5 v5 g" j1 X! O3 Q. t3 \
    . b9 M+ {# o7 w8 @. h    for (int u = 0; u < vexNum; u++)
    % |1 C( x- O. \) a! {. B8 c! X: x8 N    {
    4 _2 X1 m7 f6 `4 E/ `1 }        p = copy.vexTable.firstarc;! b9 n8 k( a' t4 \
            while (p != NULL)
    5 z+ [9 U  u# _5 A) j" i: d. u7 `        {
    0 b- c- t( i2 u8 p5 }# K            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    % K9 [$ R) Y. J0 h            p=NextArc(u,p);
    " i5 _& r* ]# y" s. V6 q        }9 `2 ^) H, _0 U
        }$ C3 y0 P6 L, j. A7 z; {
    }& q, _  n/ h% ]/ @$ W5 b
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    . T; d2 n' I5 l* e. o8 f2 zMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)' n( v7 c0 i" ]3 y$ A; o
    {
    ! \" q! J9 t$ _+ z5 v    if (this == &copy) return *this;* Q# M. @3 B) D' a! F! K
        Clear();
    9 d, c+ j, Q7 U1 m$ ?/ j    vexMaxNum = copy.vexMaxNum;
    , W* n4 J" ]; T+ @: A4 R6 v; b- @    vexNum = copy.vexNum;5 {. Z/ E1 [9 ~+ Q! Y4 k+ `
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];; \& _/ f* a% {8 D% @) a
        arcNum = 0;
    , r1 Z6 G3 u# X2 t5 j; u5 T8 A4 d    infinity = copy.infinity;& N3 ]/ h  a' C( C
        tag = new int[vexMaxNum];
    + v4 U% Y+ s4 ]- _0 u5 W4 l* P( n
    0 V" x# _5 t7 _2 u/ @    for (int v = 0; v < vexNum; v++)
    ; K& W$ W) ?. @) Z* K4 k6 r    {
    ! A/ E$ `2 T% t/ h8 B* E2 ~        tag[v] = 0;/ [( Y5 Z+ s! D1 _5 @" }2 k
            vexTable[v].data = copy.vexTable[v].data;- a  ^: U+ Y4 O. [
            vexTable[v].firstarc = NULL;
      `4 v6 P$ g# w( Y8 A    }( T! Q* g) |1 w6 g4 W4 B0 i7 a
        MultiAdjListNetworkArc<WeightType>* p;/ h" V$ o3 T6 n2 O/ u+ L' d

    ! A+ \+ [0 _$ i& Y$ |    for (int u = 0; u < vexNum; u++)
    - I' V# b1 U3 V6 n/ i    {
    1 ^; l: u8 H$ r7 L! q        p = copy.vexTable.firstarc;5 P, `" o6 Q% x% W% A; @% ~
            while (p != NULL): H# E( A6 d1 o3 R. `0 N& ~3 a
            {
    6 ~" T) V9 w- W2 O            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    3 q. e: T/ F, m7 r) c& [, }" w% n            p=NextArc(u,p);* \! o2 V* x0 v' F$ k3 ?& E" `
            }* |+ o/ b! R1 `: X
        }, b, u; r6 g- n) k) N/ N4 Q
        return *this;
    # M' r) L9 m- t1 W}
    2 x9 i. n5 H; J* Wtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*$ F* m1 m) n% s, S# i
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const3 r% v/ P5 Y% q
    {& f$ f7 [& ], n/ B+ X$ n6 O
        if(p==NULL) return NULL;
    6 M6 w2 g, f# Z4 j  A    if(p->adjVex1==v1)/ W$ L; M- K* `' ~  X: s
            return p->nextarc1;
    2 F, E8 N- @/ n2 f  z    else" a" Y/ Y, I! i! @6 r
            return p->nextarc2;
    8 m8 f4 _" h7 @1 I  @5 V}
    ; Z" J) |6 O( l1 h: Vtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*4 o' _7 s, w! c
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const  H9 I* P" Z0 U3 x) z' e9 `8 F
    {
    : |* `8 k: f  \0 G' O; S    if(p==NULL)return NULL;
    6 p/ |5 I0 m/ t/ W    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    4 P/ z  w5 A2 k" i! G- Z    if(q==p)- \  L' `: Y6 V. J# O, }
            return NULL;. V1 L) f% v- l  F! n' ?, u
        while(q)
    2 P9 \1 X, y% y* ^5 ]  h+ ^    {: K5 [. p$ K  F8 t! \6 d
            if(q->nextarc1==p ||q->nextarc2==p)
    3 d1 E  y, q2 i; L" o1 G            break;' f, Q. s- n+ F, G6 u7 G  M
            q=NextArc(v1,q);
    ; m! A7 l5 u1 q, {    }) Z  k. J. O4 G
        return q;
    , ^) Y' g2 s- [+ V" ~+ P) U) K}1 w) t# n6 c, p6 v( e
    template<class ElemType, class WeightType>
    8 E% }6 Z% K% K: Zvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)/ h- N4 V) f+ p
    {2 q1 a( z8 \  r: g  H: p8 |4 s: w
        if (vexNum == vexMaxNum)
    & P0 e1 g3 [8 [9 g5 ^% I        throw Error("图的顶点数不能超过允许的最大数!");+ D7 {6 f0 d8 e5 Q( I3 Y# B% Z/ Y
        vexTable[vexNum].data = d;
    $ P6 @* B+ x+ c) B6 I    vexTable[vexNum].firstarc = NULL;
    % f& Q' d5 Z8 e, t8 R* V  n    tag[vexNum] = 0;
    ( M6 ~! B( \4 A1 Y# R6 K: [% I! ?, f    vexNum++;
    ( J5 v/ G9 D; I6 p}
    ; T8 P. c* x& E# ~" v/ v# s5 utemplate<class ElemType, class WeightType>
    + h" b% {3 A5 [# O% lvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    : z! u- x: `: @; i6 _' V) K{
    9 O  U3 N1 e6 w; n    MultiAdjListNetworkArc<WeightType>* p,*q;7 T& \# }% h5 T- L  ^7 |* u5 }- \
        if (v1 < 0 || v1 >= vexNum)# k! t4 B$ V7 z8 d8 l3 G
            throw Error("v1不合法!");
    8 z2 U) W0 n% ?  D% X    if (v2 < 0 || v2 >= vexNum)
    $ z5 ]. A/ w( q6 Z        throw Error("v2不合法!");3 [3 |8 B- P  x# \4 p3 M
        if (v1 == v2)) N3 c% D( e$ }) m; g$ [; |
            throw Error("v1不能等于v2!");% y8 x& y* R% `! g) S
        if (w == infinity)
    ; o5 n7 A9 W3 n( W4 L        throw Error("w不能为无穷大!");- \7 L8 C6 ?! `1 v1 N2 f! r
    $ x4 i- x* Z3 v7 q) u

    ; u) a8 F" l0 Y- k$ e* a" N    p = vexTable[v1].firstarc;
    - A! J0 @$ W. E5 J7 D    while(p)
    9 j! b2 }% \1 i2 P. [* H    {" }' a! c+ L5 d" _/ \% x  y* f
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    7 e: g9 w8 w6 @+ e: S7 }. I        {5 X; [) `( Q% J* O9 `
                if(p->weight!=w)# ]3 J) |$ }0 g  U( n
                    p->weight=w;" M+ D' Z: X2 h/ N  _
                return;4 o# z; ^) ?+ a; [
            }! O: W: k) H# j1 G! [& T
    6 O; x' x1 I# C3 D, b2 \) d) b3 ?! U' X
            p=NextArc(v1,p);! G$ D4 S2 {2 j% m, f
        }0 N: p& C; d) C) i2 V8 A
        p = vexTable[v1].firstarc;! ^$ _0 [& @2 p1 j# B% G
        q = vexTable[v2].firstarc;
    9 G/ b2 m2 {. U/ X    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法& M/ M6 _8 P- H/ |/ X
        vexTable[v2].firstarc =vexTable[v1].firstarc;+ c$ y* ^4 r: l, f3 D( d) N
        arcNum++;  s, e, g, @6 u4 E) i' @- D% s
    }
    7 d' b& S! f& v7 o- ]/ f- y- m: |' V
    template<class ElemType, class WeightType>
    5 I( T4 O$ V0 X; J  y' i' wvoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    4 ~6 D. N. z* C& ^{: i8 B+ ~& v- E

    " y2 H1 o' W8 K! b2 I7 V    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    , n) ]  R* N( v$ w9 b    if (v1 < 0 || v1 >= vexNum)
    ) [( e5 ?2 k! `        throw Error("v1不合法!");
    $ H/ V: T$ _3 H6 e    if (v2 < 0 || v2 >= vexNum)
    - I: y& K3 |; q7 `. {8 [        throw Error("v2不合法!");
    4 e0 `/ S$ p3 ^! N' s8 w8 z    if (v1 == v2)
    # _5 W: u5 U2 s% I% }3 E        throw Error("v1不能等于v2!");% M3 T2 q8 M6 {$ U
    " Y! _2 R! v8 c0 L1 \
        p = vexTable[v1].firstarc;
    & J% l0 j' U! X2 b0 }    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    3 ^% V. M8 I9 r8 e# b    {
    * u7 y' Z  W0 @        q = p;
    6 W9 i" C* H, {& A' T' r; r4 B3 r        p = NextArc(v1,p);
    2 z6 K4 }: w1 x    }//找到要删除的边结点p及其前一结点q
    - f" p3 A5 j' ]
    1 D% ^! f; y+ ]! _7 |+ u1 ^  f    if (p != NULL)//找到v1-v2的边  P' H% n# j7 R+ J
        {
    0 U) }( g: A2 ?4 S+ d        r=LastArc(v2,p);
    0 G( s$ E# E, Z/ Z' X! |" y' G5 \! Q        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    4 {# t1 K* v" t            if(p->adjVex2==v2)
    5 s* V& G( x1 L7 P* ~  V+ f. e                vexTable[v1].firstarc = p->nextarc1;
    . _9 M' `& @7 ?# D, q            else vexTable[v1].firstarc=p->nextarc2;
    , i! v/ N# P: Y5 i        else//不是第一条边6 _8 M, ?( a6 {
            {4 Q: n( v, O7 K& c! a+ y+ d% D
                if(q->adjVex1==v1)
    $ g5 K* V! n( X& x6 b7 ]                q->nextarc1 = NextArc(v1,p);* z3 \4 o' N- A0 I6 \& \) v" z
                else( [) x+ f% Z  u; L2 l! c9 V
                    q->nextarc2=NextArc(v1,p);4 b+ w* ^' {/ `4 @8 ^+ s- ]  w+ s! K

    " _8 f% g2 z; W* \        }% \5 ]' B2 w- @  b" w, U. o" Q8 a
            if(r==NULL)9 b" ?# j# }8 [: d; y
                if(p->adjVex2==v2)0 Z# R+ |) w: G- m
                    vexTable[v2].firstarc = p->nextarc2;" |4 f0 D0 ?  o5 G" e' Y6 y
                else vexTable[v2].firstarc=p->nextarc1;8 D8 t" e" n5 b! y  ~/ G1 k( b
            else3 `; ?2 A/ N. L  `9 `) g
            {2 V% U7 ]- \  p8 S" a! X
                if(r->adjVex2==v2)
    2 E: n5 M" b! a2 D. w- T                r->nextarc2 = NextArc(v2,p);
    + O5 j& B' [0 h7 o- e- Y7 p; \            else
    " E( |( F' X: L+ Y0 f8 S                r->nextarc1=NextArc(v2,p);* w6 g3 R* r- i2 k8 i
            }
    " C6 `! b9 T" b9 p8 ~: ]' G1 _& X        delete p;
    4 }. d) h! e5 _4 X7 M3 A        arcNum--;2 f- a# r0 A( L) x& N
        }+ z9 I, @! X, E3 V2 D
    2 Z8 i# d+ F+ k  P+ p' C
    }
    ( G4 N' C/ J, l2 q' M: R7 ~$ ntemplate<class ElemType, class WeightType> void; U, `1 E0 q$ o  C
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    $ n- N, B( t; \6 s8 f{
    ) g% D4 u) T/ {! t4 C# S" \# J    int v;
    9 ~+ Z6 A+ e  f    MultiAdjListNetworkArc<WeightType>* p;
    - ?0 Q0 m* b% i    for (v = 0; v < vexNum; v++)//找到d对应顶点
    : O+ g1 ?) H6 L+ o3 e4 v+ g+ y, x" f        if (vexTable[v].data == d)
    2 l0 {4 j) _* }+ S/ b            break;; A3 ^  t( I. l( B" r. d
        if(v==vexNum)
    2 j3 {& U# y/ L" M8 w. H: d$ p! F        throw Error("图中不存在要删除的顶点!");
    ( ^! Z. G% y; [8 D0 L& ^: [/ [, \) h, T" I$ j5 }% I
        for (int u = 0; u < vexNum; u++)//删除与d相连的边
    " d) v! Y8 v. l9 K        if (u != v)  F, Q2 c7 ?" v  q. ?) G/ p
            {
    : I3 b  Y5 c5 f$ U, S( P1 ?            DeleteArc(u, v);
    % P% `2 F# ]  k2 Q- a% i) Y        }/ q! \. N* e6 Z' i3 P
        vexTable[v].firstarc=NULL;' N4 ~) H6 u4 b  p

    % j6 e, K+ r4 P    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置) s! ?  k: h, o% @8 s9 r+ o
        vexTable[v].data = vexTable[vexNum].data;# j% @4 `% t2 ]
        vexTable[v].firstarc = vexTable[vexNum].firstarc;
    & T) R& ~. {8 ~1 M7 W5 E4 `/ j+ F    vexTable[vexNum].firstarc = NULL;
    9 p/ n( E  e( v    tag[v] = tag[vexNum];
    & n, |# M, H: g! h* T7 e$ ^    //原来与最后一个顶点相连的边改为与v相连
    " {( @& y# Y( r7 Z5 |    for (int u = 0; u < vexNum; u++)+ X, W1 f: g- ^
        {6 l. m7 R7 u3 R7 e
            if (u != v)0 S/ {- A% k3 H& x
            {  V2 c- O$ x4 M/ g9 V
                p = vexTable.firstarc;4 d+ s2 r' ~5 ^- t
                while (p)
    % S# q& v. Z- O4 O" t! z            {$ O$ b; b0 |) A* j4 V
                    if (p->adjVex1==vexNum)
    9 s4 F. `& A" T0 z' I. ~6 u! r                    p->adjVex1= v;
    ) t$ M7 [; i- Q+ v/ I9 [( \, X                else if(p->adjVex2==vexNum); T! d' Q1 i9 D% I
                        p->adjVex2=v;
    * n- w1 k' _- j/ I                p = NextArc(u,p);( Q  b% h% L! h& E
                }
    * S, w/ `0 j5 D/ i! l& a8 L* ]        }! N6 k. e$ h+ f2 N+ D' J/ y, ^
        }- `  W- H, V' V/ B* l2 B
    }; i, J" h6 ~8 n
    ///深度优先遍历1 m) B- R3 Z0 @- Z% B0 i# S6 i
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    8 Z% K: x8 Q2 O6 K( t, i1 z{& L) c3 W. l+ h; w
        tag[v]=1;
    8 F* d) m$ ^- L- K5 {  L1 ?, c& U    cout<<setw(3)<<vexTable[v].data;. }6 i4 V+ Q$ }: T, ?0 u
        MultiAdjListNetworkArc<WeightType> *p;
    ' ]$ ^, v; h6 {$ G; n    p=vexTable[v].firstarc;
    9 N+ n2 u: a& m2 r3 o    while(p)
    4 s7 {8 d  O4 s& Z) S9 @: y    {
    ; B/ H$ x1 u) I1 D( A$ }+ S2 M' `. J        if(tag[p->adjVex1]==0)
    5 m/ N  `* X# p* r. {* e4 x& C            DFS1(p->adjVex1);
    + T7 L4 c* S: |' I4 e        else if(tag[p->adjVex2]==0)! }' ?0 X( F, E7 R- F- p
                DFS1(p->adjVex2);
    1 Z2 a! i7 @7 F6 {$ e        p=NextArc(v,p);$ W" p; }; [$ \5 V1 N
        }
    . n; k; \7 A# h+ ^+ L}
    $ b7 l( M+ G: ^( ]% N; H8 t. ?  mtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse(); w& s8 }, u2 p% J/ J+ K5 o
    {8 G8 ]' ]$ v( ?
        for(int i=0; i<vexNum; i++)7 g3 ^( U. J7 p, f) {7 \
            tag=0;/ F* w6 I, @7 e% Y( v( d
        for(int v=0; v<vexNum; v++)5 C  l& \( O7 I- L. g5 J: d
        {
    / D8 K9 t% C9 F' d. Q* Z" m' _5 H- @0 S        if(tag[v]==0)3 F7 H  r: G- i! L& K
                DFS1(v);
    , E$ {$ g2 h! r& P    }/ e" Z; k. _! V2 C+ S- `  E, S1 V5 F- d
    }$ j; ]# T5 Q2 ?/ v
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2(); ?6 Z6 E: @  ^2 m9 P$ ?
    {& J4 I, d' @& R  w! U1 ^: W# x
        stack<int> s;# ^1 T' `9 p  @1 {
        int tmp;; a& Z7 x. E  |! v# p& R  T
        MultiAdjListNetworkArc<WeightType> *p,*q;$ G8 F0 _& S$ y. x/ A
        for(int i=0; i<vexNum; i++)
    9 T4 J* z  V8 I8 ^+ H        tag=0;" K. i% F* T; T
        for(int i=0; i<vexNum; i++)7 p. U9 m) V0 E
        {
    , R8 Z7 A6 c. N- p: `        tmp=i;9 h* c, N0 ~! o$ o
            while(tag[tmp]==0||!s.empty())/ a" i7 h* d/ N- N
            {! Y  O1 p9 l, }" N) J3 |
                p=vexTable[tmp].firstarc;/ ]. t$ g1 q" D/ [: e; I
                while(tag[tmp]==0)! @+ {& r' Y" c# N% D
                {
    ' n; z& {& u7 Y: E                s.push(tmp);" r# V, d3 q3 T4 m$ V% A: m8 f
                    cout<<setw(3)<<vexTable[tmp].data;, Y9 a2 z: {$ U8 e
                    tag[tmp]=1;
    7 T' b3 M8 g5 b$ x, M                p=vexTable[tmp].firstarc;
    # U6 O: ?0 V) M: Y9 w+ `                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for6 S- F; L; R+ i& I5 o* v
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    ' p# o( X! C9 _3 a6 \/ F3 ]. x                //cout<<" 1st     tmp="<<tmp<<endl;
    + S# C4 d/ {6 V6 P            }& [' M& C, I! E  g7 j' N5 Q  i
                if(!s.empty())
    6 u+ A! m9 c" E. d            {
    + z( S& {; X& r/ V                tmp=s.top();/ J$ T& c' I# f6 s  y5 h! w- t
                    s.pop();
    + O9 Q5 C/ I% o& G                q=vexTable[tmp].firstarc;/ N" i% a6 C" k* b/ w3 c) E4 A
                    int t=tmp;
    : W' [$ b5 `8 }' H; T                while(q&&tag[tmp]!=0)
    $ v. ?5 g- p- w                {
    0 X  l1 O) D8 O                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    . |- a, D" s8 O( S. C& I                    //cout<<" 2nd     tmp="<<tmp<<endl;
    0 L5 w* q! E# {1 ^& t/ v                    q=NextArc(t,q);
    $ V4 ]' X- Y" G3 j/ |6 X                }& @9 Q) j1 k# e9 }, m: y( L
                    if(tag[tmp]==0)$ F( y( ]- Q7 d9 u6 ], v5 C8 ?. x
                        s.push(t);
    . r* s2 ~) F! k: E4 O                ///1、对应上面连通分支只有1个点的情况7 \* ]: @9 @$ j8 p: Z1 y9 F
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈' N7 c+ t1 o0 _* \" Q* q  l
                    ///tmp要么等于找到的第一个未访问节点,
    4 `% {/ F' K. K  f9 ]( w. q+ m" Q                ///要么等于与t相连最后一个点(已被访问过)2 p# ?3 q7 r8 B9 v( L
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点* O9 B! S* y- x$ S2 A2 T
                }5 I1 I( t# w- _* j# l, U( w. R
            }1 b* {: Z9 C6 |* Z' K  M
        }7 Y8 a1 H5 P' L$ C; _% s) w( @
    }
    . w( c5 e+ J- ]6 ]8 e- u: e//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1+ r6 i8 U# P3 G2 f
    template<class ElemType, class WeightType> int- Z2 s/ e$ q% R+ e0 @
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    ( q6 `. e" y% n1 U& O" i{
    : `1 `" L! X* p/ O0 W& p3 |  ^  c8 W    if(head==pre)
    / t" t) Q4 a1 i  d+ t        return -1;% Q, K, V1 j7 \2 _# L
    ' c' H, m" K% b2 y+ v& ?  _
        MultiAdjListNetworkArc<WeightType> *p;- n; P) Z3 F- i/ g3 p4 `+ P1 P! w6 Y
        p=vexTable[head].firstarc;
    ' v& o+ c! s  g8 r) w% a4 o% ^    if(pre==-1&&p!=NULL)
    4 K6 c5 P$ L* C( v2 K        return p->adjVex1==head?p->adjVex2:p->adjVex1;* A4 h7 B: @6 c1 D
        //pre!=-1&&p!=NULL9 D) x5 y% [9 }( [7 C; ~# u
        while(p!=NULL)
    + o- F: E' W: k3 X, ]; ]; {    {5 Z5 A9 w( r& z" k
            if(p->adjVex1==head && p->adjVex2!=pre)6 k1 b8 H: E9 x5 p8 R
                p=p->nextarc1;
    3 [! X! \: Q: F% B) |        else if(p->adjVex2==head && p->adjVex1!=pre)) n2 F" p4 o: ?( u$ w/ k
                p=p->nextarc2;
    8 _5 {4 k, M; ]0 H        else if(p->adjVex1==head && p->adjVex2==pre)4 b3 F/ X7 h( H- @( [( D
            {
    , J; F: l6 E1 Z# t- f2 L# w            p=p->nextarc1;
    3 C' k& h) ]3 t+ D" f% ?' }            break;
    : g! f7 S2 T! h' S6 `$ C        }' h# B; a5 {" B1 ?
            else if(p->adjVex2==head && p->adjVex1==pre)% Q" S0 U/ L- Z% U% ?) R: T# o2 ~
            {
    9 [% U  i; C' W! P6 I- H            p=p->nextarc2;# A! o5 t! \7 K$ t
                break;
    / N+ a( o* \. [0 c        }- X! @* p" k# ?! f  M
        }3 Y& \* ~4 }9 M5 }. m1 ^- z4 M
        if(p!=NULL)
    ; j5 j% T) \9 s* F3 a! f; f& f3 ]    {
    3 z  c: E* T; U8 Q  v        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    : v, O6 s4 ^2 I: @0 q  c9 ]( {    }
    * R, J5 B- \" J1 x( ^' a    else
    ' t7 M' a; h4 I" `5 E        return -1;2 [, k) T/ L$ `( w2 U) E. @& w
    }% y$ Y# n5 k9 @$ Z5 u2 m* m7 M

    9 [" D, W4 I* p4 C* q" |% X( `/ ~
    & p; |2 _5 K: S, Y( Z( {  ytemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    2 \: f0 o8 Z( V{
    ' F+ p" N" C% G$ b2 D$ m# [    stack<int> s;% Z$ z/ \! C8 @. T. I
        int p,cur,pre;
    7 G, n9 y% H$ ~4 G7 ]7 l1 c    //MultiAdjListNetworkArc<WeightType> *p,*q;; ~$ j  u2 `2 n; `7 c8 S
        for(int i=0; i<vexNum; i++) tag=0;//初始化( z# q; l" U8 X  X7 L" a& x

    5 H4 w; G0 z) P    for(int i=0; i<vexNum; i++)
    0 p; v$ B( B& g; p/ \' l    {7 r+ H' N6 l: g+ _/ w+ g# C) t8 J
            cur=i;pre=-1;* G" R/ ?5 K$ p% R0 i
            while(tag[cur]==0||!s.empty()), t, E7 O/ P* z/ X0 q& I- V
            {
    9 z/ s3 V1 c* y7 M$ N4 j4 |            while(tag[cur]==0)2 B# }2 s/ I/ p
                {1 }7 Q: O& H4 _! F/ w
                    cout<<vexTable[cur].data<<"  ";9 H( G, |( p. m/ X! j8 @2 Y
                    s.push(cur);
    4 @' s4 q$ h7 T                tag[cur]=1;
    * a' `# {0 O4 n' \+ M               //初次访问,标记入栈
    , F8 M9 g, O# T9 M' h1 W) r' m5 |) |# e( @
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点4 c4 F& _4 t/ w: J, A% x
                   if(p==-1)
    4 R' Y) b2 B" f; g' }               {
      T& Q4 e( M2 Q6 m! R0 i5 r+ _! k) }                   pre=cur;s.pop();# z5 N! ?% x/ ^
                       break;% y9 A: x* B5 z
                   }/ u; o( T: i$ {1 `$ u  A5 J: H( O9 m6 B
                   else
    7 h3 u& X! N& D' F* B               {
    ' j9 t" D6 G6 U                   pre=cur;. T+ \$ }) |( `$ E& d! X) U( M* \
                       cur=p;5 P: u1 B" g$ ~* {
                   }
    " Z) ^% ?% \! z* L, s! D/ P' I3 A# s  Y" \7 k
                }2 `1 o( K! j- ?1 e/ I
                while(!s.empty())
    ! ^: I2 g/ t7 v            {
    ( S* |& [4 ?5 M; @) h- T$ d                cur=s.top();
    , L/ Y9 O: V1 X- R! u( H                p=GetAdjVex(cur,pre);. u- j* K3 R, d5 A0 e6 I2 D
                    if(tag[p]==0)% z# E" a+ D* o9 y( o0 e! a7 o
                    {
    , ?$ C& H# E' G                    pre=cur;
    0 V# x- x8 G+ ~" A" G: f" U                    cur=p;
    7 [. d( t- {8 d  j6 u# _                    break;
    4 H" |, c) A( Z& U9 A2 A                }& s# Q7 m: I1 X) Q: k
                    else
    5 I3 O, J! |) b1 O8 L: C                {* _3 q0 W6 T5 z! F( s% \  X7 k
                        pre=s.top();4 s9 C5 L- U/ C( o
                        s.pop();1 b: x4 x6 e+ ?
                    }
    5 s2 B, p  Y! m# a# L) b3 Q+ x! K1 i/ E' ~$ y6 D) R
                }% n/ F( L1 K' `4 l
    ' ?% F- P& E& b/ b. m( L8 Y
            }- V9 x6 |1 I' g4 r. }* r
        }6 E+ y: i- j9 p7 C
    }
    6 k& w, d5 m8 B: n+ R" R# L. Otemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    % k- O) E# t2 W7 h# v{
    * ?! _% D  e+ N  H$ d    for(int i=0; i<vexNum; i++)
    - X' I! [: o8 Y; Z        tag=0;& |" b3 n  i5 P8 w
        queue<int> q;' `! w1 n, _# }# E/ `
        int tmp,t;
    5 {7 ~+ _. O4 d( w0 W4 q    MultiAdjListNetworkArc<WeightType> *p;
    2 S4 x. ]; D7 ?' U% r    for(int i=0; i<vexNum; i++)
      j5 Z0 M( c# x2 t9 r8 ?9 F! B    {" d. v8 Z! }, R  b) R; O/ d
            if(tag==0)7 j  H$ t( M  a% B3 P" f0 h
            {- O# I/ u. K. j) b
                tag=1;
    , V( ]( c( ]( X' I6 v            q.push(i);
    9 `  K% o0 m* L& d. J            cout<<setw(3)<<vexTable.data;! m% ?) k  M6 M8 l/ |  }
            }- M8 @  r, W& _$ x( y
            while(!q.empty())% }4 k7 E) V/ @7 {
            {
    1 U  \3 R, x" v1 S# M% [            tmp=q.front();
    & T. S- o5 b$ }% R5 r            q.pop();
    0 j% s1 f4 F7 L" g. F$ p            p=vexTable[tmp].firstarc;( m" H) l* @8 q) W# u' c
                while(p!=NULL): c8 y; H! K6 k7 k7 S' D
                {
    , ~# }: ?% o% m: Z5 A' _+ J6 l6 f                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);# a0 T  f- j  H/ s/ C! {
                    if(tag[t]==0)2 H' U8 c& `! Y" G* A) g9 Z# s
                    {: Q# d9 v# s9 I3 j6 {
                        cout<<setw(3)<<vexTable[t].data;
    ( o, j7 u( h) o5 d  k                    tag[t]=1;
    & o  R0 u* ~6 y1 ^% G2 O, k                    q.push(t);% J6 ]% y* `* m+ L6 S, M4 [3 j
                    }
    " U9 m0 {+ x  Q. P                p=NextArc(tmp,p);9 D2 H- G6 c" w
                }
    . x9 X3 k6 f; f% P% v2 t        }; }0 s0 M: q4 p/ I3 X
        }
    ' d! |, s$ w" f7 L6 D}  o, I4 Q6 r8 _" R/ F% [5 u
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()3 q0 k: n7 |6 a# ?0 g, r
    {
    $ F* b% U7 H1 i. d    MultiAdjListNetworkArc<WeightType> *p;. ~; Q% }0 y% k. A
        cout << "无向图有" << vexNum << "个点,分别为:";
      Z" ^3 F3 V8 f: h' }    for (int i = 0; i < vexNum; i++)& Y6 O! h% S7 T
            cout << vexTable.data << " ";
    " q( }4 l- v3 X5 z8 P) D) C3 N1 V# f    cout << endl;
    $ s3 M* H; r: D% u- z+ `  I    cout << "无向图有" << arcNum << "条边"<<endl;# U" v% b/ e" a! ?, c
        for (int i = 0; i < vexNum; i++)" g+ x% {8 p, L6 B. u5 `
        {
    4 L* \4 M1 W0 y9 n4 l& ^2 Y0 O, h8 A        cout<<"和" << vexTable.data << "有关的边:";
    7 G; \7 E( |+ Z5 I        p = vexTable.firstarc;
    " S1 ~$ F1 v  F0 }1 w4 A+ v        while (p != NULL)- _! h, M! i5 L$ c  @
            {8 g. w) L: {3 E; P" E( w
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";, b6 Q. t% P+ V
                p=NextArc(i,p);
    3 a2 G5 j  S; F$ P# I        }
    % U; M" @* }% A5 J        cout << endl;% j6 |5 z+ L3 ^8 P3 l1 S' Z
        }! ?8 O* f1 Q) R
    }
    - g' l# a1 I) H) E/ C/ h/ F! D# C, \9 u, d* z& n+ ?

    # T& j3 Z% c  [6 U- z. U4 e8 _邻接多重表与邻接表的对比" m! @- M# e9 Z- G  s1 W5 _

    , E$ ]( D' R% V& `. V8 U: R: w; I$ F+ i" R邻接表链接5 E3 P( H5 S0 A, J. P
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    ) j0 e' L8 k! d* v. @  K0 D在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    ) ~: ]0 G4 P3 P% P$ D1 ]1 k$ }; k, h为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    5 `- Y! O% |9 x9 c, w————————————————1 Y" B2 x9 \  N7 A
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ( p% p3 F6 p) k) x5 k. ]( H% ^2 C原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    0 [' v/ N, d2 e/ [2 k( u7 T, J! S1 f; e' n+ D

    3 j8 Z# g$ u4 _% S" t
    : n7 m3 Q3 U! E/ z9 f' V
    , ^/ n2 o% ^0 i  X6 e. R————————————————
    5 x6 Q; ~/ e1 M0 B2 u版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。+ o) K4 q( Q/ Y+ w6 I" v# F9 [- i  {
    原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669583 Q& ]1 }% c) u5 p( V2 f

    6 @, l' `: r" ^/ |- b5 K
    8 W$ ]& P, [. z6 `8 A5 |
    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-14 04:58 , Processed in 0.528217 second(s), 54 queries .

    回顶部