QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1562|回复: 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
    : W' H' I) }2 e
    图的存储结构——邻接多重表(多重邻接表)的实现
      H; u2 }, G  x7.2 图的存储结构
    $ @9 Q4 w* @, K$ R
    6 g! e4 g% n; b. d1 H7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    . @1 }' x3 m+ R邻接多重表的类定义
    4 i9 P( _% X7 L' \& m邻接多重表的顶点结点类模板
    " f2 z# i$ f, O# K5 H9 r5 z邻接多重表的边结点类模板
    9 _& p' P* J+ U- h7 [: p0 A) O邻接多重表的类模板' w8 \% I% U8 [% B
    邻接多重表与邻接表的对比/ O! }( C6 H) G
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist: f$ ~: [& p9 X# J

    ) I4 ~* k/ t) \2 X+ A* n% m在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    2 S, G7 ~. P( t- b: X' d! u) w: X6 ]在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    8 n+ E: a$ {5 |5 u# y' |
    5 }- H  d$ [7 l' r邻接多重表的类定义
    9 @7 u( t1 n+ Q/ x; l) a; |+ e 1.png
      ]* f% a- P4 w邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:0 `# t, y$ ^1 P3 f' {. V; h
    data域存储有关顶点的信息;
    8 i$ D* {; Y! y" y' u; \) afirstarc域是链接指针,指向第一条依附于该顶点的边。
    # z( B" B8 K% g: e( l- m所有的顶点结点组成一个顺序表。

    3 A, o# a$ b- H7 e6 C) L

    ! Q3 f! n  \9 T+ T0 Atemplate <class ElemType ,class WeightType>
    6 F# L; r7 o8 _" t; Mclass MultiAdjListNetworkVex
    3 A# k0 H2 A4 X! a3 R{/ D2 l9 _! _# t( i  |$ J) q$ Y4 k/ ^
    public:$ X' V/ O. F* T: P6 C
            ElemType data;
    4 @$ g2 `% R' d. Z& y" z8 {        MultiAdjListNetworkArc<WeightType> *firstarc;8 v( m# e3 x; x, G! j0 Y# M

    0 H+ o$ w8 V6 j        MultiAdjListNetworkVex()3 t* C* ?$ _& B0 j3 Q: B
            {
    ( [4 y% e* |& @  S' ^) k                firstarc = NULL;; m( ~6 J8 P$ |5 ~) _7 p6 \5 y- [; k! i9 W
            }) c. q( I4 ?6 D8 Q1 x" u' }
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    + D- r4 r4 u# |* u0 ~( A' `0 n        {
    ' h, g2 E$ G& W) Y0 x* s0 ]# D                data = val;
    3 ]4 d) `5 C4 M( {/ Y                firstarc = adj;
    + i( c1 r; @  O" H        }" f; N0 C( b8 q' F- _. t
    };
    " u2 E, D) U3 W' m# P7 ]$ f  _  g2 e3 D$ \; V2 b! b
    邻接多重表的边结点类模板
    - T7 L/ Y9 c0 m2 B
    2 ~5 U) [- L! b& u) l1 O% \/ n; T在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    - F/ l8 H, q3 A) r, z2 c6 Etag是标记域,标记该边是否被处理或被搜索过;2 }$ `& n5 K* ?2 I
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;) U4 x; \# e& T. r; d  Q
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    ) U7 B* L3 _1 Q; Z' [2 Fnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。/ ^2 ~  z/ o7 x. k  `+ q) P5 [% N$ I) ?

    # O& a0 F1 g' | 2.png # i& g2 Z0 b- J" k# K
    template <class WeightType>
    2 N( X, ?0 P- @% a* m4 ^. s0 yclass MultiAdjListNetworkArc
    . `0 L6 Q/ n' I; c{
    2 s+ G: f( F5 H) B! f) |  ^$ f3 Mpublic:  L+ J4 ]2 G5 a+ p8 W' H5 o
        int mark;                                       //标记该边是否被搜索或处理过6 T, h6 z: k7 S* v
            WeightType weight;                              //边的权重3 b" h3 d% A9 i. g
            int adjVex1;                                    //边的一个顶点
      [; v5 ?  {' F% L        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1% g1 Q" D" n. g2 O* [  w& |' H
            int adjVex2;
    $ h- R  W" Y& J' \" Q2 j        MultiAdjListNetworkArc<WeightType>* nextarc2;
    0 D  u+ E3 B3 r/ H/ E( W0 C
    : `; ^1 S. D0 w* o3 J! S        MultiAdjListNetworkArc()
    ) {7 x0 B( u/ ]6 `; @        {" I6 Z( n$ u* K' o* [; b) }& p
                    adjVex1= -1;$ `' N7 z4 M( }
                    adjVex2= -1;" |& `: A) P& \
            }  J3 g2 A1 S9 i! k2 b$ R1 _
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)) B3 B. ?' _! d2 o0 J2 m) T
            {
    % }; K' Y! M: v6 p; a                adjVex1 = v1;       adjVex2 = v2;
    $ b9 |+ K4 o2 }4 F                weight = w;
    2 H; q/ B  H5 L. i) ]                nextarc1 = next1;   nextarc2=next2;% D' v  `/ k2 {" P+ l  V9 b9 b
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    . ^2 ^# Q' |) H3 p        }
    ; H( V+ b2 [3 k- n) M  b- [% V' e6 D0 j2 h( v# \% {
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    ( p4 T# [7 |* s. |: _# Gclass MultiAdjListNetwork1 Z( J5 S) O8 P0 a+ O7 l" O& r8 R
    {
    / i( [1 M$ `. X. L  L, u( m  q: B0 }" kprotected:: ^6 Z7 |9 j7 i, O# _
        int vexNum, vexMaxNum, arcNum;
    . `3 O$ ^$ l7 {+ |* `    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    3 d$ Q9 T, q0 o6 l' D7 Y* E: M    int* tag;
    2 }; R( |0 `% I- T    WeightType infinity;
    ( Y1 ^- M: ]5 ^4 Z1 Y3 R9 w
    0 @7 u) |" C* npublic:
    ( ~0 W+ o  m- ]& \    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);/ c! s1 {2 d$ j$ g1 _$ W1 N1 @- I

    - X( Q$ z2 V& n" N. G    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);3 N+ F7 k" a4 n8 e, x: k

    ; E; F3 c1 t: A0 H0 B' ]    void Clear();
    8 w5 V1 h$ e$ [+ k; A+ c    bool IsEmpty()
    5 Z/ S( U; g: m, b    {
    ; |/ s# I1 w! d! ^5 |* d+ a+ _/ P+ c; a        return vexNum == 0;1 g. }0 |4 o5 F7 ]3 o
        }
    $ G* j9 k6 J5 s, l% z    int GetArcNum()const
    $ x# r" C; h0 v    {
    # j4 P9 P8 K* ~+ b1 A& s7 c* \        return arcNum;
    $ p1 [5 o% j& {8 G3 W5 A: o! d) A    }# X4 R! G: b! y2 _$ v
        int GetvexNum()const
    . j& A# w; e' o$ a1 T    {
    & }0 T/ E2 {# |! }$ @, V+ {        return vexNum;
    6 a+ `# h- `% L% s$ f    }) ?( p8 p4 C$ t/ M
    ' W' P1 L, F, W5 o6 {: B0 B& r! `
    # W* d2 z$ ~4 r0 N* g! q
        int FirstAdjVex(int v)const;2 h9 b/ a. p! B) y" r8 N
        int NextAdjVex(int v1, int v2)const;
    ; g1 g; H* `3 X0 D  T    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    , S, D4 l, U6 q+ o8 J/ \8 m    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;8 O) K2 _( @' [! S+ L) u3 L

    5 y* X& e4 a) J    void InsertVex(const ElemType& d);
    % d# R6 x5 P# d& P    void InsertArc(int v1, int v2, WeightType w);1 }) I8 T: T4 g& j

      T3 C- w5 D+ {0 t4 r3 V    void DeleteVex(const ElemType& d);
    ! [/ q4 t' C. g- F5 J2 G' p3 D    void DeleteArc(int v1, int v2);( G/ i% H% j$ k, l( H& s% S

    2 a9 z# I2 u! a, D. {3 B' c7 n    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    ) R; \. u' K% E# D1 ?9 M# I    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    , b* t% K6 y0 `; e) M& ~6 s) |$ {# f+ ]- e4 Y
        ///深度优先遍历6 k# r% Z) v2 n/ u2 E
        void DFS1(const int v);/ p7 }; V, X- h0 i
        void DFS1Traverse();0 W6 F6 K2 o9 Y% \7 \9 f+ K
        void DFS2();
    ( ~6 y& J+ X1 `  B3 E+ }* h# S
    1 ^" R0 }) j2 f/ r. K& ^$ U% p    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    / Q8 b$ }1 {, R( z( S" b2 v    void DFS3();
    8 B+ ~1 H( }0 |' x/ I/ d
    " N$ T7 A! A2 @$ a; W    void BFS();
    ) i% Z0 t2 N  s) _# h8 J9 r8 \    void Show();
    1 O/ @( \* M7 b5 s- ^& V};0 F! p  N. l5 G  s
    8 \3 P  f/ M& \/ `  a& y
    2.函数的实现
    4 [3 J; u. w" r: }8 y' l. r) k4 d1 `研讨题,能够运行,但是代码不一定是最优的。7 q, Z3 }1 f2 V& r! T

      p$ U8 U! h$ o% J/ ^#include <stack>; ?. {6 Z% {# s' w$ y9 H7 [6 D' N
    #include <queue>
    ' h4 o9 {  Z! L7 ?  q' E
    - V1 W9 v6 {: _3 ^, ytemplate <class ElemType,class WeightType>
    - E% ^' u7 M9 P$ G: C2 _! `MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)' \6 Y4 x3 v6 v& d. ^" i
    {1 T5 L) f2 m  W& ?& d) h$ ]
        if(vertexMaxNum < 0)4 |3 Q3 m! {' z
            throw Error("允许的顶点最大数目不能为负!");
    / l! Z4 d& n; P2 H  S    if (vertexMaxNum < vertexNum)/ j* W% @3 d" o* t! L+ z7 E0 i
            throw Error("顶点数目不能大于允许的顶点最大数目!");
    . p7 [4 A' U# {    vexNum = vertexNum;4 P' ~. g+ [- N: l" C2 F
        vexMaxNum = vertexMaxNum;
    0 b. D- C$ {! `/ n6 i, u' q    arcNum = 0;
    % X+ e; [4 H) B9 M# O2 S. x    infinity = infinit;
    * w2 `$ x3 \' D( g# [6 w    tag = new int[vexMaxNum];
    : |$ ^# Y: ]2 j$ _* z5 O    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    / ~5 b9 o/ d- y" [! b; \$ h: h. O    for (int v = 0; v < vexNum; v++)
    9 }) V; _; d; y9 R0 C% y  G    {) m; u: D& E) @! j3 h8 s9 o, `
            tag[v] = 0;9 O' ~/ ^" ^& }$ |4 Y; W
            vexTable[v].data = es[v];
    & `4 G( N2 N# I( \# i$ ^+ w3 t        vexTable[v].firstarc = NULL;- @2 G: m8 a3 w  P. z- h& `, t
        }
    8 l% f# S; ?# v}
    : M: O! V0 _  m1 d: Ttemplate <class ElemType,class WeightType>" k2 X, s" {5 I& a; B, w
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    9 O9 E4 j( v" c( |{* ?) r% Y% O- j8 E7 \$ L7 |9 i1 e/ Q- a
        if (vertexMaxNum < 0)
    ( P( o' A3 n% K+ }$ M7 s        throw Error("允许的顶点最大数目不能为负!");$ K" |: R5 n2 O% g; a
        vexNum = 0;# X! H& Q9 m" \! K
        vexMaxNum = vertexMaxNum;
    . S) q3 q7 ^1 j4 G6 I& u0 L; M    arcNum = 0;
    2 R5 u: k0 v4 }  t. w  i/ J: ~    infinity = infinit;
    # y/ K* m, r4 o) A    tag = new int[vexMaxNum];
    ; V1 a: ?# ~9 t  v: E    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];0 L5 j- p+ j3 X6 d. O1 f0 ^
    }
    : w) G. p  X4 |+ C% f; v$ q3 u7 Ptemplate<class ElemType, class WeightType>! J1 j5 n- N6 D
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const1 ^5 O8 {1 Y  e" g
    {
    2 R& I8 @' w/ M    if (v < 0 || v >= vexNum)7 L( Y9 F3 d& V1 z0 S/ G- m2 Z$ o
            throw Error("v不合法!");$ Z/ e+ N0 a  b: f
        if (vexTable[v].firstarc == NULL)
    . z! d- w% k/ Q        return -1;- H6 u( A/ p* Q% a3 @
        else
    8 w' E" ?* _6 U( j) S        return vexTable[v].firstarc->adjVex1;
    % e& M0 D6 i. d5 F. y}
    * D' S" c; @) N1 l; {  G2 Y% H: y, W# j2 @& s
    template<class ElemType, class WeightType>
    ) f* \0 ~  K7 H  X1 R+ xint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const3 [; t" v- _4 b2 H+ X& ^. P& v
    {
    7 E, `8 O2 ~% t& Y' ?    MultiAdjListNetworkArc<WeightType>* p;
    1 e; l7 Y* v9 \% W7 C    if (v1 < 0 || v1 >= vexNum)
    ! d9 N" p: R6 ~3 d( {9 z5 j        throw Error("v1不合法!");
    0 ?" a' A0 g' l$ \* _8 G7 a    if (v2 < 0 || v2 >= vexNum)( P- ?: l* _; ]2 B5 H/ _
            throw Error("v2不合法!");/ q6 i! J$ a4 p5 b/ T
        if (v1 == v2)
    ( {1 y6 h8 l0 _$ I% z9 ^- O        throw Error("v1不能等于v2!");# C' S! p3 Z. W$ N* {2 f) X
        p = vexTable[v1].firstarc;. w) \* l! P  G0 h
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2). \, j2 O2 j4 ~7 Q- R" D& W# t
            p = p->nextarc;$ D1 W$ O; Y/ @* T
        if (p == NULL || p->nextarc == NULL)9 h# T3 `! A! _/ M. s% W+ H( b9 o& U
            return -1;  //不存在下一个邻接点6 F; A% x8 }3 Q, x
        else if(p->adjVex1==v2)
    " R0 G6 i# o1 E" u7 `* x7 a- F        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);) O; K6 d+ p1 ]+ {9 ^# q9 D+ m
        else
    / @2 m& Z) o& n" u6 l. Z6 _        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    5 D" S; F+ u8 [% C5 K( J8 ?6 z}5 R4 ?4 t6 _$ i* C/ R; ^7 h! [
    template<class ElemType, class WeightType>. H4 W3 y9 G+ L. P, u. K
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()6 j; U* {& m( n/ V  w8 b) J
    {3 j' t) z: ]7 e1 z
        if (IsEmpty()) return;
    # O& b& F0 [/ d    int n = vexNum;# L2 s' _& V. K; a
        for (int u = 0; u < n ; u++)
    * F( f, p& I6 D, K9 Q$ h        DeleteVex(vexTable[0].data);1 @+ ?2 i# E3 l. S3 K$ }/ D
        return;( e3 J* P5 e4 R2 x* S3 n: u. D
    }
    0 m' E0 [# p: S5 t; wtemplate<class ElemType, class WeightType>
    1 \, `6 `+ A: h1 R5 sMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    2 m1 i. _) a# \6 s# D  H! Q{
    4 ]: }, Y; C1 o: u" O/ O    Clear();
    ! ^& }- L% v& ^9 l% ?& o1 e}
    # F: O6 E1 k9 x2 ?& Y  b6 Itemplate<class ElemType, class WeightType>
    & w# `2 S) ]* `9 Q# S: [' zMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    ) p# q! ?9 z- |4 g{4 k% |. e- z) j3 H4 a( k
        vexMaxNum = copy.vexMaxNum;" T" }# B" K. t5 [. _4 p* z
        vexNum = copy.vexNum;
    , G* x$ L9 }9 T* \3 _    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    1 _3 i# `5 e7 `! H    arcNum = 0;' W" q6 I  y) {2 l7 p
        infinity = copy.infinity;; L/ `" E7 Z+ `! A# j- R
        tag = new int[vexMaxNum];; r6 H9 K8 ^9 q5 c7 E
    / a4 Q. F7 x3 f
        for (int v = 0; v < vexNum; v++)6 u3 K+ z- c1 J+ E
        {5 n# ]+ I% c4 w, u) _9 }  P( n9 Y
            tag[v] = 0;
    / Q3 [- Q4 `% F0 c( s        vexTable[v].data = copy.vexTable[v].data;* V) B. `( `' [( f) h7 K
            vexTable[v].firstarc = NULL;
    4 z9 k8 J9 ^+ r    }
    9 m: d  ^8 S6 I6 }+ I; d' g; h    MultiAdjListNetworkArc<WeightType>* p;
    0 H! U0 ~+ S/ Q+ m9 U
    % h5 X+ u. ]: O. U! `$ @    for (int u = 0; u < vexNum; u++); L% K/ q0 e$ X. I0 Q5 Z' w  @
        {* q" L+ P, j7 J( {
            p = copy.vexTable.firstarc;
    ) t7 K  G% _0 r" v$ `        while (p != NULL)
      N* [& n6 e. U( |4 L, M3 e        {; r- @7 w; K  R0 U+ s
                InsertArc(p->adjVex1, p->adjVex2, p->weight);8 d: H- R! ]' Y: g
                p=NextArc(u,p);
    2 @- x( `5 `& }+ o' F        }' `+ S+ F0 O  y; J, _0 R
        }
    : }5 Z) u3 g5 D8 ?$ H% R$ M( A5 a  w( d$ W}3 j2 ~$ t% n; t) v$ r
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&6 x4 B  p. x* x
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)  S& Y1 P. M! l
    {( v# ]- Q4 `) o' i& Q& q) A
        if (this == &copy) return *this;
    * ], Y6 w' G* W& V- f    Clear();
      b4 e9 _2 m: e    vexMaxNum = copy.vexMaxNum;$ @# b+ @6 v# y' s" V' L
        vexNum = copy.vexNum;
    ; u& ?% n' H) U$ d    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];9 e2 n& ~4 _) @" v' }
        arcNum = 0;
    - c' W+ Q+ G5 z3 \    infinity = copy.infinity;1 v: f: `# e5 l- k
        tag = new int[vexMaxNum];
    ( D2 H/ I( W5 ?
    9 C; U* P, K) i8 y3 S    for (int v = 0; v < vexNum; v++)
    & P' `; i0 J. k# V    {6 R: g5 Y- y7 B& d6 {* `
            tag[v] = 0;7 l$ I) _7 j% R, z# w1 ^
            vexTable[v].data = copy.vexTable[v].data;9 A' o$ T4 X% E) r4 @
            vexTable[v].firstarc = NULL;
    3 F* X5 q+ d  q, m% |4 R+ `. j+ j' ~! g6 z    }" d* W- A$ f$ [
        MultiAdjListNetworkArc<WeightType>* p;. s* V8 D5 j9 y

    6 y8 X. s" F5 m' U8 o% F    for (int u = 0; u < vexNum; u++)
    ; b% Q. u4 F; v" c    {. Z) z. X& _7 d
            p = copy.vexTable.firstarc;
    " _- K& T9 X) U0 q5 d2 U        while (p != NULL)4 R7 Y  Z. e0 f$ \+ N( x( y' }; J/ R
            {: u3 i! V% F; `! J
                InsertArc(p->adjVex1, p->adjVex2, p->weight);3 d: W/ {% ]9 D! V+ a
                p=NextArc(u,p);
    ' c, N8 e0 E0 k+ z- N4 @% Y        }- B5 v1 `: @  Z  F+ L
        }, ]( B( u2 I' e3 U( Z, a
        return *this;" y+ w& v- y/ h8 ^# a
    }
    ) }+ u9 l1 F  V3 d$ f5 z' S( ptemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    4 b- M7 b+ G* A) MMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    " z  E6 k! _; s; H% ~{
    6 P  K8 [$ `6 x- _3 E$ ^/ B4 Q    if(p==NULL) return NULL;3 F3 K$ x/ r) C
        if(p->adjVex1==v1)* B$ _  \$ D" A0 `" }- I, D
            return p->nextarc1;
    * `3 @' V4 Q/ {5 o9 d    else1 U0 @8 k1 U- t* e4 _( n
            return p->nextarc2;2 u0 B3 R2 U4 v
    }  M+ n  I) O1 y# M/ Y
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*7 T! z" |" x) R# k/ q5 L6 q
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    6 s5 L6 j7 f/ T2 f! G. q{* R1 Y$ V3 Q  l9 G
        if(p==NULL)return NULL;
    3 ?7 N4 _" a0 @& r/ J- F- s) l    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;9 L' w3 K) L9 c; R" Z/ v
        if(q==p)" `+ z" Y9 H/ ]) F  H6 C% ]4 s5 _
            return NULL;! @6 w! H1 z1 S, a1 W$ S& x
        while(q)
    + _7 n* o6 B, k, V5 V2 z% }    {
    . M4 |' C. y. h        if(q->nextarc1==p ||q->nextarc2==p)
    % y6 r9 _% U# o& e+ h            break;
    3 P; J: _+ u& N+ P! h  i0 f        q=NextArc(v1,q);
    " S$ Q; Z! u/ h6 I    }
    * K0 W& C& E% B& F    return q;: T! y2 i2 w( @2 N
    }
    & X# P* V6 Q; N8 O/ gtemplate<class ElemType, class WeightType>
    , s/ h4 q6 ~$ g: rvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)% h& z# [' s3 p1 ?
    {
    # d1 ^  e4 j: e. {% k8 j    if (vexNum == vexMaxNum)2 b: L4 M/ m* k5 m( R! ]; n
            throw Error("图的顶点数不能超过允许的最大数!");5 L) B5 }8 t5 ]% E! ?
        vexTable[vexNum].data = d;. z. b( R: k+ \0 k$ u( @& b2 I  V: ]
        vexTable[vexNum].firstarc = NULL;8 W0 g: a7 L' G( h; X, Z+ D
        tag[vexNum] = 0;6 m, A' P( v' D  H5 B
        vexNum++;
    # X% N3 h' @& Q( T" Z}
    2 F) r. a2 h0 V- m$ K, J2 R7 Itemplate<class ElemType, class WeightType>( I; S$ p: b- ^+ y
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    . k8 `, F+ {& D/ B, o{
    % [& p5 i1 \+ D( x( z$ S    MultiAdjListNetworkArc<WeightType>* p,*q;
    2 y! ]0 S0 Z- e$ a6 L7 [    if (v1 < 0 || v1 >= vexNum)0 l- X5 L4 a1 I' n& G* t* e1 K* \* B
            throw Error("v1不合法!");
    $ i# M2 Y0 C! s+ |3 m7 Q    if (v2 < 0 || v2 >= vexNum): k) N$ n. a" B8 V6 a
            throw Error("v2不合法!");& y( c# a# b. S2 H
        if (v1 == v2)
    + a  a9 s8 V+ @* M2 p6 b( j7 |  R        throw Error("v1不能等于v2!");5 j3 Q$ v! g4 v0 I' E
        if (w == infinity)# G/ S' o) q% H0 C% U* A
            throw Error("w不能为无穷大!");
    6 M! k9 v; S# w9 P8 l0 y( B" s% N  |* W6 [, T2 z8 I, t5 p! _

    9 x  _8 B: Q6 }0 n  J! b4 w    p = vexTable[v1].firstarc;+ }5 p4 {* S/ h3 B( J# _+ Q! q" a
        while(p)* ?% S2 ~% x' R6 v* C& l1 x* X& a
        {
    4 u  E0 M6 N* M. j% @# s- T" \5 A9 u        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    & N# {1 D$ E% E0 Z$ h; q# R& h0 Y; e        {
    6 r( t5 }# z7 m- O5 }  n9 J" A            if(p->weight!=w)
    : F/ e' G1 ^) Q# k                p->weight=w;
    . C! i. H; u) F! ^" k, e            return;
    % _; e* I/ \( o3 i. l* `8 v        }: q. ~* {" [. H6 w0 C1 Q

    * y  m+ ]/ Y; b! j4 n4 P        p=NextArc(v1,p);4 p8 ]; Z& c& @2 V
        }
    0 T, h0 `* j! G/ \/ e" C    p = vexTable[v1].firstarc;
    ( G! h8 G  x5 X: ?' t+ t1 J    q = vexTable[v2].firstarc;4 X4 C- B  V. x7 Q7 w. [+ V1 G- R
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法: z' F- o9 j8 u' u/ Z
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    - d7 Y" L' ]- m4 ]    arcNum++;* R8 \( U  H! O. W- A
    }
    # p2 x7 l# n3 j4 p
    ; |& C! G9 {( mtemplate<class ElemType, class WeightType>
    * m3 S5 t0 x8 u7 t( ?% h4 S) fvoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)8 P3 q& `0 Q( B, |9 W7 c
    {) }" c6 r0 q) s% \6 A3 i
    2 J: F( D, P) f! G4 |$ w( c
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    ) U5 U- o5 O; L: ]' _    if (v1 < 0 || v1 >= vexNum)* v! t" q( \- E1 w& L
            throw Error("v1不合法!");
    % }) G- j7 ]6 `0 i- u    if (v2 < 0 || v2 >= vexNum)
    2 ^, B- k& Q7 a        throw Error("v2不合法!");0 E! S. q/ Z2 ~1 V$ X8 I
        if (v1 == v2)  \( o+ I, Y# J4 y
            throw Error("v1不能等于v2!");
    - j5 j! {+ U- \- b2 v5 U$ ]  h! t
      l1 V" Q1 y5 c0 e    p = vexTable[v1].firstarc;+ y1 w  h# D$ R- |2 b/ p# L7 `  ?' J
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)& R" [3 H* A/ u
        {
    5 Q8 p  e/ S+ E! C7 e4 |        q = p;( ?) [) D# r8 _7 Z2 x" E6 J
            p = NextArc(v1,p);) O' f8 R4 W% @0 ~' r7 t
        }//找到要删除的边结点p及其前一结点q' D& x6 k1 m* s9 L! m+ r2 G

    ( r; o2 B$ [! d8 S0 q( G+ _; q    if (p != NULL)//找到v1-v2的边4 ]# L, R7 V+ ~$ y) |
        {$ [/ n4 N7 c2 M, }% t
            r=LastArc(v2,p);
    + A7 b: j  K* ^- ~        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL7 K1 m0 x, o) o, _
                if(p->adjVex2==v2)
    * s: \( C$ J' O7 t; E/ i                vexTable[v1].firstarc = p->nextarc1;
    ( g6 w! p2 M% R0 @. e            else vexTable[v1].firstarc=p->nextarc2;. X4 E! R7 A; W: H4 G) Q5 K
            else//不是第一条边
    . N. o5 k: D' J8 w0 Z* E' D; M        {3 [- s6 C( s4 x  H6 m1 q
                if(q->adjVex1==v1)6 f9 E$ {: w/ a- \& F
                    q->nextarc1 = NextArc(v1,p);( C% V5 D0 b. T
                else
    3 ~6 m% x6 S* Q. _. m                q->nextarc2=NextArc(v1,p);
    $ T( a5 F2 ~0 b! n. I' F
    2 b9 Z$ t3 \* _9 f2 A        }
    / x* Z& m; p3 p$ f, d' u        if(r==NULL)
    ! P6 ^& _7 F3 o            if(p->adjVex2==v2)" n1 R' b) z* E/ o" _+ _' K$ N
                    vexTable[v2].firstarc = p->nextarc2;
    , M( b  P' o: a# o) i3 G" _5 |) \' J9 L            else vexTable[v2].firstarc=p->nextarc1;
    9 [# h8 g: x- f5 W4 u* p        else" t6 F8 O8 A+ a2 V
            {
    " J% y- w, E' ~+ U+ e( s: \! J            if(r->adjVex2==v2)* B! O. I; C2 I8 Z, T
                    r->nextarc2 = NextArc(v2,p);% M, |2 x5 y7 V
                else
    7 Q2 J2 ~6 t+ [! A: k5 i& ]                r->nextarc1=NextArc(v2,p);# r  B+ q0 }+ r2 A
            }! T$ C# R; Z9 q
            delete p;
    / I( I7 E, n! G) p* N: f        arcNum--;8 u# @! {( d/ B. L; t! A
        }
    0 N5 f0 W. g* o) @) t& N4 C$ k
    9 K: ]; q5 J/ F0 T: J& B3 t) _}, g: C# r- d/ u
    template<class ElemType, class WeightType> void
    . [2 `* C8 n. w" y! k, UMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    1 X4 c0 {: }8 A6 a4 ~) b{
    ! N* _, i- l8 Y5 }" n. A  l    int v;$ ]. {5 ?6 A! ^( V3 b1 q- V
        MultiAdjListNetworkArc<WeightType>* p;
    % P, [4 K  G2 u    for (v = 0; v < vexNum; v++)//找到d对应顶点
    1 ]$ ^" F) b9 c- G# G* |        if (vexTable[v].data == d)5 O) V: e7 v3 a1 \
                break;
    & _/ G4 ?9 B) t. S+ e6 R5 S    if(v==vexNum)9 C7 T( P9 |  F
            throw Error("图中不存在要删除的顶点!");3 z- V1 Y- F7 x  U9 B( E9 l9 n

    1 ]+ F0 Z# {% e$ L8 {5 r5 `2 v5 }# {    for (int u = 0; u < vexNum; u++)//删除与d相连的边
    2 A* X% v4 Z8 ]5 m+ d. c  P- s        if (u != v)7 k( |* C5 g: ~3 A
            {
    6 P8 K. ^3 H9 I9 h. S9 Y            DeleteArc(u, v);
    * ~! l. v. Z1 W7 ?$ z  f        }
    . e" k+ n) t& g1 L' W- p    vexTable[v].firstarc=NULL;
    & E) c# Y$ \( Z9 G" ~
    * {  n& x$ m0 q% H7 b    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置. ~0 _+ V* f. K" ~: M3 F3 y, Q8 V
        vexTable[v].data = vexTable[vexNum].data;
    , d" w! b/ E% [    vexTable[v].firstarc = vexTable[vexNum].firstarc;- N# `& L3 O+ O) I' b
        vexTable[vexNum].firstarc = NULL;
    5 ]' H0 Y5 p9 U" k: V% ~, e    tag[v] = tag[vexNum];; \6 F& t" u0 o* U
        //原来与最后一个顶点相连的边改为与v相连: n( U+ z9 r! r( C7 ^1 m# c- `: N
        for (int u = 0; u < vexNum; u++)
    8 ]" P$ R0 @% K& m  X    {8 J6 v7 P. ?8 F6 a
            if (u != v)
    ; ]8 }" s: i: c5 n        {5 h8 e, |: E% W, N" x% T7 C7 R4 t. F
                p = vexTable.firstarc;: n4 Q' u0 y! }1 Q& {! h
                while (p)
    8 p, M' ~7 ?2 {$ i8 l9 C            {
    $ @1 C; C" T; a                if (p->adjVex1==vexNum)( a& K$ [, p$ N$ d
                        p->adjVex1= v;
    ) d, U4 [3 d: ?1 N7 q( q                else if(p->adjVex2==vexNum)
    # W" Z7 D) D" g/ n; n$ `& t% \                    p->adjVex2=v;
    ( L5 u* Z0 p# x" I4 J, W8 L, M                p = NextArc(u,p);
    % X/ j, f9 z( e) L/ H            }6 |2 p, z; T/ d' k. c1 c
            }3 x5 R0 d5 b, c! y, q# Y! g
        }# Z$ F$ K2 H# G8 v/ }
    }
    3 w- `5 F; f, \///深度优先遍历
    - V5 j3 X* c7 ~/ |* Otemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)0 t9 G# B# A5 x2 G
    {
    1 u  ~4 R" v0 J* b( p0 ]8 f$ [    tag[v]=1;' O( j0 D) E% z8 D5 A7 C* w& d+ ]
        cout<<setw(3)<<vexTable[v].data;. C5 k, x0 g2 f" j# ~
        MultiAdjListNetworkArc<WeightType> *p;
    % E2 T5 z0 \0 b- f1 `    p=vexTable[v].firstarc;
    6 p% _, c6 b0 j: A$ H  u1 E    while(p)8 |& _3 d3 ?5 |3 w* N" k
        {
    / y. v# k# i! F; [6 r- U: a+ F        if(tag[p->adjVex1]==0)
    ; G! `. t: f- A6 B            DFS1(p->adjVex1);
    & L, p! X- N) H        else if(tag[p->adjVex2]==0)- Z: f0 p: S# o  L4 e
                DFS1(p->adjVex2);
    + P! X) O5 C1 [' @7 P        p=NextArc(v,p);3 ]; C! c7 k0 t
        }) D. p$ Y! q, ~
    }
    8 j9 T% v9 g* K/ ]% B4 Jtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    , P9 @& ~9 E: G: Y{
    - b8 S9 s1 O  `    for(int i=0; i<vexNum; i++)' ~, i$ ]; h- Q1 I) Q
            tag=0;
    : O9 r* P6 H& [    for(int v=0; v<vexNum; v++)
    5 B0 F9 b* O# U( Y7 B6 g; h* w! ]    {6 W, ^; U, d0 B, H( \
            if(tag[v]==0)& M. m$ m! M6 W! @
                DFS1(v);
    # s0 X  e; A: K* G- O4 a( s    }) f7 Y' o9 K) e
    }
    8 T+ b! m1 E& a/ r# _% k( B% Mtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    . t  y, H) @4 v9 [' `0 ^{* N5 c1 B( O+ M. g; K
        stack<int> s;0 B4 p" W1 p1 S) t3 W2 K: T5 r
        int tmp;: I5 F: Q* m3 ^$ z8 K
        MultiAdjListNetworkArc<WeightType> *p,*q;9 _" P2 T3 i; v) [* q: l
        for(int i=0; i<vexNum; i++)
    5 ~% j0 |- T: v, v* M4 L* Y        tag=0;
    : ^' T' c: n, `* Z    for(int i=0; i<vexNum; i++)5 h* @1 j4 k& v) k
        {( w. e5 [' H4 M, M- {1 [
            tmp=i;  ?4 }- {+ K% S/ O$ Z7 }- c$ ?' _0 P
            while(tag[tmp]==0||!s.empty())# O! b3 B" f8 F  o2 u
            {
    3 j, y6 u+ E7 a9 y! d1 ~9 |( z: J- `            p=vexTable[tmp].firstarc;  j3 k. L/ x' `6 Y# K. w5 e
                while(tag[tmp]==0)! j. t1 F. R$ w. ]1 }; {
                {6 u$ \$ z' O; U" I7 N% C( e- m; R2 [
                    s.push(tmp);5 o5 N2 ~) o- u, O3 g/ o/ `0 a$ v
                    cout<<setw(3)<<vexTable[tmp].data;$ u8 p( `: p2 @7 B: B5 Z" ^- |0 c
                    tag[tmp]=1;
    ! Z! Y9 Q: C. b5 J                p=vexTable[tmp].firstarc;; u: B' m7 |9 c+ ^  W/ G) H
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for  ^. \3 P2 t: w; N/ b. p0 Z- J) `
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    6 v) p, z( _8 p                //cout<<" 1st     tmp="<<tmp<<endl;
    3 r+ T* {. l- {            }
    : h( R7 y. k) c- \2 H9 t! E            if(!s.empty())
    , L4 j& @+ u" a: Q0 M' n% w; S            {
    ; |* x! ?+ J% s2 T1 S. D* ^                tmp=s.top();
    2 U% j& x* \4 W                s.pop();
    & R; |0 U1 H" Z( X# v. t% V                q=vexTable[tmp].firstarc;
    ; s3 ]7 v( v: b6 p                int t=tmp;) V0 T* T( O# k  v# s$ A- }0 h7 _( n
                    while(q&&tag[tmp]!=0)4 R( j+ |& K6 p  b: K
                    {
    + W8 |6 ], V  l) Q1 j                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    - o9 k6 |% I- K3 R3 P3 _7 K                    //cout<<" 2nd     tmp="<<tmp<<endl;
    6 A* s0 _0 |5 {: Q+ G1 Y                    q=NextArc(t,q);
    9 I1 C3 {+ q" u                }: S& b7 C% i& S; x5 C; L& |
                    if(tag[tmp]==0)
    7 P3 ~3 d) v, t5 W                    s.push(t);
    2 m; |/ P2 d* M' J1 K                ///1、对应上面连通分支只有1个点的情况# I% @# \+ {6 u# S' L; F
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈# S7 T4 X) w: p2 N- I
                    ///tmp要么等于找到的第一个未访问节点,2 [) X. W- q5 F+ t6 C* r( Z5 o
                    ///要么等于与t相连最后一个点(已被访问过)
      _2 ?. z. D# i+ F' |4 V0 i                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    - \: Z4 P3 _# x            }
    1 ~, W: R+ c" k9 T6 M        }
    9 F- [1 G$ P* r3 W) E/ ^7 N- L    }/ R% F% ?% H/ V4 G" P% L0 U) P
    }9 Y2 W& [- @8 W& Z5 r, G6 X
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    2 o3 `2 E& V- @& n+ F, ztemplate<class ElemType, class WeightType> int
    / c, K$ J' R5 X* r) ~6 ?9 o  S) WMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    ( T+ y" Y" p5 D) G{
    3 u1 ?  ]* X; a- F1 n    if(head==pre)
    6 g7 n$ ^/ F" \% R  y. h4 l        return -1;
    ! n8 E. j) E5 J: \8 i. U) z8 Q" k( Z
        MultiAdjListNetworkArc<WeightType> *p;
    4 o' M. f; @0 i! r. {0 L% W% w$ i    p=vexTable[head].firstarc;
    ' ]5 J, H, M0 u    if(pre==-1&&p!=NULL)' W& E9 V4 u* R2 F/ K/ y/ i+ N
            return p->adjVex1==head?p->adjVex2:p->adjVex1;& R( b0 n+ s7 H. V
        //pre!=-1&&p!=NULL
    6 {5 f: b: d7 n. E% R    while(p!=NULL)
    $ K! f4 M, r, l+ e  f    {
    $ W7 H; E" `. ]/ t  ]        if(p->adjVex1==head && p->adjVex2!=pre)4 N9 \  @4 m  E' R
                p=p->nextarc1;
    # b2 G6 i. }0 d+ R, I        else if(p->adjVex2==head && p->adjVex1!=pre)7 e& t# Y2 {6 \0 D9 U" C
                p=p->nextarc2;$ N( S6 @- ^) k, D9 q
            else if(p->adjVex1==head && p->adjVex2==pre)
    # h- Z% @0 P; s+ I2 T        {5 r- y& j# y( d4 c/ \  o& _
                p=p->nextarc1;2 R0 L6 ?, p. }- ?: m; h
                break;
    . I/ Y; j; l6 X7 ~; X  l1 C' \; X        }
    - k7 F7 }8 g: Q, C) T( g# j0 Y+ e        else if(p->adjVex2==head && p->adjVex1==pre)
    ' X9 @  k9 |( m- I. R& t        {) A! v3 _  @0 t+ A8 l# m7 c2 H  \
                p=p->nextarc2;
    , l' N! F( H2 W7 U            break;  L3 M1 v, i% i) J
            }
    0 T- L; [8 ^  j3 E' z5 g    }( u4 q3 F' d. t$ @: g5 W$ Q
        if(p!=NULL)
    8 F. u" x( A0 Q2 H, r, `% y# y' M    {7 }: m; \) }' \) S) T4 N* ^1 K
            return p->adjVex1==head?p->adjVex2:p->adjVex1;5 V! F7 u' z4 K) X8 }6 s( J$ `' X
        }( h, U5 J9 q8 S) [/ V
        else/ ^# W, c9 E4 }! c$ P8 I* X4 Q6 k! P
            return -1;. d2 X. v. Y# C. N
    }
    3 v! C8 R1 K1 S8 H& Y8 ]9 V& ~, }# ^, s  M, A

    " j- v  d/ S/ ^# x3 b. Ytemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()4 M2 c9 H* w2 y* ?, o! Z/ m9 m9 q
    {4 D  s9 q- A; f1 O" _& i
        stack<int> s;( M  D# C& G. l: r3 I: W6 D* ]
        int p,cur,pre;" ?: F% D& z* S& I3 b
        //MultiAdjListNetworkArc<WeightType> *p,*q;/ l9 \3 W3 H% z& Y4 J) Z" D
        for(int i=0; i<vexNum; i++) tag=0;//初始化
    & x+ Q! {. G+ D# [3 Q8 J  T2 l4 T0 q
    ! @) i- W9 V3 Q6 N    for(int i=0; i<vexNum; i++)
    6 ~. X, K) E- _# [' X: V    {' z- W3 x/ T1 R) s6 T2 L9 `+ }) Q
            cur=i;pre=-1;
    $ a, M2 d# r3 |5 X# v7 E        while(tag[cur]==0||!s.empty())
    , P- \+ B/ D: W0 L6 S' j3 [6 h        {" c# j) S; f% N
                while(tag[cur]==0)
    0 v# U5 m6 U) T$ b: c            {
    & a) u) B2 w- `, R/ X- Y: U% z                cout<<vexTable[cur].data<<"  ";" g% x8 N' b8 V6 w
                    s.push(cur);6 E; Z9 N) K: K3 \* U
                    tag[cur]=1;
    5 y4 h) b3 U4 {. K, w, A. F               //初次访问,标记入栈% f, c, @2 Q4 o, O3 ?# [) {% ^
    5 e6 H  V/ `! q0 x
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点9 V0 o  Q" P' Y2 E1 g  F, }
                   if(p==-1)
    5 q; C, k& {/ T# P( K+ `               {
    ( V2 K. Z  m! |  W) ]$ _& ~                   pre=cur;s.pop();
    4 z$ t) i* s) G  ~, B) F" C! F                   break;. T$ t* ?, H- }8 S1 k
                   }) L. ~. v2 b" e' r- N6 e4 }
                   else* \" X: h4 @& x' G7 W1 q
                   {
    6 @7 Y" j9 P" ?                   pre=cur;
    ! u4 i1 w& l* u8 Y) ~                   cur=p;" D$ T% g* Z: c6 n
                   }3 F9 W  X/ E  E' B: D
    ) |# K+ R9 U5 X; T4 ?! S
                }
    + A  u# V7 T* i' b* }! ^! i9 w3 i5 ~            while(!s.empty())
    ! w) y$ o( {. h& ^  {            {
    + t( ~0 E& n7 f% T. k. }, a                cur=s.top();& m' H) z7 L. u% ]7 @! L1 U% J' R! o
                    p=GetAdjVex(cur,pre);
    ' i! |! I' B8 q) E# c2 H                if(tag[p]==0)
    ' K. u$ x% }7 B1 I, t1 P$ O                {
    - z) |# j0 a5 B+ K                    pre=cur;
    8 P/ s# ]) l* c) h9 j; ?; u) m- R                    cur=p;5 {) g" i1 V! C  \9 s
                        break;
    2 {7 U1 {2 n7 z  l$ N5 a                }
    & B' j: m3 X. V) z4 F/ \9 X                else3 [7 X4 ?7 v! g. G/ J
                    {- H: v" `: M+ g# @# u2 o( E
                        pre=s.top();+ L6 k$ S8 x& Y: [! z! W8 r
                        s.pop();
    # L  D3 J; [, V. h8 g9 P                }
    ! f! }5 Q6 X' K9 u. t) c* I
    9 Z1 F; D* {! r, \% p' Y' c            }% M% ]; G  C- J/ h' s0 {
    : G+ B0 U$ U# j1 N
            }
    4 l: ^- X  V" W3 P% n    }
    - O2 ]7 d# u9 q! w" g% [}
    8 T# Y3 ]+ m- X6 Y/ n# N% [# xtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS(). o' _. {2 l) z% I
    {1 Z0 k" a! |7 b& Q% g6 B
        for(int i=0; i<vexNum; i++)' o: @$ f4 x$ g' g& _/ D
            tag=0;
    . r2 h) `6 |2 z3 |4 P, n4 D    queue<int> q;
    : o. b8 F3 a, z2 g' {' |$ n    int tmp,t;
    ' Y7 J6 O8 Q! f, s% N) l    MultiAdjListNetworkArc<WeightType> *p;
    2 B9 S! g% n3 S    for(int i=0; i<vexNum; i++)2 J! E& l" }- o! n% N
        {
    4 \& C5 {9 K# o+ G5 Y, u- X        if(tag==0)
    + V& U1 Y2 D$ @6 e2 ~/ k        {
    8 c9 m3 {7 _$ c; n2 V0 Z" I5 E$ o- s            tag=1;
    : ^0 R1 c% Z: Y9 P  w3 }            q.push(i);
    1 f8 ~! b- w; Z( W8 Y            cout<<setw(3)<<vexTable.data;# i& X  w, T& }6 k& N
            }
    " i" x# `3 P1 N; V! S7 ~        while(!q.empty())
    5 S& u8 }2 n% m$ p9 C- n% c8 G! k# J        {
    5 o/ a9 A. b* s) P% v            tmp=q.front();
    ; ^$ x4 r) y/ r( A* i7 t! g& t2 R            q.pop();+ z' ?$ h- V( d( x
                p=vexTable[tmp].firstarc;
    + B+ h+ P0 f7 P' E) F            while(p!=NULL)
    1 i, Z2 M6 ^; T; O9 }" Y5 c# {            {
    9 g4 M& x+ _- ?" ^                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);3 X- V+ M& j9 e. |3 Z& I  h& u  Q$ g
                    if(tag[t]==0)2 m0 \7 s) z' d/ z4 d. e  K
                    {: W* C8 C, z6 F% H( C2 N- Q* R; f
                        cout<<setw(3)<<vexTable[t].data;+ F9 R! q1 @8 T+ \
                        tag[t]=1;% x" |* J7 z! j$ d
                        q.push(t);
    " D% T7 q+ V4 e  V, x- q                }' q  {' C; l0 B- a3 e
                    p=NextArc(tmp,p);0 x! R, ?: w$ F; ^4 N) a% G6 x
                }
    ; k2 z# L% W8 u: ^" G' i( Y6 m) D        }
    # O3 L7 @' i, {! j6 M  P$ T7 e& X    }
    + r( l' M+ [' p, L}3 n8 N7 E: c- ]
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    5 G7 T/ X/ [6 u0 s& F1 L4 Q# ]{  ^3 S$ `5 G- @$ T7 N0 `* ^
        MultiAdjListNetworkArc<WeightType> *p;) b8 o$ O5 o- Z3 }# T
        cout << "无向图有" << vexNum << "个点,分别为:";
    8 f, f! t# n# L, t1 @    for (int i = 0; i < vexNum; i++)9 \3 A* V5 E& U# Q6 r! {8 p3 l
            cout << vexTable.data << " ";  V, Q7 g# Q9 I
        cout << endl;
    6 w- d9 w- O# f0 l    cout << "无向图有" << arcNum << "条边"<<endl;
    : H! s4 w; v; a1 X9 `( \% I: g    for (int i = 0; i < vexNum; i++)2 l& f1 d/ q5 o6 p' U
        {
    # n* i) v8 `0 a$ P        cout<<"和" << vexTable.data << "有关的边:";
    0 }- I8 {4 O: z) w: u! l" A* e        p = vexTable.firstarc;
    , N& D. U% a& Y% `  ?3 s        while (p != NULL)
    + o6 B: v* K9 R) G6 e7 k5 O        {( {" a4 |- M: U2 u$ M% }" V4 M; F
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    6 o  T! a" r0 e% E  E$ x/ h            p=NextArc(i,p);  M7 C' `3 R- J) \; e9 f: d
            }' K, l4 [- N4 D0 i* {/ ?: _3 B
            cout << endl;
    - {( \/ d' w. h. \# H    }+ V9 f2 ?9 A5 w. L! a1 P/ s! U
    }* S1 Y9 s" H! M; F. l( H

    3 r8 d( i7 c; i  A( y! B
    2 Q/ w% |& C9 d' ^* P& _6 H, I邻接多重表与邻接表的对比
    ) @- D2 X. D2 _' \( ~3 A+ i2 [* N  w6 K3 s9 Q7 x% y5 U" y5 e: s  V
    邻接表链接: V/ `' k. J: x, b; A4 j
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。' o: s) @6 h. x) ?! ^/ p6 }
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。* B. O1 |% R( T
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    . b5 U& R( d5 {; t; k————————————————
    $ ?# e' S: ]) f5 Z3 C1 Z版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    , ?* |* t# F  ?8 k6 ]$ ~! b原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    ) D3 j& V; c& h
    2 A5 i( [5 @& F% u  a. `+ c
    % l- c  Z" @% G
    * _; T5 J, j) j5 ?/ P  V0 ]/ b4 z9 J9 V+ q' d
    ————————————————
    0 [& V- q& n; G5 I  X版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ( j/ w9 {& x4 B7 `) \" x% G原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    6 a" p2 c" c3 k4 X/ A- U6 b% c# N5 g6 ?1 r+ M) |6 V$ W2 Z5 e

    2 z. G% ?* h4 Z. Z. f) v& p
    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-1-1 01:26 , Processed in 0.899670 second(s), 53 queries .

    回顶部