QQ登录

只需要一步,快速开始

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

    ; p8 g4 _  U! O( z图的存储结构——邻接多重表(多重邻接表)的实现- N# _2 C, Q- y. Y9 ^* n
    7.2 图的存储结构
    ; u$ f* e  r' Z7 J' [9 ^5 \+ C
    + `- r4 @! {- n1 j  u7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    # L# U+ ~9 C  |* T. V" \" n邻接多重表的类定义
    , m/ K+ J0 Z7 a# M( B4 h6 ^邻接多重表的顶点结点类模板7 e0 |& f' l- V: w
    邻接多重表的边结点类模板: |$ g5 V6 f" U
    邻接多重表的类模板3 b. B- r" ^/ n" F, S
    邻接多重表与邻接表的对比
    0 ]5 ~  G2 f3 j7.2.3 邻接多重表(多重邻接表)Adjacency Multilist9 ~4 y. a/ z2 K* @) H) r' X

    ( Q# [6 w- {: z  Z! Z在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。8 P1 ~! z5 z; O. C
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。: {! B+ {2 W+ q) N$ L4 _; s" `
    * q: Z2 P' i$ d* i
    邻接多重表的类定义
    " }$ H% h, t4 @' j$ X 1.png
    ( k/ N- _+ Q, D$ Y1 n+ m2 D邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    ; V* H& P6 e. n" |3 V. wdata域存储有关顶点的信息;
    4 R( y; l4 h( L9 lfirstarc域是链接指针,指向第一条依附于该顶点的边。
    9 y0 V6 i( n1 J; n9 ~所有的顶点结点组成一个顺序表。


    9 X# s1 f; r: j% z" t& N9 |1 Y2 R
    4 ?' U7 P8 t* W( ftemplate <class ElemType ,class WeightType>/ b4 p2 Y8 i; L$ W0 c
    class MultiAdjListNetworkVex0 B$ z2 l* C' {  h
    {
    , x$ g1 _( i3 C$ f. W$ jpublic:
    5 P$ Z' M( r6 ~' d! k' ?8 L        ElemType data;
    # F1 `  V6 ^' ^$ T9 D, ~) ?/ E        MultiAdjListNetworkArc<WeightType> *firstarc;6 w, B5 e* ?; c7 |, f# k1 c" k
    8 x) O! {' p) _+ E3 ]
            MultiAdjListNetworkVex()
    . V& C/ O2 v/ E' M, x        {5 Z; L1 m: ^" X* L$ f- T
                    firstarc = NULL;* i3 i( r+ G; T& v) n& X) G
            }/ |5 l) Z5 w/ h8 t1 \7 q3 `) \
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)* G' r0 ]/ {# {8 [6 ?; ?" f, e5 }
            {
    ( X6 O7 u! h, m1 _; d                data = val;4 R, K. u) o4 h6 O8 B" k1 d
                    firstarc = adj;- _& N9 [2 ^: n9 ?5 i
            }
    , m5 z* h) x* Y; z; ]};- h% M, v* a8 S* ^9 \+ A* g% [& C, k
    2 A% J5 V8 d5 Y  n( G6 V
    邻接多重表的边结点类模板; j  H" [( L' E4 g" ?# L
    + m1 {, N0 k% B: T2 Z$ s9 M) Z9 |2 ?
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:: ?, ^( z  C( z6 c
    tag是标记域,标记该边是否被处理或被搜索过;% [4 @4 W" F" X, p! H1 ^6 ~1 U
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    # j; x8 ]& x. S0 znextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;' ]; I( G1 l& j0 L
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    $ z, p# X4 x# u) Y, `5 Y: P! C
    $ _9 I8 r; }2 \* g/ Z 2.png 7 O, [' \! R% c* u0 E* d, G% v; [, ?
    template <class WeightType>3 ^, O. U2 N# M9 A
    class MultiAdjListNetworkArc
    4 S1 s+ M. I$ K( f! Q5 S7 y4 u{
    , T" c9 @4 r9 G( Y$ K- `7 _9 l6 Ipublic:3 u! |- f; K( |) C" d$ A
        int mark;                                       //标记该边是否被搜索或处理过
    ( u0 z/ J3 x  \: j  h4 Q2 `  t) Z        WeightType weight;                              //边的权重) e; y, b! v( X8 y
            int adjVex1;                                    //边的一个顶点
    , I8 X& Y' j7 T9 f6 g        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-13 W% \3 c) Z0 k$ E! Z
            int adjVex2;' s1 a5 W: m3 j8 l% s" {
            MultiAdjListNetworkArc<WeightType>* nextarc2;  z3 _1 @7 u  s! s4 p% r; ]: i

    # K* w5 r/ _9 n/ N+ @/ H8 A        MultiAdjListNetworkArc()" y4 E1 |$ v* }  ~. ?
            {8 X- h  c" W9 u" g; b2 R9 u' h0 |
                    adjVex1= -1;3 E# q* `2 }" D! @8 F/ l. y' M
                    adjVex2= -1;
    : o4 u8 v6 W2 I+ {9 c0 P# Q+ D        }: [8 X" ?: ]) D, f  Y1 L
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    0 N- C/ P( {- N        {# X/ }1 }0 \. U0 c
                    adjVex1 = v1;       adjVex2 = v2;/ Y3 o* w; d5 C. c# X
                    weight = w;
    ' D; }$ k# |. ?; n+ V! F# i* B3 J0 ]                nextarc1 = next1;   nextarc2=next2;
    7 ^9 d2 o7 H! |  e. s                mark = 0;           //0表示未被搜索,1表示被搜索过
    1 [3 }3 c' q9 p, v# u" q        }5 y% u0 i( @6 h

    3 B5 [4 l5 {) Y; X, @* Q% [! O邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    . c( k! _  ^' Cclass MultiAdjListNetwork
    : B8 ?& c3 m1 w{
    ( i% P$ c/ V4 ^! T9 x$ O& bprotected:) n: W9 w* p- S/ \
        int vexNum, vexMaxNum, arcNum;$ W. l0 w- }$ M% W. x3 Z
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    4 U" ?5 S: `6 y+ [( I2 x; H9 |    int* tag;
    # m& }1 t+ C( s1 S1 [% p3 [4 o( N    WeightType infinity;
    0 E7 F9 k3 u) U  N" n* X) G4 I: g. a. ]; X4 k& _
    public:
    7 P- A& l/ q9 p* t) }* t* C    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    8 O9 x" D8 P  |( j* @  g% @
    2 ~) w/ D0 e! a% z" n8 T    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    8 r2 L5 J7 d- ]( S- a9 [
    9 @) S5 R$ p# [( t# i( d6 B% _    void Clear();
    5 |8 P" f  M9 r: Q0 V- h1 Y6 y    bool IsEmpty()4 M# d3 D8 D5 r
        {) ]& e0 ~& `6 a' X
            return vexNum == 0;' W8 s' Q) x1 N% Q/ c$ @8 x( l
        }
    " x1 C: }7 {  b% g: c    int GetArcNum()const. r4 K5 z# w* k. Y3 G) z
        {! S& Q, b4 ?5 H5 F
            return arcNum;
    6 E4 F4 p' i6 \6 W    }
    6 q9 ~" H7 b0 i    int GetvexNum()const  ~: ^5 J" {8 o/ ?, h% H4 q
        {
      E4 F3 l$ u" c" \0 B0 @; n        return vexNum;8 K1 D" d7 J# J3 h/ i
        }
    1 I- @$ d! x. ?  [# k9 L
    1 d  h4 F/ O+ |: P; Y
    % I" C; [3 i( G7 j    int FirstAdjVex(int v)const;6 x& v/ x) X/ x& M5 W& ?/ S
        int NextAdjVex(int v1, int v2)const;0 ]% T) x4 i: t0 d5 ]+ z
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;) F- |0 L3 I3 u: ?
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    ) h1 K) x% g. _$ L( T% ?
    7 s# ^* Y8 a1 j: J5 i    void InsertVex(const ElemType& d);
    3 {, T4 J+ s4 @9 [5 O) _    void InsertArc(int v1, int v2, WeightType w);
    + K2 j, Q/ w1 o! g/ q9 r5 V- Z- R' a8 K
        void DeleteVex(const ElemType& d);
    & K2 K/ |. b+ s8 A    void DeleteArc(int v1, int v2);
    ! }; w; M" a3 D# t  l& C! T9 C! J; B6 ^8 K& ?' [
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);. ]1 v% ?, ^" X3 ^
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);" W# d0 ^$ I; S; a
    " h$ S3 a4 _. N
        ///深度优先遍历8 |/ K- J/ X# c( s1 @( R
        void DFS1(const int v);; p# D4 g5 F: A( q: o. l
        void DFS1Traverse();
    $ M. C- J4 P% s. y7 W    void DFS2();
      e/ {  w, {- p4 ]( g, V- V8 l4 X: M8 [' D. `6 v9 v9 }+ q
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    ( X8 U& ]% U( ?  u4 ^, n    void DFS3();
    : S! C7 t$ @9 d3 Q! W* C
    , w, p; W$ @5 @. M) B    void BFS();
    6 I* d0 [% Y$ f6 f    void Show();
      ~" F/ R3 g# _0 e, u% n" v3 T6 L& {};! }7 i" u1 p& s3 Z6 \* t
    - d4 l; o. T$ U0 ^6 I
    2.函数的实现
    * r! A3 `/ A& @6 w研讨题,能够运行,但是代码不一定是最优的。& f" \) w3 B/ P; _
    % C( t. |# q: `
    #include <stack>
    7 j% i" u- t; Z! v5 {, A' g) k#include <queue>
    & w7 g9 u' W; h8 ?; a. W3 r
    % v3 R3 y# y' Y. w# F, i7 j! O5 a6 I: Vtemplate <class ElemType,class WeightType>
    6 Z2 O1 A- }, y& z0 P8 [5 i7 B& m+ CMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    , f  W7 v$ ~9 b3 E4 e; W* @) U{
    ; `2 M9 t/ k/ T: N; c4 e    if(vertexMaxNum < 0)
    7 B, T1 D; L& \; @- B        throw Error("允许的顶点最大数目不能为负!");
    , o- E% J$ y7 ~# t3 v) Y6 Y) h9 N" T    if (vertexMaxNum < vertexNum)
    5 z6 P, n" v' g1 I6 ~        throw Error("顶点数目不能大于允许的顶点最大数目!");- L( s1 ?% u/ E% c: \  q
        vexNum = vertexNum;
      `2 d' \+ A* R  A    vexMaxNum = vertexMaxNum;
    + o+ k% ~, i  F6 V3 S5 j    arcNum = 0;
    : q6 @# ]! ?- N( r" f    infinity = infinit;
      ]/ ]6 V. _/ O2 }' l4 G  e    tag = new int[vexMaxNum];
    * M  u: M% |, A3 u    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    4 f% F/ [  p7 k7 {# a    for (int v = 0; v < vexNum; v++)
    & y, L' A: E2 ^: U' d" s    {3 [1 L9 D0 j  K* Z0 J6 P8 H6 P) A0 X9 A
            tag[v] = 0;
    $ G+ a; X/ G( A3 T        vexTable[v].data = es[v];
    % F, {) _0 B& t; j+ P        vexTable[v].firstarc = NULL;
    4 |  p1 e: o  s4 o0 U* M! O    }
    . |2 K8 f. z2 q8 h0 h, D}; c  M3 \8 y; R& p4 L
    template <class ElemType,class WeightType>
    ' @* O9 o$ D. a2 V0 z! O, K( |MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)6 s! ~+ I4 Y' Z
    {0 q7 q. a) o" |
        if (vertexMaxNum < 0)
    ' }' X% n- W; N; i        throw Error("允许的顶点最大数目不能为负!");1 {" |+ N3 k* i' U+ O7 `2 @1 K- F
        vexNum = 0;2 Y" [: F$ U2 q7 ^3 Y( n$ i# ?. f
        vexMaxNum = vertexMaxNum;) B$ f5 q9 E6 i+ k5 L9 q. T
        arcNum = 0;( L. X$ R3 W2 s6 u. a. h4 l& M
        infinity = infinit;
    % D5 _# G1 v- ~5 T& s7 a' J    tag = new int[vexMaxNum];( A; i+ [) b8 U. J- u8 L' V% n
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    , x5 U2 e' w2 g}( p0 k1 V2 T: _: p: X6 n
    template<class ElemType, class WeightType>
    " ~, S+ w8 ?: i" U& t* d4 J" Gint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    7 Y3 v, q% @$ L7 A1 |{; Z7 }7 v/ `1 i1 c, _! }7 Z
        if (v < 0 || v >= vexNum)
    0 u. y6 n! n& ~/ Q        throw Error("v不合法!");( N' }) h# x! B0 t7 U3 ^1 H
        if (vexTable[v].firstarc == NULL)$ J+ y+ ]: I5 u
            return -1;
    , x0 S- ^/ F9 [5 i7 |9 [    else4 y* z2 P. ~4 e( P
            return vexTable[v].firstarc->adjVex1;$ O% `6 v8 a9 w4 L6 f
    }* J' h& E5 U' [7 P5 Y/ V% |
    9 e& E+ }2 l+ @/ t4 e9 z3 }
    template<class ElemType, class WeightType>+ N6 ~: e/ s) ~; J3 t5 V
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    8 m, s) T3 \/ v8 q) _2 O% l{9 R+ ^/ v( |, q% C
        MultiAdjListNetworkArc<WeightType>* p;
    ) h3 K. E) P  @/ s    if (v1 < 0 || v1 >= vexNum)
    8 s: `* h4 W( @" T& A6 S/ S        throw Error("v1不合法!");. _4 }2 r# @# b# \
        if (v2 < 0 || v2 >= vexNum)3 E4 H/ x: E3 _+ U/ p9 \/ a6 w; Y' u
            throw Error("v2不合法!");& R( b5 K1 Q! Q  `* z6 `
        if (v1 == v2)% R, m! |6 q' f8 X3 C. f. L
            throw Error("v1不能等于v2!");5 Y" A0 P) ^$ u
        p = vexTable[v1].firstarc;
    " s/ y7 ~& R1 u$ f& D4 U    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    + t9 |8 Q3 n2 f: n. l1 @* h, \: o        p = p->nextarc;: p1 n, b- @; V2 I1 @  ^
        if (p == NULL || p->nextarc == NULL)7 I8 A. c4 O0 l4 m
            return -1;  //不存在下一个邻接点1 e* f3 f$ y* Z) h% {
        else if(p->adjVex1==v2)2 A+ P" F0 h+ P% {; A; K8 A6 |  j
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);* D) T4 t: ^& Z& a  X5 [6 V, ?$ C8 b
        else
    $ \' X# u% Y5 V# u) O6 K8 g; \2 J        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    . a; o6 D2 Z9 ^$ A# K2 J$ d}
    " w9 v- U0 E# F; z+ U7 W3 O. [# N' Itemplate<class ElemType, class WeightType>
    ) I0 U- R5 E. ivoid MultiAdjListNetwork<ElemType, WeightType>::Clear()
    # D) f% {8 C: `' k7 `4 a{3 O& ?. K! }& o& s
        if (IsEmpty()) return;/ i5 H4 `! `, c6 F/ j+ f
        int n = vexNum;  f# \5 k* Q+ A9 \2 a
        for (int u = 0; u < n ; u++): j, y6 w+ W: `0 }
            DeleteVex(vexTable[0].data);
    # {8 l/ {! V( f6 M    return;, A+ E& w5 H7 h0 O( \
    }8 F$ |  R: {7 q' `$ \5 L
    template<class ElemType, class WeightType>. }' W& h, u5 t& T  E" A8 B
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    # s& W- [. m' n" [1 m; K{
    5 Z9 Z0 x( j2 r: R4 a' i$ E    Clear();
    % e' j0 n5 h+ o$ W+ [( g+ u6 V/ J}
    ; a4 a3 U5 G3 D2 V( y5 L" H4 p* B) Xtemplate<class ElemType, class WeightType>$ v) W1 D) K: @  F  _' Z! H1 p
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy), s0 n' P% t( M& i; Y7 n! X7 }
    {3 c* T+ U( J$ V) B- @; B
        vexMaxNum = copy.vexMaxNum;/ m) C( ^; n; {) i! M, m
        vexNum = copy.vexNum;
    : i! E9 B5 c$ u1 N2 v    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    3 W: ]: `2 y) s/ x( }: |8 T8 i" a    arcNum = 0;
    5 e, q8 j  d  M" R8 h5 p) y, U    infinity = copy.infinity;, R& s# F4 {  j0 i5 n
        tag = new int[vexMaxNum];
      U0 T" e6 A$ V6 S2 C& J
    4 s/ ?; T# [3 A; K    for (int v = 0; v < vexNum; v++)
    , B4 K' w; s# j% L" c$ Y2 s    {
    ; j# v" i: `( K0 @% E        tag[v] = 0;
    / w3 H( H- N: X( U        vexTable[v].data = copy.vexTable[v].data;- j; u# j6 Y" q# ]" `
            vexTable[v].firstarc = NULL;% X: O# `1 W. S  m/ Q9 ~
        }
    # l  Z  T2 f/ w* J2 T    MultiAdjListNetworkArc<WeightType>* p;
    ' \9 {. n' u9 R, v8 Q# M9 c% e# D( l
    6 s/ E7 Q  t/ h. P$ ^  r! p, E: V9 K    for (int u = 0; u < vexNum; u++)
    " M: O) D% J9 _    {( ^' z3 i+ r( {8 g* j; `# {- Y& e4 e8 ~! c
            p = copy.vexTable.firstarc;; d" a  }/ L5 q, h  y7 R* h  W4 d
            while (p != NULL)$ U; m+ K% u4 Z6 b; o' r
            {8 w1 b) f! o" J7 ?2 O
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    3 ?: v% [$ ~0 ~( e            p=NextArc(u,p);$ ?) \0 V# U6 q  o, Q; Z; d
            }
    2 ~) c( D4 S# k" v% ^- [    }
    * _5 K  ~) n2 X) U) B% r1 ~) |9 h: w}
    + V- U+ s) O# K$ w/ a. c' Dtemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&1 i: ]9 l$ s7 R. }
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    7 t+ p0 f( r7 ~% O; a# f{( h+ W% P( U) g( z( B! G# d6 B
        if (this == &copy) return *this;
    6 I; L+ K3 O0 m8 N) t    Clear();- L5 k7 }* I( \" V
        vexMaxNum = copy.vexMaxNum;  W7 H; i4 w# H
        vexNum = copy.vexNum;
      ?; }2 _+ K8 E& I    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    - y( }/ [* x* r% D( I: u    arcNum = 0;
    + V  \' t* a7 p    infinity = copy.infinity;6 M) |/ D2 R( q+ v9 {: }0 S
        tag = new int[vexMaxNum];
    - q& S- q7 a9 y/ h2 \% b; A, h* i  V* T  _5 l* m
        for (int v = 0; v < vexNum; v++)
    8 \" X: l0 f0 A% Y: s: j. i    {
    : ^4 }. d3 T* h0 D        tag[v] = 0;
    ) @8 r9 e5 V! x4 L        vexTable[v].data = copy.vexTable[v].data;5 M; |) C! B5 f7 u9 S" R" t0 s
            vexTable[v].firstarc = NULL;
    ) X7 c( ~; F2 z4 R  }. B5 B0 U    }- u' l6 Y0 x! h0 D
        MultiAdjListNetworkArc<WeightType>* p;
    ( `% i$ N4 [# ?4 N' J0 p) `% a
    4 C% `- C0 I- z1 M    for (int u = 0; u < vexNum; u++)% s4 V: a+ w" z0 S; j
        {
    ! a) v- P3 p4 P- c; b/ }" p        p = copy.vexTable.firstarc;6 ~- ]7 }' ~5 w! v; `
            while (p != NULL)
    , ]8 b/ U6 I& [: D, F        {7 P" E" x1 n& {
                InsertArc(p->adjVex1, p->adjVex2, p->weight);( d4 N7 g' t( j" _2 G0 x
                p=NextArc(u,p);$ p3 j  r# J0 |! f9 o/ t7 z# |
            }
      i+ \5 r5 }" n; }  c- n9 p    }
      ^- h# f& V- o" O    return *this;
    0 ~6 S5 H4 g- x0 F0 R' C7 P}. m* _! j; D& q6 k
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    1 I8 A* U1 q8 r% Z6 `MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    . s- u' [  r8 q  n" c{3 w, k* X% e* A$ p! W0 i2 ?
        if(p==NULL) return NULL;
    8 M4 y0 u: _0 x0 J. O0 D5 K    if(p->adjVex1==v1)8 v* w8 B6 a' }5 U+ p+ j
            return p->nextarc1;2 e* ~2 s8 K- a3 H2 N
        else
    1 W8 K7 m! o5 p  e2 t        return p->nextarc2;: o. |; v( f, ~3 o7 J% M: R5 W1 R' ~
    }, g1 r: j+ v( F, J9 n; i: @
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    ' v2 K) ~# _2 P  W4 Y% O! p1 xMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    ) x1 {. Q+ I- ]{
      U( j! B, \; O. P7 E    if(p==NULL)return NULL;
    2 U: @5 q8 B/ O+ h7 W- x8 ]- D    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    % a3 h: ~  H1 x# [9 J/ d  c    if(q==p)( _. p5 u, D3 b' g  I
            return NULL;
    7 p' x8 s0 N, u6 l6 Q* I    while(q)
    % b2 b1 L0 M( z1 T  O; ~    {+ k' c' x8 r5 t1 f# m" X
            if(q->nextarc1==p ||q->nextarc2==p): q1 a; K! t% m
                break;1 K7 D# v0 r! E  u0 p
            q=NextArc(v1,q);" P2 v% f' q  w
        }9 C- V- {  [& {" ^7 Z- U5 h; Z4 c
        return q;4 Q* F: h" ^1 B+ ~# w* m" J
    }' e2 m$ @9 L& a/ |
    template<class ElemType, class WeightType>( E+ ]# X, P" w- t0 Q
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    " t$ _* R) @! {' H! S' B( b" b{
    2 l$ T1 g5 l5 l5 h  e7 e) O9 K    if (vexNum == vexMaxNum)% }" F# C) ~# ~- z# c
            throw Error("图的顶点数不能超过允许的最大数!");
    . l8 Y9 |4 N2 I5 R9 I    vexTable[vexNum].data = d;
    ! @: g5 x: N0 [+ u$ j' Q- N1 Q. @    vexTable[vexNum].firstarc = NULL;
    4 ]' i+ f' z& h, y4 E1 K1 y    tag[vexNum] = 0;
    . F4 V& O; h% X; P( ~! n    vexNum++;' [6 v% g+ T  g
    }
    5 s# M; M% _/ r1 `0 o. `; Ptemplate<class ElemType, class WeightType>1 S" k: s4 X4 v! K8 O; Y( t
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    * Q9 v" x6 V! b1 R# `. _{4 X/ u: l2 Z; T  o1 F: S  ?
        MultiAdjListNetworkArc<WeightType>* p,*q;; B5 h5 A& ^) z; \3 m# o" r) X
        if (v1 < 0 || v1 >= vexNum)9 P: U; g8 u1 k; w4 I$ C4 X; u
            throw Error("v1不合法!");/ m# i  K  M6 H
        if (v2 < 0 || v2 >= vexNum)# A# t( _- f$ C0 r9 k
            throw Error("v2不合法!");7 h5 u" P6 ?& p1 N7 C1 M0 V& h+ U6 H' D
        if (v1 == v2)# G  s# E: e8 \6 n  F: |
            throw Error("v1不能等于v2!");3 }7 @/ @  w( C# D
        if (w == infinity)
    / @' a" n' z/ @: {( }( t  ]        throw Error("w不能为无穷大!");
    2 r! X2 w) f- {: `; n" f
    8 Z; o. C$ T! a# C( A% D! Z8 p9 ]6 E
    : X6 n. c2 I7 ^. V# O' K    p = vexTable[v1].firstarc;* J5 n( @+ z2 P9 p( h6 h" |
        while(p)& n+ N# v, Q+ N% ]$ m& F
        {  C' U/ {. f' {1 S" }4 C
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    : A& z  X) b' Q        {5 T" E& D- q7 v# n" y. {  Y5 v' a
                if(p->weight!=w)9 O3 b2 Z; s0 a0 e) `4 ]3 Z
                    p->weight=w;
    ) ~; M. \8 w- X- Z' j! K            return;
    7 W9 z4 Q2 \* g. C        }+ u( K) j! \0 L/ K) t

    % h- O  \* f7 C- p$ T2 `$ }        p=NextArc(v1,p);
    & w+ u9 K! M0 Z: K4 L0 m1 s( V    }
    8 v9 }; k6 ?% V9 g: v7 }8 I    p = vexTable[v1].firstarc;
    6 h: Z7 c$ g/ `' H    q = vexTable[v2].firstarc;. b& v! P6 J+ V3 y* r# ~
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    , w- O  b# n3 a    vexTable[v2].firstarc =vexTable[v1].firstarc;) U3 X7 L- q2 s+ R( ^8 L
        arcNum++;& n" b# O& k. t3 Z# H+ ]
    }" W5 R$ Q/ v! Y% ~/ \" A

    ) B: s  r# e8 e4 ktemplate<class ElemType, class WeightType>
    ) c9 Y$ c* U  Q  w7 p/ ~void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    7 j: W$ ^! ?3 l9 r{
    , P0 w; R# ^" }1 F9 ]/ |  n% }  w9 n6 _& S4 H
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    8 \& }# V# K* {& I    if (v1 < 0 || v1 >= vexNum)3 V9 O4 t% z/ ?$ B
            throw Error("v1不合法!");: ]5 {3 i, t2 J4 c/ _$ o3 Z* _
        if (v2 < 0 || v2 >= vexNum)
    , ?' ~6 i: m  v& B" u        throw Error("v2不合法!");' a0 w. H- n& k' B
        if (v1 == v2)( i7 L9 M; [8 m% b& b9 X0 O9 G0 e
            throw Error("v1不能等于v2!");- \+ k+ t5 ?1 ~6 q

    % |' n4 M8 N0 O! @7 O' t0 T    p = vexTable[v1].firstarc;
    ! V1 [: e8 x4 _8 H! s, I6 C    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)9 I, C" u1 Y+ c- I7 D
        {
    7 \" U& C# q4 |& s( ~3 b$ _        q = p;+ I, Y* ?. K6 E* w; N
            p = NextArc(v1,p);
    & i' b3 v+ u. K, b    }//找到要删除的边结点p及其前一结点q
    5 q7 Z6 F% _7 i: h
    5 b( V; D* h' s& [8 f2 R    if (p != NULL)//找到v1-v2的边: t& i, A( p( z% \
        {# U" ?8 e; _& ~  \0 A
            r=LastArc(v2,p);
    ; Z$ ^1 a3 K4 r& Y  V. u        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL& r9 y/ W! ]$ e4 ?
                if(p->adjVex2==v2)- \% u5 L$ e- a( k- ~3 v
                    vexTable[v1].firstarc = p->nextarc1;: X# _3 Z1 N- o, x+ b1 g
                else vexTable[v1].firstarc=p->nextarc2;- ^! n% F6 L, L7 g. S/ L
            else//不是第一条边
    $ f7 b- B: _7 f* \5 |. m% K        {5 A6 d4 |+ K  G; a  X$ w+ s3 O1 v; q
                if(q->adjVex1==v1)
    % A3 A, d4 D: o) Z7 b: v4 Y                q->nextarc1 = NextArc(v1,p);4 z, a, J' {) f
                else
    ; b* C& _1 U' Q" z4 U& H                q->nextarc2=NextArc(v1,p);5 O8 ?* S) t% P- d. b

    3 t* |1 J0 \7 Y( X0 y0 g: |0 ~' X        }
    - i" k) c) x. S& G! h        if(r==NULL)
    - @9 b: L3 Y( p6 q6 F            if(p->adjVex2==v2)% [& x6 Y: F3 R8 i: t' e
                    vexTable[v2].firstarc = p->nextarc2;
    " o2 }& Z0 M( w            else vexTable[v2].firstarc=p->nextarc1;7 T1 D& r* a) B6 j5 }; F1 T% v
            else9 J" L8 ?6 N" S7 @: U
            {
    6 ?- j8 q3 e0 ?/ {3 R$ a            if(r->adjVex2==v2)
    : {8 w4 C* X7 A+ M3 f                r->nextarc2 = NextArc(v2,p);! b8 c! _# ~2 C2 X
                else3 q; X1 l8 }+ `! l5 }$ B
                    r->nextarc1=NextArc(v2,p);
    0 M! `; j0 y* J( A* X' h        }6 X- j/ J( r$ |, y" ^
            delete p;
    3 T9 A0 b$ W1 P5 Z  v" y" X! F        arcNum--;
    / V  @2 b' _6 ~    }* z. t/ l; N' b+ W
    2 ~/ A8 g+ Y) C, f1 }* c
    }/ U, ?+ _, S% ^
    template<class ElemType, class WeightType> void0 l" F& ^. H+ q
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    4 h3 o& ]( L/ k) l6 Y, x9 `; S9 y{& g+ p0 {& {1 h
        int v;3 V! e# j8 ?8 ?% o0 U- p- |6 `2 u
        MultiAdjListNetworkArc<WeightType>* p;, H: |6 i* L  \
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    : o7 ^) z0 ~' o, O' F        if (vexTable[v].data == d)$ z& j! d) \( O. ^- g. Z
                break;; t- [7 Y# o2 y' O
        if(v==vexNum)% D4 O+ V- q0 m
            throw Error("图中不存在要删除的顶点!");
    9 @6 @/ t1 R, j% q1 u" O8 l  U! X) {) l6 w' F# k9 d: [6 i* z" F* E
        for (int u = 0; u < vexNum; u++)//删除与d相连的边1 z3 F: e" E, f
            if (u != v)5 V" w# c" ?2 N5 h2 E
            {
    * w$ Z4 {7 {+ R' v4 i" f            DeleteArc(u, v);8 V: X3 b( P% R4 T7 m+ p
            }
    ( x! I. E% ?7 E    vexTable[v].firstarc=NULL;5 M( {- U1 Y& O

    9 F2 I2 x* C0 m. C    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    ' N  P7 Y) k+ D1 T% Y) i( e' z    vexTable[v].data = vexTable[vexNum].data;
    ) i  i  I7 J6 G    vexTable[v].firstarc = vexTable[vexNum].firstarc;
    / _- B/ i% i1 a    vexTable[vexNum].firstarc = NULL;+ f; o2 @" H. D2 `; n. w
        tag[v] = tag[vexNum];2 v1 C' D* R7 U
        //原来与最后一个顶点相连的边改为与v相连
    9 O+ r* D/ X0 `4 y7 A% _+ b    for (int u = 0; u < vexNum; u++)4 ~1 |- t- J) w8 @; L* O5 M4 {
        {* j5 a# \2 f  ~! z/ K6 U6 K
            if (u != v)
    / d$ B2 [) `7 W2 d! g5 s; J        {
    6 V5 \' b& u) |# n            p = vexTable.firstarc;
    3 H+ h. M% y5 h& N            while (p)
      J% F3 A- V8 q! A: F9 |            {& s( B: Q! P, g5 S* P7 q8 p
                    if (p->adjVex1==vexNum): |1 }; B+ T1 `5 v  E
                        p->adjVex1= v;
    $ h0 Q1 c( U/ }4 K9 S2 Z0 ^                else if(p->adjVex2==vexNum)0 e' Y1 R0 ]& Y; F! M
                        p->adjVex2=v;
    5 [; H2 E2 `, x  m( R                p = NextArc(u,p);
    3 x* B. |% _+ i" o$ z2 H            }
    % y8 q+ B9 ~5 }. _% t" |7 }        }+ i4 A+ j3 ^0 O
        }
    1 x* C, K& N0 K$ f/ z) z; i}
    & d0 ~3 A8 E; O4 R( j+ ]. s///深度优先遍历
    $ k6 g5 a7 C5 E2 j! Y6 t) b7 Utemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)$ R- z+ R" h1 A. t
    {/ n% F1 q6 g0 [& d( [$ m
        tag[v]=1;
    5 F! t6 i% x* f, X4 }. [0 d, f0 @    cout<<setw(3)<<vexTable[v].data;
    $ k, t3 O  L! @& t7 D    MultiAdjListNetworkArc<WeightType> *p;
    , l$ H; u4 M7 t: l    p=vexTable[v].firstarc;" B4 F1 N2 G! z# d$ h& \
        while(p)# m! W8 D# {. n. l3 P9 @% k: U
        {3 O7 j! X* W4 d2 ~2 I: y& @
            if(tag[p->adjVex1]==0)8 _) v: l7 i" j* [' s8 p8 K9 W  u
                DFS1(p->adjVex1);8 H# ]1 h6 B; L& r2 z6 B% r4 Y- c+ R
            else if(tag[p->adjVex2]==0)$ K0 g. S' o! T; v# U# ]+ J
                DFS1(p->adjVex2);
    9 @, w; M) _0 _  D        p=NextArc(v,p);
    9 g' M3 O! j- h0 f, O! Y    }% ?5 k, ^1 s" Q- k0 X
    }) G! s* T6 j' \0 K7 j( x
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()# @& u- Z. k3 e5 n+ m# O% Z* f
    {+ B% G& x% _& H3 g: s. _7 R
        for(int i=0; i<vexNum; i++), n6 W+ w4 [9 D) k  S4 Z* ^
            tag=0;5 o9 V% {8 @7 e4 f) T# ^
        for(int v=0; v<vexNum; v++)5 a. L3 L; k( [! w) \( K
        {( z1 G7 @5 }9 O8 ~
            if(tag[v]==0); o4 d, U7 b5 s7 ~" n: {3 L
                DFS1(v);
    # \7 F5 w: t4 T3 a3 V; t    }
    * e( A/ E, O. m% T8 g3 Q}- J, G; H5 P0 t6 U" U
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    $ k8 v4 l: }8 X1 ?- w{
    + n9 v; B, j' u7 w0 N9 `    stack<int> s;9 E$ j- k2 {' ^, }9 D- @1 l
        int tmp;
    $ R7 Q! n$ I- S, L! O! R    MultiAdjListNetworkArc<WeightType> *p,*q;
    + f: a/ Z1 Q' l3 a% }    for(int i=0; i<vexNum; i++)
    3 l/ o9 ^- `" [/ v        tag=0;, m0 q# Z# E' O' ?  x, W0 M
        for(int i=0; i<vexNum; i++)
    9 x6 e" I, Y" K& V% `. B& U    {7 ]8 M0 O, C% z! a5 x9 X2 x
            tmp=i;
    9 Z5 `2 M2 o: W5 F3 m9 U        while(tag[tmp]==0||!s.empty())
    1 M2 C/ Q! j. ^" R        {: w. ^% y7 p, C  Y9 j3 D0 D  P
                p=vexTable[tmp].firstarc;
    6 O; M5 q) {: j' f0 T$ C5 t) w            while(tag[tmp]==0)5 k" n) z4 ?9 G- {
                {- v; w! a. W; ?! y3 a
                    s.push(tmp);
    ' W* y2 J6 u: p. ~4 D; p/ m0 J                cout<<setw(3)<<vexTable[tmp].data;
    + r. m8 A+ l0 v) Q) {/ [$ H                tag[tmp]=1;
    1 Q7 q' M! ]+ Q% ^5 U& @                p=vexTable[tmp].firstarc;0 Z+ e0 q" Z' b" Z" h& G
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    & O  O) v  n" T3 Q# D                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);% G3 Z4 O' I3 `% S# a, F* s
                    //cout<<" 1st     tmp="<<tmp<<endl;
    # J- T. V+ G! B            }
    4 z7 D$ m0 Y- r3 c2 k6 A. w            if(!s.empty())
    ' S9 |' {0 o/ R3 @/ Y8 z8 l' R4 ^            {3 Y0 j- y' H9 V" P! k% o* m* Y
                    tmp=s.top();
    * N" j$ }3 j7 j9 b+ Y                s.pop();7 M3 Q% K  K1 Y8 H* S7 ]
                    q=vexTable[tmp].firstarc;
    5 U$ q2 m, Z0 H! m6 t) H                int t=tmp;
    0 D1 Q) _# \2 L7 `# o# l/ ?& J                while(q&&tag[tmp]!=0)
    - b! ^! b! K7 E: G0 L9 y1 U                {3 `( e5 G5 B! i' s( q: t  {! x, J
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);9 B# ?4 `3 E8 E9 {+ f; v4 L
                        //cout<<" 2nd     tmp="<<tmp<<endl;
    ( y$ ]( L' b$ F. d& S. h) G                    q=NextArc(t,q);" \0 E" y* n% r% `
                    }
      Y6 `8 {& C/ L5 I8 n; W                if(tag[tmp]==0), F( N0 b* W% c% X6 D, O" _
                        s.push(t);
    ( i- p0 f' Z" M3 S                ///1、对应上面连通分支只有1个点的情况" H  |% z. V0 l- w, A5 n
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    7 p$ V/ r/ h! \: ~4 P, ^7 Z                ///tmp要么等于找到的第一个未访问节点,/ n% D: P% p! ^, w8 y' Q3 G
                    ///要么等于与t相连最后一个点(已被访问过)
    7 _- D& t' S: V" ]# A+ M/ d                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    ) l" X% _1 b  A) B7 V( S9 s            }
    8 s% G: Z: S4 [        }
    3 C  {& d* K4 c5 S    }+ w' O8 `1 _; r( \. o. {
    }
    % g1 R9 l0 H4 c# B! Z//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    - ~/ c4 d8 Z1 ]5 Jtemplate<class ElemType, class WeightType> int
    5 S7 I0 o# V- s$ D6 p& |MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)1 @  z8 f# B% X8 o( X
    {- X# c+ C, _* G: U$ `$ G) ?9 t0 K
        if(head==pre)
    & w+ _% [4 ?  r, P  b        return -1;% c& \- b2 R2 x& z

    4 [$ R* |  T) ?3 s    MultiAdjListNetworkArc<WeightType> *p;2 v! k$ a. S* V7 A, i1 K
        p=vexTable[head].firstarc;
    : ^. C0 H/ k5 F; N. l" I    if(pre==-1&&p!=NULL)
    2 D4 m- o4 O; P7 D& A2 M        return p->adjVex1==head?p->adjVex2:p->adjVex1;9 }* {  O: R# Y7 i9 @
        //pre!=-1&&p!=NULL( c6 M" c; a8 O& [% s3 p. t: X
        while(p!=NULL)
    ; M' K4 E: V) f) l7 k3 ~& f    {
    / n1 @* A4 v* V/ {0 x        if(p->adjVex1==head && p->adjVex2!=pre). S' a, C/ r) O$ m/ M4 `
                p=p->nextarc1;" g+ ~6 e0 {7 r1 I0 S0 h! V- |! f
            else if(p->adjVex2==head && p->adjVex1!=pre)5 _5 S1 W+ V$ }1 M
                p=p->nextarc2;
    3 Q# Y0 V3 T& Z" s        else if(p->adjVex1==head && p->adjVex2==pre): A$ [- U* S! B* O6 U7 ~1 E
            {
    1 @3 M6 p; J( G8 c' b  a  x. Z( b            p=p->nextarc1;- q5 D3 K/ s+ q% K! E* b; c
                break;
    9 m- J& ^6 ^% M. d: \$ k. [+ X        }+ F/ @. E' |1 ]( [% y* Y
            else if(p->adjVex2==head && p->adjVex1==pre)- ]5 K( v: b" I5 I9 i0 Y0 M4 b# S, S
            {
    / ?$ n' b" y. j* J            p=p->nextarc2;
      S  @+ X9 q- r! `- S/ U: i- Q            break;
    8 A: o& O# r7 {- o- Q- t        }$ c* K, A8 f* s  h, D  j) k# J5 i2 G0 y4 S
        }' h5 f1 H5 ?* f/ L" o
        if(p!=NULL)
    / `. h5 ]/ Z# V" E    {8 F* x' o9 k7 }+ m7 E; r
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    & l, [9 a$ Y5 l. v6 N( p    }5 y9 t2 t4 Z# l$ F  j% U- u) S
        else
      n, {2 t4 C: ]3 i, ]% S! F        return -1;! F- R' Z2 N8 `, b3 B
    }' R- G2 T0 B/ g6 \# F  }7 K
    . ]# s* e- Q! S5 {
    - J. W. K% b: y; D- V9 ?
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    5 l9 V6 B. P5 l8 r{+ Y; {8 @3 O+ a' \' O' g9 v
        stack<int> s;
    . u2 j, @; x2 r& E& _+ W; K    int p,cur,pre;. D( g/ u$ f5 i$ G, u- H7 E4 h1 x' O
        //MultiAdjListNetworkArc<WeightType> *p,*q;7 ~5 a1 S4 e% V+ w
        for(int i=0; i<vexNum; i++) tag=0;//初始化. o7 F( Q, z! X- u9 r, _; l) Y0 o( R
    7 A2 e8 y5 c5 Z9 D2 {/ t
        for(int i=0; i<vexNum; i++)+ e9 O! [) {) S6 f9 J3 l
        {$ p' E2 i8 O. i
            cur=i;pre=-1;; O! J# n8 |+ ?" @
            while(tag[cur]==0||!s.empty())
      Y1 l; L! T* a1 D/ e2 B: j" D        {
    3 D# q  f1 r" j$ o# [4 W            while(tag[cur]==0)
    + \9 h8 k* Z' U  F            {# b# S" f4 e" j) v1 M# O/ a
                    cout<<vexTable[cur].data<<"  ";
    8 E3 z; L5 b: Y5 N9 G" S                s.push(cur);
    , C, D  H5 |2 k- o* e2 |                tag[cur]=1;
    * v' }- D/ C/ q9 l; ?* ]               //初次访问,标记入栈
    : ~" G* H- e- U1 ^; ]+ E4 V
    . M/ ~$ ?" u) a6 @. q               p=GetAdjVex(cur,pre);//p是cur的连通顶点
    - H# z; L9 l) C               if(p==-1)3 @& d- w% V2 K' |4 j
                   {
    / o, X  n# p: V/ e1 z, Q  y                   pre=cur;s.pop();
    8 U) {" T! ^/ n# j, n% Q                   break;
    ) l. Y6 b, Z) D& T! W# v  q' X" {               }
    ( y7 W& |  f' R2 _               else! ?7 s% J; c3 ^/ o; O: j' O) J
                   {
    4 u* _4 C) S2 |8 p. E. t                   pre=cur;
    $ d+ a, T' v0 c( B3 g  g$ R: ?                   cur=p;
    0 U% V! [4 L0 [$ Y! X- O               }  Z3 C  L9 W. y3 _6 b6 q( B& \
    & t9 h& O; Y2 g+ Q9 A' e: R" N
                }, T0 W- v$ G- e
                while(!s.empty())
    9 ?0 J9 T2 @9 r8 C            {
    , W- o, |% B" q" c9 n                cur=s.top();/ ]! ]2 i1 A, A7 D3 M6 l
                    p=GetAdjVex(cur,pre);5 M1 F$ N7 u: X' _, x# `, w$ ?; ?% R
                    if(tag[p]==0)
    : |, U0 Z* q+ g9 S( f- Y+ H' E7 U                {0 G8 D3 I1 a" I( L
                        pre=cur;
    4 J2 l: `( B7 V, K" m: m: G                    cur=p;
    6 a2 t1 a  t$ U6 r2 ^; @                    break;8 }- Q! H# r/ T: w) U0 {, R  e
                    }8 W3 x! l5 r% a# d! _
                    else
      ^' R) N8 S6 |) o, |7 v1 Y# u                {
    + F) v& ^3 q1 z, S: e                    pre=s.top();' A2 c4 U4 G9 F
                        s.pop();" j& J1 S- B2 W6 |& `1 Y
                    }
    , @5 I6 x* C3 Y) W3 d+ a5 ]6 m0 ?8 R6 }. k$ Q
                }
    - `7 ~( O9 u4 `' w6 C0 y8 V  Z* y
            }
    ) a/ h) k( L, d# a4 T    }
    ' A" P  C! _9 y1 b' s}; y& \7 w5 k4 S% {7 Y& f+ X, h
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    " d$ }6 a3 ?4 v$ w/ ], x{6 ?& y0 g" J' h. e- `
        for(int i=0; i<vexNum; i++)
    % k- j* p5 a/ G& x3 A: K& l# p        tag=0;" q4 a# ~$ v! ^
        queue<int> q;
    . D& z9 J$ r( Y, K2 V& ?: ?$ q    int tmp,t;
    - c/ s* N; @2 t* y5 m    MultiAdjListNetworkArc<WeightType> *p;3 Y$ s9 X6 l6 x8 N- _2 }! |& ?8 ]
        for(int i=0; i<vexNum; i++)8 x1 e- L# H; x
        {
    " t+ j7 _, H7 d# G3 p) X+ u        if(tag==0)
    . G7 l# s- [) m7 s  p8 ^        {
    8 }  r6 o8 |( @8 k4 M) n            tag=1;: H" A% J2 `0 A& e
                q.push(i);, n- w: P& A( t
                cout<<setw(3)<<vexTable.data;+ A) f+ k* B9 p6 x& C
            }
    4 R, P5 s; y4 Z        while(!q.empty())
    3 ~/ C4 `" G, o$ h  q% l        {2 F$ ~9 o3 n; [8 g
                tmp=q.front();
    6 \! X. ]2 @2 X* _            q.pop();! ], v3 a8 S8 N3 V8 m( z& t, m
                p=vexTable[tmp].firstarc;
    , g2 H( r# W. R& d            while(p!=NULL)2 N+ H2 v6 R# m0 v) N  F  I
                {
    6 y1 B0 d- G. O' O3 U8 {                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    7 s0 D) V. R% }" Y; Z                if(tag[t]==0)+ r; l, r' H9 z9 Y1 J/ [  z
                    {
    8 u8 d7 _6 ~6 X& a9 h1 ?                    cout<<setw(3)<<vexTable[t].data;
    5 y( b6 D" d! k# Q2 V                    tag[t]=1;
    1 v0 H8 b% U6 }2 J* I                    q.push(t);4 i% |7 x0 A4 }0 `: D1 t6 Q
                    }0 `: w4 _, D- s0 k, H5 L
                    p=NextArc(tmp,p);
    ) }9 M* t/ Z# m: J/ @# D            }) S/ j7 s( ^! @! P% r
            }
    : \- V( H6 H( Z- N    }
    8 V- P2 r$ N: y}" q# f! y6 u: L9 P8 D
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    ' a" u& l6 X% H3 e8 V0 H{. ]: O) S, S! X: {  ^- N
        MultiAdjListNetworkArc<WeightType> *p;1 h0 K0 @' N; P& E: V, q
        cout << "无向图有" << vexNum << "个点,分别为:";4 A5 Y6 f0 D, x6 F; F: _
        for (int i = 0; i < vexNum; i++)/ Q" H5 M7 J: g# q- H2 _8 O5 e4 e
            cout << vexTable.data << " ";
    2 C0 q& p4 B; }% \    cout << endl;
    6 G/ k0 Z0 d8 ^  l( G( X    cout << "无向图有" << arcNum << "条边"<<endl;2 M5 g  X! U3 l0 w
        for (int i = 0; i < vexNum; i++)
    : C  O+ E; L" Z) U, A5 q6 D' J3 ~    {
    . \- c! @3 A3 T. [/ g+ F# A        cout<<"和" << vexTable.data << "有关的边:";/ R: S" e3 ]- j! n0 f
            p = vexTable.firstarc;8 H& x4 u4 e, Z! H7 R1 p% I+ i
            while (p != NULL); |5 ^% H; ?* `+ L, u! U2 S5 L
            {
    2 X- s8 E# J- q2 E# h( ?            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";! r0 q: G1 F( D$ @) i/ F+ L
                p=NextArc(i,p);4 h) [  m3 L  M3 C- |' J6 L5 P; n
            }
    0 R8 w" F) Y  p  D4 ]4 n        cout << endl;
    3 ]  f) O6 i7 n" `, @$ P    }
    4 [! `' q; |4 L8 e& @" z3 r}
    8 }% U0 Q! D4 X4 P6 D/ P0 w/ O  D) E
    % N6 F& l3 E7 Z: N- n! I/ `
    邻接多重表与邻接表的对比& {$ a) K( @, W  H% U- Y1 {: R, m

    / o$ L: P: \- D/ \$ m9 a6 q) l邻接表链接
    ( d# y, e( m' c  `" g* Q# r在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。! j) V- x* C0 F$ e4 Z$ ^
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。0 J) F6 y% E3 I: @
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。; y. w1 X! {( b2 A, ]% e
    ————————————————
    * v6 k& N: |; R4 Z版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    7 Y6 n* ~! g/ p' R1 A6 ]原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958: B5 h, E/ b& G* R
    * j, C4 c" r1 K' Z0 S
    / ^9 S+ u. S2 ~0 K+ R
    9 \/ j3 O7 @, t& R) m. B
      ~. Y; v7 @5 S, C* m/ b& y
    ————————————————9 j! O5 I) `8 d9 G
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    & S& z0 B2 l; u( F6 y& ~原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958% E* e) u( B" d

    % Z* `& g7 N/ R. M& B7 P/ J+ M/ c: @
    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-10 05:08 , Processed in 0.500893 second(s), 53 queries .

    回顶部