QQ登录

只需要一步,快速开始

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

    8 r) I0 J- a4 c, N' C/ i图的存储结构——邻接多重表(多重邻接表)的实现5 A' R: R3 O1 Y7 D. a! g" P0 M
    7.2 图的存储结构. i. l5 H- K1 r7 J% x

      t6 m) P3 F, G+ V4 Y5 i/ i7.2.3 邻接多重表(多重邻接表)Adjacency Multilist/ }, T  x- q2 W6 ~/ W( \6 [, C9 C% n
    邻接多重表的类定义
    6 ~, D1 c2 y& W邻接多重表的顶点结点类模板
    2 h( j8 x  I* T2 A% [# H" b& z2 N" c邻接多重表的边结点类模板
    % g( I' B, k' [& ^) A  v邻接多重表的类模板* ~) t- h8 O- S* K8 I( m
    邻接多重表与邻接表的对比
    - {/ k6 ], m% O5 ~7.2.3 邻接多重表(多重邻接表)Adjacency Multilist! J) D7 \& W6 u& Y
    $ R# R0 a- c6 B' u* c
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。2 Q5 W* M. l) w7 }  R, \
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。7 H7 l4 Y0 G1 {9 _# U
    , K1 T9 M6 C. A. l2 ?7 T1 k4 x
    邻接多重表的类定义  j1 b" Y' j3 A8 K
    1.png
    7 g/ l* |# R! L: \2 p邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    3 p" e' T6 L# B& O0 l; E" U0 Pdata域存储有关顶点的信息;  P) R; c. U# v- W2 B
    firstarc域是链接指针,指向第一条依附于该顶点的边。, \" Z+ I; F, C  C% _+ j
    所有的顶点结点组成一个顺序表。

    ) l& W$ M& i% p( z$ v1 R& w, w

    & Z6 y9 r2 a* L& Ttemplate <class ElemType ,class WeightType>
    - h0 }4 S: D) y/ V6 S) n. ^$ zclass MultiAdjListNetworkVex
    . D. |$ a6 G0 h  u% w- t+ C/ @5 m{4 d7 A7 _/ ], p& j! g/ g
    public:: h/ q" K# M" ?
            ElemType data;
    - {) J6 s# e( k        MultiAdjListNetworkArc<WeightType> *firstarc;2 `0 l1 j$ H: Z. m

    1 L" h2 H( |; j# f$ h2 c% u        MultiAdjListNetworkVex()! d" H8 h. g6 y2 Z, k4 w
            {7 f+ w. K- Q5 E. P
                    firstarc = NULL;
    ! \# Z. p; o7 L# _2 C        }$ A" w, J( ~* ]. `2 d
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)1 j7 G6 v6 o: o2 C- F
            {, g5 H* `. H6 c1 k; K; h9 P
                    data = val;
    ; K7 E% p: }. K! X                firstarc = adj;' {! u! ?: x3 I4 b! C9 c4 |
            }
    + K5 i5 n' p# l" \6 p. W* A};( s# K$ P, `* n( i1 s( `

    . F7 |& {% s0 v5 K) Q邻接多重表的边结点类模板. X7 [& f! N9 K( o

    # _7 d, o- T2 o; J7 X在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    - f/ N8 E6 j: d% S( {" o- M6 Etag是标记域,标记该边是否被处理或被搜索过;
    ) ~* s$ x4 A2 c2 e+ @weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;' F# q* Z) H4 m1 J% i0 E+ l
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;2 ^) O  L8 c" M; P
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。+ j& c; r) H- L) L
    % l! {0 g# T- y7 w. Y3 A- ?
    2.png + F% v0 ^4 J2 W; s
    template <class WeightType>
    8 n2 i# r0 R1 e- H2 h+ b' f% @class MultiAdjListNetworkArc$ K; }4 N; l" y6 u( ^/ S
    {
    8 y3 W1 I4 ~+ z, C# V7 D7 I! |+ lpublic:
    : A; R& G( b% ]3 V    int mark;                                       //标记该边是否被搜索或处理过+ Y8 H5 d0 @9 w, m1 G
            WeightType weight;                              //边的权重
      c# p9 f8 B. I        int adjVex1;                                    //边的一个顶点& x2 r8 v8 I/ r  x
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-16 N" E3 _2 V! p6 p+ z3 r
            int adjVex2;
    1 }$ y; P0 F' G3 [- x% P+ K( r        MultiAdjListNetworkArc<WeightType>* nextarc2;" g2 G- p$ b7 z9 T
    ! x# y( Q  [6 i; f3 u3 A0 J% a
            MultiAdjListNetworkArc()
    7 z+ B% E3 T. a$ u2 V" v        {- f/ ^( E! t. H; {* }* y- s8 @: f
                    adjVex1= -1;. U$ F0 U- o7 ^1 k
                    adjVex2= -1;
    4 F) q) N9 u. k$ M3 S! M$ Z& E        }
    - K( ^  p* V5 W3 l1 z$ W( |        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)2 P  |& W2 O  h0 v
            {
    # ?3 J- @$ c. o/ B) l, {! u3 Q                adjVex1 = v1;       adjVex2 = v2;9 i- t/ o* {' p
                    weight = w;* K& }5 v( i( E! \+ t7 _
                    nextarc1 = next1;   nextarc2=next2;
    ! {9 r+ N6 u, E                mark = 0;           //0表示未被搜索,1表示被搜索过
    $ D" _+ Y. L$ K# \; f        }
      |8 N' {  F  E+ B6 q
    6 c+ w  e% `6 `邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>7 T) S1 o* c# T; X; Q6 D
    class MultiAdjListNetwork
    + c- j# Y$ U5 c5 B& Y0 ]{$ v3 ^' T. F1 }8 Q$ Y
    protected:/ [- E/ ]4 Q6 z" W
        int vexNum, vexMaxNum, arcNum;3 v( E' u, N% |$ m
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;7 }" B7 s/ A1 x  \! p5 v" M
        int* tag;
    $ ^' i9 I9 Q; N" s6 n    WeightType infinity;4 O; t( ^7 \- C: s) i

    ' }, C  S( I- j7 Kpublic:
    7 e! w1 C4 U4 Q* m8 t8 g1 O! H1 T2 R; w    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    . I! x6 ^( \% q; g$ x1 k* ^5 L" f- z/ y, u; Q+ t4 b
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);1 u% `) r! L% L; k

    ! `0 W4 z0 l" D: N% t. I: _8 w5 x" l$ h    void Clear();7 r' D" n5 g, Z  [7 f9 A! o
        bool IsEmpty()
    % p. a! t( L- I( s8 d2 y$ A( c    {# T* k* i, G- L
            return vexNum == 0;! D( T4 [! Z2 j' R3 }# z
        }: Q1 p; _# |9 c( x" t  b/ h. p/ o
        int GetArcNum()const
    ) E" B% w" E' T( d    {
    , @, r* u7 T; W        return arcNum;* X9 H! M. N& A7 W
        }$ h( G7 q$ d8 W
        int GetvexNum()const2 U# g1 `1 v; q9 U; C2 ~* i
        {
    1 r* w4 C) D: q7 Y  c* i7 h( F        return vexNum;
    " \: q" j- }, r4 m; O8 y6 q  h    }
    * F8 v7 \4 @& z9 M& H9 @& f5 D) J; S) e; W7 b* h" o
    , Q% ?0 I& L0 C! c
        int FirstAdjVex(int v)const;# I/ d0 Z5 y  ^/ x1 q
        int NextAdjVex(int v1, int v2)const;
    8 v. o3 f1 H4 I, m1 j, l    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;7 t5 @) z" Y5 h8 V+ ^8 B* z
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    : a& h! k" O/ J3 U: \: I
    4 N! K  e% G, A) h9 @0 o6 C! m1 X    void InsertVex(const ElemType& d);
    + V& ?% Y5 o% v  g) i0 m    void InsertArc(int v1, int v2, WeightType w);$ P$ y) x0 S2 V& ^

    $ G1 R, I) k, H/ r    void DeleteVex(const ElemType& d);: Y7 _! o% Z6 n5 I$ ~' Z% Q% L0 a
        void DeleteArc(int v1, int v2);
    1 c( Q; [3 e2 u
    & ]# G, m; Q- z7 x    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    * v/ F! _5 ]. w- d6 R* s) {9 u    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);$ t8 B/ P& b+ L6 O, E6 _4 U* Z9 F

    9 t" @4 W) M7 R6 z" A/ ~/ }5 H5 U    ///深度优先遍历0 |7 G1 T( o0 e" u2 ~1 v
        void DFS1(const int v);/ D! x& T6 x8 o1 y  o/ V
        void DFS1Traverse();
    / ~& t: U  G! f! H' t" ^+ L' i; Z* C    void DFS2();% [% X, O1 g% a' q
    + e' E! N- k5 C% @
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1. v% {5 x7 W; W& l: s- l) y
        void DFS3();
    / p+ N" I$ \+ g/ P
    3 b# S& j6 U, L1 ^    void BFS();
    ' _" T: H# Y4 l  W4 T6 u  q( u    void Show();
      e; J0 d; v7 _7 B. O};
    ! ]2 w7 N( L7 T7 K$ P9 {  N* D2 ?1 y9 o1 N1 a! z9 @
    2.函数的实现* R9 j4 F9 @3 K, Z9 y* D+ B
    研讨题,能够运行,但是代码不一定是最优的。+ z' W. y* G3 r: Y
    ; Q6 s& w% N+ z- X0 |: B+ k/ n1 [
    #include <stack>
      d+ m% o! O5 V- A* X, ?/ @#include <queue>
    0 I$ R  M' E' p3 g; L2 ^
    " v2 Y' d6 e$ y7 _6 k+ J* O/ ftemplate <class ElemType,class WeightType>
    ; m) Q1 ?  k, c, {( |4 T  h- ^MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)$ Y5 v7 n( t! g# v, d
    {
    7 ?- B: R, N- M0 W5 @    if(vertexMaxNum < 0)0 A* H3 w  m  |
            throw Error("允许的顶点最大数目不能为负!");  n9 \3 {( F8 o/ J
        if (vertexMaxNum < vertexNum)
      F' b1 w. r/ g; ^" W; s' l, I0 w        throw Error("顶点数目不能大于允许的顶点最大数目!");
    , x6 ^& b  h9 }: ?8 I    vexNum = vertexNum;
    1 V! K* Y0 d$ N/ M    vexMaxNum = vertexMaxNum;
      z/ T+ R6 s7 Y- R! [    arcNum = 0;8 C( k8 H( Z6 Z$ U. I( b
        infinity = infinit;/ [8 D" A; N7 D9 \. |) o0 ?- u
        tag = new int[vexMaxNum];; E' N8 ~& ~" l- j% `
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    4 M' w8 J0 T, t. ^    for (int v = 0; v < vexNum; v++)
    ) t; d2 Q6 ~; z3 E2 N    {
    6 L; L" e; O0 ~% G, u7 t        tag[v] = 0;
    % [* ]2 D# w+ q( o        vexTable[v].data = es[v];7 G) Z% n0 F2 @3 \
            vexTable[v].firstarc = NULL;
    7 r* E$ y9 n. ~3 a/ f    }
    0 a  y, t" w8 W}3 b/ l2 R5 X$ L7 b6 m6 j7 J- H0 D
    template <class ElemType,class WeightType>
    3 N, g# C2 h) o" @* x& WMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    " f5 r$ J  H6 i5 g+ z  {# ~{
    9 X6 v) g5 k, n) z    if (vertexMaxNum < 0)
    , J, e+ a- A0 j, @7 ^        throw Error("允许的顶点最大数目不能为负!");
    8 X. e" N5 x' _5 k* Q6 t    vexNum = 0;
    . o$ x5 J- P3 l0 l    vexMaxNum = vertexMaxNum;
    0 q: w5 o* Z* e4 K' y    arcNum = 0;
    ) }5 }+ j6 z5 @0 _    infinity = infinit;
    / l, f/ q$ I: F    tag = new int[vexMaxNum];$ R- A1 e8 C2 P, `4 C, ~. ^
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];  G3 C; `1 w1 D& b$ t: a
    }3 R6 [% P) T6 k; U7 H) b
    template<class ElemType, class WeightType>! o) A+ i+ [( Q- c0 e
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    9 U/ S  Q( N6 E5 c{
    - k) w% J' F+ U, w* i" n) s" c    if (v < 0 || v >= vexNum)
    ; |3 `. w  w2 w. E" [2 _        throw Error("v不合法!");' E3 j# r* x  `( B
        if (vexTable[v].firstarc == NULL)
    , ?# k1 J# r& c        return -1;
    1 s( e9 `, h6 e) e, Y    else
    . W3 `' B: E& O6 P1 |        return vexTable[v].firstarc->adjVex1;3 |) n& l. m2 k1 k8 e# i
    }, s: u1 b8 R1 B
    ) N# ]" r7 q* X& @% ^$ b
    template<class ElemType, class WeightType>2 z6 a. {; T- N5 m
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const# L4 r& r9 A0 ]# @- I
    {
    * I( z7 T! Z7 p9 g/ q% j7 A! y. b    MultiAdjListNetworkArc<WeightType>* p;
    3 B; c6 T% B% N: x    if (v1 < 0 || v1 >= vexNum)8 K3 r  \' e8 o1 z5 U% o7 S
            throw Error("v1不合法!");
    4 C' @  F8 o  ?, O8 e" A2 W9 a2 L    if (v2 < 0 || v2 >= vexNum)  }' n9 f. C8 I% j* m  G! H: q6 l% ~
            throw Error("v2不合法!");, T' h4 A. q  d
        if (v1 == v2)
    $ E- R4 p) I, }! z7 ^        throw Error("v1不能等于v2!");$ [" K( |' z0 X6 \3 w( I3 D" s
        p = vexTable[v1].firstarc;6 v) u# V1 Y1 {4 h/ g
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    . `- B8 A5 v/ N9 Y8 i9 a        p = p->nextarc;3 s" n& h) h7 |4 p9 f* Y; m8 d% u
        if (p == NULL || p->nextarc == NULL)
    : h+ Z) z) p( `9 M        return -1;  //不存在下一个邻接点, |9 {; ^6 O4 [" S1 T
        else if(p->adjVex1==v2)
    ( R7 q. g* _* y# {7 E$ \6 W  {        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);" a  `; B2 V) K- g! ?# n, P
        else
    , g+ f- `4 ^" ^/ B* q% N, L0 E9 U+ l        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    3 N3 ~- D. i! H1 t* P6 a, w: q}
    . \$ h7 j8 k7 z+ T( gtemplate<class ElemType, class WeightType>
    . n6 ^: A* A2 A0 Z/ Mvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()
    ( B% c- p9 w: `/ k2 R9 w; m' W{+ t3 Z+ _/ {" E* R$ \' K
        if (IsEmpty()) return;
    & ^& `* F+ X+ ]! T* X5 e/ V: i    int n = vexNum;7 \# _9 o# s( R) b9 R1 E( M
        for (int u = 0; u < n ; u++)
    1 j: Z0 Z( D, r        DeleteVex(vexTable[0].data);' }$ Z# {" P; x; \; c  A4 j
        return;& g; @: X( @' G5 t1 z! ^( O. a! G
    }
    6 p3 Q5 b! m9 C. Ctemplate<class ElemType, class WeightType>
    * @6 N$ a0 X8 z% l9 RMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork(). l, k5 p4 a. u* W9 P, w4 y# o/ p* F
    {, z: U) v) I+ t& V9 m
        Clear();
    * s+ ~( p" D; d( h+ _# {}
    * b0 ]3 C$ A  d9 P6 ?; s0 u+ p8 jtemplate<class ElemType, class WeightType>2 j2 J$ _- `/ {6 s6 ~
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy). x/ L7 e. m- g& t
    {& C2 k$ C0 @) s# j2 n, G
        vexMaxNum = copy.vexMaxNum;
    4 q6 q0 ]7 Z& k# }    vexNum = copy.vexNum;
    . u1 v: o8 W! M* X; F$ ]) M# ^    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];4 i; e" v' N# T7 [- ^
        arcNum = 0;/ H$ ?$ S1 @# A2 g  R# k9 l8 |
        infinity = copy.infinity;; D$ Z6 S9 D( w& Z" ?) F) M6 s
        tag = new int[vexMaxNum];
    ! }! z. E! E$ Y# b: P, O. m1 |& I3 _  j
        for (int v = 0; v < vexNum; v++)
    5 b2 T  G' J. f4 c& P" q6 V! T    {
    . I9 ?' q( v1 U* h, i. f        tag[v] = 0;
    & Z2 q1 L' b- x) m- J        vexTable[v].data = copy.vexTable[v].data;% O( a5 A; O' J% F5 B, ?
            vexTable[v].firstarc = NULL;/ P% z9 W  V* z% w4 R  R  Q
        }
    * B. C7 b* r) S9 i    MultiAdjListNetworkArc<WeightType>* p;$ `) I  b/ j0 `; k0 r

    1 I( M" L& P, @! @" U! |1 S/ h    for (int u = 0; u < vexNum; u++)  }$ A, y8 V9 n4 ^6 p4 Q2 G
        {
    ( w3 F9 y/ H/ e6 `- i        p = copy.vexTable.firstarc;( V  C4 [3 J  C* ]' w* ~
            while (p != NULL)
      s8 x0 d$ Z, H7 c+ u  f& v# G! m        {$ S1 D" \. i- H- m$ J
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    % U. N3 H0 C3 d- }+ W            p=NextArc(u,p);9 U  j3 Y  V0 D6 w: T
            }& u8 x3 X' n7 `
        }* V- S% b; }& Q; l; S0 ^0 P: {" B5 ]2 l
    }1 l! r7 o6 G3 I) Y! }
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    7 `; k* N4 B. G, H: OMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    , {$ i; n' {5 ^; c1 {5 w2 e: ^: ]$ d/ b{
    * S; O9 p1 l9 `' `4 A8 g" f1 `1 A    if (this == &copy) return *this;# v  P: {- n* b/ ^4 E) l3 V. u
        Clear();% ~0 ~: U" d- d/ ^7 J
        vexMaxNum = copy.vexMaxNum;
    . y0 }' f  I: s+ y! @" @- I+ {- E    vexNum = copy.vexNum;8 a# V6 Z0 D6 r% k9 y
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    4 T% _: G& S/ \    arcNum = 0;
    ! U9 X# q3 U2 R: o3 E    infinity = copy.infinity;% Z  V  U6 Y, A$ N+ f( y
        tag = new int[vexMaxNum];  q) \9 g" B5 o8 ?( o
    / e5 C) u$ L) J6 G& Q4 d
        for (int v = 0; v < vexNum; v++)5 y: T1 p) ^1 c+ q: A
        {+ a& d' [+ W' s6 A- O5 z7 ]6 X
            tag[v] = 0;. g$ G0 Z; u4 j, n" x4 [0 w* G& X
            vexTable[v].data = copy.vexTable[v].data;
    4 ~3 a5 z0 o7 Q# _- y. r& g7 T        vexTable[v].firstarc = NULL;0 r# {4 y0 v* ]' j
        }
    0 b7 u7 P7 S) \, D4 ~    MultiAdjListNetworkArc<WeightType>* p;, z% v& a& G5 p8 d+ `9 E9 k, A

    1 p2 @& j/ x& D7 a$ C8 {- O    for (int u = 0; u < vexNum; u++)
    0 h5 @0 b; ]1 a    {
    2 D" ]' d: \# I- ^. A2 |; U        p = copy.vexTable.firstarc;
    3 A5 P  `4 P  P% S' A        while (p != NULL)
    , |, u$ U- n: e" ^0 V' g        {
    + U( j+ i6 _2 ?$ }! w  {6 X% j            InsertArc(p->adjVex1, p->adjVex2, p->weight);: q% [+ A) s9 T
                p=NextArc(u,p);
    # v; z& F7 R: f# J; M/ c        }
    1 V( H- t7 q) X7 W4 K( C) w* `7 x. @    }9 U1 q; t5 t! F5 ]/ G
        return *this;! r3 P$ j4 n  G* h5 ~4 h
    }
    ! F3 |! s8 b* T1 U" Stemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    : Z7 s) j. K6 Y! Z6 H! {) n9 nMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    0 R8 d, T8 Z, m% ~{% z4 Q% w" g( D) n" O
        if(p==NULL) return NULL;' P& }" h: Z( T2 j# O2 o
        if(p->adjVex1==v1)
    0 \" R5 t" ^. e' M/ t/ m        return p->nextarc1;
    3 m$ B& L  x! H' _4 D    else- h8 g3 P$ i0 v+ X, M
            return p->nextarc2;. U1 a0 s6 m9 A# x) b9 J7 }' f
    }
      Y2 b7 ]5 p* O1 U7 a# v. ptemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    4 k. |; ~& d6 o1 K3 ~* X6 lMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    2 j0 v! ]4 _. \5 j8 D& u( d{
    - i. D  Q# l# d4 \" E* k    if(p==NULL)return NULL;
    5 Z* m" ~6 i; M7 H6 ~6 A$ Z    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    , B- Z( N; y$ T* _6 n    if(q==p)
    # X6 E$ Z- h' \, w$ h        return NULL;2 z: a. U9 @$ ]+ v
        while(q)+ Y$ J9 I! q4 N: p- ~3 q$ Q4 e
        {
    $ I2 t, o% F+ e( `! R        if(q->nextarc1==p ||q->nextarc2==p)
    $ ~# u/ F4 g$ F8 P9 Y. [1 \& e            break;
    ) p& ?" m  q9 k( J" t        q=NextArc(v1,q);
    " n; G3 j. C  E# V$ X, _: m6 N+ H    }
    ' T  T3 P& l3 m# v! T    return q;, ]8 @0 Z. W0 a' ?  u
    }
    0 F8 A* ~2 L: K; P/ Etemplate<class ElemType, class WeightType>* y. a! G  t1 W+ ^* C  A
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)/ C0 X& o6 J% d0 F+ J
    {
    , }2 ^0 ?; V6 h; S# ]    if (vexNum == vexMaxNum)
    + e) n; y8 [  h1 D: F7 k+ Z        throw Error("图的顶点数不能超过允许的最大数!");4 U6 e0 y! C- g* a6 A1 F! U
        vexTable[vexNum].data = d;3 }  K5 H$ W2 |, e5 Q3 I) P
        vexTable[vexNum].firstarc = NULL;
    ' c8 H& {. S7 ^- B    tag[vexNum] = 0;& C4 }; r' k' r; U9 o
        vexNum++;
    : P! B2 _6 R, k* c% u3 C/ B}; W: g7 A3 i. D' [
    template<class ElemType, class WeightType>
    ; F$ N/ M: S9 ^) ]void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    5 w3 v/ r+ @. [{
    7 J4 u  b' \6 i. A% Y- O+ @- I    MultiAdjListNetworkArc<WeightType>* p,*q;9 V; [8 j; k) g# D
        if (v1 < 0 || v1 >= vexNum)
    8 ~- h. v! t. w0 i% i+ {1 \# B        throw Error("v1不合法!");
    5 c: k) O( S& s* B' E4 b1 S9 V8 {    if (v2 < 0 || v2 >= vexNum)+ {# k! i) [! M/ J9 ?- D4 a+ ]
            throw Error("v2不合法!");% _( N0 q& x' c" O2 x% ]8 r: t
        if (v1 == v2)$ t$ r" O5 q8 @! |4 S4 l
            throw Error("v1不能等于v2!");
    # C5 n$ O; q1 z1 z, e8 t    if (w == infinity)
    8 {5 s9 g9 _% i+ t: b1 j        throw Error("w不能为无穷大!");
    4 [  Z3 C- G# H! s: n
    " W6 s' @. Z. I/ I- b% a- R8 Z- D& u  a  \
        p = vexTable[v1].firstarc;- s5 R' ]" o7 @7 ]
        while(p)+ D- ?: ~5 f7 E  D- x
        {
    # ?+ Q# c% E/ e2 p2 R8 I' {        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    7 t9 s) m, ~" a        {  y+ I- X$ e3 e5 g$ w* h7 c+ I
                if(p->weight!=w)" I* H. _" Y# [7 C0 M
                    p->weight=w;. v, a, n$ W$ U6 j  [
                return;4 C' q3 `8 {8 @6 H( ]6 A
            }, j( Z, `( z9 ]% j! @
    - R7 n& S, O# H$ D/ L8 x
            p=NextArc(v1,p);5 q: W8 O1 F8 m& H" \! Y) `/ U8 D+ O
        }
    5 L' i2 ~% D" T2 j$ V0 r    p = vexTable[v1].firstarc;
    7 x* w: k) z, _$ @8 {9 i    q = vexTable[v2].firstarc;
    , p5 T4 f. Z7 m4 N$ v9 I; B1 U, k    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法% {! b: H, }6 C0 x6 h
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    1 i# j9 |" U4 Y. m2 z    arcNum++;; x' m9 m; m8 Z# S% O2 x& D
    }
    3 F, H6 f4 s% Z7 Y
    % i; @# S( r1 Rtemplate<class ElemType, class WeightType>$ }* A/ X( f3 ~4 G: S6 h! M
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)6 q4 ^3 r# M( {4 g; h& p! H% M
    {+ e% x( n8 q7 y  K& n" K. L

    , V- m8 ^5 ~& W    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    & V9 h. |  S; R: Q  P! F/ _  q+ k    if (v1 < 0 || v1 >= vexNum)
    3 i: p4 t( u; \: n2 X( u5 J8 B& `        throw Error("v1不合法!");
    * Y! b0 a1 W' l    if (v2 < 0 || v2 >= vexNum)
    5 \8 e; s' X6 }        throw Error("v2不合法!");1 ]& ?5 G& ?" y' b( f  ^/ }  x+ K
        if (v1 == v2)$ t) k8 R3 b7 P9 H  `; v' `
            throw Error("v1不能等于v2!");( M) A1 w- G( j- C* e
    2 d7 V. L- U: a" O* A) @) I1 U
        p = vexTable[v1].firstarc;$ p0 M: i" }5 s( F9 }7 i) h  Q
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    * Z- [. H# X5 Y9 ]    {3 _5 Q: A+ X' \( L7 W! v4 o
            q = p;
    6 C' P# _* k& }- ?7 x, g) m; Q        p = NextArc(v1,p);
    ; z1 D% M- r' d8 E$ ~    }//找到要删除的边结点p及其前一结点q8 [$ \0 ^4 w) G& ~, K

    . E, J7 u, [1 q) V6 ?( K  A    if (p != NULL)//找到v1-v2的边9 i5 ]2 J- {  A! [- F
        {4 T4 Y5 q6 Q1 U1 w
            r=LastArc(v2,p);
    6 S' z* {( J+ r5 }        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL7 T4 Z/ E3 B$ ^. N; Q; `
                if(p->adjVex2==v2)
    ! @& i: Q$ L; O/ Y1 l; \                vexTable[v1].firstarc = p->nextarc1;
    3 m, i# c/ K8 c- O            else vexTable[v1].firstarc=p->nextarc2;
    ; B7 x/ D: [# I0 v9 A2 ^3 n        else//不是第一条边; x( L6 x) @% C: e6 M* m
            {
    % ^( c8 Z* j! T; A+ i8 {  n1 ]            if(q->adjVex1==v1)
    ' O* i* _# a+ R# T& L                q->nextarc1 = NextArc(v1,p);- i' }- N2 r! v- y  C% e- i
                else
    6 p) H& ?  X, O; b8 [8 I                q->nextarc2=NextArc(v1,p);; Q* b, }/ U4 T
    ; C" Y6 o- X8 x4 H
            }
    % Y0 q& f8 B1 n+ F0 F3 J& |        if(r==NULL)
    5 \0 l8 ^* [( D7 W            if(p->adjVex2==v2)/ V$ [. u6 c  u+ p# r) [
                    vexTable[v2].firstarc = p->nextarc2;* B6 ^, E& J/ `
                else vexTable[v2].firstarc=p->nextarc1;5 B( E5 h& D5 [9 ~( `- |
            else
    2 o7 V, }- V2 b& `9 c# M        {# Q* a$ q7 w9 r7 ^: y" c
                if(r->adjVex2==v2)
    5 C% Y; Z5 R3 l# R0 p                r->nextarc2 = NextArc(v2,p);
    5 w; d+ C  p1 T4 h4 V            else" c  h/ _0 a6 |7 v' H6 g% \
                    r->nextarc1=NextArc(v2,p);8 x! k) v! W( q* T; r* @
            }
    8 f% H7 l2 R4 E: D        delete p;0 D* c/ K: W& o; T  Z) }9 @
            arcNum--;
    ! w) o: Q- ^- B% _    }1 p% `: r( W. C/ Z4 j$ v

    $ w! v$ S5 E% c1 S' m0 L( I}
    " F) X# n7 H3 B3 A! t6 `template<class ElemType, class WeightType> void
    , J+ M' C/ ]6 L- EMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    : w/ h; X: M2 o8 z{
    , t& ^: k4 T' R$ v& A9 h    int v;2 F# A! U/ _$ \7 \7 W8 B$ m
        MultiAdjListNetworkArc<WeightType>* p;
    - S; z' c$ `9 ^. {1 y3 e    for (v = 0; v < vexNum; v++)//找到d对应顶点. P2 F9 ?7 N+ O. @
            if (vexTable[v].data == d)% c  M$ ?9 c  C7 m' t
                break;1 r: b1 a. g( ]/ x) h
        if(v==vexNum)% q  `; @0 ]2 G: B. R/ V, V$ L" O
            throw Error("图中不存在要删除的顶点!");9 z: X) N7 K9 L* i

    . v6 p3 |+ K2 h& O6 e- y6 c    for (int u = 0; u < vexNum; u++)//删除与d相连的边; A; N% s' O2 a' M/ _3 v
            if (u != v)  p3 O5 e+ U4 m/ w! M& M
            {
    % r- P$ C5 P+ J: K+ N$ z            DeleteArc(u, v);/ U( ~' \3 ~- W; c9 L
            }: y& z2 M+ ?+ _) c) Q
        vexTable[v].firstarc=NULL;
    # G. `* D7 _, L  N. c7 i& D) E1 W* P) n
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置' w8 W* y+ `3 t3 e8 q
        vexTable[v].data = vexTable[vexNum].data;. i( c+ k9 O) r" f" r% }
        vexTable[v].firstarc = vexTable[vexNum].firstarc;/ [3 B7 d$ l9 a9 q+ f/ D
        vexTable[vexNum].firstarc = NULL;% r1 W( V, r5 X; w6 b: o" M
        tag[v] = tag[vexNum];$ b9 ?" P7 v. l0 _" I# h& _% Q1 C7 x, V
        //原来与最后一个顶点相连的边改为与v相连
    % d: A- N, w* i$ p; x, [    for (int u = 0; u < vexNum; u++)
    0 G. \% {/ }3 r8 n! e    {
    1 G9 e% N: G8 W4 }& u* j        if (u != v)
    5 Q$ u+ e4 ^7 ^9 r        {, W$ K5 y& u# [" S9 v* m4 L, w: e4 s
                p = vexTable.firstarc;
    ; Y% f3 o8 B$ G' T. F, v) \            while (p)  m8 `4 }4 b8 X  N: K( X
                {
    * ~0 L& r; v9 t( s8 v                if (p->adjVex1==vexNum)# g- l- i) S- W3 q$ J3 z
                        p->adjVex1= v;
    ! I- r$ C% G! m5 I# }5 O                else if(p->adjVex2==vexNum)" h- d* }) u% ]( Y
                        p->adjVex2=v;
    - ]2 z" @. m/ u" E7 {7 H9 d                p = NextArc(u,p);- F* l) l1 o0 z) ~* n
                }- s) ?- Q0 {3 J; V* _' R
            }
    ( T, v0 G8 l0 S0 E5 `: ~2 Y/ \    }
    ! x! L; Q; w0 ~4 o+ N* W}* i9 P. @- V5 Q3 m2 Q
    ///深度优先遍历
    + Q, n1 o2 |, h; m0 R+ N  D" h9 Ctemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)4 _* }; w& n* I) X2 I
    {) ^) q+ f! Z0 N
        tag[v]=1;8 c' v: u6 H" Y& h
        cout<<setw(3)<<vexTable[v].data;
    + t8 V1 c- h  o% g2 J0 A6 u4 k    MultiAdjListNetworkArc<WeightType> *p;2 k9 y9 R0 U0 f' K1 P9 \/ Y
        p=vexTable[v].firstarc;1 x: \( Z2 a* @- \$ F% p
        while(p)& i6 `. u% ~- ?
        {
    " H5 X$ j/ _0 {8 X+ R        if(tag[p->adjVex1]==0)6 L2 u7 H' G  j# ~1 a
                DFS1(p->adjVex1);
    ! {7 o% w) J4 t        else if(tag[p->adjVex2]==0)+ J4 i- x. N; }
                DFS1(p->adjVex2);
    : \9 t4 r( \  B. ^2 S        p=NextArc(v,p);% C. r- d% X$ \' j8 S! t* a4 Y' S5 a
        }8 t6 z, D6 P# Y2 D
    }
    - W* z! B" x" _7 Stemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse(): `8 l5 S  e% ?8 K
    {
    + @6 S8 M" u; ~) R1 s    for(int i=0; i<vexNum; i++)
    8 k/ M4 t. W" i        tag=0;
    3 Q. ~5 d; s) x1 ~    for(int v=0; v<vexNum; v++)4 E  [$ u+ P9 L7 Q7 [) s* _
        {; j' h& l- y8 X- g: R
            if(tag[v]==0)
    7 D4 m' [% G" n6 R            DFS1(v);
      c" F6 G6 y  k    }# O& r6 i- D  T% c2 `/ F7 Z
    }
    ! B& `/ f, _5 l  Htemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()  G0 x& o9 h7 g/ r4 `, W* {
    {$ s1 o/ m; {: \8 G  M: h
        stack<int> s;
    ' ]7 I3 I; a. f# K    int tmp;/ \7 ~8 [+ }# t2 ?( L
        MultiAdjListNetworkArc<WeightType> *p,*q;
    * Y$ f( L# a+ P8 q4 b/ ]: K5 h    for(int i=0; i<vexNum; i++)+ t  |) ~! L; W# I8 @7 @" H% Y, r
            tag=0;/ f8 g' W& Z& `3 x7 l# E4 w
        for(int i=0; i<vexNum; i++)+ P, K7 c; ?; [7 ]3 l
        {
    ' ]- [0 H, w& E- N6 V# _6 i        tmp=i;
    3 ?) d6 X0 F+ \        while(tag[tmp]==0||!s.empty())
    / c+ ^# m" E% V' h) |        {( _! }! ]: r, M8 [6 B9 W6 e
                p=vexTable[tmp].firstarc;
    - X/ f8 ~$ e# y, p- ~' m# o  s9 Y            while(tag[tmp]==0)/ ?, Q. Z3 w2 A. \* x
                {  }  C3 p. {& p* b! _& O" s$ T
                    s.push(tmp);
      ~  L. A2 z5 K. _  U/ p                cout<<setw(3)<<vexTable[tmp].data;
    4 K2 Z) F& I: v& M2 W                tag[tmp]=1;
    / j1 J" r* c# z6 c% C* }                p=vexTable[tmp].firstarc;% \% `- u8 H: Y
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    9 t: z  q1 v& K+ U5 p& }                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);1 Z9 d+ ]9 f( c  H
                    //cout<<" 1st     tmp="<<tmp<<endl;' t( S, b# f* T- q
                }
    " I$ v. `- M3 W; @! c6 M) `% O2 a            if(!s.empty())
    ( w" X7 n7 u4 P- F% G            {
    0 u) A2 F7 D. A5 }$ H* V                tmp=s.top();
    ( J( \2 [! |. U; B. I. o                s.pop();
    3 y" g/ B! T8 S  A2 _                q=vexTable[tmp].firstarc;% D8 y' f% q5 m8 R: @3 x- @
                    int t=tmp;
    4 M& `1 k# ]- L                while(q&&tag[tmp]!=0)
    ) y- d, s* G3 u+ H. W+ n9 N                {/ N4 R( H6 K% i& X2 S2 _
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    4 ~6 M$ q+ E; M5 v+ n                    //cout<<" 2nd     tmp="<<tmp<<endl;
    % B1 Z! l* S/ j9 p0 X                    q=NextArc(t,q);  P: R" l0 G8 c4 ]2 m5 m
                    }& V6 T6 N- W9 C/ ^/ r
                    if(tag[tmp]==0)% |# N$ m6 H3 G2 I: b( n+ {
                        s.push(t);4 v$ ^% E/ ^% d1 C
                    ///1、对应上面连通分支只有1个点的情况
    , L& E& m3 ?- L                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    8 E" K' k' N% l! o                ///tmp要么等于找到的第一个未访问节点,
    . o" R0 m6 s& p                ///要么等于与t相连最后一个点(已被访问过)
    2 p. d/ \/ l+ Y. n* X5 Z( }                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点% i/ O* H# {& x" Y4 `) b) `* R
                }
    + ^2 r% _) U/ }! u7 s! W0 K        }9 {4 z( y8 n/ Z- b3 f+ C5 H
        }5 m3 \! O! E: g5 X
    }
      L9 Q$ p7 r- h# Y( f, g//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-13 g2 j  t( ^9 V! t8 g% Q
    template<class ElemType, class WeightType> int0 g0 [! P4 |, \" U
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    ; J) O9 ]$ o: a* U* Z) `{7 y) H: p+ ~7 z, K5 n
        if(head==pre)
    - ^( }6 m: C% e) |        return -1;
    ' N2 Y/ O! E' e3 P
    $ ]4 P* X% Y: o% g7 |9 ^/ i    MultiAdjListNetworkArc<WeightType> *p;
    5 g1 a4 u' P6 s3 t& {    p=vexTable[head].firstarc;
    $ R8 a+ S$ X+ y: I) c5 a    if(pre==-1&&p!=NULL)
    2 d7 }$ l% Z2 h9 r5 o4 t        return p->adjVex1==head?p->adjVex2:p->adjVex1;. o* B/ x4 W$ y# Q$ P0 I( c3 A
        //pre!=-1&&p!=NULL
    5 I* C" A  K8 \1 s- H2 B5 y( m    while(p!=NULL)2 T9 \5 ^8 Q# ?- h! A  g( b- g
        {4 a# C" ~& Q4 O+ J  m8 ]6 R
            if(p->adjVex1==head && p->adjVex2!=pre)% y! J) J8 B' d$ J  l; E7 D3 R
                p=p->nextarc1;
    ; ]* {# W$ r/ Q3 r! [7 @0 q% p        else if(p->adjVex2==head && p->adjVex1!=pre)
    7 Z( Z; U& a: f2 v  ]            p=p->nextarc2;
    " l* @0 }5 d2 X# a        else if(p->adjVex1==head && p->adjVex2==pre)
    5 N0 F% m) \8 |        {
    3 G! q: u; S2 t: z. a8 p* Y$ a3 Z            p=p->nextarc1;, Z8 U& J$ o; s4 t7 @
                break;; [6 w! q2 E4 |: f
            }* B0 ^+ Z% `6 ?# K
            else if(p->adjVex2==head && p->adjVex1==pre)# |" d3 N8 b- y: ~
            {) h! z0 B+ l6 E: Q" Z' S) h# b) D
                p=p->nextarc2;
    * U( @. N; r; J  I            break;
    - h' V; s5 l) w! C- y  t        }
    $ {) Y7 E$ q5 `" `& ~5 L) R8 _    }/ F; a, p: o  k; V
        if(p!=NULL)( k9 k+ o+ w. M1 P( R! u7 H- A
        {
    5 ~9 @3 z# f3 Y6 e2 M: T        return p->adjVex1==head?p->adjVex2:p->adjVex1;& P0 |4 z" U1 J- \: [5 Y
        }9 ^; O6 q3 e3 E- K% T( }
        else) D! v4 {0 H& Z: ?  \
            return -1;
    9 n3 O( k! K  \. g; ~7 d6 Z$ i}- G. o8 f  ]- B0 X8 L% f
      C" a" M- b1 e  M. t

    / ~: {) q, @: v: H' Etemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    ( s- E, f  F4 f$ n+ Y{8 ?6 i( w; x  a0 g# O
        stack<int> s;
    + V; X5 Q% Z" X2 H  S* ~. v6 w    int p,cur,pre;
    2 F- l/ p5 @6 Z# O& U    //MultiAdjListNetworkArc<WeightType> *p,*q;
    % W2 J3 o5 ^% o" c    for(int i=0; i<vexNum; i++) tag=0;//初始化
    * {6 }- A; W( B+ A/ r- {/ u$ X' x; q( O0 u( O' I: [  m$ l' \
        for(int i=0; i<vexNum; i++)
    0 z' W  |( u  z- V9 \) ]    {
    * m. D3 d* _6 D4 q/ M( R        cur=i;pre=-1;
    4 o9 s6 S. v# \        while(tag[cur]==0||!s.empty())
    " U3 Y  C: m4 U8 J" P& _        {' e5 X/ d5 K3 v6 @! Y) t
                while(tag[cur]==0)
    " e3 w- f- l" Q3 b+ x            {
    7 c% K# ?! {# N: }                cout<<vexTable[cur].data<<"  ";
    2 W' V% y+ @. d& @* p                s.push(cur);; X) T6 t+ s# B4 A
                    tag[cur]=1;2 u, T- p$ x% g. k
                   //初次访问,标记入栈6 u7 R* [; k' \# L9 ~1 y2 d: I5 g1 _
    6 u+ E7 c4 f  P/ O7 S
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点
    ; {# e; j! j% O' x% Y% B9 e9 H               if(p==-1)
    3 S  L* ?8 e! c0 Y/ I" B0 D               {  B2 f5 m7 n6 _. Y: d' d! o
                       pre=cur;s.pop();
    " R! j- B8 Y" n1 `& X9 ]                   break;. L/ _; u! I2 r. d5 j# [9 Z
                   }
    3 K' N4 q; `9 q" ]               else! O$ L, |- t1 l  T% K4 K
                   {1 T# V/ }( o* I6 X& N$ l' R0 u" ?1 E* k
                       pre=cur;3 Y9 S8 I# Y7 z2 Y
                       cur=p;. S* D' r, z/ {
                   }
    ! B5 Z5 J1 j7 ^. ^
    ( l. V2 V+ ^& @4 F            }
    % R, C+ E* m- `0 l            while(!s.empty())) m& m% Z+ C9 r! P6 f& Q
                {
    7 w: {4 |7 `# |( a# {$ z, E4 A                cur=s.top();
    2 \5 P5 S2 [6 e) T6 \7 I/ }# J- d                p=GetAdjVex(cur,pre);
    & Z0 X# k6 h, \3 m+ o8 f9 K                if(tag[p]==0)
    , [# @% c4 W. J% C9 D" M0 [                {! h% Q2 K1 r; B7 _% Y4 L( J5 E1 I
                        pre=cur;
    . @9 w' M6 z1 R+ n                    cur=p;
    , `4 w0 w; h  R2 ]                    break;
    & L1 p8 V. q! y4 P                }
      t+ [8 Z! G& V  h- u3 j. M  e8 F                else
    " K3 C0 x2 H0 D                {" m' u+ V* ?5 v/ C! R
                        pre=s.top();
    ! q6 ]  }! p# v4 M" f6 I/ J                    s.pop();
    ) k  v: h) J& [& R                }& b2 z" u8 `# k: C
      |8 M! C9 U9 T- W0 m2 @' q3 d9 M: e
                }
    8 S# D1 x5 }2 q$ x! s3 \0 B0 \: U  }2 W5 v
            }+ |; U& @: I7 G; |( Q
        }8 r5 w" I1 t! J/ ~, K) M' c
    }" I$ J& p  j7 f! W
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()7 L5 e9 ~2 b9 v
    {# O' r& k+ M9 w& {6 @* [* J
        for(int i=0; i<vexNum; i++)0 O; f, i' h8 g
            tag=0;% S+ M/ l" q2 t: n/ e
        queue<int> q;
    ! y1 e2 Q8 G1 Z1 d    int tmp,t;
    # p  l' u5 Y2 S* P: M% @6 U, z6 y    MultiAdjListNetworkArc<WeightType> *p;. o' Y- w% j: b. `1 Y
        for(int i=0; i<vexNum; i++)
    ) Q# G' N" u( @    {+ U  |3 |$ F, U* y) E
            if(tag==0)1 T9 P  x. P- O
            {
    & X* W: N1 n' f            tag=1;3 g- k0 l' L  b  {8 s* v' P- G2 j7 N
                q.push(i);7 t' C: A' G3 b7 t+ |* ?' j
                cout<<setw(3)<<vexTable.data;5 x; B+ L- E! O7 K/ [6 Y
            }
    6 |; ~2 J7 O3 `6 P$ d& s        while(!q.empty())4 }. m& k6 `/ t2 M
            {
    ) v9 Q/ ~% r- j4 }4 d& C( ?) |: S            tmp=q.front();4 i: Y" B, M4 H7 s2 Q
                q.pop();' ?- Y, G9 y1 O. D1 ]  ^
                p=vexTable[tmp].firstarc;
    $ v$ F$ e+ w5 p( H  U3 r# H            while(p!=NULL)
    * J9 c, ?# M% v, K            {2 m$ e, r  |; f& J+ M& y. F" Z! ~
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    & p' {  I1 f$ `2 `$ @                if(tag[t]==0)
    % Y% m# t# S8 z* C                {2 [" I$ v2 R) d! F' k
                        cout<<setw(3)<<vexTable[t].data;4 B# e6 N+ D# E1 m' ^& z. w7 O
                        tag[t]=1;
    " \% \3 y% P) R4 ~1 K8 i+ l                    q.push(t);6 |+ ?( K* \0 C$ H9 R  o9 W$ n
                    }! }# x: U7 w* J% \  }1 W+ k: G
                    p=NextArc(tmp,p);
    5 m( f3 Y2 E; F# A. T            }8 F' l6 z; Z2 J# F& T
            }7 C; q. [5 Q- [+ ~- @
        }0 A! ?% x* J2 C, }5 ?  F
    }. B1 S% x$ H( e" }* H
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()( E) W0 M! ^, ~3 P# J$ k+ K4 ]
    {
      z& q$ Z$ k4 n7 A$ [+ j; m9 G    MultiAdjListNetworkArc<WeightType> *p;9 F' k( P; K. _+ Z# _5 N0 o
        cout << "无向图有" << vexNum << "个点,分别为:";
    9 ?$ v' X3 `" W, o    for (int i = 0; i < vexNum; i++), n$ D  D, c# w6 w% n+ w) h
            cout << vexTable.data << " ";
      T( r) L. g" |0 r" r    cout << endl;
    ! Y. o  g) A  }8 k/ [    cout << "无向图有" << arcNum << "条边"<<endl;
    ) m/ |2 L6 |; Y0 z: _    for (int i = 0; i < vexNum; i++)
    ! I8 q$ ~' p# O3 T    {
    % A2 M& I9 _* K4 p; e" [( {        cout<<"和" << vexTable.data << "有关的边:";
    " j" t- A8 K% V$ e6 V, p! I$ R        p = vexTable.firstarc;
    " \5 Y) I4 @) r, A! l        while (p != NULL)! a+ \+ O  q) K0 W# o
            {
    . I$ @" h0 K! H( E5 b            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";# T" r, C! r0 E/ e5 v7 a2 Y
                p=NextArc(i,p);# \7 G! k7 y6 X: I8 Y
            }
    8 E9 L/ q$ X% m" p$ _        cout << endl;3 k4 C) @3 K, ?. s
        }
    4 {% }( k; @- v+ D4 H9 D" t}
    ( {8 N6 @5 r$ r5 q) y- v" K" I
    9 A* H2 h' @- Y$ \% X
    3 b- b: v2 b4 s/ i: ]. l0 x邻接多重表与邻接表的对比
    ! O) `! l, M- d* d/ |  X9 @* f" u+ C' Y7 z/ M5 d0 u2 N
    邻接表链接, i! W; h, e/ X0 T. ]6 l
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。  x/ W$ N2 c" z  q0 v, z9 ]& ?
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    4 Y: z# d( x. b+ J. N为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。" c8 v7 ^% L7 c3 S4 s
    ————————————————  I, C' F9 v# l  |% D8 o
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。" u! h  W! E$ _
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    ' B6 r/ l! |, m0 E& H9 B
    . ?2 _8 N6 Y( ~0 I0 H* ^
    6 |/ V) S" m, o4 ^' f3 P
    7 X' _& P7 X7 \* U
    3 {) }9 @2 i8 N0 ]————————————————
    1 l) U3 D1 X. |5 }版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。  c  X, D* y! ~' r9 F
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958) t+ P1 c; R9 k: v

    : R0 i! Q9 V; \6 p# w% Q: P3 v3 `+ Y) }3 ^* j
    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-19 16:01 , Processed in 0.439706 second(s), 54 queries .

    回顶部