QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1369|回复: 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
      K1 S1 y5 ^3 x0 f: P
    图的存储结构——邻接多重表(多重邻接表)的实现( `( ^' K' E1 {7 G6 _
    7.2 图的存储结构
    7 C1 {! G5 |, q$ A
    1 p9 B( U" d! @+ D% m+ ^; o. Y7.2.3 邻接多重表(多重邻接表)Adjacency Multilist% w6 I; I/ L  N8 G: Y. L% S
    邻接多重表的类定义9 w4 b7 q+ o: V
    邻接多重表的顶点结点类模板
    1 i8 c" V) k; f) Q; n+ t/ D7 ~邻接多重表的边结点类模板! C3 N0 n1 V: c, P! ^5 X( T, l
    邻接多重表的类模板2 N6 F" q9 U5 r5 q& P1 j  H' g
    邻接多重表与邻接表的对比/ o$ l% X! Z, P# t: n) V
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    : {0 M' C* |1 p' l  U7 d
    ) b1 z' @( u- x; P在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    : E; e) ?$ U/ l, n4 p+ g0 `在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。& f# h4 [3 H. I: V! [5 a
    4 G8 X, i# q- j4 w+ A( }3 r
    邻接多重表的类定义
    + [$ V& M% E& b8 E8 b0 } 1.png 9 R, T. x! r; Q' T7 r+ I
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    2 J/ u; F8 l& E' I" ^: i) ^1 vdata域存储有关顶点的信息;
    # I; x0 y8 V7 ]! `' g, vfirstarc域是链接指针,指向第一条依附于该顶点的边。! m! T3 Y% r8 z  z5 t2 y: d& @# K
    所有的顶点结点组成一个顺序表。

    4 P: V  y& d4 e# o* {$ Z

    4 ^# P, p: g! k4 Q* j1 D7 Wtemplate <class ElemType ,class WeightType>
    + k3 I* M( V- T$ r- q9 z. |6 j& b5 oclass MultiAdjListNetworkVex
    9 @# D4 ?$ ~; G$ M3 d! f{' \  N/ r- j2 g0 O" y9 t5 X) e
    public:( k4 j( U  N& G4 [" ~
            ElemType data;
    1 U7 ?( ?3 [: x, q        MultiAdjListNetworkArc<WeightType> *firstarc;3 O7 y' N% m2 ?/ ?3 m, Y
    . ?  i! o$ C2 j  w
            MultiAdjListNetworkVex()
    ; q2 R& }- T4 u. r& l8 M        {2 y8 o" f$ q5 _1 j2 [0 i$ q5 J# O
                    firstarc = NULL;6 ]5 h/ N8 y/ \4 A
            }$ u+ E2 k: j/ E+ s, ^6 v6 w
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    5 ?8 r. l, a1 I- K5 w3 y        {
    # U+ K" {8 N8 f( C" v7 J                data = val;
    2 @6 s0 ~. `5 G. ]7 q' J- u                firstarc = adj;8 ^4 b0 D6 ^" S4 p# U3 r7 m" q
            }# u+ T8 }$ G+ z$ f3 C
    };
    0 k+ B: F' E. H0 q
    8 G' S+ M3 P4 e+ n0 q邻接多重表的边结点类模板7 _: O$ B( H0 }, u7 ~
    8 \1 L( e0 q# o9 {  s7 ~
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:" w: U; n) ^1 W: z' i$ W, G
    tag是标记域,标记该边是否被处理或被搜索过;
    3 h- i* v4 w: _7 dweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    # u  C* q4 M; v8 ~# onextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;( Z+ I2 F' m8 I& N
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    , A' E/ S  ^% A4 E
    + b! W) m! p, N: h7 G 2.png
    ; k' ]! f& w/ Q& l# c( Ltemplate <class WeightType>& f+ P( ^8 o6 n$ u: t$ Z# r+ ]
    class MultiAdjListNetworkArc* P& T5 m) x! ]/ g( ~5 `; B
    {1 `& d6 f9 L9 w- D1 m1 ]$ p  s( N
    public:1 |* @  R8 B" H( v2 k
        int mark;                                       //标记该边是否被搜索或处理过
    * ~3 J5 d# z+ _1 u; A        WeightType weight;                              //边的权重
    ! `1 Z/ {* _7 b  h1 n        int adjVex1;                                    //边的一个顶点  F) J" ]# k& E2 Z. Z+ `
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1. r1 G3 w8 W* G+ n' ]
            int adjVex2;
    , y- h* H/ G' u) ]        MultiAdjListNetworkArc<WeightType>* nextarc2;) n1 U; F2 u' g0 f" E/ T
    ! t/ A( r$ J) o) V/ ~) v% i
            MultiAdjListNetworkArc()
    ; {( [% {+ V+ z$ a! ~  w        {1 ]7 Q& ?) t0 S4 C; w" W
                    adjVex1= -1;7 E! C9 r8 R! Y& I- }
                    adjVex2= -1;, k0 y4 `( Q4 {
            }
    2 g. F: [6 e+ C* `5 j        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    - X+ f7 f+ [2 ]+ `" x2 j        {
    6 e* P) N, `4 H: \/ q6 T                adjVex1 = v1;       adjVex2 = v2;
    5 C) J) H% `; q; Z  _, E! C. \. l                weight = w;% w. H, [4 E5 r3 l$ K! g1 B; j3 G" W
                    nextarc1 = next1;   nextarc2=next2;
    & I: p, L7 j+ L& g- [                mark = 0;           //0表示未被搜索,1表示被搜索过+ a0 v, @' k+ L' o
            }, J$ h3 _" \* `8 g/ `" L# Q

      _, w: M2 N% @; X7 |邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>9 o' c0 ^: E# y% }) ~6 ?1 W
    class MultiAdjListNetwork4 d/ z4 A2 Z' \6 I- F7 o. u' a
    {7 w6 P% z, z4 P8 s6 M
    protected:
      L2 ^; b9 S& W    int vexNum, vexMaxNum, arcNum;1 ]6 `# q. n8 j% T: a# A
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    ; r' o1 ^3 M& a7 N    int* tag;2 d$ x: ^4 S0 K/ |' o
        WeightType infinity;
    6 S. k' I- V. i5 C( m6 A8 h' J) ^. J0 t. o( E& B1 M" f% p& P. M
    public:
    0 m- u4 {% G3 D, o: P    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    $ u" P" K$ E9 G+ a( |- D: ^( j
    + n5 p# @" E$ W* J8 S    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    - J# Y/ A6 i" \; A+ X
    0 c2 v+ z2 K5 B/ o# d( {( ~    void Clear();
    ! r5 r3 U# v* I7 f$ A& x) b    bool IsEmpty()
    / o* w8 d# X- F+ U& u" D    {
    3 N" v+ w0 Y1 b% u+ n        return vexNum == 0;
      U1 D, P9 V% \! A8 w    }
    / w6 @# O$ h( X  |' M. h. v    int GetArcNum()const
    2 B: C* o! c: L" X    {+ @6 u! ]( \1 F6 o  r
            return arcNum;
    & d) |, b! O* F* R1 S) ?" G6 M# O0 i6 O    }8 W( D1 i, k& h# S& G9 y! O
        int GetvexNum()const
    6 U3 ^% _( t4 F4 X# F7 Q& s    {' o  z" a' _; y% D5 L
            return vexNum;
    * h9 g, S. t# V" O1 `; j# [    }6 l  }6 O, `1 a" E8 k% B1 B
    . E; e5 U0 L5 e9 u( i
    % D& ?, Y# s* O0 Q8 R% N
        int FirstAdjVex(int v)const;
    & U9 u* R2 Q: Y    int NextAdjVex(int v1, int v2)const;
    $ h: S; Y% k5 A# @. c. I) C    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    ) E: n6 {: x& L    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    7 @/ n: `* o, p7 {- \; r# f1 V  |0 b: [' [# t& \
        void InsertVex(const ElemType& d);+ e# o# w; b+ a/ v8 c( a  c
        void InsertArc(int v1, int v2, WeightType w);
    + X9 p  A' l5 c$ q4 F- ]
    / x8 l# n7 D8 Q; h    void DeleteVex(const ElemType& d);* E$ A% K( w; `5 j2 ?% i6 q3 m. K
        void DeleteArc(int v1, int v2);7 g: `3 @" K3 X- W4 \6 Z: ~
    4 B( b$ l2 ^% R2 G! u
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
      V( O- P* V0 j' G2 v% e, Z    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);5 J( `; G# b+ T0 x; f
    2 r" {1 V; k* v% |* _( A
        ///深度优先遍历" \. F. R/ P9 z. A  C% ?9 T
        void DFS1(const int v);! N% i7 D: l8 A2 }/ i. H: ?: N5 Y1 K
        void DFS1Traverse();
    8 \( q6 N8 M8 Q+ E# K; ?4 Z  @    void DFS2();2 @4 ]' ~$ B/ r( U, {+ X* Z

    - S" h( ]1 X  \5 M( r* t    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    " q$ F. b: @: L2 I" q2 C- i. J    void DFS3();
    % n! T( i' H6 s" O  @) C- j, x) O1 \& r9 `, U
        void BFS();
    7 g! d+ i; t6 D+ C    void Show();1 o* j: k8 z% F, [/ u% x
    };
    2 C+ M& T& N/ X, b6 o+ ?5 ~& h* N  k* [; m6 g" v( w4 [" O' S
    2.函数的实现
    $ h! k6 n( D$ b/ W5 ^4 O研讨题,能够运行,但是代码不一定是最优的。$ y8 J/ J1 [: s% {4 a

    & c) N6 d. q0 P4 [2 e2 W#include <stack>3 i+ ^$ X7 Z9 s- ~
    #include <queue>0 o3 y. V$ V9 i  k) H" O
    5 X, p: X7 A9 `8 q  Z  `3 I" |$ j
    template <class ElemType,class WeightType>- I. W" E5 n- z( N
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)$ N' H' H4 R1 f$ h, @' x# o  w7 ?7 |
    {
    % }- e) z! L  {( h0 F" [1 ?$ ^    if(vertexMaxNum < 0); C/ h# I: U, U' _; _  k, K) c8 [
            throw Error("允许的顶点最大数目不能为负!");5 a" r; a% o$ h0 e
        if (vertexMaxNum < vertexNum)) W9 Y7 i2 p9 \1 Z6 X1 S1 Y" o
            throw Error("顶点数目不能大于允许的顶点最大数目!");  i/ Z" D4 t: w! T
        vexNum = vertexNum;" U3 F; h! n5 F" r
        vexMaxNum = vertexMaxNum;7 B/ ~0 v& {& K  c2 }- c7 E
        arcNum = 0;
    9 Y8 N+ R+ z) d    infinity = infinit;
      \# p( w: F- U! e9 B# y    tag = new int[vexMaxNum];  `, }6 Q+ U7 A
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];; N% Z1 R, |- [* {+ a
        for (int v = 0; v < vexNum; v++)4 t0 o$ Q* O# i/ M$ p
        {
    $ s+ H1 D) v4 y6 z- U        tag[v] = 0;2 _8 M6 O" p  N$ P% h& V& g
            vexTable[v].data = es[v];
    2 f% l4 e$ D% x1 S* h2 e7 @$ `- O        vexTable[v].firstarc = NULL;6 Q1 e, M: k  i- Y
        }
    % `, M  m9 O  V$ @8 V4 c! a8 I}, k  Z. }1 F% d8 l( d! r3 t
    template <class ElemType,class WeightType>
    ' ?; g& Q$ f6 F5 u7 R; o0 k3 ~MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    5 R# Z0 c# T8 o- M- G$ {2 C{0 |. w# ^8 [9 R! j# Q$ G: |$ f
        if (vertexMaxNum < 0)+ B$ G1 s4 U; _) a- J3 U# }7 g$ d% \
            throw Error("允许的顶点最大数目不能为负!");" V: b: Z# C, c7 _2 {
        vexNum = 0;* r( x9 A8 X& F( w4 g  [
        vexMaxNum = vertexMaxNum;
    9 @( k4 p$ k( G1 K9 m  W# B    arcNum = 0;
    # _/ T0 G( ~/ |  A4 h. c$ T    infinity = infinit;
    : ]% R1 F* N! I( ~: e6 @! |! G4 t4 S    tag = new int[vexMaxNum];
    4 W) m9 @& s( e$ Y9 X    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];( ~1 @0 |: n; L2 V8 d; p3 Z2 ^* Q
    }$ e+ ^& X* X  p6 ~  Z& L. W
    template<class ElemType, class WeightType>! n( v: V  g4 m
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const* A/ s/ p$ c5 p9 v* I" v2 Z
    {
    / R7 ~+ r$ D1 }+ Y4 T8 _: Q* o    if (v < 0 || v >= vexNum)2 P) @/ U. K5 d( C8 }
            throw Error("v不合法!");7 M$ A) R: f& O/ C$ s0 @! \$ M
        if (vexTable[v].firstarc == NULL). S; r* I: N4 M+ E/ Q9 {2 w) n
            return -1;$ u( j4 o6 I( [  N, Y) z
        else
    9 D2 _$ t& O+ A4 s/ K1 k; v% G        return vexTable[v].firstarc->adjVex1;* B- d& m( r) u  a
    }4 V7 s4 ~) c* B; |( @% q

      A. H  |- X5 a: F. w% o8 `template<class ElemType, class WeightType>
    9 a) W9 a# J5 T6 Q* a/ p* oint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    $ o" u9 m5 n: @+ d. Y{
    / Y& [5 M7 y! h3 _7 Z    MultiAdjListNetworkArc<WeightType>* p;
    ' ^" O7 i7 ]1 O9 K. e6 y' m    if (v1 < 0 || v1 >= vexNum)4 {6 F4 A3 ^% j# j; I+ o8 `/ i
            throw Error("v1不合法!");1 a+ t% N  ^& r5 }
        if (v2 < 0 || v2 >= vexNum)
    4 l7 d- |2 H- m; t3 }( I        throw Error("v2不合法!");
    * w3 s1 b: J7 `+ ?/ X    if (v1 == v2)
    . Y  C9 k7 h& _1 ^        throw Error("v1不能等于v2!");
    6 H) r; D# W" M    p = vexTable[v1].firstarc;
    + }' s; L( j- U/ e* ^3 a- a% N    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)9 J' T6 w0 q5 z% I4 l$ P/ e
            p = p->nextarc;
    ! \- j, Z+ ^; P  M    if (p == NULL || p->nextarc == NULL)
    + H0 }5 ^) g( }; j  O        return -1;  //不存在下一个邻接点. G* y7 X( `9 k7 x
        else if(p->adjVex1==v2)3 h" I9 E8 [2 x. J
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    9 }. o2 f) l; l0 C+ g  s    else
    - I( q- G1 L) V' @2 C6 U) q/ b+ A        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);! g9 |* H& N  J/ n: L9 k
    }
    , ]& j8 h& v0 y% Rtemplate<class ElemType, class WeightType>  E2 W$ X/ @; l, E$ S
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()6 o4 x( ~( p5 O) D& M, G. n4 g
    {4 m( g) v8 {( L  T" y! L/ `, D7 I
        if (IsEmpty()) return;
    2 |4 |) B% w' x4 F5 H9 ~) d    int n = vexNum;: ?9 d# J$ Q! C) w; \
        for (int u = 0; u < n ; u++)/ Y3 j  H+ r/ j) x5 W
            DeleteVex(vexTable[0].data);! y( V2 _7 H0 b" b1 z* O. s. O
        return;
    - A8 M) t  C) R$ d+ r}/ S& ~) G' F; v4 |9 }% b8 ]
    template<class ElemType, class WeightType>
    & [* r0 N; A4 a; O# f' f- k* OMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()9 }7 t" F9 w& l3 h* G* |
    {5 J2 N8 d7 u7 M& O8 j
        Clear();3 t9 j9 m9 C7 ~* f' N
    }6 t9 x! b& C% T
    template<class ElemType, class WeightType>
    * ~) N' \  h7 y) X# V2 _6 HMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    . |3 t2 J2 h" |" _: J{
    ' k" G  m! b$ c) p3 g    vexMaxNum = copy.vexMaxNum;; M0 x) @# l8 w9 d" e( |  ~
        vexNum = copy.vexNum;
    3 ?, x/ p' ^! V5 b6 p' n3 j    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    5 a  `: D3 h8 o) u- m    arcNum = 0;
    ( O& y2 U4 V2 M) L1 |& c    infinity = copy.infinity;# e& N  }9 x$ ?. b  z
        tag = new int[vexMaxNum];7 d0 q# R; l* s7 {% b; r- Q' W
    ; [/ w) q$ S1 s; E" C$ Q
        for (int v = 0; v < vexNum; v++)8 {( A3 m9 h, V" V5 f+ q
        {
    # Z6 I: [* i' u        tag[v] = 0;
    4 D% M+ K( e- G# E        vexTable[v].data = copy.vexTable[v].data;5 J+ S  u3 `) v2 V, I" B: h% y3 ~
            vexTable[v].firstarc = NULL;2 d. k+ P: e: Q2 _
        }
    9 |0 B4 e' [6 ^$ @    MultiAdjListNetworkArc<WeightType>* p;' q- E& p. ]9 D4 o2 L0 i( Y
    - P6 r6 l  f1 L' y
        for (int u = 0; u < vexNum; u++)
    7 T' z) o! Z; ]! n    {7 y8 z6 w3 {0 s) p9 U" I4 B  ?
            p = copy.vexTable.firstarc;
    " f/ l, d! V0 O$ d        while (p != NULL)( N8 j) r* C0 z8 z* o, V9 o
            {
    : P  j/ k( D" }+ S5 w6 g$ F            InsertArc(p->adjVex1, p->adjVex2, p->weight);* {. n* C; x. Q# l3 O  N
                p=NextArc(u,p);
    - y, N& l( c3 R4 e9 j" E        }! D3 v- m; M+ K' f8 G: T5 j1 V* R
        }  g0 W  l7 r: ]" |
    }
    : L' b3 X1 b3 _' P" G7 F, }template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&2 a2 O4 j6 Q: G9 ^& ]
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)1 f) G# k( V3 I$ C) U
    {
    # b+ t: S# D/ z+ h. r9 @    if (this == &copy) return *this;; K* C0 I  w( {1 |
        Clear();6 j( v; N" l' w- Y4 Q
        vexMaxNum = copy.vexMaxNum;
    & b! l7 Y" B1 z. {    vexNum = copy.vexNum;7 V+ H& g% k, {
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];! u# l8 q$ g9 c6 v$ j, W
        arcNum = 0;
    ' g: t: I7 U7 {1 ]# ]3 |    infinity = copy.infinity;/ q+ P/ z% O; O' s! @/ s
        tag = new int[vexMaxNum];! F- j( a6 Z3 v8 J4 x3 ?8 Y
    ) y, y+ y) U$ ~) D* U9 P% m
        for (int v = 0; v < vexNum; v++)
    & m- |/ a8 \9 E    {
    : I& F& R# f  ^  g" P9 q        tag[v] = 0;
    , [5 E( w) u& ^: f6 n3 _- d& c        vexTable[v].data = copy.vexTable[v].data;
    : n# b, E+ E, b$ y' t- h/ s$ S( A        vexTable[v].firstarc = NULL;
    ' d% G; A. m4 U% c" P  o% l    }
    ; U3 i9 ~1 }5 o    MultiAdjListNetworkArc<WeightType>* p;
    ! e! t/ R2 L, K/ j7 u7 V/ x+ W/ z
    2 p$ t1 a8 ?' k4 H, y! G    for (int u = 0; u < vexNum; u++)# q5 b! g+ o. Q& {7 L4 z
        {
    , K' c# W8 \8 C0 M8 ^. {/ n        p = copy.vexTable.firstarc;7 g/ d0 T3 y: }4 c+ y
            while (p != NULL)
    / n7 o; H* W# l& d' t        {
    ( d) i3 t0 l4 V* I! m( }/ q2 r! I            InsertArc(p->adjVex1, p->adjVex2, p->weight);) D) r! H7 {, {% f2 H& ?3 k
                p=NextArc(u,p);) s' T  D' e: T, d$ ?, u4 W
            }7 M7 ]5 \$ a0 Y; X  _( J, k* ]5 S9 ?8 }
        }
    / U" w# v4 v8 I1 s6 A    return *this;, ^, H4 R& R2 ^* I, Y
    }7 |+ ^, J  O7 S! ?+ p/ P
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>** J$ h" r- m; Q! c# X5 i& h
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    2 v! E- N) S1 W/ L# `" k{! l4 z* z" i- w8 `. |* E7 R
        if(p==NULL) return NULL;/ v2 a7 T6 _; X0 n
        if(p->adjVex1==v1)
    : z5 V' R/ ]+ P        return p->nextarc1;4 x7 ]+ W6 C+ ?$ }* y0 b& D5 _& k
        else
    6 I/ W+ @! `: j        return p->nextarc2;
    ) c/ X( |. |' R3 |}* ]5 v  m9 y, Z& k2 e! Z9 h8 U
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*( {8 P5 M- P# J, E3 X
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    / M+ ]% v0 ?, L; j% B7 Q/ U{
    6 f; W! w2 m6 L    if(p==NULL)return NULL;9 N; G$ V: f$ U2 H) o' L2 P: v
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;5 e6 V5 E4 u8 d& e4 T
        if(q==p)0 s6 c- i1 M9 j5 `3 x; U
            return NULL;
    # q9 h/ b7 S! R    while(q)+ t4 y# [% g; w( `; g1 k
        {) s. {9 f# V0 V. E
            if(q->nextarc1==p ||q->nextarc2==p)
    + Z1 @6 a. I. _  t- S3 j/ S/ r! t            break;. ~/ a& O( [( Z& I5 J2 n9 O$ O
            q=NextArc(v1,q);
    $ ~! z  u# T2 c: J' p    }
    3 G) {3 T( U3 D% E, z) O    return q;
    , f& n: ?9 g! W1 J- b}
    ( H: V3 ?, E5 g( ~$ J: Ztemplate<class ElemType, class WeightType>: P! u% Q2 H9 I; S( P% M# b
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)* r3 J  C5 x; }/ r! J" B& V
    {1 h8 h# S( }' {- g+ ^) p$ a9 O
        if (vexNum == vexMaxNum)
    - B# Q6 w8 k5 c, Z        throw Error("图的顶点数不能超过允许的最大数!");4 }, i# E2 w9 |
        vexTable[vexNum].data = d;
    6 P" A5 A2 H. |& @8 y: E( \0 C    vexTable[vexNum].firstarc = NULL;
    - d& y( `* E6 v1 [    tag[vexNum] = 0;
    4 v2 K1 M* A  l" T6 q' h: m    vexNum++;
    9 e& G1 o& k; u8 h, Y, R# [}% S. a% b  E, |
    template<class ElemType, class WeightType>3 o- ]# ]6 Y3 w/ |
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    ' {: \8 v1 ?$ R9 |7 X1 i( f{$ X/ W- t  |  s3 n0 Q
        MultiAdjListNetworkArc<WeightType>* p,*q;' ]- k  l2 t: w7 W2 p3 `# U
        if (v1 < 0 || v1 >= vexNum)
    , y& B3 n- ]. H. ^        throw Error("v1不合法!");, ]0 _: D5 K( D7 _& u& C
        if (v2 < 0 || v2 >= vexNum)
    3 [9 v& Q; w6 c) R        throw Error("v2不合法!");
    5 q$ ^5 _2 Y2 h- Y    if (v1 == v2)
    + k& T1 Q, Q$ Y" v* X        throw Error("v1不能等于v2!");7 s4 A# U" p4 W6 ]& X
        if (w == infinity)
    5 C; F* F$ Q  |5 n& u        throw Error("w不能为无穷大!");* V. C5 q( ~: q1 C

    # b3 z+ Y- @: Z% x3 z6 x& k9 c2 W1 P# ]- F
        p = vexTable[v1].firstarc;
    * b! H, V5 n/ Z: r+ l/ F0 D7 a3 ^    while(p)- n2 P! [$ U' M, K
        {  @' O! ?  u8 E& Q6 c) }
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    7 G& L$ z! |* F        {' r5 O& f. k, z. Z
                if(p->weight!=w)
    6 `4 F" Y- }$ U  M* ?9 c8 S$ g+ K. l                p->weight=w;
    5 F. h+ R9 J! v9 H$ ]            return;* w( R% n' ^  l4 x  e$ _! y
            }$ V& Y$ n$ J% I1 v

      v9 f+ B: F; Y+ a9 H" }& U+ {( S        p=NextArc(v1,p);
    ! P4 e% @, F) u& j    }
    $ \% y' ?# _  ]: Z7 ^    p = vexTable[v1].firstarc;5 e$ m4 A  Q) `' h! n
        q = vexTable[v2].firstarc;
    ' A& G8 a3 B; J/ O- {    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法+ i, C, l9 t& ~; x1 B
        vexTable[v2].firstarc =vexTable[v1].firstarc;" n, |( n% {/ c  p8 R
        arcNum++;
    # H! _" ^+ n7 [1 F: V- c7 m}6 E" H& |8 a5 x1 ]) l
    ) {1 o4 E# V( X; e" h) F$ |
    template<class ElemType, class WeightType>
      F; ~& B: P5 {7 Z) J! p! rvoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    * w8 p# v9 W+ X{
    : S- R" P+ n! F$ ~% J, b% Y7 f
    / M7 v* r5 P9 U    MultiAdjListNetworkArc<WeightType>* p, * q,*r;2 U) F) [  c5 m$ N
        if (v1 < 0 || v1 >= vexNum)/ _. f$ s% k  G  }; ]4 B
            throw Error("v1不合法!");
    ) S! Z0 f( v/ ~    if (v2 < 0 || v2 >= vexNum)4 u5 {5 c3 s. Z7 Z7 n
            throw Error("v2不合法!");+ O1 W' v  S2 F4 D  m) i+ W
        if (v1 == v2)9 z' G5 e7 V: i9 o/ u; k0 E# T
            throw Error("v1不能等于v2!");. E' b( y3 a. M, z" H7 s, M
    * z% P' Q& ]$ K6 J' ^1 Z% @' U# _
        p = vexTable[v1].firstarc;" ?* B" u& ]8 z& r, T0 x; d
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)$ d' H% Y. n; j0 f$ U
        {6 M* U5 o" O& M( Z# u* E6 P4 }8 U
            q = p;
    ) d  W4 F) }/ X3 _- `, |2 A! [8 f        p = NextArc(v1,p);# r; Q0 v7 v2 X  p- G2 I/ [* v
        }//找到要删除的边结点p及其前一结点q
    9 T" V, U" p' t5 A/ o
    7 F3 B, ~( a  ?! Q# K    if (p != NULL)//找到v1-v2的边  T  N3 q5 ?9 ^* I' |
        {6 e. [4 y: q1 N
            r=LastArc(v2,p);- d& c* b7 q. }6 F. m2 J& _) R
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL7 \3 N' C; V: I: ^- t
                if(p->adjVex2==v2)
    ( V2 D3 Q+ y3 ^. y4 d7 E1 L                vexTable[v1].firstarc = p->nextarc1;/ Q0 n! k' u: T' W$ r/ _* \( C; Q
                else vexTable[v1].firstarc=p->nextarc2;: A% D) B; J3 O0 A/ W
            else//不是第一条边# m$ Y. P4 u1 |1 b) d) n
            {
    ; M' w) K$ y) i% a            if(q->adjVex1==v1)0 A' ]6 A6 v# {+ t0 p
                    q->nextarc1 = NextArc(v1,p);$ o" E% z( D0 G5 y
                else
      o8 d# m) l: }                q->nextarc2=NextArc(v1,p);$ ^+ p3 L) Y4 j0 G( x% u+ G, l; o7 X" X

    . n( }( q% |# I/ x  A  ]$ Y        }
    ( n6 ]& p/ g& D        if(r==NULL)
    * i7 G! X) \& L, }            if(p->adjVex2==v2)
    1 l$ W/ }; q5 V" A& Q- ^                vexTable[v2].firstarc = p->nextarc2;
    * O+ A& S; B" M  p$ Y2 T; Q            else vexTable[v2].firstarc=p->nextarc1;
    & H* P  f0 I% D) I        else
    ' X& }) o3 H: Y+ ^        {9 \# s" y) H% \7 D2 F  D. p! y
                if(r->adjVex2==v2)
    0 f6 R( [) U# v8 j' U                r->nextarc2 = NextArc(v2,p);- s- y) w. J! u. ]5 G
                else- ^  N5 e1 _( C2 K% U
                    r->nextarc1=NextArc(v2,p);
    ( Y+ O& c0 f+ z6 Y* t1 h+ F        }
    5 d+ T3 }" U, M- r        delete p;
    8 n) _$ R% X( O0 w- p( m        arcNum--;
      I4 b* f; Q& z6 ]" u8 e& k    }
    2 a& {, Y  p; O* G; k
    ' d5 c  d9 k1 s) X}' u9 x' ?! \0 C, c6 C
    template<class ElemType, class WeightType> void
    9 L+ L, Z2 {& q! mMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    6 T% g" A- ?/ E, R{5 n3 Z% J1 q& D2 l
        int v;- ]' T8 S2 i0 T1 W  }6 w
        MultiAdjListNetworkArc<WeightType>* p;; H7 Q- ~+ E$ Z
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    ' Z6 ]" q: s1 H* ]1 G+ M1 K        if (vexTable[v].data == d)  W2 T( v( g2 x$ A7 e& l7 q) ]
                break;
    ! v+ l' X8 E, J" O# x% c# @    if(v==vexNum)! Z# c7 e" d; u; K8 m
            throw Error("图中不存在要删除的顶点!");
    , a4 Z. x( e: e! P* Q8 A# z4 H( d: p% W# j, n# r) z
        for (int u = 0; u < vexNum; u++)//删除与d相连的边
    ) ?! l4 T4 w* o" n8 g$ `+ s$ C        if (u != v)
    7 Q9 R0 H9 m' f7 n# P        {1 h, x% B1 [( z- p" e5 ]
                DeleteArc(u, v);7 R* a* b4 d$ |" }5 i
            }
    8 Q1 |3 y4 A) G  F% s    vexTable[v].firstarc=NULL;7 G1 ?  }, d. a6 E* T% E8 C
    : |* Z( L( Z/ @
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    ; \, M! D# S- _5 @2 |" I" t    vexTable[v].data = vexTable[vexNum].data;
    4 F% X% W3 r* M$ F    vexTable[v].firstarc = vexTable[vexNum].firstarc;; s& h* y/ A1 X$ S) T
        vexTable[vexNum].firstarc = NULL;
    0 \3 a9 F; _8 N+ d9 Q3 D. c    tag[v] = tag[vexNum];
    + `" p3 R6 i3 @% E1 Y* E* g$ S' l    //原来与最后一个顶点相连的边改为与v相连, z- g) g; T. A- v8 g  i8 \$ w
        for (int u = 0; u < vexNum; u++)' O" F5 d  s+ X0 D5 X  s2 z8 b( ^
        {8 V5 }( ?1 S# _/ q% |, I
            if (u != v)* ~2 W. Z- P! D+ e1 \& W
            {
    : H" ^& a0 Q2 H& n8 |            p = vexTable.firstarc;
    * `% N! X: a; h9 z            while (p)
    0 R3 e& h5 o1 W            {
    . O3 [7 z' J2 P& f5 O. U                if (p->adjVex1==vexNum)( x5 y# w1 r7 I3 t$ z% I
                        p->adjVex1= v;
    ! q. u; i( P) _' X  Q: ?# [                else if(p->adjVex2==vexNum). `' M8 s+ a- H
                        p->adjVex2=v;& K( \0 x* @- ^9 [# v0 m
                    p = NextArc(u,p);
    2 K, }% w0 |; X            }0 H) U, v  N0 g0 B( O
            }
    ! i3 w! ]5 G2 ?4 X/ Q4 _% T    }% T4 Z9 h( a2 H1 J$ u
    }
    ( Q3 }6 B) Q9 a# L1 X///深度优先遍历" T3 S+ ^! T: I% y
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    ( B6 h# z4 \" J$ i0 v{
    9 E" C; {* J1 V' t5 j* ]" f. _8 t    tag[v]=1;2 D, W+ f' `) w; l/ F
        cout<<setw(3)<<vexTable[v].data;5 o. g1 R7 T9 ^' ]
        MultiAdjListNetworkArc<WeightType> *p;
    . s: E) Z! c% N' O7 [& }    p=vexTable[v].firstarc;8 _6 q8 n: `5 q+ S9 e
        while(p)
    - l9 G0 H0 }- U, B4 k4 U! i; s    {
    3 U" e& K# y) B4 w        if(tag[p->adjVex1]==0)
    : D! U: c: W& Z3 g            DFS1(p->adjVex1);" w; s# j$ b. z: {8 N
            else if(tag[p->adjVex2]==0); k" C6 W4 P) E8 w/ g" _2 x
                DFS1(p->adjVex2);
    ' z. @, s) f. W. v3 u  y" Q8 i        p=NextArc(v,p);/ l7 j  ^6 G9 h9 @) f
        }: ~7 m) [9 m8 G- ]
    }
    5 p& p( W  k0 @- d, l8 @2 ^. Ttemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    7 |2 w0 u. x  s( [4 F  i; x* E{7 |2 s$ X, P/ g: x$ m
        for(int i=0; i<vexNum; i++)3 i7 E& v8 s2 m5 H: U2 B
            tag=0;) f0 g! t) j/ M8 f" P/ q
        for(int v=0; v<vexNum; v++)- G6 D) J# L' m, H8 K
        {# R2 @5 w) E; v1 V/ M% u+ [
            if(tag[v]==0); O+ n3 t3 U1 W0 _& e2 c
                DFS1(v);
    4 q/ x0 `" D! f2 X1 T5 U    }. C6 G; |8 O" N/ ~4 A/ K
    }7 @* }" y! S3 Q' X* w4 i
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()$ k) P& m8 ?8 O' f& S- D
    {  d, S. ]3 v% x, [- y
        stack<int> s;
      U& k( R& y, r3 U5 m! m% i    int tmp;
    - t0 u1 ~3 c0 t8 J    MultiAdjListNetworkArc<WeightType> *p,*q;$ S4 ~- a% O1 [) d- I7 a# j1 Z
        for(int i=0; i<vexNum; i++)$ n7 R. g& W( A  e. S/ I
            tag=0;$ I; B$ r* L: t) M, `/ `8 t! s. n' A
        for(int i=0; i<vexNum; i++)3 B1 Q6 d) @( T) l
        {$ J8 w! Z* m  _+ e  p) h( Q
            tmp=i;
    7 {; v; e8 j- _( J3 S2 N        while(tag[tmp]==0||!s.empty())& r- S* ~6 ^- g, K) h% ?: |
            {
    ! M: j2 d6 _/ Q4 u  P( \* B! A& s            p=vexTable[tmp].firstarc;
    " I" D7 G1 A$ O0 b# Z" _! X            while(tag[tmp]==0)
    % \  i+ G/ j) J! \# P  y# i- M* y            {' O' B" v: L! `& [5 s
                    s.push(tmp);
    # f4 ^& Z: s$ Q1 W* P, T7 h                cout<<setw(3)<<vexTable[tmp].data;
    9 {! F* I% a) b/ x* F6 z                tag[tmp]=1;/ V: b( q- h! E. s2 h& ^
                    p=vexTable[tmp].firstarc;: [, f8 `& ?0 V3 i7 Z) a: g
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    7 u1 d* R5 V9 l, t& F                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    0 z1 A5 z: z2 G' u" [) M                //cout<<" 1st     tmp="<<tmp<<endl;
    " V0 A- O& U2 O5 J            }
    + n' Z4 D; m: P! i& Q0 A            if(!s.empty())$ L' O! f4 F0 N& y7 U8 _
                {2 u' D# A# t) Q
                    tmp=s.top();
    ! y7 [% f" W) q                s.pop();
    $ k1 ?/ W) r' y                q=vexTable[tmp].firstarc;  A6 [+ k# q+ }% i/ s9 l
                    int t=tmp;+ L! l8 D" _! r/ f5 d
                    while(q&&tag[tmp]!=0). i! A: O$ L! d
                    {
    * @  j& Y% ^% |0 b; m4 K                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    7 [1 {! F! d$ R9 n% l# E" M6 h                    //cout<<" 2nd     tmp="<<tmp<<endl;# _; E) @! \3 m; w& }! E7 b7 |& p
                        q=NextArc(t,q);
    ; G4 j: N3 i6 D" @                }
    6 |$ y, {" ]' x3 ?3 T4 t: h4 P/ H                if(tag[tmp]==0)) p$ w% |. x' b* d/ }0 h
                        s.push(t);! _* ^6 m3 w6 p+ |/ g# ?% X. @
                    ///1、对应上面连通分支只有1个点的情况
    7 y- B, `7 D: @% V9 ^9 t* _                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈/ m: k0 r( u" u
                    ///tmp要么等于找到的第一个未访问节点,  M) U  J$ p  Y* e# G3 w7 \
                    ///要么等于与t相连最后一个点(已被访问过)
    - a' a9 Q8 b* |6 G; N$ d                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点9 R: ~! |6 ]( l/ ^
                }- S5 F9 P  _! o
            }
    6 T6 F' {. ?: u2 G+ O; I/ F    }
    " t9 z# H- b: ?. M) m}. @7 ^2 h( K/ a+ |
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    6 l! k' g5 F- D0 ]. v3 s& Y: p# Itemplate<class ElemType, class WeightType> int
    7 K# ~; |3 Q4 q% y; s3 S7 }MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    / R# {) C: g2 g9 G5 }- Q) C, ~0 F{& _/ ?. @' |7 b. ^, h: \1 U6 Z
        if(head==pre)
    1 R* N- \! C  E        return -1;% X, {1 Z6 \, h& b$ N

    . p: \7 b4 f9 q8 f  r4 {" K    MultiAdjListNetworkArc<WeightType> *p;
      ~  n- p$ t0 t, v+ ]    p=vexTable[head].firstarc;
    - e) _) [. }  \5 l1 N    if(pre==-1&&p!=NULL)
    3 H3 T  U9 z5 ~, S3 S6 R( s        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    ; s9 L0 U3 E6 Z% O- @5 O2 D( f    //pre!=-1&&p!=NULL1 E% j( O+ l6 g0 ?$ B# J
        while(p!=NULL)
    , R3 c- h, _# B    {
    * P8 [4 V: L2 [5 D0 B+ V. G4 C        if(p->adjVex1==head && p->adjVex2!=pre)1 i) }+ G4 k2 E6 u
                p=p->nextarc1;
      e) u: x8 s% B1 |4 C1 l- k1 [        else if(p->adjVex2==head && p->adjVex1!=pre)
    3 m8 H) ?- V1 B            p=p->nextarc2;
    8 G! A" w$ h* y; J& y0 g& P        else if(p->adjVex1==head && p->adjVex2==pre)' y6 J8 ^; a7 c2 ?. ~& }+ C
            {
    ( c6 |4 d0 Z/ E7 h# i            p=p->nextarc1;
    6 v. M, `; Q8 _- s            break;
    ) @5 V: k3 o( [1 t) R) `        }
    ( y. A0 F& r3 H1 f8 F1 s        else if(p->adjVex2==head && p->adjVex1==pre)5 W& I. y5 ~; X8 n& w2 r
            {
    3 _1 ?  A2 G% H7 v0 r3 v. V            p=p->nextarc2;
    ) i0 S. ~3 ~) O- N) T) u2 O            break;
    / F- S8 P+ D7 e1 H7 a3 |; R        }" L2 C2 s) a0 Q0 B
        }6 o' w, ]. J5 s' q( s7 N
        if(p!=NULL)$ L- m3 {+ D% z0 S5 C2 O
        {7 s/ K/ N9 N: V& x
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    2 A$ m+ t% r# a. w9 W7 P    }" N" Z+ x  K$ ~8 H" W2 t
        else3 }" f7 Y6 [7 _4 E1 l
            return -1;8 c* `6 D1 x# v' Q) {0 S
    }- g7 F4 F- V& a7 y* A1 r
    + C6 i+ M  z+ D$ ?2 T/ o
    - n# c5 d( T* {" k: W' ?
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()+ b) u2 e0 S- Q
    {
    * j4 k" X, ~$ M% D: U% J    stack<int> s;
    " z* v) @$ X1 M% a  U5 u, [    int p,cur,pre;
    / r( \, Z* V% C( M5 u    //MultiAdjListNetworkArc<WeightType> *p,*q;
    , A6 W6 H* {+ i) n+ `    for(int i=0; i<vexNum; i++) tag=0;//初始化  V$ M) n6 R; `/ R
    & G- y/ ]7 l" ]) ?/ u" }
        for(int i=0; i<vexNum; i++)
    8 N5 Y4 ^8 j) I- I; I    {
    1 `( U8 R. @9 a4 Q4 t0 \' \        cur=i;pre=-1;; n/ E6 P$ {1 @( N/ D% T+ e% g7 k
            while(tag[cur]==0||!s.empty())
    : D) {* l) K6 x- t, P: c        {2 `) v7 g+ ?3 K  U$ s$ R1 a
                while(tag[cur]==0)
    0 b7 W- ?; m' F; \+ g1 q1 Y            {9 U" c. z  W1 I- r, o# z& x
                    cout<<vexTable[cur].data<<"  ";
    + t( h4 b6 ^/ f5 u6 ^                s.push(cur);! d0 J/ b# L& |# O2 j
                    tag[cur]=1;7 X5 G( S. w& A( y# c) J! _
                   //初次访问,标记入栈: F+ v' K1 z7 G

    : p2 _; e/ `8 ]7 E5 T' P               p=GetAdjVex(cur,pre);//p是cur的连通顶点
    , U- M# H  }* @9 S4 r9 P2 w               if(p==-1)
    ! ]3 [1 ~1 d8 d& Q( _1 L+ Z               {' i) R) g0 [( D6 g2 \1 b! r" H+ i
                       pre=cur;s.pop();% ?1 J- Y0 k! W
                       break;- I9 b) H8 J* h% t) n0 o
                   }
    6 g, F- @5 q4 Y1 l               else# P5 h8 t7 ]; }$ C9 U4 v6 L& L
                   {
    2 N( r. ]2 U0 a6 C                   pre=cur;* G6 M* s! t5 M# X9 D4 ]
                       cur=p;
    6 ^, K+ E2 i8 ]3 V! f! E( R! n  n               }
    - d! X" v3 H6 ]
    + W6 L) f( M; W2 j            }
    - J& p! J7 V1 \% ?: X/ v; A            while(!s.empty())
    1 u# F5 a6 S" I            {
    2 _6 d& q5 t3 ~2 ]                cur=s.top();
    : _' w/ [7 t& k                p=GetAdjVex(cur,pre);: l% {+ f/ D5 f7 R- k6 B
                    if(tag[p]==0)" o3 Q0 C" B. l
                    {
    5 q, h8 r" v+ L" h5 E$ V2 R, T; |( |2 C, M                    pre=cur;) j4 g$ u7 D0 I
                        cur=p;
    - v3 `6 N+ P7 h9 N7 g3 o8 b2 N' W' K                    break;! ~4 V4 p* w3 e* ?! M2 C$ z% |
                    }3 E- y# L- k' q5 v' S- B
                    else
    0 W$ ?7 [4 R6 W, A2 d" \/ L* z/ U" L                {
    1 ]( f# C: ~- z+ _                    pre=s.top();' c, b  `0 R; l: L7 J* p+ w% E2 N7 J) J7 a
                        s.pop();
    & g1 m8 y& U4 O5 \6 h$ N                }
    0 E6 M1 Q& q7 i9 `2 S2 r; e( m# ]( l3 |$ [- W, U6 G
                }
    ) t" W+ O: U( g! T
    ! Y; c" Z9 o- P1 Y4 e) N        }; h8 q9 L# \7 u# B/ r* p
        }
    7 p7 t& x( r; P}. t9 F/ b2 H9 c! M+ M" g8 Y
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    ; {* s. i# i( y* n  l2 T' A{
    6 y. I: Q( E7 z4 K0 x    for(int i=0; i<vexNum; i++)
    / Q3 ^" y0 \( ]# b: H        tag=0;
    ! i# m' y* Z2 J0 m. ?    queue<int> q;5 t+ ]8 ]( ]% s) v. o
        int tmp,t;  [/ W- j9 Y8 b2 |( W$ c, E/ Z
        MultiAdjListNetworkArc<WeightType> *p;
    & z! E! i# Q7 {7 }3 Z/ u    for(int i=0; i<vexNum; i++)
    2 e2 a& C' g( q  `    {
    * D4 U+ a0 N4 y$ t* }4 Y8 s. Z! {$ j        if(tag==0)4 c3 b! x6 T, S0 y/ ]+ t. U% z
            {
    ; }5 x% S# m# f; D$ ^$ R            tag=1;
    ' L; e! i8 d, |& s            q.push(i);
    : i# x1 C8 N- s' F& l  q1 O: }            cout<<setw(3)<<vexTable.data;. ?$ s' P0 V9 d$ ]5 j
            }. u5 g0 v4 r: b; H8 D, i
            while(!q.empty())( {  [' t- w6 _3 ?% b+ S4 @! _' ?
            {
    0 T/ u' V2 R* I9 h& n. {- t+ }            tmp=q.front();; P. K) K' g2 j2 m: H! [% G
                q.pop();  M, ^: _4 L( k5 W+ m  ~
                p=vexTable[tmp].firstarc;$ ]' H$ D( ?8 ~
                while(p!=NULL)
    7 X- h" T' T* h  j! s  i4 Z            {: c' q+ e) o/ c
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);' Q; p; v( b; _; T! A
                    if(tag[t]==0)4 ]7 @! B/ Q5 S6 N$ R
                    {
    * T7 m: G9 |% d7 o! J$ J                    cout<<setw(3)<<vexTable[t].data;, v' l/ o: ~& Y3 O4 \
                        tag[t]=1;/ I# `7 J; O+ `5 A2 Y. y
                        q.push(t);
    9 K" B7 G  e* x9 t                }) L- ^, V3 j6 d
                    p=NextArc(tmp,p);
    ' C  K) c, k$ C( j            }  Y  ^  x0 e: T7 R% U% G  J
            }
    + G6 N3 s0 P- G) g    }
    $ I1 I4 P8 x( o- `% |5 T- E}
    4 K/ w6 f0 t; Z2 L6 ttemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    9 R7 d7 @* d  @1 H5 L- y{2 i7 j' h9 z: x
        MultiAdjListNetworkArc<WeightType> *p;4 Q- r) b( S- m+ P! h# [* C; o
        cout << "无向图有" << vexNum << "个点,分别为:";
    ' ^0 b. E. S& t    for (int i = 0; i < vexNum; i++)
    2 [3 n5 @6 S& T0 l        cout << vexTable.data << " ";
    / `5 Q2 v# X* u; A- S    cout << endl;
    1 L$ _" F, [% u    cout << "无向图有" << arcNum << "条边"<<endl;
    / j0 t7 P# N- A; B" }6 q/ w    for (int i = 0; i < vexNum; i++)5 s4 Z5 O' p1 c
        {9 t3 |+ s9 F4 A1 g4 H  z+ L, q
            cout<<"和" << vexTable.data << "有关的边:";
    , z. P, M3 W1 M# B        p = vexTable.firstarc;
    % P1 n: q8 @0 x. x6 g2 S9 L        while (p != NULL)
    ! I4 }/ O5 [6 o0 C0 Z3 U        {
    % \6 j5 M/ G) q1 U: n5 u            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    # L- n2 e2 Y  s1 |$ X            p=NextArc(i,p);
    " l9 U5 b7 o+ [" F: z. ?( M        }
    ' c+ }8 w9 S8 T  B& b' d( w4 Y        cout << endl;) \, X/ X. R+ r$ p* o; d/ K( J
        }' Q; _( w7 N7 n
    }
    ' I8 f: G) E8 v! _: T' l" i3 O9 _# ~6 r, m- q
    ' a* d! L) x) E* c
    邻接多重表与邻接表的对比, v& e  \: F6 W) s  W# q2 S1 {/ t6 N

    ( \- ^& ^3 q5 Q9 I" N邻接表链接
      p! \* G0 }  M  Q在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。1 Z( K: P0 B4 W: i) M" b
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。; K8 O& k1 U5 d
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。0 _: B7 J/ _) K6 j
    ————————————————& i# i% X/ Y# F1 q3 A( G2 a/ l$ ^
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    + o/ j/ _( D8 u) T+ z原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958- b* K/ P/ _2 L! w# ^( u( F$ C  w

    1 j9 [* ^+ D. X* E5 g2 B2 f5 R/ n4 l* A( d& S& t
    . U* G" Q' b; K4 T6 Z5 F! o3 a

    & n, p( o( O4 @& M. U————————————————' s2 P* \9 q! w% ?( m3 Z
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。- W- A8 A  G* C+ H- L' Q
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    . J; w5 r0 W9 V& w( |( e
    ' h: t' D7 d, J% C+ F4 J
    + X. C" r& @, y8 k5 D- [- s% K
    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-7-23 00:57 , Processed in 0.711667 second(s), 54 queries .

    回顶部