QQ登录

只需要一步,快速开始

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

    5 d2 s5 i- r  K& C( O; R7 s! Y图的存储结构——邻接多重表(多重邻接表)的实现
    # t* j  G5 r5 ]7.2 图的存储结构
    2 X% A0 T# |4 E2 B
    * j8 h! I6 p8 ^  k7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    : a- j4 s7 r, r0 q4 C: `1 [邻接多重表的类定义0 y+ F% c2 f! Q+ J3 F
    邻接多重表的顶点结点类模板
    5 o3 x9 L: [5 h) h! l邻接多重表的边结点类模板% g( J& D8 A: _7 u" j1 C7 I
    邻接多重表的类模板
    4 ^3 j2 y& b# r) E9 r1 {$ U% a邻接多重表与邻接表的对比' S* u4 X  j8 r7 \" a5 d7 ?
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist5 s1 L2 X% F1 h" P7 e: N
    # m" ]$ `) E9 `
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    3 Q* p9 V5 F5 i4 I! O$ P* M8 d在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。$ X1 f& Z" @+ O: m

    , p3 l6 A/ o1 @% U9 S邻接多重表的类定义
    7 n" R/ j' c6 K& k; p, v2 Y 1.png , @7 b! X* g* {# u$ h% v
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:! M$ v1 \: Z/ |% {
    data域存储有关顶点的信息;
    8 m# X2 Z& v% o' p0 Gfirstarc域是链接指针,指向第一条依附于该顶点的边。/ p& w, X4 j( N1 D& r
    所有的顶点结点组成一个顺序表。

    % k6 W$ Y; u" s/ h* O& _% G
    ( m/ }* @3 V, q5 B. G
    template <class ElemType ,class WeightType>! l  y3 S9 i3 ]* t2 E, l
    class MultiAdjListNetworkVex& x7 Y- x, i- c  ^) \
    {
    4 l1 Y' [# \* b8 qpublic:
    & l# s' w& j/ C' G$ r        ElemType data;& c, p8 ^9 b9 c9 b% M- ?
            MultiAdjListNetworkArc<WeightType> *firstarc;5 U  c  m' T# Q, `; z/ B! P1 K

    0 r8 ~5 J, V5 u( ?6 j$ u7 n7 Z& a        MultiAdjListNetworkVex()
    . q2 k& [6 Y+ V& {& m% S5 S* F        {
    . J- @8 I) H+ l                firstarc = NULL;( [: N, s1 j8 g
            }. N9 L3 [9 r- L/ B2 h4 f- D0 t( w, c
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    9 b' F3 M. [/ t, ?  L- v8 b) I4 A" D5 l        {5 Y$ w6 k4 i# V/ y+ a6 Z/ R3 c
                    data = val;- s: D6 z+ X# [1 N! Y0 \1 e
                    firstarc = adj;
    1 s9 Y) L  ~7 _4 V        }2 T% M4 {) H9 b9 t  r: Q7 Q
    };
    ; t# e' G4 S1 G; ^2 K8 {9 {& ]' X& m6 C  \9 F3 e% f8 C; {
    邻接多重表的边结点类模板% F! a' s' G! S9 F! k( {  D

    5 D& h7 L5 R. J$ d. B% E5 z在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:. w2 q% O+ \- i" X
    tag是标记域,标记该边是否被处理或被搜索过;( j% k+ c* g2 g/ g/ _3 ^0 e6 A# H
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    + j. J0 j' D! |7 }; t% k- Inextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;+ x( |, e) }7 a
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    + l3 ]. o7 B+ {- V- E! ^0 _2 Y7 ^
    2.png
    , H; L' X( O) j1 J, Y' h2 ktemplate <class WeightType>- r9 V! {; n; \. F, T. F
    class MultiAdjListNetworkArc# H# T' e, m( l. o. k
    {
    : d* v; w& l( x; c6 t4 V2 _. Opublic:
    $ u  H! \1 R5 v+ k" \& E    int mark;                                       //标记该边是否被搜索或处理过7 i9 K5 S% d& S: D- P
            WeightType weight;                              //边的权重4 w$ \8 G3 T0 Q& g& c
            int adjVex1;                                    //边的一个顶点
    * b% E( s3 z6 x        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    , Z8 h7 s# e# Q& S6 O( H        int adjVex2;
    0 T2 ]9 U! p, O9 \/ h! J        MultiAdjListNetworkArc<WeightType>* nextarc2;0 b+ m, ]/ o3 ?5 s, S! [9 V
    2 J: C4 p+ H' Z' [
            MultiAdjListNetworkArc()$ M" s( D5 S( ]3 S2 S2 C) |
            {6 o: D5 p* p2 M
                    adjVex1= -1;4 N8 W# w8 o( U- K
                    adjVex2= -1;
    4 k* b5 z: }  J, s        }7 V! B+ b3 }3 o) Y" s" X6 }
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    ; [+ j5 R9 {1 T$ F2 \/ L# ]        {0 G9 z% h! |' t: |
                    adjVex1 = v1;       adjVex2 = v2;4 C5 J* N0 T# i" t$ \5 a
                    weight = w;
    2 r% [! B8 L# z0 b                nextarc1 = next1;   nextarc2=next2;
    ( }7 I! a) a5 G1 {1 v                mark = 0;           //0表示未被搜索,1表示被搜索过
    * F- d- _* F2 O* Q/ z8 h        }) U3 i& {: q$ _- z2 u

    - Z# }3 H0 G& c- ^5 o邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>9 H1 [. Z( g% x0 m( X$ R" Q/ s; l
    class MultiAdjListNetwork, o" d$ v5 b& f- j* V9 d9 x
    {8 g/ ~5 W7 D  k3 e% [/ _. ?
    protected:8 h: K: m8 p+ f, a2 Z0 `# L& J
        int vexNum, vexMaxNum, arcNum;: \- R5 h& c% B# I" e* L! Y
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;/ C. R  U1 Q2 |* T% l6 b
        int* tag;
    ) ?! c1 s, s" M    WeightType infinity;
    ; g+ f+ n+ L  a
    0 ^) X; i' }! Vpublic:5 o5 R1 h/ d; S( M
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    / X. C+ L7 }( @5 V  Z' z" j% m, ^+ z5 }! c3 W1 e# D6 Q+ e# g) F* `
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);) |* a5 ^3 g4 `4 z0 @' {" m2 g
    3 Y: G- i+ N4 B
        void Clear();
    8 e( w& n( K0 u    bool IsEmpty()
    8 `) L* ]5 b4 Q& o3 O    {
    . L0 `0 F. r" G$ i' t        return vexNum == 0;9 p, B) \, E1 ?' s0 p4 c
        }
    + Y) ]. g) B  H& G6 }$ H    int GetArcNum()const8 e  m6 Q: x% w% n
        {
    7 q7 i1 t  K# u# C' a1 S        return arcNum;; o0 A; ?2 v& y8 T/ p9 l
        }# Q! V4 b  I3 r- z
        int GetvexNum()const4 I* F1 l7 I7 V* b
        {
    # \  }1 m0 m  a! `! D0 q6 K2 H3 k        return vexNum;: W$ Q2 r& h1 R/ p- d% o4 }
        }) m* {6 ]3 _8 d
    0 e! Q# R4 W! v! f4 B6 t8 j: O% U

    / h8 E' g% a4 N. d    int FirstAdjVex(int v)const;
    $ C% y2 u0 S8 W% G6 J    int NextAdjVex(int v1, int v2)const;
    . n4 b( E% O/ f6 f    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;0 l- p" a* |. [" C, ]: p. g
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    1 e6 `2 p; t3 O# R1 L+ Y- P! b$ O" Z) O+ E$ }/ t
        void InsertVex(const ElemType& d);" Z/ K" f" _& i! q/ c
        void InsertArc(int v1, int v2, WeightType w);
    3 ]2 M& W5 p' X3 r+ n+ r& @& n6 v+ W( [
        void DeleteVex(const ElemType& d);
    8 e/ o; D. O( E/ \' D- E1 p( H7 N- d; k3 V    void DeleteArc(int v1, int v2);
    ! d) W# N' B+ e' \0 W+ H' u8 H( r/ y1 y
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);$ x" R& x* K6 @5 c( G' s
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);$ _! @( u, b) p5 O6 N

    8 U/ z9 j- Y9 I" ?" g" a7 w' Y& ~    ///深度优先遍历2 p; Q) ?- h$ |# k
        void DFS1(const int v);
    3 O: m+ R6 t) z3 b( J2 \5 I    void DFS1Traverse();9 \9 Z' W# Q* L, N  B0 p# k4 d
        void DFS2();
    $ ]( I: ^* ?9 g  ^8 ^
    ! v2 x7 i% @9 D' M% H' C' K    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    # b$ G6 }. L/ m: v, M) `2 k! X5 y0 O    void DFS3();5 c7 a! ?6 p( Z9 V
    ( \2 {; ]; N) p+ B
        void BFS();
    & x. P8 \3 F% R. b    void Show();
    3 F" |# Y' c; B& L8 l' \};7 _; T( H( |$ _. y, c) u

    & W& k$ d- G! G- _4 B2.函数的实现8 h! I7 N4 I! V% Y( O  A
    研讨题,能够运行,但是代码不一定是最优的。) Y8 i7 F# ^) D2 B

      I$ r; d/ Z  R#include <stack>, Z  G( H( J% l' i% i6 ?, _8 u
    #include <queue>
    8 P. i$ r1 b/ g
    # D, Y- y( K' t' d" C( etemplate <class ElemType,class WeightType>
    + M. n( t  M, n% X+ a8 aMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    ( ?6 I6 z/ O; o) U) E0 b6 e{. [) k  ]7 \  X. ?5 F7 ?
        if(vertexMaxNum < 0)
    ( Z3 s- N0 Z! x* O* F, l' m7 l9 t        throw Error("允许的顶点最大数目不能为负!");2 Y& s! k; c  ^' B
        if (vertexMaxNum < vertexNum)
    9 q$ n* J$ q% D  h# O* t        throw Error("顶点数目不能大于允许的顶点最大数目!");
    ! W5 Y5 Z: x( `0 w4 Y5 X$ K# w    vexNum = vertexNum;
      R* D) Y- G, ?: \* Z    vexMaxNum = vertexMaxNum;& s6 g" h/ H7 c  `
        arcNum = 0;8 t0 U, ]+ e6 z9 ?6 d0 S
        infinity = infinit;
    : V  c) d5 |1 k7 o8 a; A8 P3 C    tag = new int[vexMaxNum];0 O6 u+ Z$ s" |. M. J
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    9 m4 p0 z$ ^! b3 x' J  d! N$ p    for (int v = 0; v < vexNum; v++)
    ) z) a- Y& @0 c7 W, y2 I    {
    4 Z' U9 r, h  z/ X" F% m        tag[v] = 0;
    1 \1 \" _  M( W. O' h        vexTable[v].data = es[v];
    ! J9 Q9 X; s* v. v9 O. Q. w        vexTable[v].firstarc = NULL;& a" ], r  C& P: r2 t0 X
        }
    ; [5 U8 g9 N) _9 d: r" n}
    . w8 T6 d  V. G1 z- K* Wtemplate <class ElemType,class WeightType>" A8 o" q/ E/ C6 P3 \8 w
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    , r! a9 ?* Q, V, ]& B: Q4 o( k{
    , @( {. \& J0 n" {/ |0 e    if (vertexMaxNum < 0)
    9 _0 a$ p# H) e2 D& y5 M* E        throw Error("允许的顶点最大数目不能为负!");
    / Y9 g/ O% p/ G  k" R    vexNum = 0;! m( L' H# ^6 K' s% h+ J
        vexMaxNum = vertexMaxNum;
    % t% c3 m* R7 e; E2 r/ u0 V    arcNum = 0;/ |  N( _% A" n1 A
        infinity = infinit;! r$ N; }7 x5 I$ w  ~! ^) C% n5 ~
        tag = new int[vexMaxNum];5 K! N: y7 v8 _
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];6 W& {0 u0 l- }: b
    }1 G' i* K- ?& P0 p7 C4 w
    template<class ElemType, class WeightType>5 A$ \( v' h0 M% `
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    0 |6 I6 y) q  S# m5 E& M{8 @& v7 U' W9 W( @6 W
        if (v < 0 || v >= vexNum)
    / Z) g! X( Y/ W2 ]7 |        throw Error("v不合法!");
    ( ]( e( ~2 f, u& z5 @    if (vexTable[v].firstarc == NULL), L1 b1 E( h; c, D% w  [/ v& [
            return -1;
    ! Y! _- t+ E' ~1 |    else3 V% C8 ~# M$ b9 y& g( v! Z
            return vexTable[v].firstarc->adjVex1;
    # A$ x6 F  \  l}
    " h# @8 j. b: Q; x+ C4 k
    2 A( V! l1 b1 ]; Atemplate<class ElemType, class WeightType>) ^3 f2 M; g+ J* y* p
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const8 |% h& A, L, a7 A
    {
    ! \' _6 {+ x& w, ~2 U    MultiAdjListNetworkArc<WeightType>* p;
    ( y7 {7 [" U" |! {" X    if (v1 < 0 || v1 >= vexNum)
      K5 G2 {. d! p6 @1 Q; b# j        throw Error("v1不合法!");+ \: q% C$ _0 F. X7 F4 f1 w6 y
        if (v2 < 0 || v2 >= vexNum), u( ?1 P' w1 ~
            throw Error("v2不合法!");
    : d* X. c+ b$ @: F5 `    if (v1 == v2)
    1 ]# S+ f* o) k3 M  q        throw Error("v1不能等于v2!");
    : g' d, Z9 K3 w$ Y% J    p = vexTable[v1].firstarc;3 w: ]' e: B  C
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)! z$ v/ X" D6 m2 W
            p = p->nextarc;/ f/ ^; |! k/ r8 p- ?- z
        if (p == NULL || p->nextarc == NULL)* H& J. I3 }& i
            return -1;  //不存在下一个邻接点
    7 Q, e- C7 i8 H1 Y) a( ~# _    else if(p->adjVex1==v2)
    7 M/ k; Q: P: q+ {* q$ x        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    8 s# y6 _1 D0 R, ^    else9 a# r  u0 X- {
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    8 X( Y& Q7 j# ?}, ]7 q2 O! D( u0 L
    template<class ElemType, class WeightType>1 \% n9 t- e2 E1 V# t5 u+ }4 b
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()/ A+ c3 T" q9 i3 d  {+ b
    {
    1 \% Y; E' U2 Y" p' O' j: P    if (IsEmpty()) return;
    . [0 i8 D9 x! Z    int n = vexNum;: t! g& [3 o% `3 _! s9 q
        for (int u = 0; u < n ; u++)
    # z+ U# S7 |6 T! h        DeleteVex(vexTable[0].data);
    ) P* V7 B; n  B7 n' g! z! J/ X    return;8 c; o# o& g/ |+ ^' L6 D7 b
    }
    + K$ S, W, o# v% _2 }) @# C& atemplate<class ElemType, class WeightType># l3 B0 F! B4 r
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()( j6 s* c/ O- |
    {
      `$ j- e! c3 Y1 Q7 z$ J; r: W    Clear();) t8 T# l( ^( o' K  U
    }
    # I7 S& P, [. {1 s8 ^template<class ElemType, class WeightType>
    * e/ t# p% [+ H7 [3 C! H$ CMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    - m$ Y7 L8 U# [3 Y- d7 o3 H+ E{$ c; ~2 b. x9 h; G% q9 K' \4 [
        vexMaxNum = copy.vexMaxNum;
    & v% t5 B! E) R+ s' O    vexNum = copy.vexNum;. D" f2 _7 z) `0 h: K& d5 {
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];7 l; O8 L5 K" b
        arcNum = 0;; L0 W* `! `& U$ t$ N# q. Q
        infinity = copy.infinity;
    & P) |, d2 X' ]+ Z    tag = new int[vexMaxNum];
    7 J+ l* k+ G/ W: G$ i. _# h% F0 n! d/ Z7 R
        for (int v = 0; v < vexNum; v++)
    : J' Y- P* w  ^' [( A8 G    {
    7 ~" f. q" R" ?' A        tag[v] = 0;9 h/ [, C' A# \- L; L
            vexTable[v].data = copy.vexTable[v].data;
    6 a2 l# H5 m- d0 {        vexTable[v].firstarc = NULL;/ j% l# F; @0 h0 U& Z
        }/ y" {/ ~! P2 l/ s0 W
        MultiAdjListNetworkArc<WeightType>* p;9 Q: D( }' y  N' E5 D& e9 y

    2 K7 P: D" Y% Y6 L; e/ W1 ^/ F    for (int u = 0; u < vexNum; u++); J; f3 w9 \1 }$ |8 J) e3 S
        {! q! {0 l# x! P6 u6 E+ S
            p = copy.vexTable.firstarc;
    6 I: r8 _' ?# \- _        while (p != NULL)# t8 m( ^: s) O
            {
    4 |5 s4 g+ `. T! j5 C) B1 d5 H, ~            InsertArc(p->adjVex1, p->adjVex2, p->weight);" Y: C% l& o. f3 _
                p=NextArc(u,p);
    # Q' F& @& U, T" H) E. M9 l        }
    6 |+ R. w& F" e) g- }; ~    }4 j: X8 |; S/ G+ K- l* {
    }
    ; ^7 k! B5 M! P% k: i- ]% ttemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    0 N! s/ Y" v7 ]7 A0 M# T) fMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)0 B- S  L3 p* a' ?" ?
    {
    % |6 b& P( \' X0 E; s4 K" U    if (this == &copy) return *this;
    7 C" Q; i4 u; o    Clear();* a4 `; B2 }& L0 B; E+ r
        vexMaxNum = copy.vexMaxNum;
    2 B/ T3 Z. {! v' X( \    vexNum = copy.vexNum;# K/ `) J# F& _6 i1 B. ^( d
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    7 T' @9 Q' @% L    arcNum = 0;4 {' D2 {% q. e/ D! o
        infinity = copy.infinity;' J- b1 q/ i5 @, j7 K
        tag = new int[vexMaxNum];) }( Y/ S% n% a- R, b! }- M6 q
    , Z3 u: z) A' s. D$ J
        for (int v = 0; v < vexNum; v++)5 l* X: |) [% j. q5 B
        {# q! A/ T- t: Z" S- m- g% f
            tag[v] = 0;
    * Z4 j6 l6 X% K3 w: q& _        vexTable[v].data = copy.vexTable[v].data;2 w0 P4 O5 @8 A; }7 }( U" r( z
            vexTable[v].firstarc = NULL;
    % U  E- a3 A( f2 P, v9 |+ \    }
    % I* N# M5 F1 u/ O% F: X! |    MultiAdjListNetworkArc<WeightType>* p;
    " o" K9 l' i' ]9 R6 P7 f/ o" j- \* ~2 b2 z) B
        for (int u = 0; u < vexNum; u++)% _+ @/ ~4 c( O0 n8 y, p) t- t
        {9 u# l# k& Q/ E7 v: F3 q! g
            p = copy.vexTable.firstarc;% F: h' ^/ T* i1 t6 B
            while (p != NULL)
    4 y& _4 H, `9 F+ O. E        {) E5 }; v1 G& X7 [) y! [" }- d
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    8 l) ^! G; P+ T$ }8 E4 W2 Y) w" N/ r' E            p=NextArc(u,p);: D8 O! h8 V8 u
            }
    0 F- O7 {# ^9 ~  b) j  c; e    }
    % c8 r/ ^' h6 x# e    return *this;, b! E. D/ y. M( }
    }, ~" x% |7 u. H5 A
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*& d3 b# ]# c2 k
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    + E6 O' y/ B+ b) }% R# e9 N: p. J{
    * s* A9 g& ?1 M% o% I+ t9 W4 z    if(p==NULL) return NULL;4 p2 U0 j7 v4 \  s9 i" {( D
        if(p->adjVex1==v1)  L5 Y: D% {; O. N! Q3 @
            return p->nextarc1;1 e' [+ e0 E; p7 `* n/ z: l$ r  n5 D
        else
    7 R) Q+ ?. i/ G4 n/ v4 c        return p->nextarc2;& N! u8 ^% i: Z* V# c8 {% p5 v
    }7 v$ x/ I. \( A3 R: J# y2 r
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*% k& l+ f. v. l% E$ R8 I7 e
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const  l6 e( O3 x, P" W4 ^  C" i# z
    {
    . l, X4 R& N" D+ Z. I2 @    if(p==NULL)return NULL;
    + v4 m! x" U% {    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    7 d8 c! {) z4 P    if(q==p)
    ; J4 V5 s; ^4 z9 D2 K  F4 r8 }8 U2 ?/ [        return NULL;  M8 f' S3 J0 j1 F# Q4 _
        while(q)" h! D7 H: r( F# J
        {8 `7 m' L* Z/ |/ Z' x. ?
            if(q->nextarc1==p ||q->nextarc2==p)
    ; U- M% H+ C  _, B            break;0 T0 c9 M5 g' w9 v5 D. p4 u. R
            q=NextArc(v1,q);7 S7 h) O# _0 N3 ~- {
        }
    + s% `9 |- N  o2 r( V" X- m& w    return q;& M; ?9 w2 a4 i; k/ n8 N
    }5 K# O" O4 q; Z. @8 n  Y
    template<class ElemType, class WeightType>5 W$ J% U# R  R% [. U( f4 G- o
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    : L5 M1 D4 C9 B, L  H# d- \{
    $ E1 H$ d" p9 \% b7 s' G5 ^    if (vexNum == vexMaxNum)
      o: t4 P1 x0 [1 C* d, ]" V        throw Error("图的顶点数不能超过允许的最大数!");5 l9 V$ b9 u' s" Z8 v
        vexTable[vexNum].data = d;1 o) U6 j& Z3 g* b( @! j
        vexTable[vexNum].firstarc = NULL;& n) N" w' n3 E$ O# T0 L
        tag[vexNum] = 0;
    ! B- H, K1 s( I: ~$ H( U5 y3 r+ k    vexNum++;9 E4 m( H: y7 n, S9 [0 M
    }
    9 }' s1 e8 g5 W$ ?template<class ElemType, class WeightType>
      x' U/ B# W) D, ^0 svoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)4 [* f  Y7 Y5 w9 R. [
    {+ R& \9 e; u9 C0 g( F
        MultiAdjListNetworkArc<WeightType>* p,*q;
    ; j/ u9 s# d( Q    if (v1 < 0 || v1 >= vexNum)
    / ^, e1 s  |3 ^% A. Q( \        throw Error("v1不合法!");" T) c  U, v1 W& w, `. S
        if (v2 < 0 || v2 >= vexNum)
    $ W$ B, i  R" \        throw Error("v2不合法!");0 B6 a4 s; A3 _4 p0 c
        if (v1 == v2), g1 j! q  [/ f0 ~. E) p
            throw Error("v1不能等于v2!");* N1 h( B$ U6 _0 L% E4 p% k; z. b3 W' x2 z
        if (w == infinity); {/ T* k, j7 A! b( {  D5 k
            throw Error("w不能为无穷大!");* @$ B( r6 B8 t: Q: p( \( `6 R

    ( T) R9 e) e- x# D, V% N% S/ Y7 Z
    $ |: Q% r" ~  g* J. ?0 {! G, X. b! z    p = vexTable[v1].firstarc;  z1 }! @, r. N+ p5 C( d
        while(p)
      C. T& a: U/ @6 \% P2 j. w    {
    5 j7 w- c% B) U: c; Z7 a1 q, n9 X        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    $ \4 c- j6 `) M1 X( ?5 }+ h1 \        {% E  `4 Y8 j) M% |
                if(p->weight!=w)
    ! V3 |1 p0 R3 T* I/ E1 K                p->weight=w;
    - F0 \+ g; u6 S! ?6 G3 J            return;
    / b* [+ F: ^+ U9 M# e1 \5 k        }
    ) g0 P$ u; k/ |, i! R5 |* f$ A1 Y7 ]2 ^1 K, V* J/ H
            p=NextArc(v1,p);2 Q! z, D  ^0 K7 |0 s
        }
    * `9 r; S8 F* r" t  a    p = vexTable[v1].firstarc;
    " I& n9 s8 e2 |    q = vexTable[v2].firstarc;
    + ]6 y  Y& c5 H  f1 q, ]    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    $ R' m9 C( ]7 M. B    vexTable[v2].firstarc =vexTable[v1].firstarc;. a4 e- s5 N7 k' `4 [& H
        arcNum++;
    6 k2 \7 t  ^; T0 m0 ^6 ?3 L3 D}
    / \5 F9 s( m! {6 @  W/ Q' ?9 l+ s( h5 |
    template<class ElemType, class WeightType>8 c& ~/ \0 V" {* Z, a& O
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    9 z$ S- b. P4 ?2 w) ~% S{
    8 N, S. T! A" Q9 c% C& E3 o; Y6 H. ~' L) j4 {$ f
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    * i  V/ h& @4 x6 d    if (v1 < 0 || v1 >= vexNum)9 n8 Z5 y# K7 E" L6 }: ~& ]
            throw Error("v1不合法!");/ G6 X! a/ \/ @& p% ]9 D7 Y
        if (v2 < 0 || v2 >= vexNum)8 p; u$ y, U" P. W( x4 V
            throw Error("v2不合法!");1 W) D4 v5 @1 ~4 D9 u
        if (v1 == v2)) t4 s2 O1 A! U- Q7 ?9 h( ]
            throw Error("v1不能等于v2!");3 r: G& `  T* V/ m9 H9 S
    8 {+ ]% |/ w1 O/ J/ u
        p = vexTable[v1].firstarc;
    / L3 j% z; U5 s" |- D4 ?6 N6 Z$ ^% f    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)) o+ T0 ?& i0 Q. m. G( c- N3 l
        {
    8 k6 `5 H+ v7 _6 K        q = p;
    . ?) _, G/ V* T' N. u- s% c        p = NextArc(v1,p);4 {; y5 O  G+ M% c  p. H# d
        }//找到要删除的边结点p及其前一结点q, x$ i  j: ^- ~
    . G3 v- l  W' N
        if (p != NULL)//找到v1-v2的边
    7 Q! F# l$ r* U4 V; |3 U7 J    {. v8 @, K! i8 X7 e9 n
            r=LastArc(v2,p);( P( F* q& \( |) X5 ?
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    * O7 k' r6 s0 x            if(p->adjVex2==v2)4 v% _" G' R( \( j& s
                    vexTable[v1].firstarc = p->nextarc1;) F6 r$ N1 h; D" f8 O
                else vexTable[v1].firstarc=p->nextarc2;
    0 A: W2 j' g4 Z# ^        else//不是第一条边
    : r; y, e8 R# v- }7 X        {
    / o8 f! Z4 a$ q7 C- n9 ^! @9 Z& S' W            if(q->adjVex1==v1)
    - N& b6 I+ w& `                q->nextarc1 = NextArc(v1,p);
    & Y/ A3 u6 ^9 C! [5 h# @            else
    $ P& x, ]% z8 c' M0 t1 o1 v                q->nextarc2=NextArc(v1,p);
    $ A# u! P4 b1 o: C
    % c6 c& n7 S% s! L& o  A        }, y) {$ ^8 ~' s, ?' J  R
            if(r==NULL)
    & E' o+ y+ Y- |- r8 p* P% o: e            if(p->adjVex2==v2)  X' g8 }% ~$ ^' t
                    vexTable[v2].firstarc = p->nextarc2;
    ; ]0 r+ |4 q/ M( [/ n: V# l3 `            else vexTable[v2].firstarc=p->nextarc1;
    1 I! i( S, O5 O& ~4 ^        else
    0 M# y0 a& ]/ A% T2 f        {4 U5 R# \6 l' }: c$ [( D& c
                if(r->adjVex2==v2)# T& ]6 Y' B4 J6 Q: I) X9 C5 w
                    r->nextarc2 = NextArc(v2,p);
    2 C, D3 p0 e1 E            else' m- }9 O  f2 k8 B' ?6 v
                    r->nextarc1=NextArc(v2,p);  n& ?4 }0 Z( g( ?' D3 T
            }' o' |" Y1 b1 a5 K/ p
            delete p;
    2 [: \+ z" A6 N/ g% J4 `0 u9 ^$ q        arcNum--;
    0 v0 {) _6 ~. g' ^5 Q3 g+ B    }" O% p0 w9 q4 V! E+ e% @# L" \

    7 I! A6 {7 g1 t- W9 S; k7 R}
    ! m  N' G9 p3 [3 h4 Ptemplate<class ElemType, class WeightType> void6 v% R' I. G! K. \' W
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    + g& @5 J" @* A{$ m% G6 U& |7 N. w1 b
        int v;6 M8 D4 N$ ?- W0 ~* d6 q
        MultiAdjListNetworkArc<WeightType>* p;
    $ I/ `8 g8 ~! |! o+ [, y& H9 ~. Q    for (v = 0; v < vexNum; v++)//找到d对应顶点2 W3 c! A3 N* l* M6 X4 r# e
            if (vexTable[v].data == d)& Z* A! ]6 ^+ ]! [
                break;
    0 w  b$ |. l5 @0 _2 J8 v& h% ?    if(v==vexNum)) w0 J0 m( N+ w1 g  g$ z. P9 L3 U
            throw Error("图中不存在要删除的顶点!");6 L! L5 i6 y% U8 b& ^. u* M

    2 K" D( X5 Y/ x' W! u$ w    for (int u = 0; u < vexNum; u++)//删除与d相连的边0 s+ f5 j8 p$ v/ _" S! V
            if (u != v)
    7 i8 Z7 H; W! h. S$ l$ p/ F+ C        {
    , Q* y( @0 W% [& a% J& D            DeleteArc(u, v);; w) K' P/ Y: i& b' W8 T
            }/ X4 L4 n3 i' G
        vexTable[v].firstarc=NULL;
    + T- t8 `8 c5 x3 q; g
    & S8 h. E1 `/ u! M, T    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    ! c3 i$ m$ K. N9 V5 Y    vexTable[v].data = vexTable[vexNum].data;2 y9 R* E% v8 g1 k9 X8 ~
        vexTable[v].firstarc = vexTable[vexNum].firstarc;) z7 b' o7 u7 {. G: Q- ^+ C
        vexTable[vexNum].firstarc = NULL;
    ) d( C, q1 G' Y# E8 Z    tag[v] = tag[vexNum];$ F7 |: \* E8 ^" ]% S- N/ v
        //原来与最后一个顶点相连的边改为与v相连
    / j& y, Q& O6 z& A0 w. d1 C( @    for (int u = 0; u < vexNum; u++); h) y* j# O8 ?! w/ _! b
        {$ R+ B5 Z7 S2 X3 w% y7 ~0 ^+ p* \. \
            if (u != v)
    ! t7 \- J. W+ t8 ?* e" S" _        {
      |( k! m* x% C0 R( s: `            p = vexTable.firstarc;8 `6 `9 P, ~: M9 u( I! V
                while (p); n. U5 K! `& s* F
                {
    6 x% h- `5 n5 A; b& ]                if (p->adjVex1==vexNum)
    4 g3 w' B3 o7 q  J! T                    p->adjVex1= v;
    4 \8 s2 I- G- w+ N- h0 c0 x                else if(p->adjVex2==vexNum): q7 A  ~% M( Z3 I# F& ]. `! a
                        p->adjVex2=v;2 q8 g, |6 c: g! e7 X0 K( I
                    p = NextArc(u,p);
    , K+ f9 }. @4 X, M9 Q: j3 p5 ]/ e            }
    1 B5 o$ i+ L7 @0 d3 \/ z& Z        }
    4 F3 _  K( c& @) f9 X    }9 [& p: l* p3 r7 u  Z2 x* K
    }$ ~+ a  I9 R: r! t. b7 v& R
    ///深度优先遍历& |8 q  R7 ^2 w. H' F' i8 }5 `7 K
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)' G: ?& F6 _; Z
    {) K% P6 f4 s- o1 X
        tag[v]=1;- P8 R: s# \8 A: C, n& h0 ~
        cout<<setw(3)<<vexTable[v].data;
    : d. ?9 X% q& h/ K8 G) y& r    MultiAdjListNetworkArc<WeightType> *p;
    2 V2 l! z3 d6 I3 F- @    p=vexTable[v].firstarc;
    + b& U9 \' V& s  W    while(p)
    ; l' B) c% c! F: ]1 M; r    {
    5 d: F7 f# w" N3 s# i5 Q        if(tag[p->adjVex1]==0)
    ! J8 G; n- k. x4 g$ O* o% U# v! R            DFS1(p->adjVex1);
    9 E5 l+ G8 o& G6 N; K        else if(tag[p->adjVex2]==0): t" O) F3 }! U
                DFS1(p->adjVex2);7 o4 m3 s( c7 D1 ^
            p=NextArc(v,p);
    $ d+ L5 W! y: [: a    }8 L7 i$ _8 j  v# M2 z
    }0 t  r+ j6 K* s7 I. v) N
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    ; L4 C: j( t) G6 F{3 K/ x' h/ c' d( f+ T
        for(int i=0; i<vexNum; i++)
    " ?- ]3 l& Z: @. H" @        tag=0;
    9 o- X" \+ ~+ U3 C    for(int v=0; v<vexNum; v++)
    ! N  B: I4 |# D5 F# A' g    {
    + k2 m8 ^9 c  k, ]! q        if(tag[v]==0)5 O. f6 V' `$ A! S- P
                DFS1(v);
    ; }5 a, h$ }; G+ c    }# r$ d; O# T! J- O7 H" q- ^
    }
    5 G: I8 l+ n0 b" G+ |8 E- dtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()$ X; X. Y  Q3 l$ M
    {
    6 E1 F" N- y* l2 u2 l  X) s8 r    stack<int> s;
    7 v. _/ Y9 j; t4 }    int tmp;
    7 T0 s, `' k- W: s; [/ l2 ~0 s    MultiAdjListNetworkArc<WeightType> *p,*q;
    5 u6 ~7 m8 N6 `5 f0 c% H    for(int i=0; i<vexNum; i++)" G2 `2 j( _4 f2 _* t9 n& C% [: S
            tag=0;# A* v9 g' n0 H+ ]* j( E4 o
        for(int i=0; i<vexNum; i++)
    : Y2 p* u/ f) B& ]0 k+ o    {
    0 w' }2 _5 h7 o: n& l6 j7 Z        tmp=i;' |% R8 t: N2 o! }+ b
            while(tag[tmp]==0||!s.empty())
    - Q1 S; g, g3 U" ]        {
    2 @$ }8 I; }" l0 T& B  ]( o3 ^            p=vexTable[tmp].firstarc;0 k2 q. }. A$ E4 r6 R
                while(tag[tmp]==0); W. H8 h. p1 P6 {$ H
                {/ ^1 D6 y! k/ e& R! ~  n) z1 _
                    s.push(tmp);
    ( o2 L" ?! v, u$ n5 Q                cout<<setw(3)<<vexTable[tmp].data;% _5 C3 t. h3 @0 k# B
                    tag[tmp]=1;
    5 w- a# d- Z% z8 ^                p=vexTable[tmp].firstarc;
    # L& }, [, Q: D! c; l, Q                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for6 K* `! a! K' J7 {5 |+ q. M" E
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);# a8 s0 p+ E: W7 S0 F" ^
                    //cout<<" 1st     tmp="<<tmp<<endl;
    6 z  K, H2 v7 N$ j; u4 X            }$ m. i7 c' }" {; V2 a
                if(!s.empty())
    7 H8 n1 I! x% j; L; y            {
    ! x: e( T, J0 f                tmp=s.top();
    7 f9 g6 V" e3 d! t$ m, i% B                s.pop();4 Q6 u8 Y0 W9 J5 Z2 T- P8 a
                    q=vexTable[tmp].firstarc;
    " S8 k  n. O0 a3 R* W4 h                int t=tmp;- o7 Y! _" e" \9 W7 k% z5 d
                    while(q&&tag[tmp]!=0)
    * ?5 D& u3 r$ F5 x  |                {
    2 F6 m! v2 T9 H                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    ) M- z0 D3 f, m" z8 g& \" Z                    //cout<<" 2nd     tmp="<<tmp<<endl;
    9 x& v2 K9 ~& z! v! y# L                    q=NextArc(t,q);
    4 i! e2 T- X& X8 G$ ^3 b, m8 F                }* j) ~8 m/ ?5 j# q
                    if(tag[tmp]==0)
      t- d0 i4 d% }* l! C7 V                    s.push(t);  K  m2 {. _# w$ ^% N1 T
                    ///1、对应上面连通分支只有1个点的情况5 j% w' Q- D2 T1 Y
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈+ f( x( L! w* Y, r8 c- |* g
                    ///tmp要么等于找到的第一个未访问节点,) H' Y# e, v- _
                    ///要么等于与t相连最后一个点(已被访问过)8 o) d: `* a0 h+ c
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点4 j' e/ h2 {. x; j! k& N3 U# W
                }" E. ?; R- C. H. ^8 p) T( g# F/ }
            }
    9 c4 Y9 \% |) @2 n7 B4 v  b& n8 A    }, ^/ q& Q9 m0 W3 V- w  @
    }
    . o5 ]/ V, z' R. p5 R& u- O0 b//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    , p4 l' R' B, M8 ntemplate<class ElemType, class WeightType> int7 W- J. E' r4 j# o! x
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    " g: K7 K, w1 c! u# |. v" Y1 u{
    ! Q1 ]5 ~/ ~/ d/ |( ~6 |    if(head==pre)
    * i! Z3 Z1 N+ T, h9 R% T( r        return -1;
    0 @0 \3 G) s3 H% I1 M+ q* }, v  l2 T2 k. g  _, }6 i
        MultiAdjListNetworkArc<WeightType> *p;) u  o9 p' o( P; U9 M
        p=vexTable[head].firstarc;% N3 w/ ?  K9 i0 F4 {- Z
        if(pre==-1&&p!=NULL)8 d2 ^# L# a) j" ~6 L* f
            return p->adjVex1==head?p->adjVex2:p->adjVex1;& ?( p- E* K% w% S2 v: j
        //pre!=-1&&p!=NULL
    1 c6 \' t8 r; d7 k% m. F; L* y6 D    while(p!=NULL)
    2 C* ~8 P6 |  P    {
      A  M5 `* l. h! N5 m3 H3 L! h        if(p->adjVex1==head && p->adjVex2!=pre)
    . G: ^* O: u/ J            p=p->nextarc1;
    $ j& T: u# @$ S9 R        else if(p->adjVex2==head && p->adjVex1!=pre)
    6 q9 g( i( x& C6 |+ m3 K$ P9 ^            p=p->nextarc2;: x2 W, M& e# c0 d7 h2 {
            else if(p->adjVex1==head && p->adjVex2==pre)0 [5 z# U8 o( k( g
            {
      g7 {; C! q6 A            p=p->nextarc1;
    1 N+ a9 Q9 V5 @3 ]+ a            break;
    * S8 ^3 T' |5 {$ L9 f: y3 y! L$ s        }+ t8 R5 y5 l  g1 A
            else if(p->adjVex2==head && p->adjVex1==pre)
    ; K) e, `/ a8 H! ~6 K9 ^+ d        {
    % H. `9 F9 S4 f: M8 n: q' V            p=p->nextarc2;
    : [! J+ \7 e; n9 H            break;; E% j6 y' I% p2 m9 F; g
            }5 r: j; H& \" O$ J; X0 Q
        }
    5 g( A$ D# o, O" h8 J% n) s+ p) G9 c    if(p!=NULL)
    / r6 ~& d2 m  A3 \% M- ?    {: J8 k$ ^# u! A
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    6 l' D7 L6 _) X    }
    4 D3 M* Y1 i( [0 y, r3 M    else  q, [0 z5 f8 I* W( G& B1 X: B; [
            return -1;
    ! [- `; n7 @5 \, M, s/ d; b. l}1 f! A& J. V" {+ t/ G2 c7 I
    0 Q4 j/ Z: h3 ?2 e* U4 @
    ) g0 [3 o' w1 s/ V
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()' }, m& r9 l# L$ o- F9 S6 u2 E
    {6 H" e: S5 I/ a8 b- f. P
        stack<int> s;
    + M5 p* _0 A& K6 f9 s6 H    int p,cur,pre;, r2 b" Y! c# w" s, A& C; T
        //MultiAdjListNetworkArc<WeightType> *p,*q;
    - |/ _4 M0 s& h3 w) z3 O) s( {# v% ?    for(int i=0; i<vexNum; i++) tag=0;//初始化
    & M  }( h( P4 D9 |8 {4 Y( D" C' L- V4 ^0 s' F, F, p& y$ v
        for(int i=0; i<vexNum; i++)" K" Q: n- v8 T$ C6 |& b: K
        {
    ! W+ R" b7 a. d& [        cur=i;pre=-1;8 R! \; c2 k! I/ }  A
            while(tag[cur]==0||!s.empty())! Q& U5 G# ?; R
            {% P$ A6 g( e1 Y* O0 C  Q& N
                while(tag[cur]==0)
    & F! O9 j( n3 a" i* Z- a            {6 C8 R4 L8 s) T1 a7 O
                    cout<<vexTable[cur].data<<"  ";$ ]: }% z8 f+ y# H, o1 H' o) J
                    s.push(cur);1 o) m$ k! \2 H/ b4 j6 x+ d3 T6 Q
                    tag[cur]=1;: k9 d: I: d7 `/ S
                   //初次访问,标记入栈! w; N6 [2 j3 q0 m3 m6 v4 S
    $ _# V3 I+ B9 X
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点- @) L1 a( k2 @- e9 D
                   if(p==-1)/ |4 w  x- u& G" `- w/ @+ u
                   {3 {" H$ x: h  d
                       pre=cur;s.pop();; {- C+ c0 H# Y  t/ S
                       break;# [. o! J. T8 t) l2 N9 G+ m
                   }
    & r! ]' V6 @( [1 @0 V! Z* a               else
    2 M, a5 g% s; m6 w: h               {
    0 f5 K  \" k" }9 r9 i' c% H' D                   pre=cur;3 L1 f) t" ^- C: P3 r. ~
                       cur=p;- G/ W% N! p) J8 p* V
                   }2 I9 o( ?: y8 ]6 M8 N

    ) W) L: W2 s7 p6 l& s8 i" _            }
    " Y+ I) G/ S2 k& t$ k" _9 B6 W            while(!s.empty())
    1 ]# S, J! B( f' }0 D) a7 h# z0 R            {
    7 j+ B/ ~$ l! O3 R0 x  I/ e. x$ Q                cur=s.top();
    . u: A% m6 b% W8 l. H/ C6 e, O                p=GetAdjVex(cur,pre);% `# u2 L1 |- Y5 C2 R$ l+ @" X
                    if(tag[p]==0)
    9 z- S- l( H& A, A                {4 `/ X9 w2 B) F! M/ J& P, V
                        pre=cur;  G, w% F! z- R% p
                        cur=p;
    6 w0 d- ~  w0 ~4 `9 d' ]                    break;
    * e; o- Q  Y+ s3 N                }. b! ]" W- [( p! l9 a" c
                    else
    / x6 T8 L$ }1 L                {
    + E# A* [9 o) _! Y7 ?! t3 G8 m                    pre=s.top();9 \: X" t3 x; T3 U- k( `) A
                        s.pop();
    & f* o. _- Z. i* y: W0 S                }7 w/ w7 D5 r3 x

    * N2 \0 m5 a# T) l; X            }7 A# E  W9 Z& {

    2 m) s: |6 M- q6 N( F        }* d' Y6 T3 D3 h+ s- o  w. ?
        }
    . }& `# l  v6 ^. |: j/ H}
    / V( ]' Y5 Z2 n% i8 k  ]$ ctemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()/ ^5 P& ^' i" `# D% {6 \
    {3 Q; i/ a3 R- \; ~3 [4 Q& ^
        for(int i=0; i<vexNum; i++)
    # L8 C* E9 m2 S; ^0 y; C1 A        tag=0;
    7 ^, [5 ~! j% {8 n3 y+ U8 W, d    queue<int> q;) }0 H! }# c: x; f
        int tmp,t;$ o* l# U3 ^- I# F$ N# Z
        MultiAdjListNetworkArc<WeightType> *p;! b1 o- G. o) m8 H
        for(int i=0; i<vexNum; i++)
    0 o6 s0 e; c5 \2 i, O    {8 d# ]6 I9 F* o
            if(tag==0)
    7 R# q4 g* W# [4 X, `! A4 ^9 t# O        {
    # n# e; l4 s( u3 n% P- J" k; @+ G1 F( Q            tag=1;( S% |* _" V8 @% j: K. a% ]
                q.push(i);
    8 ^7 D8 [3 f1 K            cout<<setw(3)<<vexTable.data;, m& t& X# J$ q
            }  `6 H- Z  u  O; _0 k# c
            while(!q.empty())
    ( X/ n* U5 }& l# [9 V        {
    9 O6 H: O. a# d6 F* m            tmp=q.front();
    ' T- ]! T- p, a5 A            q.pop();- r8 F8 C/ ?8 a; O
                p=vexTable[tmp].firstarc;5 M# p0 v5 L6 {* r+ b
                while(p!=NULL)
    ) a6 s2 ^% L2 C' h: l            {8 f$ G6 |- ^/ Q
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);; j8 ~" Y% v4 f* r
                    if(tag[t]==0)
    ( B+ K/ @" x+ D( A  ]                {6 X) K+ h5 k; p; |
                        cout<<setw(3)<<vexTable[t].data;9 x& V- Z" _+ T. m
                        tag[t]=1;' @9 P- z/ ?8 V- v* s& ~
                        q.push(t);' D( m: ?; G# g/ O+ W; J
                    }0 O2 ^9 ?% i, ^  K6 r: h2 u
                    p=NextArc(tmp,p);
    5 _6 |0 U3 Z% `8 J# d4 B            }( g" y; Q% H9 ~# t3 A5 t( N
            }. u/ H! x% p; C/ k2 Q8 M
        }/ |  G1 I, }5 }  D: w
    }
    , W5 Q: g* V1 B, Ltemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    . ?8 S$ W& ?/ H4 x{
    ) I% y6 o  ]! u4 s* N# z9 I    MultiAdjListNetworkArc<WeightType> *p;8 Z+ y0 \3 H* ~* n0 j* l
        cout << "无向图有" << vexNum << "个点,分别为:";% K) I$ `& B2 N( R8 L# v2 @( h
        for (int i = 0; i < vexNum; i++). Z. X7 I2 K, C" Y: M% U/ w
            cout << vexTable.data << " ";
    ! C! u! h; K' C    cout << endl;
    / h# O" o% |; Z( e: }    cout << "无向图有" << arcNum << "条边"<<endl;
    + W9 O6 H1 R% G1 I/ h, F    for (int i = 0; i < vexNum; i++)
    5 z. i* A2 l* ^0 }+ ^& s% l& k* e    {! d) w( b  \, C, f
            cout<<"和" << vexTable.data << "有关的边:";
    ! }' ]0 y" W) H( m8 J9 ^/ a        p = vexTable.firstarc;6 J; D# D) Q% d
            while (p != NULL)  k3 v9 y! ^1 F
            {
    2 L& ^: T, T3 ^' u+ ^            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";4 C& {! ]) h( b% p- N# S
                p=NextArc(i,p);
    , F1 u! x  C5 b% Q* |: v) J        }
    * K6 b2 ~2 H' S) z2 n        cout << endl;
    ! W7 l- e5 N# q' E: M+ ^    }2 b; `: M, e# g2 g. y
    }2 `+ V: F/ P8 A

    2 m) u' K2 K8 b! d; D: S3 u8 i; t) x! `$ K# d: Y
    邻接多重表与邻接表的对比9 N5 K$ k, ?6 w. }. f7 R; ^
    * ]; A4 n: A( l! c% ?% U( U+ ~
    邻接表链接
      v# p% I+ I% ~2 [8 H9 p( m5 A在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。0 y7 ^5 A( ]/ p" T
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。, ?3 q" G& W; R. e& H& i; |
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    8 d6 ^* H; P9 h7 v————————————————
    5 d3 m& u% {$ y: t版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。" _7 }3 a; h1 N0 A3 l
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958  D9 D7 G9 Y$ y: L/ @0 @. J0 O
    1 o9 A3 G8 ?) k8 j" S' E: N* Q

    3 `. b1 u, k9 V* ~5 g9 O/ I( T3 u1 U+ L# V. C

    * w6 u/ f  L( z; [+ M————————————————
    8 y* Z+ H" M, T! J$ ^( k版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。, S+ N4 n& ]" D: w& c1 J
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958+ t3 i, W- G' G; m& }2 b

    * ^- j/ W* c5 |! H5 p* z2 B& H& x! h  \# c$ J8 f
    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-6-9 13:15 , Processed in 0.436358 second(s), 54 queries .

    回顶部