QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1663|回复: 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
    ! Y/ w- M; R) ]/ Y% T6 W. m; E
    图的存储结构——邻接多重表(多重邻接表)的实现- y# V, \* h; Q
    7.2 图的存储结构
    ; w1 f; y. ^: ~8 Q$ @0 k1 e  T/ `2 I: L' y
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    - D" {% u/ f) Z7 J邻接多重表的类定义
    3 W, z4 u% J0 |, `3 ]' V6 x; j邻接多重表的顶点结点类模板/ h4 R+ q) u; z$ I
    邻接多重表的边结点类模板
    ! U  q0 U! B( ^/ R8 E, {' V邻接多重表的类模板
      M! K* f8 G; A( i邻接多重表与邻接表的对比) @- J  {3 \7 W' z9 Y3 b2 B
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    ( V  n! `3 q8 g+ C
    + G) n' y5 D. f9 X. [7 K在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。3 A* T( A% J/ E! m  N
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。4 X' V8 q2 z4 K9 J
    ' m$ s; P, A2 C0 `# ^
    邻接多重表的类定义1 \0 L1 Z3 A, _4 }! Q# D: ~0 w
    1.png
    9 i, a9 K( Y( Z9 m邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
      ?4 Q0 b  j, E2 H9 odata域存储有关顶点的信息;2 I; `% f: \! w3 S% M8 b6 Z
    firstarc域是链接指针,指向第一条依附于该顶点的边。
    + y" Z" \4 h. ]0 I所有的顶点结点组成一个顺序表。

    ) @, j, H( c$ K. X5 G- U& j0 f
    ! J# Z8 T$ Q+ a- u# j6 w6 v- v
    template <class ElemType ,class WeightType>0 E7 G  ^: \* m* ?5 x" F. M4 Q
    class MultiAdjListNetworkVex6 U8 P& s7 ~! L
    {" y: u( R  N+ s. p; b/ l4 S
    public:' K, B) k, ^4 I
            ElemType data;
    7 ~% U; p+ k3 ~% j        MultiAdjListNetworkArc<WeightType> *firstarc;* N% N  H$ q& Q( K
    7 `  x% d/ o/ y1 n( J
            MultiAdjListNetworkVex()7 h- y- N7 V  Y# S% z% o
            {
    7 e6 j1 e+ k2 ?: S# ?) y' _                firstarc = NULL;
    6 D- g4 d) D0 \6 H+ ^        }
    , W7 k, y1 E  F  g" W        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    1 V4 X4 P8 h" m  n6 L        {/ y, W! |% a' K$ U( {2 @
                    data = val;% X0 U  H' Q. l$ d3 k) Q1 j; i* T& z
                    firstarc = adj;) w8 {' C, @! c
            }& n% c; X2 ~- r: D; _
    };
    : S  x4 J9 k; b/ Y& y# f& O$ G0 E0 _+ O) Y5 G7 R
    邻接多重表的边结点类模板
    ! Q/ D' B! Q! |2 B9 y; G' }8 M7 u: W6 h, D$ u
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:  W$ `' K! i& V4 [% b3 g" `- r- s5 u
    tag是标记域,标记该边是否被处理或被搜索过;
    $ X& g  w. ^! k' Z" Q% b3 tweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    ! P% {4 K6 b) F$ inextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    + U- q' L% @( u1 l7 dnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    ) R9 z3 o# j$ U9 W) ~1 x9 I8 c$ \4 U. r4 z3 I9 @, h
    2.png " e2 T& V! `; l$ H
    template <class WeightType>" ^# i. r% S9 |. [
    class MultiAdjListNetworkArc
    ) O! R+ C/ D* I1 F2 _{
    4 i; i* N+ j/ H% wpublic:/ d0 y# q" L  K. E- c
        int mark;                                       //标记该边是否被搜索或处理过& V/ a0 E5 S* j: \& R2 S. R
            WeightType weight;                              //边的权重0 T, a& c6 W9 s2 W) ~
            int adjVex1;                                    //边的一个顶点
    . W. e+ {$ h- J* X7 }9 L        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    4 u( K2 ^/ t$ N# N        int adjVex2;
    : Z6 T' n/ Q; O; R( ?: z        MultiAdjListNetworkArc<WeightType>* nextarc2;
    4 [" `: B# {* R( g* m. o% o2 v% h% d; V* g& {$ E6 [
            MultiAdjListNetworkArc()
    7 N% l! C1 ]# T1 [  S+ p        {, a0 l9 ~9 @$ W" C
                    adjVex1= -1;) Q7 u* s1 O6 Q' i
                    adjVex2= -1;
    9 h% N" c, r- y' Q        }$ U" m6 i6 r. n, h: j' C6 w3 J
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)) N. x* r0 }$ S& @/ S, [
            {! O  G* W" x( z5 K/ d6 b6 X% E
                    adjVex1 = v1;       adjVex2 = v2;
    7 j* S. ^! X- H# E% {8 X                weight = w;
    9 z! q3 k* c6 K                nextarc1 = next1;   nextarc2=next2;
    9 s' \% r# |( g7 O. C" |  D8 _                mark = 0;           //0表示未被搜索,1表示被搜索过
    ' c4 n" e6 n  i- S0 R) x! _        }+ E- t( p+ G4 |) v
    8 P$ [9 ^& a. X' ]
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>; Z( `: |( K- O/ n
    class MultiAdjListNetwork& {0 ]0 m# h6 P$ ~1 ~2 M
    {
    ' F+ V* m& b. lprotected:2 P  m0 v5 t+ S# m: U' U" D( N! b
        int vexNum, vexMaxNum, arcNum;
    ) `6 `5 q& D$ l9 r( Z. q+ ~    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    . f$ t1 [' v, e4 M; B    int* tag;4 Q, @$ P, k& o9 Q3 R, J$ d
        WeightType infinity;
    . A/ Y) G  U# ]
    - G# `# o) S9 }8 I( Z+ hpublic:' x4 o! m4 o& r5 j
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);1 n, ~& f) U8 L; x2 K/ v/ u  A0 J

    , d4 a6 T9 k/ _2 D7 P0 @1 P3 h    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    + b, l( H$ g* H" [9 S- h( ^$ g7 \8 g
    3 \# N( i& p% I5 T) [8 g    void Clear();4 \) `4 ]1 V( P. ?
        bool IsEmpty()
    0 {2 R& u& P5 G4 @+ Y3 X5 \    {* J$ o. Y! l6 P5 V
            return vexNum == 0;
    % ]3 m6 ]9 b* @: s    }7 s, s" c) ^* k$ ^' U5 u( B
        int GetArcNum()const
    % N4 U8 M. s* t# k    {
    1 T2 G! e' l; q/ S9 z" P        return arcNum;
      T, s- y  x' j- [' v    }
    % S$ q: ^, ^1 U& m    int GetvexNum()const
    , x' e8 O$ L, A    {
    ; N" r0 z# M. @        return vexNum;
    * @3 X8 H- g7 Z    }
    / i' J8 \2 B* y' K! X. a- n
    1 j0 L& b" i5 y8 T  I  L" U
    , ~$ [% z  j0 ^    int FirstAdjVex(int v)const;" p6 c& h" G/ O/ g9 u
        int NextAdjVex(int v1, int v2)const;
    ; j# i6 f( |6 C$ Y- J6 }( M    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;% R5 S. D' K- O' `& M3 U" ?
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    : A; S2 ~0 Y) q# {% p/ K% Y# C& T& S+ L3 A8 m* o2 O- n
        void InsertVex(const ElemType& d);2 ~: T, [- o1 @7 M' {$ {
        void InsertArc(int v1, int v2, WeightType w);6 q' b. ?$ @! j' T: A
      s1 [7 E' u5 f2 a' O
        void DeleteVex(const ElemType& d);
    " V/ M/ T+ t3 X8 |$ b' C8 a4 q    void DeleteArc(int v1, int v2);
    2 m$ T! B4 y0 e  ]
      y1 j" g6 Z# j6 h- A    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);" e. O, K9 M2 w+ B6 v$ z* o* o
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    2 `$ X2 l8 o% ~% R. ~* E& A5 P( [% j) X
        ///深度优先遍历- O8 w) K. n9 J% q& w5 o- I
        void DFS1(const int v);0 S+ f/ }3 g8 R3 R& _
        void DFS1Traverse();( d# f6 S& j* Z8 k% D& {% v2 x
        void DFS2();1 S) E! g# ?; p+ X/ \7 _
    . H8 W; Q3 D+ J/ v: P" E$ w
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1% y2 p% N4 w# s+ E" e# B
        void DFS3();
    & j+ K0 h9 r& v! k  W/ \- S! o  `' m7 b" s9 N
        void BFS();/ m. V7 r. h  x9 E
        void Show();. Y, M! A3 f3 J' H, s0 s
    };  P- V. G1 m' C; N0 u3 @$ _
    5 k5 X3 m) H5 a
    2.函数的实现: S: W# y. l: {# r. O( P% P
    研讨题,能够运行,但是代码不一定是最优的。
    5 y0 ^, e% O7 N. b3 z
    % G% H5 H8 }& r#include <stack>
    ) `# c1 ~5 a" b7 c#include <queue>9 [( ]( ?& P: l. I
    4 F( B: [! e* s* x. f
    template <class ElemType,class WeightType>
    + `3 K  l7 z( H  c8 `# j: }MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)2 a5 t- P# j6 X0 D. I
    {
    6 C7 e4 f% z0 L4 S& [    if(vertexMaxNum < 0)2 b0 {1 Q  B2 t3 T. H* h
            throw Error("允许的顶点最大数目不能为负!");
    8 e0 d8 g+ v8 G. F) i    if (vertexMaxNum < vertexNum)" y  _! j7 o8 B, o/ l' k8 R+ O
            throw Error("顶点数目不能大于允许的顶点最大数目!");4 [4 L; N2 s1 j. d. F% M
        vexNum = vertexNum;
    0 w5 v" |  h0 B- ~. I8 z7 d    vexMaxNum = vertexMaxNum;! @3 ~* I" \+ v  \1 V
        arcNum = 0;
    ! B  j" O, Z( r* ^0 x4 k- F. a    infinity = infinit;* {! K* B8 ]" ?+ ^3 M! Y
        tag = new int[vexMaxNum];- r( F# }7 k6 s) X/ h* S
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    ) V6 ^2 y' ]. _$ D    for (int v = 0; v < vexNum; v++)' k; ~. p, S. l( m% {4 O. d
        {8 }1 h. j! C' j& H6 v
            tag[v] = 0;; L' ?3 P+ _$ O; s: D) P8 ?
            vexTable[v].data = es[v];
    - C! x+ U8 k  B0 |3 `* n, J- b) M7 E        vexTable[v].firstarc = NULL;
    4 n5 h* F7 f3 ^9 ~4 h    }
    9 [# R0 R7 v" v) x7 s}8 j( O" `* ]) A  f' f
    template <class ElemType,class WeightType>
    ! R: z% E! A5 F, l/ bMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    ' {( d/ o& D2 Z' H$ {* `. e, ~{
    4 p  n* g/ v! b5 \    if (vertexMaxNum < 0)9 A. e7 c7 D! P- c1 @9 J
            throw Error("允许的顶点最大数目不能为负!");
    " ], E* K/ ?5 |    vexNum = 0;" _, j4 i7 k* Z. ~. v
        vexMaxNum = vertexMaxNum;2 ]2 }9 p: J' @) u) ~$ g
        arcNum = 0;* M8 @$ u/ N* o3 ?& R+ j& p& e) _
        infinity = infinit;
    2 x6 \" [  p; u0 }0 X    tag = new int[vexMaxNum];
    % v4 S  Q  J! P( f& c/ y9 H1 x, J    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    6 t7 {7 F; S; Q& s) p% ?}2 X6 |1 q2 J0 i
    template<class ElemType, class WeightType>7 d: k, {- u/ z4 x
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    % d1 p; W2 H4 C$ l5 O{
    6 J) e( S! C3 O: x7 }) G    if (v < 0 || v >= vexNum)( h) C* ]6 E# z/ K
            throw Error("v不合法!");
    & \6 T) R% Z1 N2 L    if (vexTable[v].firstarc == NULL)
    8 z* s' r, w# }5 O2 n        return -1;
    $ ^  O& T" P* j+ L: P    else7 S& M) k5 g. o" n
            return vexTable[v].firstarc->adjVex1;" _; n& H0 V7 L; w; F9 Q" S  X
    }
    : Q5 _% v( N! P! l5 T6 E  `  {) F' I4 g' M  E* l' a7 N
    template<class ElemType, class WeightType>, S  p) C$ q( M" F/ f
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    / l# Q0 L( l+ _5 s5 @{
    ( v4 B* x' y* c# t# `# H% P, Q    MultiAdjListNetworkArc<WeightType>* p;, a* k, ~5 Y6 N4 ~
        if (v1 < 0 || v1 >= vexNum)1 \  K) Z! m. H1 w+ V! O
            throw Error("v1不合法!");7 k5 s' L% A- X  C6 F
        if (v2 < 0 || v2 >= vexNum)3 }! o6 n3 B7 x3 f: s; p, y
            throw Error("v2不合法!");  X+ H! Z. i3 [/ v
        if (v1 == v2)
    3 J% B; S; I5 X- T" b0 p7 e: _& E        throw Error("v1不能等于v2!");
    & r: ]( w' n% O3 C$ W. z    p = vexTable[v1].firstarc;
    3 }' f& o% H* b$ ]5 ?    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2), p, X) N- S$ u( b8 a& d3 t9 c
            p = p->nextarc;+ o: b2 \5 h. [. a
        if (p == NULL || p->nextarc == NULL)/ e  r' G( h. F9 f  y5 y
            return -1;  //不存在下一个邻接点
    7 m% H* E7 m# D- ^; ~0 _+ T    else if(p->adjVex1==v2)
    * p. X0 ~7 m$ h8 N- o1 ^) j& L4 m        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);: [9 g% O8 F' M0 m9 H( E
        else% u! Z" L" l" |& B  i
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    , @8 V1 L9 l+ m' W+ w% X}
    4 |3 q4 N# E, ~1 Atemplate<class ElemType, class WeightType>, D$ s& j7 v! _0 x
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()7 t% w) E/ O; t' S
    {
    * e- b5 i8 T% T" D; l) D* i2 @    if (IsEmpty()) return;+ a8 ]: [4 u/ a) Y) ^+ `
        int n = vexNum;5 U' R4 P" V8 p5 A8 u# c0 p% q
        for (int u = 0; u < n ; u++)
    . @0 q1 [- c4 j: p* @        DeleteVex(vexTable[0].data);! l* k- }: n8 N& u
        return;! A8 h  h, ?* O7 D
    }$ T5 D7 t- b5 y. o6 g
    template<class ElemType, class WeightType>
    . O% R4 }# R! wMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
      f' c" a' V( Q9 z{$ ]2 g1 N8 q! y: d: ?
        Clear();
    $ S% M' Z7 d5 D/ [& N5 @}! A( f; B) I2 x9 Y# T" X
    template<class ElemType, class WeightType>( i, p6 }9 y9 z  `9 n
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    ; ~, `/ z4 \6 e/ f{
    2 ^" A0 R, y# x2 W  G& v    vexMaxNum = copy.vexMaxNum;1 o; t" F! N5 s  B* g; `& O
        vexNum = copy.vexNum;$ A1 m+ p% p& K3 r! T  d8 x8 q) g5 }
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];- Z/ b, c+ ~+ b  u! ^& Y5 c
        arcNum = 0;6 x. O# \" b+ d
        infinity = copy.infinity;
    * {8 u, G0 s: \    tag = new int[vexMaxNum];
    3 i! v( G" c, I( [) p. c: d& y$ A4 y% }# \6 X
        for (int v = 0; v < vexNum; v++)- z& d) d! A: [& \
        {
    % N% L6 |0 f4 a        tag[v] = 0;
    3 O, N/ d6 o3 K, y9 I5 r        vexTable[v].data = copy.vexTable[v].data;; T8 U& k" w  l3 W0 M2 E
            vexTable[v].firstarc = NULL;& s; j3 {" R+ l+ S6 ~
        }
    0 k! ]& o" X4 o# N0 O    MultiAdjListNetworkArc<WeightType>* p;
    / o3 ?3 m1 \. o; }3 @$ O! b
    : W3 F; t8 A9 \  j    for (int u = 0; u < vexNum; u++)0 t4 [! r. w+ H0 \9 i' B9 Q
        {) n5 Q% o" D, f' r8 P
            p = copy.vexTable.firstarc;
    6 H; m( U5 L6 S* D- }        while (p != NULL)4 K/ }  I3 F* Z5 r0 I
            {
    + V" I* J2 I4 D( v. e            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    # u8 l( [' H8 ~. z            p=NextArc(u,p);
    1 l2 x2 D7 e3 e" e4 X- }        }: C+ t: Z: Z9 ~1 y( i1 G( @
        }
    & r$ P8 k: a: S0 b}
    * g2 c; T8 a$ X  |7 _2 e; {! Etemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    " i! y1 r) G+ y4 b& D4 `MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    4 p$ c5 A! s  ^{
    # |" c% _) w& n' v& G7 z( E    if (this == &copy) return *this;$ |! }) i9 _- R% Z; ^: D7 s* K
        Clear();
    0 M6 w* G+ M" }8 r( v  z    vexMaxNum = copy.vexMaxNum;+ _" _" l3 z8 R
        vexNum = copy.vexNum;
    $ }) ~) W" s3 a! Z    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];: {# L( p/ g) h; M
        arcNum = 0;( h8 F$ C" M9 V' o( J: v
        infinity = copy.infinity;
    ! T1 Y; a" W# d, S3 q8 V    tag = new int[vexMaxNum];# U7 \" L# ^' r
    $ _( }7 y# ^/ L+ b) q* D( _6 D
        for (int v = 0; v < vexNum; v++)
    * b% j$ {: `3 J" {/ N    {7 J% I; w" [( H( Y: L! b
            tag[v] = 0;
      q' ?9 V# A( P* ~        vexTable[v].data = copy.vexTable[v].data;
    4 ?" H3 Y/ v1 Y. O& ^3 Y4 e1 f        vexTable[v].firstarc = NULL;, G( B& v- W8 t# W; p. M/ r1 M* m$ P
        }3 u: |+ Y" R7 y! c0 Y: H! h; H3 k; h
        MultiAdjListNetworkArc<WeightType>* p;
    ' ], [* t9 G; Y
    % @' d0 i. [" j3 ~9 M    for (int u = 0; u < vexNum; u++)
    0 J8 _% k3 x, m8 X3 L+ l  c    {+ y: b1 w7 A9 u& a  p& B) h" i. _
            p = copy.vexTable.firstarc;
    ) ^8 z0 r+ a' ]8 [* D        while (p != NULL)
    4 {  I  J. }) ]/ h0 F        {) f% r' u0 Y9 ?$ V! ]. j4 g
                InsertArc(p->adjVex1, p->adjVex2, p->weight);) d1 @4 M: u& Y' @1 Q) H) c2 L+ i
                p=NextArc(u,p);9 G: N, |/ i1 c) {
            }
    5 r5 h5 b. l) |, @: O) `    }
    + m* E1 j: [; L5 p) a- D    return *this;$ r; s# i: Z; z
    }3 ]1 p5 W3 O5 b( {9 Y0 i
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    $ R( ^" O) q6 KMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const8 S3 ^# P3 p$ |2 L. w! h0 ^4 @7 Z2 D* ?
    {
    1 T" \) e; @: f4 x5 K9 E$ o    if(p==NULL) return NULL;6 ?+ A) Q1 {$ ?
        if(p->adjVex1==v1)7 h3 P9 @$ E9 Q" t& [2 c% |1 q
            return p->nextarc1;
    / c3 u' ^/ T$ N8 S# e    else
    ) t$ e5 l) z7 n  c4 m- d. B7 H        return p->nextarc2;6 I# t  X5 d2 v, n* J1 u* S
    }
    ! L6 l9 k, C" D7 m1 O, v5 Ttemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*7 O* @! c5 M; I, t* n$ q" C% s" D& w5 i/ K9 e
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const# }0 R& u- C( A# a- c4 Y
    {' t+ t" [, j: p- I* @4 b, G! S
        if(p==NULL)return NULL;3 z  A. y3 E( o9 f, u$ B, n/ c6 o
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;! k$ v7 g% B3 B. a, p
        if(q==p)
    6 F' z3 o8 `, ]- {) d        return NULL;/ }$ o6 _  F% ?% i- t
        while(q)* ]- ]5 y+ ?' K
        {
    0 N. x  _1 S: P/ g6 R  P        if(q->nextarc1==p ||q->nextarc2==p)& O* J6 o. d* ?8 R5 m: k
                break;
    8 [- R; ]- Q- k" P) m" t4 m4 }% r        q=NextArc(v1,q);7 b) l2 l" C) x
        }
      ~3 M. l/ Y5 U2 d- u; ]    return q;
    + U( s4 F4 S5 [! a  Y}
    - t. S& s0 p1 a4 y* wtemplate<class ElemType, class WeightType>4 x9 y8 h6 }. X+ o% `% K5 g
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    % |! ~% Y7 ]/ w+ `. e0 s5 X7 c5 Q{4 I  r# s6 n- n& p
        if (vexNum == vexMaxNum); q& k) S5 _& e) K. C1 A. b: X$ g
            throw Error("图的顶点数不能超过允许的最大数!");
    ; l3 ?' |. H6 X9 |    vexTable[vexNum].data = d;
    ( L) |# l3 d6 j    vexTable[vexNum].firstarc = NULL;1 y0 Y( E& d- f5 S1 _
        tag[vexNum] = 0;8 u& Q: \/ p; K+ t  R
        vexNum++;; q% e8 e& i8 n3 T
    }7 V, {  U4 Z. ^
    template<class ElemType, class WeightType>) @5 D  v; O- x% r8 I. E
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    " e0 v1 E* T, q1 j' b* n1 F{# U3 ?1 _* s5 b8 y
        MultiAdjListNetworkArc<WeightType>* p,*q;  ~! I' k$ q2 c9 `; c! ?; _$ n4 n
        if (v1 < 0 || v1 >= vexNum): m" p: W4 K  F" O3 @2 F
            throw Error("v1不合法!");% W4 r$ J, k% |8 f4 C* @2 y
        if (v2 < 0 || v2 >= vexNum)- }; y. y' g+ F
            throw Error("v2不合法!");4 E9 I" x+ _! r. B  b6 L# N
        if (v1 == v2)
    7 q7 m7 K6 [" y% o( |, _        throw Error("v1不能等于v2!");
    , U( l8 F: c9 a4 g! h! T2 h6 N    if (w == infinity): V* m+ ^7 ?% k+ L1 n, D
            throw Error("w不能为无穷大!");
    # C* [6 L7 @5 }; T; [, `
    ( w& o8 G: @1 f2 I( A& U$ x, o7 e5 j0 @7 M
        p = vexTable[v1].firstarc;4 D: v& M' ^$ y
        while(p)
    + r* c. r* O# M5 N    {2 F/ T: h; F8 R( k0 j
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    : O6 a+ I! Y) A' m  X8 J        {% _5 K, b" z# f- _# g7 I
                if(p->weight!=w)
    ( Z: Y- x7 i9 [& S* q                p->weight=w;$ d  p+ ?6 w5 E' U
                return;. P9 c) U) ~; z, J; L. ]3 F3 p
            }
    3 M/ I2 B' y9 q9 a% _2 [5 X) [8 z, u2 |( X. Z
            p=NextArc(v1,p);
    + B; ~: I, ]0 f& k) W    }  v  Q  K* b- u  k+ A
        p = vexTable[v1].firstarc;: n- ]3 v5 }& G9 L+ B
        q = vexTable[v2].firstarc;
    0 a8 |5 T! {/ q- N+ g$ A/ d    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    3 h0 |& S# C% n) s    vexTable[v2].firstarc =vexTable[v1].firstarc;
      H1 x* o0 N3 A    arcNum++;
    6 D' e. o/ J" c( W}
    3 K* g  o' W0 o0 L: V* B6 H
    : Q2 M  ]  u* ~. R3 X& M  s% j3 Jtemplate<class ElemType, class WeightType>3 r5 Y* q( n/ Y" x* M
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)9 T8 B/ K) S' c/ ^) k$ a
    {; I# G- {( ^2 T/ F$ I7 ]

    & F$ R: ^6 m* |" [$ t    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    % h& \, o* [$ j6 }- P& V- k    if (v1 < 0 || v1 >= vexNum)
    ; V+ @6 V5 H/ ~, X8 V        throw Error("v1不合法!");
    " |) T  p- C$ U/ X: V: g    if (v2 < 0 || v2 >= vexNum)
    4 c) p# C  G0 z' b# z; I; f5 b        throw Error("v2不合法!");
    & C1 z  {! `. ^) Z    if (v1 == v2)7 a& d  m# Z' ~) ]1 g! T
            throw Error("v1不能等于v2!");3 ^) Q9 u# i# h0 C7 K

    & G) h- `5 V0 t/ b" M& C    p = vexTable[v1].firstarc;' n  A: P; n; X
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)9 n5 D0 L  {' r2 U# n
        {
      Y. i# m; _2 D1 p        q = p;
    9 h: K9 h: u2 F* w        p = NextArc(v1,p);
    # P0 y) L: m; l4 @2 r    }//找到要删除的边结点p及其前一结点q$ p" R  x4 x' b* X
    5 O# _1 `' g2 c; w9 E3 L" s2 g1 H
        if (p != NULL)//找到v1-v2的边
    ) F/ U* }8 t/ G$ h+ ^7 P; {    {
    * ?8 ?0 f* f- T# |        r=LastArc(v2,p);
    + X! e; G% |' N        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL, X( b: \# Z9 q( F- L4 ]* {
                if(p->adjVex2==v2)
    - Z# G% E2 o- e- x! B                vexTable[v1].firstarc = p->nextarc1;- Y( `9 W0 `4 k$ [+ ]
                else vexTable[v1].firstarc=p->nextarc2;" t  U7 j2 N+ `$ X' Z
            else//不是第一条边+ z. T% @2 ^9 a7 }% D
            {+ s- [4 @9 o& I
                if(q->adjVex1==v1)  n! b/ P, m3 q" o
                    q->nextarc1 = NextArc(v1,p);2 Y. Y; Q7 A9 H+ M
                else" F) W, P4 j6 u( a5 x7 D
                    q->nextarc2=NextArc(v1,p);
    5 n+ P; t+ Q, K7 r& W, ^% b$ C. ?
            }
    ( b+ Y; I6 E) R        if(r==NULL)4 D! {1 \" W2 k: N1 y9 r
                if(p->adjVex2==v2)4 D# _3 N  L5 i; d+ p: Z
                    vexTable[v2].firstarc = p->nextarc2;
    - N4 G/ `. o- n' a! x            else vexTable[v2].firstarc=p->nextarc1;
    7 u9 Y0 ]1 Q# P" ^1 C        else
    & O0 x5 Y7 K% ]. X' J3 B1 e9 O3 {        {. m. a- N$ D2 }6 q: F% `
                if(r->adjVex2==v2)/ d* ]6 @9 f2 [: i4 j5 ]
                    r->nextarc2 = NextArc(v2,p);
    7 b9 }4 t) ]. w  k            else
    $ ~2 d5 Y" g0 g  X1 c                r->nextarc1=NextArc(v2,p);
    ) D2 P* Y1 y( }' S' C6 D, M: q        }
      M$ V9 m7 g! T' O/ [+ i        delete p;
      a$ n/ R/ R/ [" j& x0 I1 g        arcNum--;: a1 O4 ]# j2 H, p: `4 O' D
        }( I9 @6 |5 L  d4 Y8 K' m

    0 q% l) F; `1 z$ n( `}
    ) `) ?! |* @/ r8 ^/ B3 @5 \template<class ElemType, class WeightType> void! S) c" b( i9 P6 _5 K9 V. I
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)4 C3 Q3 z, n: c5 j. ~8 B
    {# C; H$ y- n  h% x
        int v;, _+ L, F1 m& a8 \6 W
        MultiAdjListNetworkArc<WeightType>* p;$ P6 _% a2 T  i( c
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    9 {6 q  h- @4 P) E7 z0 j3 L' f        if (vexTable[v].data == d)
    ; q7 r( q  P& Q7 Q" k7 H: X            break;
    1 }* }& L& D9 V5 y    if(v==vexNum)
    & i7 R! e4 W% ]8 H) l        throw Error("图中不存在要删除的顶点!");
    + r. u2 o  t, x) w7 H& S# s3 J' V+ Q$ k6 x0 L
        for (int u = 0; u < vexNum; u++)//删除与d相连的边
      Q  V4 @# O; _. Q7 L4 \5 Y2 j; Q        if (u != v)3 n( m/ J7 l. m' C4 |; [; y
            {! @' {$ `. {( \8 V; Z
                DeleteArc(u, v);
    * K; H. c; M# v- p9 v        }5 o, u! W6 g8 z/ {% W2 S* _
        vexTable[v].firstarc=NULL;
    & z' s! w3 e. D- Q0 C1 ?. R
    " E6 w/ W  g' Q% e! N    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    ! X+ ]1 o5 M6 G    vexTable[v].data = vexTable[vexNum].data;
    7 h* o4 R3 E8 ~' N7 N    vexTable[v].firstarc = vexTable[vexNum].firstarc;9 F( f, E5 H0 W2 U" w$ o0 t
        vexTable[vexNum].firstarc = NULL;. M( z5 F0 ^0 j6 [. Y) j
        tag[v] = tag[vexNum];
    3 q( D, L0 {, N) B2 O6 z    //原来与最后一个顶点相连的边改为与v相连
    4 T$ Y9 l) ?% v! b1 I    for (int u = 0; u < vexNum; u++)
    7 O2 C& V  _, m9 t6 r' L    {- G+ L0 x5 n2 b; ]: V) R" e! g
            if (u != v)/ w1 w: z. s/ e( Z. \5 C# c! D
            {
    3 J6 F* U- Q' z4 B' o  ]            p = vexTable.firstarc;
    * s8 A4 ^! z% t- \; L            while (p)+ N/ e: e' T% N$ B* U! b( v) S  @
                {8 h# o# h/ G1 H) b
                    if (p->adjVex1==vexNum)
    ! ?) i- S8 K$ E' h. x                    p->adjVex1= v;
    * L* s) u6 K% {% v( T                else if(p->adjVex2==vexNum)+ v" E  U% h1 f5 Q- g$ [
                        p->adjVex2=v;
    ' z* m5 F! v5 U: n$ `                p = NextArc(u,p);" M: c) f" E! h
                }
    " Q' A4 |8 j" N1 P  E" V- ^/ m        }5 Y" M# O, W/ `1 ?4 ^
        }
    5 L% b; g% p/ {0 a8 n7 ^' R}
    . F; b+ q  K1 c. K+ v///深度优先遍历; N* @7 T0 q3 c% ?" ?" H! W
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)$ q$ J! q, d2 b; D4 u% B
    {
    1 r' R) ]& \) x    tag[v]=1;
    . Y; d( c+ S: a( A+ H) V5 k+ L% }! \+ w    cout<<setw(3)<<vexTable[v].data;: e) g- b( m: e. a1 O
        MultiAdjListNetworkArc<WeightType> *p;* d4 ^7 o- c) W) p8 g0 ^
        p=vexTable[v].firstarc;
    8 a" |% i6 }: f! g. p    while(p)5 ~7 ~; r4 w1 N) B1 W+ N  D
        {
      {5 F0 u9 k+ x* f8 z! I0 [        if(tag[p->adjVex1]==0)# \1 i4 o. S) R5 S# v" m; l
                DFS1(p->adjVex1);
    * x& Z/ L* D; p5 N% c5 |2 U        else if(tag[p->adjVex2]==0)
    5 F' {& X/ V  v! k6 S            DFS1(p->adjVex2);
    . k% F' t6 [; e7 E' s        p=NextArc(v,p);8 x, s; j( P3 _- U& s/ ?
        }3 h8 s5 P3 T3 x0 |4 x+ z
    }! K0 K. Z  u6 C/ o% D6 [  ^
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    " O% h0 C+ g7 t6 Y' Z% n# P) d{
    : ?9 ~' `2 t: O9 ~! t7 J5 B    for(int i=0; i<vexNum; i++)8 V3 u. K) F, p  N2 q7 u
            tag=0;' T9 O# _7 r, G: [& A
        for(int v=0; v<vexNum; v++)1 G0 }6 r0 p/ n* |
        {: @7 B5 G- ^% S9 r2 D
            if(tag[v]==0)0 q% J) Q1 \' `  Q2 t- n1 Q$ ]8 i
                DFS1(v);3 R/ K- q( i) t& H2 v; X; m
        }9 M2 J) b. C5 A5 I8 y% C9 E7 S
    }
    , q3 Y4 `7 ?+ t* I! o2 }: r! otemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
      G  c, A9 r; I' u- e{: m; L/ S# |3 B
        stack<int> s;
    : E5 h) u- b% Z+ c4 J( F    int tmp;
    & M8 S3 W: `# x    MultiAdjListNetworkArc<WeightType> *p,*q;
    8 ~1 Z8 m4 [* g% h* w7 Y    for(int i=0; i<vexNum; i++): s# J: l$ z' j8 b
            tag=0;7 P# Z% g/ Y! I
        for(int i=0; i<vexNum; i++)- ^8 J  x6 u! _: [- M. H# C7 Y$ ^
        {; {+ d4 F, `4 ?) x8 e( T6 F/ u
            tmp=i;
    ( _; Z! E* R; ~( e' b        while(tag[tmp]==0||!s.empty())9 Z- ^1 `$ V% ?- R, K5 |
            {
    " E) _" x7 C7 @) G3 I, Z3 E' N            p=vexTable[tmp].firstarc;
    : O" j; B5 I3 k+ |7 C& Y2 E' i5 x            while(tag[tmp]==0)
    + L) `9 C$ v9 }0 W0 l" t, |: r            {) G3 E9 s4 V  M, U
                    s.push(tmp);) q; t: K0 c3 U8 N" Y
                    cout<<setw(3)<<vexTable[tmp].data;
    / i* J% F% \! C: u# Z0 T* _                tag[tmp]=1;! O) G4 K( r% o6 S! t
                    p=vexTable[tmp].firstarc;
    - X( M9 Q8 `0 w                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    - ^3 d! w9 ~, e4 j6 [* F7 C                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    : m( ^" x4 x& I& B' x5 r! N                //cout<<" 1st     tmp="<<tmp<<endl;4 L: ~5 X6 f1 n
                }. u; G- G' c9 j5 x, B. T6 T9 S
                if(!s.empty())1 e- O# H/ F! x  T% b6 N1 W5 _" E! `
                {% Y( M* q- W! I
                    tmp=s.top();
    % g- Z0 Y+ i9 L  H! X$ j! G                s.pop();
    4 x8 j+ l6 f- u; `1 l/ L; i5 \. r                q=vexTable[tmp].firstarc;
    0 U0 j+ K  f0 o                int t=tmp;2 l1 L3 l1 N. P! J
                    while(q&&tag[tmp]!=0)# }- \2 Y) L' N. s2 u
                    {
    , j7 e2 d+ |2 {( _! g                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);; [& L9 p" n# E# ^# @. k4 \
                        //cout<<" 2nd     tmp="<<tmp<<endl;2 [% ]  S% z# O
                        q=NextArc(t,q);! K' L# x3 j. \0 d3 h4 U! F
                    }
    4 O7 j3 x" C, g; l+ r8 {' W                if(tag[tmp]==0)/ R2 m5 X: r3 L0 M# h& l2 E9 g2 e
                        s.push(t);
    0 x& p6 A% U* I  z! l9 A8 ?2 s                ///1、对应上面连通分支只有1个点的情况: e; G/ }2 ^# k, a% B( i3 N5 W
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    ' I0 a- `" C( {& i$ M" t                ///tmp要么等于找到的第一个未访问节点,6 k* m: j2 @* T1 I( F
                    ///要么等于与t相连最后一个点(已被访问过)
    # u; n1 s. u2 G5 Y: W" f$ [9 T8 V2 y                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    ) P0 y- B6 i( c3 P* q) ]            }
    & ~5 ^6 G1 U0 X& F        }' M9 G0 b4 w- ]+ o4 D  L
        }5 r8 R( i* d! ]( z% u
    }
    + b) V  j3 M- r! O//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    ! b3 E& J+ [0 u7 ztemplate<class ElemType, class WeightType> int
    6 w6 g1 [7 D) i8 T5 XMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    " t: u: s  G- g. r* p. c* O{2 ~: i( d  j" I0 a6 o- B
        if(head==pre)
    4 _9 ~! x" I5 y/ T% _3 x4 A        return -1;
    " g# I: M- x/ L. \6 s4 g6 O8 r
    6 X( q' W1 E. e    MultiAdjListNetworkArc<WeightType> *p;8 S9 L, e: w. Q" {0 l7 s. b
        p=vexTable[head].firstarc;
    % l6 h! m3 z5 V- s+ |. P- N6 c+ }    if(pre==-1&&p!=NULL), I9 B/ H- N. T  H4 v
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    & [# T+ k  g- ]% X5 r6 f4 I- O; \    //pre!=-1&&p!=NULL
    : N) g/ S0 X2 _( q+ N( L    while(p!=NULL)8 ]! w$ D. l" v+ T+ ~
        {
    $ `2 v) S8 z* `4 P: s0 [        if(p->adjVex1==head && p->adjVex2!=pre)
    4 c6 e' T$ t/ `- y* U* A            p=p->nextarc1;: Y& K" q+ w( i, |7 h& B8 |
            else if(p->adjVex2==head && p->adjVex1!=pre)
    / \, P: m* g0 e2 D            p=p->nextarc2;! c( |* ^" o" n+ M
            else if(p->adjVex1==head && p->adjVex2==pre)* e7 W7 i% b: n0 N) \
            {1 x* t8 x! F3 B
                p=p->nextarc1;
    " F  @/ o. ~: c/ H# p            break;3 e/ H" z" z1 c2 L  I- r1 Y
            }
    ! k3 M. _6 U$ w        else if(p->adjVex2==head && p->adjVex1==pre)- c" X) d' c- C% J
            {) Q" X3 K( c+ ^9 D5 |5 n8 v8 r8 @
                p=p->nextarc2;+ G  a+ P! Z& `' P) b9 S
                break;7 ]2 R4 h$ O) ?' \. y  r2 N  c; ]
            }
    ; @1 Y; x' [) e8 z/ c    }
    ; d5 C( C$ R: i7 @, Z    if(p!=NULL)
    & N. C' `+ H& |4 ^    {
    8 g% {3 R( _( G  b" f; g. G; |  s! |1 ?        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    ( I) k9 v' O0 U" n( t( j    }
    : G7 X% C; o- ?$ F! ?    else
    ( f: c6 @$ a$ _8 Z4 h% z9 T! B" n; B, H9 V9 `        return -1;
    ) F0 t' Q# ?+ Y# t: p2 R( E) s}0 c& ?% _1 L6 L& K
    ) \' o/ Y& y8 l  ]. k# v: _

    ' {0 G1 C" o1 q& h- ?6 Stemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    + v* ?9 k& Q" R0 m; H; ]0 Q) x% A4 m{
    5 f9 Y  l: e7 o; `, W    stack<int> s;
    : `% B4 N( \# g% ?    int p,cur,pre;
    / ]3 C* U" q: b5 K( e& d' x    //MultiAdjListNetworkArc<WeightType> *p,*q;
    5 P4 K0 ]' }& U) |5 v: N; d/ O9 S    for(int i=0; i<vexNum; i++) tag=0;//初始化
    % i9 M- k- W4 w: f( G  ?  }$ }
    , o# g& m  j: f! N    for(int i=0; i<vexNum; i++)
    . I$ }. n9 H( E/ |" I( G' m8 n    {
    / o& n% H- {- g' F  L        cur=i;pre=-1;& u6 @- z! C: X& B  Y
            while(tag[cur]==0||!s.empty())
    ! [$ W( d6 r, g3 t6 H3 v        {
    ! {: s( N1 W4 s0 N1 _            while(tag[cur]==0): z$ j" E, b* B! K! i; R8 k5 H/ O
                {
    0 @9 j0 @1 E' |) K# m  t                cout<<vexTable[cur].data<<"  ";
    ; l) |* S+ U: U  e  R                s.push(cur);
    4 s6 p& o8 x) V# N                tag[cur]=1;
    / w7 C9 D) a2 c1 c- Q! b& R               //初次访问,标记入栈6 \7 C# d" d% D! d5 \! T* i3 w. _
    " m" N  z, e, i: }3 i
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点
    : \! A( a, l* S, @- v, v# h               if(p==-1)# V+ E1 p, X( [; T# \2 B
                   {
    % O; {* p! O  l  a- e* s9 c) O3 y                   pre=cur;s.pop();( N, k2 R# z5 d8 Q* z$ U
                       break;
    ( Y2 W; Y" P) ]2 I8 w4 V               }% J/ G7 ^/ q! ?% Z( K/ L
                   else& J0 E/ M1 q( O* l( G' ?1 z8 ?
                   {
    . }( l& {; W. k                   pre=cur;
    3 ~- t' c1 g5 Z- ^( p2 g                   cur=p;
    % c3 I: C0 g" q8 A               }$ b0 y% w- Z- ~
    $ Y' p6 S" a5 p2 u/ f5 s( T
                }5 k# q' @9 M' A4 L# {
                while(!s.empty())
    9 _. F9 e0 {/ z. a# }$ q            {
    / ^1 x2 G" K! Y" h. y                cur=s.top();
    8 L, q* Z1 A+ Y' O& t4 X" s                p=GetAdjVex(cur,pre);
    , c0 m: \( S6 b  e. V                if(tag[p]==0)9 d2 h( P9 o- ?- k! g* ^
                    {
    / c9 }/ u8 I) h* `6 ~                    pre=cur;8 M2 u* ~! _; f
                        cur=p;
    1 M& F4 P0 O- W                    break;
    7 q2 T' k) ^- `  R' w                }
    * b1 }' _! S) Q, U                else
    6 ?, d* D8 |( A7 k5 s( g                {3 d3 j3 D/ a: t- V2 L! R( }* z
                        pre=s.top();; s, a5 h, `+ m# q% B9 n; s
                        s.pop();3 W( v' r) p) e$ D
                    }" {4 e! V# g; u' [& f; Q2 s

    ' Y3 V  m6 ^  _" d& T            }4 o/ c/ p* D7 V9 r( w! h/ Y0 U
    6 [7 m  t" Z2 H; v, t! q# H5 C
            }8 }+ {! E1 f- f
        }4 {3 q) b1 q& T) d  M& ~5 E
    }
    + O% a: r  u$ F  O3 h3 K( Ktemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    ; U( M2 o, k  H' K{- p4 |. p9 r& ]/ U3 r- B
        for(int i=0; i<vexNum; i++)
    ' J# E$ j  R" I! @1 I        tag=0;9 C6 j- i( ]* s: P1 N
        queue<int> q;
    $ t$ q$ q$ o, P0 [' p    int tmp,t;
    8 |+ e  M3 Q+ f7 _- R2 {- `9 s. L3 ^    MultiAdjListNetworkArc<WeightType> *p;
    9 W3 c  y2 v5 V! v0 ?  ?. D    for(int i=0; i<vexNum; i++)& R: G- O4 U# k+ Q# z3 L
        {
    0 n) G& D2 V- ]" F        if(tag==0)
    2 C$ `: P- {' h- I6 m8 ]        {
      p9 ]( T6 }/ [0 c, u$ g3 z, A( m            tag=1;
    6 s" s% M9 ]- u* ~, S% X9 C! y            q.push(i);
    2 S$ F3 [' K! _  `. B            cout<<setw(3)<<vexTable.data;
    6 T; }$ N8 ?/ N. R        }
    ) T" M. x/ ^8 N% U        while(!q.empty())
    " v7 I* r; m: v( L. C- X        {
    " C( [" h( f7 o; }  S% l            tmp=q.front();
    - z" N0 D' d! d$ X4 W0 L            q.pop();
    6 k; ^! E$ O- r% [3 v; I0 K! D9 g            p=vexTable[tmp].firstarc;
    1 |1 w6 R; ~  t' w' I. v1 |            while(p!=NULL)
    0 j$ a! N( P5 s- M2 ?; ^. `            {
    4 M2 E6 s% ~0 G% u, U5 t* ]+ d                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);5 l* {  `  b  t
                    if(tag[t]==0)8 ?5 B6 x/ v) H1 ^: l9 s+ ]( p
                    {
      k; Y0 A/ {$ L9 F) I                    cout<<setw(3)<<vexTable[t].data;
    , V, Q, C6 T! ?6 s" a8 D7 l; u                    tag[t]=1;: V: r& Q3 A6 K; Y. J- S7 g
                        q.push(t);, j) |, [  c/ z. g+ z
                    }8 M0 I! O: u  K0 Z9 }
                    p=NextArc(tmp,p);
    2 w' o* q6 e4 G5 ~            }* i: Q# J. S% k: b  K, w
            }
    ! K% R" |/ d( t4 u! h7 h# w* a    }4 [6 M7 m5 G! e0 b
    }# A# c/ h0 O, Q2 _
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    3 {7 M) g& F9 `& x1 i{) n1 Z0 u. \0 \& N
        MultiAdjListNetworkArc<WeightType> *p;5 W  T$ M- O- G. s" ^: ]/ h' N
        cout << "无向图有" << vexNum << "个点,分别为:";
    , O: v+ \$ r$ Y' l9 p    for (int i = 0; i < vexNum; i++)
    1 O0 O3 m6 D1 a9 @: I) v8 _        cout << vexTable.data << " ";
    ) q) [$ F5 \$ p0 D- R8 B8 ^    cout << endl;
    0 N* d( n7 ~$ X1 E8 ^& s( R, u3 B    cout << "无向图有" << arcNum << "条边"<<endl;
    5 t; O0 }5 ?& o" B    for (int i = 0; i < vexNum; i++)* W) y7 a5 G. }( ]7 c% Q: R
        {1 B3 ^5 f8 u+ R. d
            cout<<"和" << vexTable.data << "有关的边:";
    : ~, Y2 l5 \9 T+ n, `/ ~3 r: u        p = vexTable.firstarc;: \. ^& M' K  R, w" z5 u& E
            while (p != NULL)
    2 ?( e# g0 _' V( p" J3 L) D        {
    6 e9 y" J& X( L; k/ Y            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    $ B; \. o0 h+ M" F; v9 e+ \$ O            p=NextArc(i,p);& ^1 ?, D7 m% s, v
            }* c# |7 X/ G7 f- w' R
            cout << endl;
    , _3 C3 t0 U5 \) `% o, [    }
      Z# h4 L% h1 [8 ?}2 a  n, k( {4 D% S& I$ J5 g6 j

    * V/ m! F8 Y& b  u# D
    * y& `/ ~7 D8 r( v6 X邻接多重表与邻接表的对比2 n8 U' [+ K: o: Q6 q
    ) H% m8 J* o8 l2 V  \" b& a
    邻接表链接. G' x. [/ W  N' w, k
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。" }  o- \+ b" }. m% i( u. g/ l
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。! U- r0 }& l3 V: o. ^, r
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。0 \1 h+ i+ ?. Y! O( h
    ————————————————
    , `% K& K" [6 e% m7 Y; U6 S; g版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。) f- l& j' E( m9 s
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    , Z9 I) q* o" j. E: o. w$ b1 o' c
    $ r  ?# U2 T: u* w8 W3 g' |7 m( I" a
    / B  c6 O- o  Q1 z6 T' `; d
    $ S0 L$ {) r+ Z8 _4 b" @/ u3 B  z
    ————————————————
    + m8 R, _/ Q1 I0 Y) ~* U* x版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    4 {( ^/ N) H5 w% U! G原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
      b$ S! w/ a+ r5 h' G$ m
    $ Y2 ]% H: R9 Z& P5 A! ~6 v# e. |: o  Q4 o$ h( Z+ x$ K! E
    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-9-11 02:02 , Processed in 2.490227 second(s), 54 queries .

    回顶部