QQ登录

只需要一步,快速开始

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

    : Q8 k: t0 U8 n% \图的存储结构——邻接多重表(多重邻接表)的实现+ o$ B5 Y4 J/ a5 y2 r
    7.2 图的存储结构
    ; l$ R' E  `2 V5 Z! L- i7 o5 L) P( K
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist; ?- H' j. ?/ I' q4 I
    邻接多重表的类定义7 t* E# F9 m) |  l6 w
    邻接多重表的顶点结点类模板! ?0 W$ P& d6 _: G  ]" I
    邻接多重表的边结点类模板
    # g- X+ ]' n* I& A6 K邻接多重表的类模板% E' B0 D3 x7 P$ B+ ?
    邻接多重表与邻接表的对比
    0 A9 T  |0 A" K7 ?  K7.2.3 邻接多重表(多重邻接表)Adjacency Multilist9 U' l. Y) \& F& a$ L; K7 S
    + F+ y. q" f% K
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。) I; j5 r6 Q. v2 s2 C0 ?$ s  p
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。) `- n  A4 F* x, Y8 K- G! `
    ( b5 C+ j+ ]2 h
    邻接多重表的类定义3 w& i$ A/ i9 M% e5 _- o+ i
    1.png 6 s: @7 @+ M# z& j
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    & I* A, T0 l/ a9 {; t$ L' Bdata域存储有关顶点的信息;
    # x- T7 C3 s- Q/ Qfirstarc域是链接指针,指向第一条依附于该顶点的边。$ X5 q% e% Y2 C. P  K; L
    所有的顶点结点组成一个顺序表。


    : v- |$ c4 ~/ {" s7 E8 \( D, d3 e' O! E- V" l- W
    template <class ElemType ,class WeightType>
    % T0 A9 |) ]9 H; Zclass MultiAdjListNetworkVex: ^: ^0 ^: \4 a
    {
    # [2 p. Y3 R1 y6 r2 Tpublic:
    $ w4 A  z& ]- O' }9 q6 l        ElemType data;/ M% E8 B) y& z- d0 \$ T7 y
            MultiAdjListNetworkArc<WeightType> *firstarc;
    2 `3 y" B6 @+ s) H: ~9 G2 O' d) {, ^; Y3 |
            MultiAdjListNetworkVex(): [2 h, \& s+ q% Z
            {% O" z1 x* ~! V5 [
                    firstarc = NULL;7 ?1 n. \- S2 n% b+ ?! J9 m
            }
    ' [( c( ]( d2 D# n+ ^$ q" x+ V! x  `        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL), x2 k6 k' [# _; c5 ?  z
            {! ?  j- }* Z+ M: G( O1 B1 S( g
                    data = val;. R. A  ^2 Z- t% `' ?
                    firstarc = adj;
    " `; o5 ~' ^# x7 `        }
    , Z% g& g/ y- J. g* C};
    % k3 b  V) N# D: {- W6 v9 A/ a, a) j6 _: H+ C
    邻接多重表的边结点类模板" E. [! h- [/ [7 h8 U

    7 ~( N9 F6 O2 v0 o5 |6 T5 |. E1 R在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    ! S" \$ {) {: v* N# Y: Qtag是标记域,标记该边是否被处理或被搜索过;
    ( W( S7 E2 n  D* N# C* T0 N2 |weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    ( Q% K  l1 b( v' ^nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    % h" x7 S- x6 {2 v, i; wnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。" ~" @  |- d( q3 V' f
    ' x/ q  u8 j% Q1 K. H
    2.png - w8 w8 Y7 U2 m0 H& y; j
    template <class WeightType>- r; I% R" a* A) f" d& w
    class MultiAdjListNetworkArc
    9 z+ ?) c: ?9 f{
    " r4 L9 c$ U6 V. U, c  b7 {) ~public:' V9 E2 ~/ T" {+ P! {3 J' d. s2 ?
        int mark;                                       //标记该边是否被搜索或处理过
    * q# z6 }4 F0 f. {! \        WeightType weight;                              //边的权重
    ( k1 I- n4 w0 e+ X3 W  F1 t        int adjVex1;                                    //边的一个顶点' b3 Y1 c0 G3 }6 ]. a& V2 ^
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    ; i0 R1 K/ [! \" u        int adjVex2;5 S# e6 O9 D, X6 I
            MultiAdjListNetworkArc<WeightType>* nextarc2;
    2 D0 L3 `/ A5 q+ y# O
    8 K/ k  \% M: S$ T8 Z8 h# ]% B        MultiAdjListNetworkArc()! \# |. _, S: V( b, E, w! `7 i
            {
    8 M  W  Q& v  e7 A$ C" o# g' \0 u                adjVex1= -1;
    0 J! P0 ?( V% ~4 _: w                adjVex2= -1;
    4 Y( x' S2 B4 |        }
    9 \; A& x8 a# n6 h  E: ]3 }        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
      u+ X- V3 w& E2 V5 j        {
    & g" u( n* P  B0 x0 d                adjVex1 = v1;       adjVex2 = v2;, M' k0 [+ a4 J9 z- L' }9 F& r. N
                    weight = w;
    ' v8 K( h1 L- R                nextarc1 = next1;   nextarc2=next2;
    & g1 `; n2 R7 `                mark = 0;           //0表示未被搜索,1表示被搜索过/ f7 F' E  K. w& Z7 v
            }
    1 X& B7 @# e+ |1 k* w, j6 E# r" O8 g; O
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>" T$ W: y1 p1 J, w' s6 e/ @
    class MultiAdjListNetwork
    $ A7 H7 G8 y( A+ D. x7 C# T{5 y1 K) A: u  U& Z4 `# W# H) c
    protected:2 v9 `* E7 `5 p$ g% j
        int vexNum, vexMaxNum, arcNum;
    - t! t1 P5 u- V    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;* ~$ z# N# O* |% O
        int* tag;9 q0 O3 x, A, e: D: v: Z
        WeightType infinity;' {& |- H- X  Z7 k1 ^8 S6 g

    % }2 `, ], L& _, e' hpublic:/ w3 @6 k5 S4 K9 c: ~
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);% `' U6 W- a3 m3 \8 x" \
    " v$ Q; q; p: n5 \, V
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);/ _; C$ ]$ D0 v( b& K; P4 F2 m1 g

    & B$ U7 U+ I' K  L' i) ~9 R    void Clear();6 ~  e# W! x; b3 o
        bool IsEmpty()& e5 T+ Q0 O6 I- d3 Y2 U2 u
        {0 r$ o, Y% g0 e7 H
            return vexNum == 0;
    # U9 d# ^& Y1 n* s    }
    8 M- \+ w6 `& Q- s    int GetArcNum()const; W3 j6 X! |/ ]2 q
        {7 ~6 Z1 Y, N2 T2 j" w. H
            return arcNum;: m( \; Q# K3 K0 ^# u
        }/ V4 [9 @$ G8 J/ n/ S
        int GetvexNum()const
    # a" i, [" S" ~* y0 W    {
    , I" n- q  m, b" e# y0 K& B* \1 Q- @        return vexNum;
    # a; y% s$ z3 v4 y$ I. d, W    }
    # Y& w) t1 w7 C7 I- S
    1 p. q( D0 g% W3 L) c7 v
    5 d9 u# n# }0 Y6 W4 k    int FirstAdjVex(int v)const;' E. r- H: w; j3 e6 B% A
        int NextAdjVex(int v1, int v2)const;
    % a0 q+ X' O7 F0 G    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    0 X$ x7 N; o( D+ U0 N" z) \    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    1 h! F6 @6 @3 B; b
    # m. F' E" s8 n* X# j0 r# X# \5 M    void InsertVex(const ElemType& d);
    % h4 r% K+ s0 G" j- h    void InsertArc(int v1, int v2, WeightType w);0 E$ ~7 I! q! j# z+ ?
    ! H4 C6 l+ R. Y$ H6 P+ r' u
        void DeleteVex(const ElemType& d);
    5 F5 {- H8 T4 ]" o: N5 W0 s; L    void DeleteArc(int v1, int v2);* j; C+ r. M6 B4 G. c# {8 G
    4 Y+ n& {1 I* Y9 `0 p
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    + c( d! ?1 h8 ]* _* e# k- h2 R    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    $ H  E: O: {4 w7 l+ ~4 [( P$ L4 s, b$ I0 U
    - h; z2 N2 j6 ~    ///深度优先遍历
    1 p, d: d9 d! m% V5 U3 L    void DFS1(const int v);
    & f( T9 z5 ?' R! j. r9 N/ V    void DFS1Traverse();7 L: v% b9 A. Y+ z; t. }
        void DFS2();
    " m6 Q9 q5 _! {: f6 `: A, Z
    * h! z$ Z. u0 `9 A' D    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    5 L5 S8 v) v9 W$ M. Z* f    void DFS3();, i1 |- b! c# t
    2 \! U" }" D7 g& T4 Z6 t2 }
        void BFS();0 Q2 ^' I% p) Y' Z
        void Show();* X/ h9 f# ?: M" g* Z8 M
    };2 S- z% i- }3 M1 I# |
    ! a8 E$ X$ \, W0 g/ p
    2.函数的实现
    2 T6 ?4 t2 a6 _) s. Y研讨题,能够运行,但是代码不一定是最优的。
    / K% W5 x2 \( m) J% ^6 r6 C. a* U" G8 E9 `6 y) o
    #include <stack>
    6 d7 |- n8 i0 W: G/ C#include <queue>
    7 w9 U* ^, z7 Y( `, A
    ' Q& G- z) }- B2 g9 ftemplate <class ElemType,class WeightType>
    5 f$ F3 s( K( a6 p7 F4 [MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    ! |! M* t- f% K, }1 t* A+ \{! C/ A2 W9 I4 D" {9 ]
        if(vertexMaxNum < 0)
    % l5 Y5 t6 T  I+ w        throw Error("允许的顶点最大数目不能为负!");
    - F# R6 |# y4 y% W$ c    if (vertexMaxNum < vertexNum). o; X% W! s, o, I( ~$ P% A3 |. S, I4 l
            throw Error("顶点数目不能大于允许的顶点最大数目!");( L9 z* }3 k: q+ H
        vexNum = vertexNum;
    & G# G7 p9 @3 L7 T( }* a    vexMaxNum = vertexMaxNum;1 z1 ^4 A, p$ `& x5 `: j/ R
        arcNum = 0;, W/ l0 H8 k' l9 \4 W, E( h
        infinity = infinit;
    ! G" J7 x" K. O    tag = new int[vexMaxNum];
    # N. }1 a1 ]* y/ o# }    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    / R+ H6 ], K5 M' F    for (int v = 0; v < vexNum; v++)
    0 |. m5 ?% ~# O, J* o; h# l    {4 h3 m$ {: s" G2 w
            tag[v] = 0;* a3 |4 ~( g) O5 ]2 X: S9 O* F
            vexTable[v].data = es[v];
    , [( o% Q1 P8 F. ]        vexTable[v].firstarc = NULL;5 ]8 y0 E/ y+ ^5 x7 G( j
        }
    + ~; g* ]  T# B" k}; a8 X* m2 j4 K5 V. d" X
    template <class ElemType,class WeightType>$ m9 L+ Q1 P  Z6 n% }8 s
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    * s& h3 X$ _% E$ ~& [{
    ! n0 P5 Z8 C5 C2 z# |: t. `5 }6 _    if (vertexMaxNum < 0)
    1 u+ M! V* J6 U) M+ f% |! r/ l        throw Error("允许的顶点最大数目不能为负!");
    , Y) t; b- ~1 n, G) ^' S9 d    vexNum = 0;- w# x2 N# D6 W
        vexMaxNum = vertexMaxNum;! q' B8 j- M' b" k! P# J5 X% Q
        arcNum = 0;* R! `- ~! u: G' `" Q! d
        infinity = infinit;
    9 b/ F! u& U4 O; b    tag = new int[vexMaxNum];4 G5 P% _4 P  b
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    5 D" }3 t* e  c5 q) u' D}
    5 \7 x) t* d* x# y. {' e( wtemplate<class ElemType, class WeightType>/ `* G* }* R% s5 X6 \  U- F, r
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
      S" m1 \, ]" U* F{& v+ o$ O! f( f5 A
        if (v < 0 || v >= vexNum)+ h; j& L" f7 c+ u! \. G$ q
            throw Error("v不合法!");8 O" F' h( E- r3 w- ]& M! K& f
        if (vexTable[v].firstarc == NULL); ~/ @5 q* \0 H9 a  j) B
            return -1;
    6 ~( K* \) J* C, [* W3 X2 o    else& F7 Q/ H9 V6 T* u
            return vexTable[v].firstarc->adjVex1;& p) b, n0 S* I. A+ ]# O8 F0 x
    }
    8 h: s, R. g8 O6 _7 i# a' X. q4 F9 u$ C0 h5 P$ M2 ?' z
    template<class ElemType, class WeightType>
    + q$ k$ f6 y1 \! r$ t  x( kint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const, h+ n# a) `5 i: N" `
    {" Q1 [1 n# }. i8 k3 C1 M& {
        MultiAdjListNetworkArc<WeightType>* p;" P/ f+ \( d& O' h6 a; B7 j
        if (v1 < 0 || v1 >= vexNum)
    ; U4 m: Q7 i- f: b! ^; e        throw Error("v1不合法!");
    $ g% n. \0 V1 p3 Y, E/ w* }4 o# o9 `    if (v2 < 0 || v2 >= vexNum)1 Z3 L$ |: m5 J1 K
            throw Error("v2不合法!");
    , y2 @# j9 U" ^. o: }1 I, u8 u7 J    if (v1 == v2)
    , ^& o; g- ?, U# w* A$ P        throw Error("v1不能等于v2!");5 Z! m- \7 ]  v2 I8 w+ x1 \" }
        p = vexTable[v1].firstarc;5 p- o$ D' Q) @3 M" _3 H/ {. U% J
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)5 n: ]9 k9 _8 p8 z5 C) r
            p = p->nextarc;/ m  X5 V. [, V9 ~
        if (p == NULL || p->nextarc == NULL)1 j* o/ A6 C' M5 t
            return -1;  //不存在下一个邻接点9 [' j+ c; y2 v8 L, Z' S& e
        else if(p->adjVex1==v2)
    7 ?) l) j! G3 r2 ?! r; d; i        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);) V! y1 \% j4 Y% g
        else
    $ N% F+ t* U" F! X9 Z5 w' N        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);# U: I$ L, e$ z5 Z3 z; a' c/ X' G
    }: u" O. P6 O( x% g( A% H: m
    template<class ElemType, class WeightType>5 n  w3 b4 M1 n7 X
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()
    9 n, R2 D& S) B2 ]{& t2 u) O- ]! S+ g& _% x" I
        if (IsEmpty()) return;
    9 a& T; t7 q) k  {$ D  N    int n = vexNum;
    9 o) s9 V; h1 |; d* h8 J9 X3 t" w    for (int u = 0; u < n ; u++), H$ h, y; x0 g; a
            DeleteVex(vexTable[0].data);( b4 b+ t, J! |: R4 |" y& b/ y
        return;
    & I) W& D: c1 o! G% @}+ q5 W7 J4 Z! ^3 {
    template<class ElemType, class WeightType>
    / H; J' R$ Y- _1 ^6 n& {; \6 z' g5 aMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    . g/ C  `5 P# N4 }{, p. w+ G* k/ v* E
        Clear();8 V: v/ l# {8 Q" Y6 B& Y' c
    }
    ! o4 V& L8 P. K1 \. F( C6 rtemplate<class ElemType, class WeightType>5 S$ _6 a% M3 r. F4 v) Q  p
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    : g3 G2 i0 ^  H+ u# U+ r/ p1 U# _{
    % O1 L% o% Q, X0 l$ g    vexMaxNum = copy.vexMaxNum;
    * B6 X5 c" H+ L2 c, K    vexNum = copy.vexNum;8 o, e* u" I" q3 W7 m% t* M
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];$ `: n* V$ L% x2 z1 b, [
        arcNum = 0;1 |0 _- f* r# u
        infinity = copy.infinity;
    ( H" o, u7 k. a% a9 J( v    tag = new int[vexMaxNum];+ i+ |# J; n* ?7 i2 |! Q3 U! P/ ^

    ' L$ ~0 l9 ~$ @4 g2 \6 z) ^7 k    for (int v = 0; v < vexNum; v++)
    # C% D# j6 B7 R' [/ x: _    {
    * G! I% V/ {2 s& F* @        tag[v] = 0;
    ! M; V& e8 s0 x- W8 l+ Z5 `3 v        vexTable[v].data = copy.vexTable[v].data;
    - @+ y, N) ^/ v' E! B9 V        vexTable[v].firstarc = NULL;
    / q+ o: w% y" [) J# R& \1 i2 A9 t2 M    }
    4 o. F1 K; Z# _0 Q: r. r* E    MultiAdjListNetworkArc<WeightType>* p;8 L' l4 `3 ^  X/ r. Z' e
    ; F1 G% B, b/ L: C
        for (int u = 0; u < vexNum; u++)
    ( K( d# v* C4 T" W    {5 j' w, o  f  S: h
            p = copy.vexTable.firstarc;
    , U$ K8 d5 x8 m& L- W: X2 V3 Q        while (p != NULL)! D6 e1 o+ b, S/ A0 M; H
            {+ I* A& j7 r  [/ i) B" j
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
      U: v& l( d9 c/ |            p=NextArc(u,p);
    ' J& ^* ^- ~3 y2 M/ ^% N  V        }
    $ C* I5 Y6 Y4 ]: h1 P; Z    }
    * C' \+ e3 r. L( F, d% e}
    9 W/ X/ X" j3 a4 T. [6 `1 Ntemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&5 g+ H+ f; v5 U- |/ }; S
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)4 }1 [: g! p( N" H. _6 _
    {# V! v1 m* _: V- O% T! P
        if (this == &copy) return *this;
    * k# f8 f, K# ]. N    Clear();# o5 o. r/ n) d6 z9 W& y, I
        vexMaxNum = copy.vexMaxNum;1 L3 V  j3 k$ Q, D1 ^
        vexNum = copy.vexNum;
    % [3 |. K  J; e) B+ Y; f    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    : [& v8 h+ N6 {2 g! i/ T: ?    arcNum = 0;
    + w5 P- b* [4 |. r( f    infinity = copy.infinity;
    5 v5 A8 J; g  [8 r5 K. L/ S    tag = new int[vexMaxNum];: U9 k2 e, h8 e0 Y- t2 g
    3 c- C1 X) M+ C( H% L
        for (int v = 0; v < vexNum; v++)) D& _* j" L: Z: A. x) j, i; d
        {
    ! K, C7 }, S9 j, G        tag[v] = 0;( o  p9 \5 W9 }& T* E. V/ M
            vexTable[v].data = copy.vexTable[v].data;
    5 |) ^+ V, ~+ L4 D0 k# G8 |        vexTable[v].firstarc = NULL;3 u% Y7 q0 y. S6 F+ L) C
        }
      s/ k! J  H  p    MultiAdjListNetworkArc<WeightType>* p;
    ' B4 O+ i2 t+ q" w0 h; |. O
    3 o4 d" z, s9 d+ x+ \( \    for (int u = 0; u < vexNum; u++)
    ! F+ ]- A8 r7 Q7 D$ }; \8 L, p    {& s$ H, u3 X  M% h7 _9 S
            p = copy.vexTable.firstarc;
    0 `) p# V- d3 W* f( N        while (p != NULL)! l+ x" \7 X3 @) C
            {
    0 w6 Q- a" M- N" ?5 W. i+ N            InsertArc(p->adjVex1, p->adjVex2, p->weight);* N# M6 v) [& y3 W+ q/ W: W& x
                p=NextArc(u,p);
    ' i! z$ c9 c6 k4 e0 I8 x        }  x; W' O3 C0 A! h5 I5 A
        }3 n2 s- p) y5 E' D' q' H; Q
        return *this;
    ) A7 q6 y% n/ G7 E, T6 u}0 x* C, k& `5 J7 a( S
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    / r+ C' h# d7 @7 I; o" H8 OMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    $ U' S  }& M" b{
    # W3 n( a: q- h8 t1 r+ W    if(p==NULL) return NULL;+ M4 ~7 ?3 W. G  G, K
        if(p->adjVex1==v1)
    4 B) ?  H9 X1 q* y6 |        return p->nextarc1;
    9 Y# @  u$ d+ r5 E    else# S* D% E: k+ h/ V
            return p->nextarc2;1 ~% K9 p5 F3 |8 G* U# G4 U
    }% I+ x- D% u2 X1 }0 c, q
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    8 E; u4 k; P& X- m4 g' sMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    6 b8 E, ~+ ^* W0 I: I{6 L8 l/ c: O6 D9 u, a: g  A7 Y
        if(p==NULL)return NULL;# d1 j- X. N0 k$ E! Z3 C, v) {7 |
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;8 {+ E" o7 J0 \# w% I8 H
        if(q==p); A, A5 `0 b  F! q+ P$ Y4 O; R( e! x8 Y
            return NULL;
    6 j) A8 \+ v. b* t2 L    while(q). X1 h' d" g/ h; n. ~4 m1 l$ d, B
        {/ X9 f: M+ ]5 d, ^* a- F6 O$ _  g
            if(q->nextarc1==p ||q->nextarc2==p)
      M3 b- T* l+ Y, m( Y9 ]            break;% G) ?& N% Y% w" X4 c0 P. u
            q=NextArc(v1,q);
    9 F5 S& ?  ]: _. J8 O. L* ^+ d7 ~    }" j) e- Z; Q3 a5 z$ V, F
        return q;
    6 S" d) I+ m! f9 w6 z/ c}0 \% m9 Q, g( s
    template<class ElemType, class WeightType>
    6 u3 t; ^* o$ c3 u1 b& ^* x; Q4 Qvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    : `3 i  G" }, }6 T6 }/ I- p; j# P{9 J. i% Q  r& g5 A, f8 a1 ~
        if (vexNum == vexMaxNum)1 ~5 f4 ^; U2 c4 c
            throw Error("图的顶点数不能超过允许的最大数!");
    9 z' \  H8 j7 X) r( N8 y; i    vexTable[vexNum].data = d;$ A+ C% g. ]+ @2 R& g' p
        vexTable[vexNum].firstarc = NULL;
    " I2 }! [+ O/ G0 f  K: J    tag[vexNum] = 0;1 N/ m& Z8 D$ m: q' y
        vexNum++;$ ]8 p- W& b/ {& @* v6 c
    }9 r# x4 {* F% T0 j0 w% q. p, q% b2 |
    template<class ElemType, class WeightType>
    4 k! q: d+ E7 X+ I' ?  x( E9 q* pvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)$ D) X. h& y( [  D% m
    {! ^2 u, q: U% |. [, y
        MultiAdjListNetworkArc<WeightType>* p,*q;# c2 j6 ^5 h$ Y5 w" Y
        if (v1 < 0 || v1 >= vexNum)% A7 x  ^% A$ d* K0 `
            throw Error("v1不合法!");; J2 |+ G8 Z% L! b
        if (v2 < 0 || v2 >= vexNum)
    1 v8 {- ?7 ^4 k$ e% p9 W        throw Error("v2不合法!");' |/ a3 S/ z3 g$ M9 y' V& D. |0 c
        if (v1 == v2)
    9 c" |; d9 m0 ^/ g        throw Error("v1不能等于v2!");. j" Q. h3 S! ~( q; x
        if (w == infinity)
    ! X, E# p* Q( E1 Q# |( I: _  R        throw Error("w不能为无穷大!");8 }% E$ Y9 q) V; B- E0 _5 `# `# I
      b: E. O) M7 k" e1 G4 K- t% y

    % d8 O6 a7 E  j: W. a  X# A7 z+ [, q    p = vexTable[v1].firstarc;
    4 K# a5 E6 U5 j7 ]3 A    while(p)
    9 X, k/ v; r. [0 f* \+ r    {
    ! H4 r. U; E) |; t5 b( ]8 H+ [        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中. ^0 j$ n- M( a& `  r5 @) E# [
            {# j8 V9 r9 @1 x& a) T1 @. }
                if(p->weight!=w)
    & E+ y$ {% m8 T+ k8 l! J: Y( M, L; p                p->weight=w;; I$ L( X4 d. G) l$ C
                return;
    , ?  m$ w+ W2 u# }* n  X8 k7 y        }4 S( q# y9 @# P2 Y! h" t* v" q8 h

    ( p( [) g, m4 z$ t; m! i# y) ~1 U        p=NextArc(v1,p);7 h& P. t5 i4 B$ `
        }' ~# d$ h. R& O
        p = vexTable[v1].firstarc;
    9 `, O1 p5 ~& l2 ~4 v. H* y    q = vexTable[v2].firstarc;
    3 D* {9 v* M) s, s( J6 g0 \    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法% J9 ]; C4 C" S/ l& ]% C* P6 K0 E
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    5 {& d2 _' F; _* Q0 d7 p. v  o    arcNum++;. r5 l! [- C7 t! i# e5 Z+ p9 ~4 T' D
    }
    : T8 B: \! [& O  I0 O: A2 t: [2 l9 ?. O0 W
    template<class ElemType, class WeightType>2 g( k8 x. ?& d4 i
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)8 M! X- o% B. a) e
    {$ v; x  W$ `- ~
    7 u1 k! m9 ?3 c* _1 c% l+ t, X
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;! ?: C7 D: w- x4 A$ u9 Z
        if (v1 < 0 || v1 >= vexNum)9 w# X6 F- R; ~' k) v
            throw Error("v1不合法!");
    + k" C2 v' @; H5 [$ p9 g1 T0 K    if (v2 < 0 || v2 >= vexNum)2 T/ S4 ~& g" D# D6 q, h' s
            throw Error("v2不合法!");
    4 V: Y3 ^1 I) g% }    if (v1 == v2)) H, |4 f, s" ^% E( e" Z! |9 c
            throw Error("v1不能等于v2!");% L2 I: Q: I7 u" t5 x
    ( ^/ P& n2 ^# x0 g( j
        p = vexTable[v1].firstarc;5 o# n% y% s2 \# G( D* s
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    : R$ @3 I+ |' P  p# [    {
    $ g6 J" A6 x1 {% H7 f, T        q = p;6 w4 J& n3 t% @  f
            p = NextArc(v1,p);
    , j$ Q5 }) p& b- g9 f0 M    }//找到要删除的边结点p及其前一结点q* [$ _; b, I# x
    7 U* t% m- X# P% e; e  x
        if (p != NULL)//找到v1-v2的边
    4 r* R. ?- j) _1 K/ i& j# r# S0 a    {) h1 a% j7 h% t% E
            r=LastArc(v2,p);
    # o) r: N% }3 G- c" ~: H( Q        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL5 o+ A  U2 x" y, C/ k2 v
                if(p->adjVex2==v2)
    ) s. p0 O# N! ~6 g) G7 B                vexTable[v1].firstarc = p->nextarc1;
    9 ~+ Q1 s8 t: b' c/ p/ B9 \            else vexTable[v1].firstarc=p->nextarc2;1 K! P! A! w3 N5 S7 h! C& c
            else//不是第一条边
    1 ]; E( Y6 d- }; f2 e  \        {
    ' |9 o$ ]) ?+ Z. P( K' F! e            if(q->adjVex1==v1)
    : q5 p, r# b/ i4 e8 E                q->nextarc1 = NextArc(v1,p);
    7 H! R8 |: g1 X7 u: e" ^) d$ G            else
    6 b0 f) _$ U( k5 h: Z1 l  G                q->nextarc2=NextArc(v1,p);
    3 r: E, [* {& w( G4 K  h
    ) v8 d5 L; ]- Q, g  g8 S- ~6 i        }
    - v! ?) {: }( A5 E        if(r==NULL)  P9 S; w5 ]% N
                if(p->adjVex2==v2)1 b! r1 m9 {) M$ h5 f
                    vexTable[v2].firstarc = p->nextarc2;; Y" u/ |; U4 G7 q$ U4 D' }& f
                else vexTable[v2].firstarc=p->nextarc1;9 q) Y+ q9 ~& c" K, I9 x" f
            else/ X: U- |. t- U6 ^; M
            {
      ^7 K. T, M6 q+ g' \1 v" i            if(r->adjVex2==v2)
    : Y+ \" [2 [8 r, P: o$ ~5 u                r->nextarc2 = NextArc(v2,p);
    & `& D6 \; }" v3 I& t) M8 t$ c1 s- W( ^            else" k8 G6 }; K' x
                    r->nextarc1=NextArc(v2,p);
    4 i) d& [( X: @8 y" |4 F        }% E' p% @! h3 i, }5 G4 R! S6 i- |0 `
            delete p;
    ' H% f+ Z1 U" j6 J) A6 U; f        arcNum--;" ?" ]3 G/ J! X7 g9 C* h- R
        }
    . s6 _& j4 Y9 U5 `5 ^1 s- e
    4 B6 |) G3 O9 Y3 Z}
    " f9 w1 g1 G! Ftemplate<class ElemType, class WeightType> void6 x) g7 E: b* q+ P5 Z. Y
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    / Y& W/ E% Z2 |% y5 i{
    9 Q0 T1 P# P% X  {  B! k( Q    int v;
    5 y/ L% f' H2 s6 h8 c    MultiAdjListNetworkArc<WeightType>* p;
    " F8 o. b- O- s    for (v = 0; v < vexNum; v++)//找到d对应顶点# C1 V, w$ K8 P
            if (vexTable[v].data == d)
    & N4 e: V, m: j* W) V( V; p            break;
    , d7 Z9 {) d' I$ F    if(v==vexNum)
    % |# q6 \2 S" @/ A3 V' T& U        throw Error("图中不存在要删除的顶点!");; p2 F; v4 S/ A

    # `/ I5 t( D, W/ D1 x8 o7 W( j6 ^. T    for (int u = 0; u < vexNum; u++)//删除与d相连的边
    ' D" Y  ~8 a9 e: j9 o& `( |        if (u != v)# n( o" j& T! \$ K, u! E
            {. Z! D6 `! o/ E3 I
                DeleteArc(u, v);) R7 X1 M3 p6 k9 N' i
            }
    " y5 h3 K, \: v4 k' O+ S2 O    vexTable[v].firstarc=NULL;
    ; b. X% B- @! k" S
    # ^9 \) v1 \: h3 l( F    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置& a4 ]$ F4 R8 v" D0 s) _* O
        vexTable[v].data = vexTable[vexNum].data;- e. g! A% t8 L+ Q6 E
        vexTable[v].firstarc = vexTable[vexNum].firstarc;4 I% S1 t; ^; h4 Q* b5 S: v
        vexTable[vexNum].firstarc = NULL;# Z4 C0 c  ?9 s* t( W( a
        tag[v] = tag[vexNum];% Z6 d' }9 q+ K+ V2 L! F+ S
        //原来与最后一个顶点相连的边改为与v相连
    : j4 \& O- h. F7 [* P  F    for (int u = 0; u < vexNum; u++)
    ; d# F9 E' g. x, M    {
    6 U; ?6 g' k# x" C+ \        if (u != v)0 R; u$ u5 M' `
            {8 a$ o1 E/ Z2 E: ^2 k! z; {
                p = vexTable.firstarc;, K% i& z, `, d8 V
                while (p)8 I, S; @8 I8 D9 N1 s; x! l
                {, X% {' W* ~+ o+ |; T
                    if (p->adjVex1==vexNum)/ v+ y: u; R/ g/ J, H! ~
                        p->adjVex1= v;! @: e! ]- r6 b" D. i
                    else if(p->adjVex2==vexNum)
    9 P5 c$ Y8 P( X  J                    p->adjVex2=v;
    % e) ]( F& r1 p9 R5 v$ D                p = NextArc(u,p);
    ( A3 K! q& ]2 [, l9 v9 f            }" a' H  c6 m$ f3 g7 t7 k8 J
            }8 n6 e* h5 d; {7 E7 K; @% b9 V
        }: J2 ^5 U! h0 J, k0 _
    }/ L% Q7 }2 u  S$ H. C- J
    ///深度优先遍历; m: r5 f  q. }! w  a' I' S* C- O
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)1 D) s& r- ]: H+ R& C
    {, E( V# C1 C4 G6 C
        tag[v]=1;
    # L6 \: S6 f$ Z; ~    cout<<setw(3)<<vexTable[v].data;8 P# `6 [9 g3 d$ f4 F% O; N
        MultiAdjListNetworkArc<WeightType> *p;  i  Y( a+ w1 B5 k
        p=vexTable[v].firstarc;$ {/ Y1 P8 [2 J9 t9 {; R  w
        while(p)
    % U* M8 ]" ^9 ]# A8 d1 D    {
    # O. d8 Y% b/ W1 m% }& _* ^- m        if(tag[p->adjVex1]==0)
    3 {9 k( z3 y! T3 |8 p3 d. Y            DFS1(p->adjVex1);
    * v* r) b- s0 Y8 l+ q        else if(tag[p->adjVex2]==0)8 L( ]! u3 D: x+ s
                DFS1(p->adjVex2);% J/ \7 @7 y0 t4 G$ x3 d# ~9 u
            p=NextArc(v,p);1 L; d! p. Y1 V9 g, a; _( e* L# R- `
        }5 h) p( }+ q! N& x
    }
    5 x1 {' p3 f% G% J( @template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()2 L) v7 s8 e4 s& {2 d
    {
    % c& m9 Z" ^! v8 H  o) {! ^  ~    for(int i=0; i<vexNum; i++)
    3 @# K9 U/ G# _  t& Q5 b        tag=0;3 _, J5 R, r" b# H: p
        for(int v=0; v<vexNum; v++)% H9 {* l' k7 l/ g6 f' ?
        {" ?0 U- f& K: Q5 R- s/ q0 c5 ]: v5 X
            if(tag[v]==0)
    0 z) D. i8 h' ], Q) x9 L            DFS1(v);
    * _7 D+ B  `# T- a9 y1 B/ S6 q    }4 e( Z; q6 s$ ?9 B3 D" a$ Z( M0 q
    }# w+ _) b' J- D7 B  V" J
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()' O4 p9 c* i, z  u7 d
    {! x! ~; w! u! x2 j- @  T
        stack<int> s;
    5 ?* N" S/ X; F6 \  g    int tmp;" x: a0 O9 v; B. |3 T
        MultiAdjListNetworkArc<WeightType> *p,*q;
    ' B: w6 p0 _. W+ c8 s. T    for(int i=0; i<vexNum; i++)
    " f% H4 X9 a* z3 q6 i        tag=0;. S1 Y" N. j" _, a% x
        for(int i=0; i<vexNum; i++)# v* u* b% h- y% j0 j
        {+ W# S, |- d% P4 [) \% ^/ `+ {
            tmp=i;
    & |7 ~) V2 Y# ^' K! V0 S        while(tag[tmp]==0||!s.empty())- U$ S6 S* n4 U9 ?
            {3 U7 w; o/ ]- _
                p=vexTable[tmp].firstarc;
    & j$ v8 }9 x6 f# K            while(tag[tmp]==0)
    $ `5 [' }) R" _            {
    ) N1 Y# K+ _- r% r% }9 r- V/ x# h7 n                s.push(tmp);# N6 {' H# z! i
                    cout<<setw(3)<<vexTable[tmp].data;
    * r  r2 R( i% p                tag[tmp]=1;
    6 r& V! T+ K0 m5 u0 ]' z                p=vexTable[tmp].firstarc;; g) K; {# i6 n1 _6 D
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for- @" r& y% z1 H3 J' r$ L
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    5 B% L/ N; E) m) _: \, V                //cout<<" 1st     tmp="<<tmp<<endl;
    * T: V9 q: }3 G0 J            }
    + m) j4 g0 ?- ]            if(!s.empty())6 X+ f9 D. Y. _
                {
    # k' X1 L: p+ i* ~                tmp=s.top();
    + s8 g" h- {% Q0 f                s.pop();
    ' s; K* C* H8 v' W                q=vexTable[tmp].firstarc;
    ! K/ q3 x$ S& t& [9 d  a+ d+ n9 ]                int t=tmp;+ b$ X' x& J2 V. H
                    while(q&&tag[tmp]!=0)
    3 U" @4 n/ S0 d( r" A                {
    . y5 M" B3 s0 l* g" n                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);0 v: `% t0 Q: ~$ ~1 H! i
                        //cout<<" 2nd     tmp="<<tmp<<endl;
    " q4 |: i- O8 m. s1 e                    q=NextArc(t,q);
    + ~9 _, i& g' G  Y                }
    7 v# X! O: Q  P1 W. w/ ]2 U                if(tag[tmp]==0)$ n" y0 H8 t4 v. g7 k% O1 n
                        s.push(t);
    # z  }1 \) F7 y( C                ///1、对应上面连通分支只有1个点的情况
    * B* [$ S. A7 i% j" H" b6 @$ f                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    % h' z8 R) ?6 J) D8 [                ///tmp要么等于找到的第一个未访问节点,/ V0 a9 Y0 L# o& P* `/ g
                    ///要么等于与t相连最后一个点(已被访问过)% f- B" W- u  D
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点) k3 l) U7 \8 f( {# e4 q- o
                }
    ; Y* l& [4 Y2 M' D1 r) `8 y6 T        }
    % f8 Y2 H: \2 ^/ x1 u" }& |* f( g    }1 _( N# a' o, p: r  j4 T$ |! a
    }
    7 S& m' A4 j1 B6 ^2 i//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    : {* \$ z/ U1 p. r' w* Jtemplate<class ElemType, class WeightType> int  F8 d: [  K2 T8 e# c2 k0 Q
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre): G9 h2 m6 k! x3 _$ z. l$ n' {( O8 W
    {$ e$ w& ]( ~$ s5 E
        if(head==pre)
    5 v- P1 t1 B, S1 H        return -1;
    2 G9 }$ f& r* J2 C. S: k5 C& k  U& i
        MultiAdjListNetworkArc<WeightType> *p;
    4 |) y3 ?# U+ o    p=vexTable[head].firstarc;
    ; I; L0 }+ V* n2 f- N  K    if(pre==-1&&p!=NULL)1 ^* `6 u7 u6 a5 g
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    ' i+ V! Q& x1 p/ O( V    //pre!=-1&&p!=NULL9 T, |2 y1 b) _1 r
        while(p!=NULL)
    ! Q! z; x# v: d! s# v  C8 ]    {5 |( Q; S/ u2 M
            if(p->adjVex1==head && p->adjVex2!=pre)# N/ K# w* R+ R% I, Y& b5 S
                p=p->nextarc1;
    ) }3 t2 c, O1 e5 ?+ x1 m2 v) a6 _        else if(p->adjVex2==head && p->adjVex1!=pre)
    2 k4 U/ R, o" J" a            p=p->nextarc2;
    1 {; J3 X! |; _4 d+ K        else if(p->adjVex1==head && p->adjVex2==pre)7 ^7 h( E% H2 m+ G" ?/ r
            {
    ; e  m7 Z+ M% D! o0 p* w! V% u            p=p->nextarc1;4 d3 H  V- g& b$ \) G6 M* |
                break;
    . @* {. T( w/ I. L. O* P% `        }9 o, K) }( P4 \3 b2 @- Y
            else if(p->adjVex2==head && p->adjVex1==pre)
      a8 B+ l* }3 b$ i+ X) K# L        {
    - Q6 S7 u4 {" z            p=p->nextarc2;. ~6 }# J/ K3 O1 Y, G* f& V5 {1 v
                break;3 [. b6 f) q9 L
            }1 @2 y% ~& `3 C& e
        }
    / |/ }, B# z" G3 {! f4 W    if(p!=NULL)
    # B' r. }' l- B) _    {
    % e& m' Q, I6 f        return p->adjVex1==head?p->adjVex2:p->adjVex1;) Q  y3 p$ h6 m1 |6 p) b) t( ^
        }# [9 P0 s! `( H; S+ a  n
        else" D4 _% t) A; |9 O" A
            return -1;$ l: E: _' n( D. U  b( {
    }
    1 q* d& G8 w  K8 i! w8 y, a7 z
      ^3 T( x+ T$ q# C
    - {. b' t) V! @$ F/ ytemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3(). B8 _, `4 |3 s  \6 ^* i' |
    {
    1 C( R. S. Q3 z. E0 |    stack<int> s;$ v- n# j9 l  u8 W. v4 \8 K0 }9 a
        int p,cur,pre;$ z0 Y, A/ \5 X) K0 D9 ?; ~2 N
        //MultiAdjListNetworkArc<WeightType> *p,*q;( ~5 N* K' h# j2 X8 f. y
        for(int i=0; i<vexNum; i++) tag=0;//初始化
    . f1 a0 Z/ j" W" [0 [' N' z6 U9 h( T- L* w. o
        for(int i=0; i<vexNum; i++)
    6 u7 ^' q4 j; j9 O* [& u    {
      C3 b# s+ C0 B        cur=i;pre=-1;
    ) L/ X8 F% a8 ]! d        while(tag[cur]==0||!s.empty())6 T/ @: q+ o$ Z5 @  o
            {
      I0 a7 k4 ]) U6 B            while(tag[cur]==0)
    3 B0 K1 M, d" S5 Z            {; w& t3 G" O3 ^& p4 }5 e
                    cout<<vexTable[cur].data<<"  ";
    : q2 L+ J7 h/ [% n8 x                s.push(cur);
    4 r5 y/ B, @( ]! _                tag[cur]=1;# ^1 C+ w& {! J7 J7 u/ r2 o
                   //初次访问,标记入栈  ^6 X) Q4 A/ V

    ! F3 g2 I! N0 f0 n               p=GetAdjVex(cur,pre);//p是cur的连通顶点, t7 [+ J* }% X& f( W* z
                   if(p==-1)
    , ?$ s, v  {; w' [7 \               {
    3 K+ |. F9 a* d! A                   pre=cur;s.pop();2 S' M7 p- ?( j% U) o% w5 J
                       break;
    ( V# s* d8 Z6 h# b4 Y( d               }; y# D# j( _' j2 p* M% Z# w
                   else1 Q' X7 g5 L; a; K1 |' P
                   {
    $ X0 y1 a) @: U                   pre=cur;
    6 C8 S" ?7 P! H# Y4 G                   cur=p;
    3 u! n* N1 _5 g- }               }
    % V! s# B7 n- t* Z- u8 a5 q6 u
    9 u9 K( p: }6 N6 M" m            }
    ! X# O; E# T3 [" T            while(!s.empty())' W( q* _* e& @0 L6 C
                {
    . |, c+ B8 i& u& A                cur=s.top();
    # ?- i& E: x3 \* h  c5 n4 C7 Z                p=GetAdjVex(cur,pre);
    3 F6 `5 _& ?8 w' a2 q                if(tag[p]==0)
    + ^. J& K* v7 _$ k                {1 j# d4 U& \7 o& u( C! L+ A) y
                        pre=cur;, r! y' j+ r* V; ]  l4 O8 ]! J' f
                        cur=p;7 s% P# ^, y5 U: Q
                        break;6 s. a  E# u% P! _5 c+ _6 y
                    }
    4 j" E+ ?, Y0 _/ O                else5 E6 Y  b9 m7 M# z
                    {
    9 \. H  {+ ~7 ?6 e' g$ l" i8 ?                    pre=s.top();
    . m8 S. z* s2 a: _( j, a                    s.pop();
    & A! H( L/ @: H: X2 B4 U6 g                }+ K4 O( l0 x  }4 i8 X) ~& I

    . F# c3 o: Z- Y( Q8 k& \* Y5 W" N            }
    $ `$ Y) E, U+ a$ ]$ F; i/ s8 Q* V3 L
            }! r" ?7 w2 W7 |4 x
        }
    + q  Q. P' O3 `& K  U3 v& |  k}7 s% n0 h4 f4 Y
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()* O* o4 q9 Z4 \! ]7 @1 M
    {. N% f; I$ z2 h) w+ ]5 e
        for(int i=0; i<vexNum; i++)
    0 x6 [; P# y1 G5 y# j% h% _+ [: Z        tag=0;
    4 x: s$ j+ v$ }7 L! r" ]3 w    queue<int> q;
    0 C$ K* V; @. Y- ~) h    int tmp,t;
    1 R# W  a+ N) x: f9 I    MultiAdjListNetworkArc<WeightType> *p;' x% f, x! h6 ]
        for(int i=0; i<vexNum; i++)
    1 z' Q; N3 ~6 d, S5 G+ j+ h) J" c, q    {! Z9 t. q8 T0 S4 G  u- w" i
            if(tag==0)
    ( F& w  \- M, Z, i4 R! Z4 F: L        {
    " D$ J, W% G' M6 K9 J5 c  l            tag=1;
    + `4 k, ^1 O0 z8 g% \7 h. z# \3 d            q.push(i);$ M* L* r. B/ q$ |( z% a% {$ t& R
                cout<<setw(3)<<vexTable.data;5 l& z6 _0 i- Y  k& J4 U5 Y
            }
    6 E6 i4 L- t3 [6 ?) e* _        while(!q.empty())
    + ]: \! E: d, I        {4 @, D; [& B& j! I' s9 K- s
                tmp=q.front();
    ' W+ Y1 I, [8 Z3 g2 n) J            q.pop();
    8 R' p/ }9 F! |            p=vexTable[tmp].firstarc;
    - i2 a9 }2 v3 J* h( Y            while(p!=NULL)
    & b, i7 O- y* n            {
    4 W9 K: I6 T, V. x+ t2 L: B- ^                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    ' \( Z' m5 S0 [/ J. B, r                if(tag[t]==0)
    6 H( ], H/ K8 Q' X+ d                {
    $ t- q; \3 b8 Y# ^4 ^) J: N                    cout<<setw(3)<<vexTable[t].data;( q9 W; w3 U& M/ g6 [' {( ^
                        tag[t]=1;# A1 g( G/ t5 a
                        q.push(t);
    3 f5 m# r  k% U: i" O2 ~! c# n+ n0 C                }: }% ?+ c8 O: {) w0 K  t& W0 @
                    p=NextArc(tmp,p);' _( ?/ g) x' [" L! A5 U7 }
                }' q: w/ c$ b" V9 z7 k/ P
            }4 y7 x& E* V" u: H9 a
        }% ~& n) ^$ M  _2 Q: u# l2 l
    }
    4 k. o7 U- N  j$ b( ]. Vtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()( i. a  U; U6 h, D% b" ^$ Z7 a
    {( Y  a' Q5 e$ T& O0 C. f6 s
        MultiAdjListNetworkArc<WeightType> *p;
    # S, n8 i# n3 P7 w/ U! k/ J' G4 l    cout << "无向图有" << vexNum << "个点,分别为:";
    7 B" S7 z; h3 A+ [/ [" l8 r7 }$ V" e/ Z    for (int i = 0; i < vexNum; i++)4 I2 E7 Z! O% o4 C. D9 K
            cout << vexTable.data << " ";
    / F1 `! e( n/ Z& @; l4 g+ O    cout << endl;! _5 R4 O$ o% Q/ E
        cout << "无向图有" << arcNum << "条边"<<endl;$ \0 a1 @2 F0 U& D) E/ j- a# |+ P
        for (int i = 0; i < vexNum; i++): z* q) c  z* j. W
        {' H2 H3 l; q! P* j& e
            cout<<"和" << vexTable.data << "有关的边:";, B8 a1 Q* O& o# W1 e( R
            p = vexTable.firstarc;1 M) p$ E7 h1 @6 e( S# B; z8 A
            while (p != NULL)
    : G  E) M) N9 ?* d' {  ~, P) \        {
    6 q& |# X% _' z7 E5 |! c            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";2 B$ o  d; p3 [9 Q7 i, ?
                p=NextArc(i,p);
    / N0 d+ o& G( A3 l& E        }
    ) E$ Y) E0 a9 H$ |1 A0 n        cout << endl;
    7 h  t+ Y, @# x0 s% v    }
    % O( J! Q8 Q. B/ [( u8 \7 o}
    + b& }" }/ N" g* R
    ; x. C7 p+ V; J! I) a
    $ A$ l2 d- |4 N邻接多重表与邻接表的对比0 k, {! x* J$ s' ?
    ! X4 I5 Y8 i2 U- K% i2 M) r
    邻接表链接+ `5 ^* ?* ^. v0 T
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。: p* C* C3 X) x% V& S# a
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。0 v3 c$ m4 @2 S: N
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    0 r# G( G9 J6 ]9 d( V$ A5 j  A————————————————
    $ p) D5 u$ N: I& Z  {5 H版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。( [/ x- H2 e. t
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958: K  S/ \& c, K' o
    ! u1 g9 H1 ~! O1 i" n) @
    # _- @" k9 J0 j

    , {/ Q6 Y# k3 N& U. w1 E& r( d2 a/ O7 J8 }
    ————————————————
    & r, r) }1 }# g* P$ u# S版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。; Z/ N0 R( D1 M8 Z4 ~$ \' K
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    1 [, ?& `4 x4 d
    ) x$ c" H$ F! r3 o' E; |% j
    8 U" x% b! C3 }6 O3 q
    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-10-20 05:01 , Processed in 0.364178 second(s), 54 queries .

    回顶部