QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1605|回复: 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
    - `7 a# L- `- X
    图的存储结构——邻接多重表(多重邻接表)的实现4 P9 _6 E/ b. z: N6 o
    7.2 图的存储结构% s+ C6 Q  a1 z! e. J" R

    9 Z+ [) W8 Q% w' {$ }2 q* s  Y7.2.3 邻接多重表(多重邻接表)Adjacency Multilist# Q7 ]: T9 f0 ?! @+ K/ d8 O0 @
    邻接多重表的类定义3 N" [5 x) f: ~4 y
    邻接多重表的顶点结点类模板
    , D. P' D1 ~, j/ B/ h5 `邻接多重表的边结点类模板
    / o5 B  K& |+ l. k8 k邻接多重表的类模板/ _" ~2 e* ~4 f
    邻接多重表与邻接表的对比
    ; L, M! R, t; N! F$ W, W2 S7.2.3 邻接多重表(多重邻接表)Adjacency Multilist' _7 Q# R' D6 A$ S. w- `, S+ j
    . t+ V1 x; q" l6 Q# J
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
      o  G4 F# f* z在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。) U: L$ _. ~5 h8 {1 ]$ D. Z! |
    2 k; H, T7 o% g+ X  w) l! X
    邻接多重表的类定义2 q6 v; \9 I! y6 c, T
    1.png
    : I$ b9 l9 W7 L邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:# A2 k# i4 k! p3 x4 D% v
    data域存储有关顶点的信息;
    0 P1 K# S& N9 bfirstarc域是链接指针,指向第一条依附于该顶点的边。" L8 K4 {: y$ L' w$ E, ?) J1 W' I
    所有的顶点结点组成一个顺序表。


    2 G. v$ r1 @9 e5 J8 f; ^2 A
    / h; u' \% `' C& Ktemplate <class ElemType ,class WeightType>
    / [: y$ j5 Q3 xclass MultiAdjListNetworkVex9 y6 B, K2 s1 A$ C/ A. [! n, Y
    {
    1 `6 Y9 g( `  Q8 i7 Apublic:
    . M2 S3 D2 J. v: ~- m7 o! Q6 Q        ElemType data;* K3 R7 [) n! \' W/ ?
            MultiAdjListNetworkArc<WeightType> *firstarc;. }$ ]) X) f& b1 k+ }9 `* W
    , R8 `# G. ^  A# k
            MultiAdjListNetworkVex()! _$ n+ @. h. E$ O# x
            {2 ^) N+ {# v4 f+ Q, p% b
                    firstarc = NULL;2 Q; i3 b* _# o) ]2 h* K6 i
            }
    ) [% i/ C3 M) |% W) X4 T& O4 A1 T        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)3 L) L2 P* P/ ]! ^* _
            {
    4 W8 k: O6 ?8 Z4 m; |8 ^$ E7 R& y3 {                data = val;
    - ^2 R* I4 ^& A2 Z) M                firstarc = adj;3 T3 R$ Y/ [# T. O+ f( U  l( B8 ]1 g  c
            }
    ) Q* l5 o7 d& P};; t5 d! h# B9 n6 l" l
    + t8 y/ O6 V2 [/ n
    邻接多重表的边结点类模板
      \$ j+ |; e, T# F; j' c1 T5 i6 p
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    + g$ |* P5 i2 g* x4 k1 c- c$ Vtag是标记域,标记该边是否被处理或被搜索过;4 @7 o+ W% m' X& J) f
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;% Z9 M' n0 D! y
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    0 s- {8 {$ {1 C9 d& \# p. snextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。; S( j* Z# B! {7 W
    % A  ?: d' p8 _+ M( M; s% P
    2.png
    % K  o0 l) q4 B7 e$ Xtemplate <class WeightType># f; k- Y5 D# D; P" T- u
    class MultiAdjListNetworkArc
    2 `4 h9 R+ e+ m6 z: i5 c% h1 P5 a{
    % f4 y" w( F: V8 d6 ]3 Wpublic:
    8 Q9 g- {  B3 L. D    int mark;                                       //标记该边是否被搜索或处理过
    & R$ {( F) y- D& J/ j1 _. r        WeightType weight;                              //边的权重, e' W7 y8 N, i6 E# a2 Y5 l
            int adjVex1;                                    //边的一个顶点$ @# e+ W3 e6 g: G
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1& m3 h' B% @& [% e8 |6 Z
            int adjVex2;5 G: y& j% F" c' T9 r2 \
            MultiAdjListNetworkArc<WeightType>* nextarc2;( s5 P' D4 Z  p( [* `
    " o- M3 ]" z& ~1 N$ w2 Y. i
            MultiAdjListNetworkArc()* B, {2 T4 F! I9 H: @; o
            {
      ~9 P% \1 D; a; M/ U/ A/ a  U/ X& e                adjVex1= -1;/ G; b. v. s: r) X. A- l2 k* @) l
                    adjVex2= -1;8 t. \  l3 p4 r, Q9 n( \; ~
            }
    ; x6 D, Q2 O$ P' a        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    2 ]% `5 ~/ ?4 p$ f, h/ f        {6 O8 C! S8 m2 g
                    adjVex1 = v1;       adjVex2 = v2;
    $ T" u4 y5 @0 O/ @" \                weight = w;' l# Z, \$ v6 Z8 v$ m
                    nextarc1 = next1;   nextarc2=next2;2 C. g8 c/ J+ b2 m; o! u
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    3 S! N5 O4 x/ p1 P* `( B; |& z        }6 k8 {5 Q8 b* E
    ( A! q3 E6 a* L" H2 r$ Y9 ]" m
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>$ [4 q7 ~+ s5 r3 Z3 d* V
    class MultiAdjListNetwork
    2 Y( b; L* X' _- D; r9 n% w{
    ; v% X3 W+ _7 P* C; p7 C2 aprotected:
    # _4 m9 i4 y5 I, T    int vexNum, vexMaxNum, arcNum;% n1 d0 N% f, \4 j: B) j7 X+ l+ v
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    7 b% J9 |2 f* y    int* tag;
    ) n' p( {) |1 k/ d2 o    WeightType infinity;
    ( S3 z" o2 C, b* E% u+ @; B) u# s6 A. x& o
    public:
    , q) H6 \) u: J% K/ x: y3 t/ z    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);+ E8 a' f" E2 P
    ( w' ?8 G6 c  l/ t, X, g) c# _
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    4 T  U# ^- `2 C3 C) I
    % Y1 G( d1 D% s$ |9 |8 |; k" ]    void Clear();
    6 `+ W! f  U. ~6 L! [+ {4 O    bool IsEmpty()
    4 C% I7 F/ h, b: J7 x0 r    {
    " I0 L( M1 {, d/ [$ y# q+ ?- \, h        return vexNum == 0;
    ) U( C- ~6 G4 P2 M" {0 O6 X- d    }' K5 d. U, w" r2 y( B
        int GetArcNum()const
    7 i7 T  G9 q4 q2 Z7 U; C# \    {
    % S5 O  J# Z- h& c9 K        return arcNum;
    ; r) y' w/ A0 S1 i0 e    }
    7 z8 L! Z! N3 T    int GetvexNum()const# c' a. c( T  R4 T7 x
        {
    # b" _. D! s) W% q1 `$ P3 }6 m        return vexNum;+ E9 ^7 h9 D9 z* K* U
        }
    - u3 f, e" R. B9 q1 s8 t, F0 U
    / q. ^$ J3 q4 P3 S% Q, ^6 f+ q" s1 ]
    7 M$ A6 d- r) U- B% L4 ?    int FirstAdjVex(int v)const;
    5 i* z6 X# j0 e+ e    int NextAdjVex(int v1, int v2)const;/ R6 ?/ b  h2 T5 Q9 e
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;1 w+ x6 W) {' _4 a- u) J% y* {
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;+ [9 G7 p4 w4 c9 N3 {6 d

    % N( E$ A5 {6 b6 m5 W( j    void InsertVex(const ElemType& d);8 U) X) s* D# ?% Z" P
        void InsertArc(int v1, int v2, WeightType w);% L% H; S5 q2 ^

    $ e9 r: ?5 t. ?9 ^0 ]7 \    void DeleteVex(const ElemType& d);
    1 ~0 \$ |' o+ e% \+ Z, B    void DeleteArc(int v1, int v2);
    7 o) d8 q$ G: `1 G; A& T) |4 e  n8 y* d4 ]8 u7 ]
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
      h  q) M1 j- J0 b/ ]0 p6 l0 G, X    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    1 d" i( }& I4 Z3 f+ u. p3 }/ t) Q* W) m# V1 }
        ///深度优先遍历! d& `) S$ h& A& x
        void DFS1(const int v);
    - R. D* u" @! s4 R2 x  S: H    void DFS1Traverse();
    , `3 D: G& z# K0 P* v+ d3 c    void DFS2();
    , V1 X* N8 u% N$ t0 k) @( ^* z+ f* R/ G* P. W0 _
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1+ I  g/ S! x2 P  r  Q% k* {
        void DFS3();% o9 v( l' v7 J

    1 F* w$ w+ K1 h- M/ u' ]' ~    void BFS();
      r5 a. f! i; p+ c, R% l% X9 t7 w    void Show();
    ) Q& O8 U/ J. U2 m3 Z4 S; W% b/ M8 ?% m+ J};' U1 h0 y% I' I! a& G1 {3 {
    + k* R5 q7 ~6 i& d! _- V
    2.函数的实现
    , h: B, X, `& a7 w0 }, m  _4 }研讨题,能够运行,但是代码不一定是最优的。) p/ ~' }! e* `2 Y4 J4 |! @! J

    9 S8 r! [- v" v* E$ O0 |# s( v#include <stack>; @9 E; |9 d2 m
    #include <queue>. B/ E9 g6 W, a
    " B/ h! g  C( N/ j8 z
    template <class ElemType,class WeightType>/ W" f& c& h: ~3 H: ~! [9 t% d) G
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)/ M$ j1 Z6 c- M' E4 Z
    {
    % v  @) C% f& u' a- |    if(vertexMaxNum < 0)
    ) L2 L  p% f1 W" I        throw Error("允许的顶点最大数目不能为负!");- E7 V% _' M7 K4 c
        if (vertexMaxNum < vertexNum)
    8 L$ F$ J7 ?/ l# u. f        throw Error("顶点数目不能大于允许的顶点最大数目!");* E9 J9 H: s3 k% e0 Z- ]
        vexNum = vertexNum;
    ( g3 M0 i+ r3 @) F    vexMaxNum = vertexMaxNum;
    6 [; ~! z  S4 t& z' a    arcNum = 0;9 N# b# c8 k9 S4 q) f
        infinity = infinit;
    , R2 ~# D5 k" g  ~7 y: \9 u    tag = new int[vexMaxNum];
    : K; M: L" f7 p  ^    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    " `4 c% N! N8 v' q$ n4 W    for (int v = 0; v < vexNum; v++)0 t% C9 j/ y3 r' B( u
        {! s9 X- v0 n5 O( x  i+ A6 n
            tag[v] = 0;7 N2 b6 E2 a' l
            vexTable[v].data = es[v];- a7 P, d) o, W/ s, l  F! F3 n
            vexTable[v].firstarc = NULL;& \1 L0 C) _$ N3 d
        }0 P9 u" ~; C- C( E& L# H
    }7 z" v: X$ }! Z  Z& C
    template <class ElemType,class WeightType>/ w# `9 [3 h  v+ e' V5 u- {8 g  |2 w
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)7 w8 Z6 b/ Z; k- }% `
    {: ^( L& V: i) J$ S2 u. c
        if (vertexMaxNum < 0)
    " s$ C% ]$ @) c' E        throw Error("允许的顶点最大数目不能为负!");4 b7 L1 C& V3 O1 u( |, R% ?' M
        vexNum = 0;
    : O/ K  U- l+ {8 @8 A- `" F    vexMaxNum = vertexMaxNum;
    ( ?% ^. B$ }3 [0 v6 U" i6 ~    arcNum = 0;1 ]+ Q  Q! v8 Y! x/ A2 v
        infinity = infinit;  M+ Q# B% r7 \
        tag = new int[vexMaxNum];. X6 L% |3 G% w  y
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    & ^2 t7 M# C4 d1 G}# d8 P7 o  h9 J" Y4 ]7 N" e1 D
    template<class ElemType, class WeightType>
    0 e( X: P2 I4 y1 Q& Cint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const7 \6 W5 C$ X1 O* p1 L- P, ~
    {
    $ c. ]4 a  u8 X$ O& A    if (v < 0 || v >= vexNum): Z6 Y! Y. `% \( ^0 _0 C
            throw Error("v不合法!");9 S* |. x3 K2 j5 w! Z) a( C! [
        if (vexTable[v].firstarc == NULL)# S) Y" |4 j1 y
            return -1;
    & l4 `  c& B3 E% J! J% S    else' S( |2 G7 z$ y
            return vexTable[v].firstarc->adjVex1;
    1 N  q' [+ j$ N}* _- N2 Q) E! G& P' Y/ `" B
    ! [9 ~7 N: e! n+ M6 V' y0 o
    template<class ElemType, class WeightType>
    9 K, t, ^& G1 H  e, o+ Vint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    + I0 N& p) k6 R8 h7 N. q{
    1 K- l9 B( \5 ?* Z    MultiAdjListNetworkArc<WeightType>* p;. z/ q6 O( a* L6 S6 x% z
        if (v1 < 0 || v1 >= vexNum)% V- K$ [- S+ D/ T4 g, N
            throw Error("v1不合法!");
    . n# R3 c6 w! j8 Z. c5 h$ y; |    if (v2 < 0 || v2 >= vexNum)
    ! Y9 ^- _! G# O/ N5 M. a1 @        throw Error("v2不合法!");
    " H. M7 g7 z5 u, t" i    if (v1 == v2)" U( M8 M' l3 S- h) _$ R/ I$ L* r
            throw Error("v1不能等于v2!");- z& h, N1 M8 B+ V
        p = vexTable[v1].firstarc;
    & z& g% `8 R: g    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)* K7 K6 t; F* E/ o7 o
            p = p->nextarc;
    2 T9 z. W. y% c2 h; l( M    if (p == NULL || p->nextarc == NULL)
    . P$ X- j! a0 ^+ V        return -1;  //不存在下一个邻接点
    2 K# `  W2 @# f5 a/ d$ t    else if(p->adjVex1==v2)
    1 ^4 u9 O# I2 t; P) J5 I5 a0 {* _        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    ! y/ B) d  B% F    else$ K# u% h. c  ~# ^: R5 S. P
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
      O; L1 f3 p- |; U/ @% x}9 a0 j  Y  i+ Q, D  W
    template<class ElemType, class WeightType>+ L- N( G/ q( Z
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()3 R& O& j0 l% }9 `- f4 O" A  R
    {5 T1 A' [4 ]5 o; \( h- `
        if (IsEmpty()) return;
    ; V- |9 d8 Z" S' E, L7 L    int n = vexNum;
    * C# _1 L$ w. l/ g2 L9 j    for (int u = 0; u < n ; u++)' S. ^9 F6 D) c( G# b# r
            DeleteVex(vexTable[0].data);$ D, k6 S% G( ]; n$ e& i7 C
        return;
    % J  q/ G: k) Z9 @( L}- W6 l( R  h5 C/ e
    template<class ElemType, class WeightType>
    0 a& G+ O+ C5 I! i# A& RMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()  A0 J! m$ q( B! l
    {
    0 E7 H$ E- ?) Y0 P% M( G- R    Clear();! q* f* Z4 \, T( K
    }6 j  @. T! @( E, L% r; _7 x" u
    template<class ElemType, class WeightType>2 P9 n0 O0 P* Z' {* _; a3 ^# B' D
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    3 `- Y" N- c+ `& y{2 H1 M* ]& ?/ F6 E3 I3 g* A
        vexMaxNum = copy.vexMaxNum;
    ; ]% t  `5 s2 z2 i6 L    vexNum = copy.vexNum;
    ' o5 N5 j* S4 q0 G6 s" h: N    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];/ c6 h6 j! F9 |. q
        arcNum = 0;
    2 Z. P9 B4 R% X4 r5 `, a; Y9 C    infinity = copy.infinity;
    ! M/ X" i: V8 r    tag = new int[vexMaxNum];
    7 G" }3 v1 N+ @- {
    + N" T% Z, K- l' R8 J7 s' Y    for (int v = 0; v < vexNum; v++)
    * c2 h$ F: h1 u4 O    {
    / T) C+ j1 j3 T5 \* }- b2 T9 N        tag[v] = 0;
    " i% m; P0 p% l6 [! _4 I0 S        vexTable[v].data = copy.vexTable[v].data;
    & A% {, j) K! u# ^        vexTable[v].firstarc = NULL;
    1 \# I- C- ~3 d. {0 @    }
    % ~+ ~8 d9 C3 [! Y/ p    MultiAdjListNetworkArc<WeightType>* p;
    - j5 Z- C. g- @. {9 \+ C9 ^2 x3 N8 A) G, z2 E; R
        for (int u = 0; u < vexNum; u++). d1 E. a  D, ~# n  H* f" J4 d
        {) p1 q' a4 B* c
            p = copy.vexTable.firstarc;, x7 k4 V( u  e: G' j
            while (p != NULL)
    0 T* S4 `) n9 h1 C        {+ O+ |* m; i  N. J1 L
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    # T  I* ?$ V% T3 j$ g            p=NextArc(u,p);5 |( S$ z0 \3 o, T8 q
            }
    6 h' |" v" q) o5 l    }2 q" H) ?7 S/ d( `7 @
    }
    4 r: x) M6 R8 j0 f0 R/ Ttemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    0 L2 }3 e* t6 i: d( N4 M  uMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
      p! H; x' q4 V% P4 T# k3 i: p3 {{
    + y+ L. l! H* e4 ]! ~5 H+ ^* R    if (this == &copy) return *this;' h" Y- D! T" M4 y0 g) X6 u8 h
        Clear();
    $ C) ~7 \4 C4 `; Q/ l    vexMaxNum = copy.vexMaxNum;
    . w$ m2 P: C' l! c+ u  c" I$ s    vexNum = copy.vexNum;
    ; z9 L7 Q3 v. e8 l* d    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];9 p, q2 O# u6 v( h, g
        arcNum = 0;
    ; R5 z) {, m# u- L* H7 c& R    infinity = copy.infinity;
    ( S; T) c' }4 Z- Z$ z- G$ w    tag = new int[vexMaxNum];5 p9 V* Z5 V- `' ]1 Y& n: n: h
    ( O: U: t  y3 ^3 g' r
        for (int v = 0; v < vexNum; v++)) ^; ]: q  c% u! t
        {! q" e% E0 I7 v% b1 W
            tag[v] = 0;* _4 f4 V4 x- k6 k
            vexTable[v].data = copy.vexTable[v].data;! Q% g. W9 X) s8 @) u
            vexTable[v].firstarc = NULL;, o- ?- b4 x" R, w! h
        }( Z+ ]2 w7 c8 m8 _6 j% m9 E
        MultiAdjListNetworkArc<WeightType>* p;( C1 }0 G3 l& z8 w# A: p

    1 c, O; E4 J* S9 A    for (int u = 0; u < vexNum; u++)
      r$ Y0 J  p; f( n4 B# r( u1 S    {
    1 c$ l; G) M! ~) g        p = copy.vexTable.firstarc;" {' |) }) u3 V9 a; v  x, B
            while (p != NULL)8 O8 E+ S9 d0 h" C5 w, }
            {& g2 C7 x" M% Q% j. M( K
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    . j$ A# w6 t, _, p: c9 Q; H  G            p=NextArc(u,p);' F) T( y: A/ v5 i. j( L1 d9 W  |
            }1 \- A' P! L& d0 [" z2 [5 L
        }1 y; q3 Z* d8 p* _
        return *this;; T  ?  g( B" \0 E! a
    }3 B$ n8 @1 P; k8 x
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*8 q2 {: l0 e( P4 B
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    $ Q- V( y# ~+ I9 S{
    7 |- Y, ?1 ]7 g  Z9 m    if(p==NULL) return NULL;7 ?" r  h0 F6 |2 Z
        if(p->adjVex1==v1)4 }: A& Y, t; Z& d; j" f' q! j
            return p->nextarc1;. @. Y/ g& @, R; i) h  T  I
        else
    ) g0 r% K0 }' d6 [7 @! B% N5 L        return p->nextarc2;
    % S, V  |% k# ?0 W6 G}4 H2 o( E7 X! n1 C
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*7 m! Z2 [$ ^2 m5 h
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const8 c( f  v  y" F1 t7 e3 e' k
    {
    ' [0 B  d- x5 o. y6 [6 W    if(p==NULL)return NULL;: M% ?6 G3 N, @3 v
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    0 l: F+ e& v( L: e& ]    if(q==p)
    7 X. d3 r6 ?# N! K% K: Q: [        return NULL;
    " l9 f: }, q1 @2 F/ {3 k9 r; h    while(q)+ G2 m& f% n9 r6 T2 T
        {
    ; z$ L# F/ O1 d& ^# J& V        if(q->nextarc1==p ||q->nextarc2==p)6 m+ X, ^  Q  m! R* ~4 \
                break;3 e6 X) b6 M  b; A2 ^
            q=NextArc(v1,q);
    ; }' {+ A/ ^+ n) r! N    }
    0 w: H* D% |) y' O9 P$ ?! {. k- E    return q;
    & U  W2 `2 R% l, A}) N/ x2 j) }2 _* F9 E: M4 H: b: B
    template<class ElemType, class WeightType>( N( O# i. S; C# F
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    ) d; R* m: I8 t( K+ R8 F! a{  V7 I$ y. i2 B$ k7 p& a! b8 b
        if (vexNum == vexMaxNum)
    - n4 {* n+ l4 o% F& q1 v        throw Error("图的顶点数不能超过允许的最大数!");6 q! e4 ]# N1 h, [+ @2 T
        vexTable[vexNum].data = d;
    8 H7 Y$ M5 l, ~9 ^4 X    vexTable[vexNum].firstarc = NULL;
    ) t- B' t  s- r" h8 Q6 K    tag[vexNum] = 0;# H! v4 o$ e) ^0 ^5 Y, R
        vexNum++;, [+ M; l3 S8 v4 Q3 M, \
    }$ E: i# J  G- S& z
    template<class ElemType, class WeightType>
    ( f# k/ q: H6 c! Ivoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)/ T) C4 g8 c) z! z" S5 t3 p% b
    {
    0 Z6 l# _! i, G/ P    MultiAdjListNetworkArc<WeightType>* p,*q;# D8 d- `* C' A5 `
        if (v1 < 0 || v1 >= vexNum)7 {( I. x- T0 w& b4 M
            throw Error("v1不合法!");6 y" b# J1 ]) q4 ?* H
        if (v2 < 0 || v2 >= vexNum)9 R: Q% V3 h1 L5 K1 @  Y
            throw Error("v2不合法!");
    3 D/ y" b6 T# V3 l! N0 `    if (v1 == v2)0 [: `( {" c/ [0 E) I/ y. d
            throw Error("v1不能等于v2!");0 k! P" ^; S2 W
        if (w == infinity)
    " o6 f2 g) V; P        throw Error("w不能为无穷大!");
    . s/ F! c7 h. ]! g: F- M9 p0 C
    ! X( x1 ]3 d0 c- F- z# b) }0 E: m+ S. x. t/ I0 Z
        p = vexTable[v1].firstarc;
    & o3 E6 r/ T" r2 V2 I. s3 e    while(p)
    0 _. `" G. Z% o* U4 Z+ U" [  H; O    {( e: T8 C: `6 d& r& v* C1 T$ R
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    : }, b) Q2 g+ e6 [+ p        {
    # c5 P/ O) f* O, Y            if(p->weight!=w)
    ) m: i/ V$ k+ e8 A                p->weight=w;
    7 `* J, F  s; ^4 @; }            return;
    ( F! d1 d( j, {  q        }
    ' r$ P/ B  m! S1 p" c& X2 C6 K8 i: R4 m$ _! S6 ~- P/ U# u
            p=NextArc(v1,p);
    3 R5 A0 @3 ^6 w2 w    }5 Y* n% b. i) e) j& O4 k
        p = vexTable[v1].firstarc;! Y& W. f8 d* b7 S
        q = vexTable[v2].firstarc;
    * `3 O" p3 k- w. m9 L$ l    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    ) x2 a& I* Q6 P3 U- x    vexTable[v2].firstarc =vexTable[v1].firstarc;% H1 \, z9 `2 F+ A4 D$ W9 I- `
        arcNum++;$ G" S! n; t) w. s1 H
    }
    ) }8 W, w+ Y" H5 P4 ^
    ' p  N* x% B, k" F; u# u. Q! ~4 G( mtemplate<class ElemType, class WeightType>
    % r( \9 g) Q% ?  Y, r5 mvoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    ! \& `( x, \4 Z( z  k{0 Z2 L/ M6 M1 l. h$ c4 K0 p
    5 U( v0 M5 E) [& @1 |: X
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    4 }( V5 @* @3 v# I# T# ?. S    if (v1 < 0 || v1 >= vexNum)
    , x7 _& S; e" X+ R  G' L$ z4 G- c1 E        throw Error("v1不合法!");6 k5 a" j( }2 _* I9 `* _; h# ^
        if (v2 < 0 || v2 >= vexNum)
    : @! F- x+ ?& F        throw Error("v2不合法!");
    - B) j4 C# P; P0 E, e    if (v1 == v2); `- ]1 a" ]' Q9 U! ~
            throw Error("v1不能等于v2!");
    8 w! O& C! o. A  W* W" c1 V7 H8 p$ h* i" P  C
        p = vexTable[v1].firstarc;
    ' F+ |9 o& ~. c' |& z2 p5 r/ c. T  H    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
      M% B' }0 B4 N1 n; W8 U8 X    {& p$ X3 ^( ~* o# j2 [- G
            q = p;
    7 t, u) t7 y( E6 m# ~9 {        p = NextArc(v1,p);
    % \" O" r& H7 R# g5 k( j    }//找到要删除的边结点p及其前一结点q9 [1 F+ m% t1 _3 V, }2 i
    ) N$ E3 t0 Z# ^- m8 j
        if (p != NULL)//找到v1-v2的边! U$ \' ]1 w% |5 w
        {
    % M, W/ c, m, c2 {8 M8 `2 H3 d        r=LastArc(v2,p);
    ' F0 [# Z/ a' N) i        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    % O2 u2 }8 e% J$ U            if(p->adjVex2==v2)& W/ I; Q. G) A
                    vexTable[v1].firstarc = p->nextarc1;  H( }; o$ ~  b. R1 i4 i
                else vexTable[v1].firstarc=p->nextarc2;
    ( r: U, S) v" M3 J; R1 O        else//不是第一条边
    6 R; M2 i3 C8 }7 p' _0 |1 P        {
    * Q" [1 p) X' N1 Q            if(q->adjVex1==v1); j( E  J( w# a, m, T* g( L: S
                    q->nextarc1 = NextArc(v1,p);" K2 j* Z* @$ q' ]: q
                else" G" Z; g& R4 @5 g. |+ G; N
                    q->nextarc2=NextArc(v1,p);
    % }0 {; W4 p0 ]- ^- b
    + O( P) E! E  K* G- r- w$ {9 E0 [        }
    4 s6 d2 x- M) i0 G        if(r==NULL)) p" k1 m( ~: `; A5 r0 ~' W7 b
                if(p->adjVex2==v2)% B3 m. `" b# f
                    vexTable[v2].firstarc = p->nextarc2;& c# N5 W; B7 T* B' S
                else vexTable[v2].firstarc=p->nextarc1;
    6 S5 [) z( u2 Z+ I- Q        else! w) t) [  j+ U, k# R" D
            {! Q1 o( Z" u' r! o% b5 R0 O( ~
                if(r->adjVex2==v2)8 e5 d) a0 k- f0 u
                    r->nextarc2 = NextArc(v2,p);$ J( k. _/ a  X; Q
                else7 }2 c+ Z0 T# r/ a( U" v) N
                    r->nextarc1=NextArc(v2,p);
    - f; {7 ^8 G$ f4 |  L        }
    5 D1 H! S4 `" L        delete p;
    / k2 l( Q+ A& n, c% _+ O: ^2 V' t: v  [+ J        arcNum--;% m" x, h' v  o' _
        }
    $ m7 J8 |+ e4 ~$ L! C6 U. C- N' E
    2 b2 h& L' |+ O! o0 Q: z/ e}) X  K. H: f* |- C
    template<class ElemType, class WeightType> void
    & @' L& Y( o6 V- R" S0 CMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)7 g9 e# w, E  G) G6 G
    {
    8 k7 M  `' n% k0 K+ C, V    int v;
    / X! u2 U6 y" G, C& G    MultiAdjListNetworkArc<WeightType>* p;
    4 P. F2 t; P3 z* f% g1 P% D    for (v = 0; v < vexNum; v++)//找到d对应顶点
    3 ?: w9 N$ D7 F/ F6 Y        if (vexTable[v].data == d)
    ' W0 F! ^- Q6 S7 X            break;/ o% X* A; \( w* x
        if(v==vexNum)5 @* @$ B# _% i6 P' h) w
            throw Error("图中不存在要删除的顶点!");, r. s" y4 b  |! x5 B2 S9 _% H

    ' C1 T& X& v: h+ H    for (int u = 0; u < vexNum; u++)//删除与d相连的边7 x/ L- G2 I' `0 ~* g7 {: T+ K
            if (u != v)
    7 @" s$ u, G0 U1 E$ g( r        {# x7 v9 n: ~4 J+ D1 I" t
                DeleteArc(u, v);
    2 Z" i- `0 X, W2 q3 c        }
    / z$ y. r- K0 v: G/ B' l1 o    vexTable[v].firstarc=NULL;6 T& p4 q2 M" ?3 R! p( v( d
    % ]2 p* J0 e. @5 S5 K0 i. q! n
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置( D  E% M$ o3 f4 ]$ y3 b
        vexTable[v].data = vexTable[vexNum].data;
      x4 Q- M8 Q. A; }5 D    vexTable[v].firstarc = vexTable[vexNum].firstarc;  B1 I8 `5 g, A
        vexTable[vexNum].firstarc = NULL;; `- f; l3 g2 ?1 B/ Q7 A3 {
        tag[v] = tag[vexNum];( `/ o& ^& Y0 }; s+ C" D+ G
        //原来与最后一个顶点相连的边改为与v相连4 y: q- ]5 W4 [$ d' O
        for (int u = 0; u < vexNum; u++)
    9 J$ O3 n& u& m    {
    4 T3 [- y! H9 i. u        if (u != v)
    ; P8 q+ F3 l9 _0 }$ q        {
    . y/ p" i" R" Y  J2 \7 ~            p = vexTable.firstarc;
    4 N- P. b& P* P# B* T+ d5 J            while (p)
    # r6 j  I" f1 {" |; D& Q7 ]6 @# r            {
    : ~% C; v4 B. G, C" Q% c' P                if (p->adjVex1==vexNum)5 C2 ]& }# }  o) B
                        p->adjVex1= v;
    % W( L2 C% O# a. u6 t; ^" C- a                else if(p->adjVex2==vexNum)
    7 J' K1 ]5 m; F                    p->adjVex2=v;
    3 L9 t7 ]/ @$ a1 S9 W                p = NextArc(u,p);. \! ~4 E" }2 [  @& P: M7 b- R5 b
                }- ]2 Y( S9 q/ m
            }, G8 a1 N% X( }7 G4 |; t
        }1 Q8 ~4 [! b/ m) {+ E/ Z
    }
    * d. X6 S2 x) R/ H* Z3 I% @1 g8 F///深度优先遍历
    " @; z1 [; |/ vtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    ; L1 W* g4 B6 I; \{, S/ _2 Q; ~2 b/ @
        tag[v]=1;0 v, q# S9 }; H/ x0 ?0 a  H
        cout<<setw(3)<<vexTable[v].data;8 G/ E! e( w" S* m3 Q
        MultiAdjListNetworkArc<WeightType> *p;
    7 I1 ~  B- \$ g. f; E2 G    p=vexTable[v].firstarc;
    + T9 r- i6 c+ H' h" J1 a$ y    while(p)
    & e$ B5 i5 ^* s. d9 b+ `4 k    {
    # b9 a) S; e% l: @        if(tag[p->adjVex1]==0)
    7 ]+ q* R+ O2 {+ R5 k: l            DFS1(p->adjVex1);% l& f( a6 W: s6 E/ c
            else if(tag[p->adjVex2]==0)
      ~6 y% r# W  W0 w            DFS1(p->adjVex2);% K0 r5 E# U" l
            p=NextArc(v,p);9 c  u% d' o3 y, a( O/ r3 V$ }/ ^
        }/ h0 F$ U6 Z9 T
    }
    8 h) j1 z2 s' L7 L2 I" Btemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()  b) Y* D) Z  T6 h! P) D
    {
    9 L+ W) _6 X% ]$ k9 }1 e, ]5 ~4 j    for(int i=0; i<vexNum; i++)
    ; y  P, M9 ?8 [  p1 a  X2 g        tag=0;, I5 b/ a' C8 Q4 z. O
        for(int v=0; v<vexNum; v++)/ I+ j. Y' E5 a9 l, f$ e5 R
        {
    3 U  @, t+ w# B. r) ^, Q        if(tag[v]==0)
    ( K) I" D7 F( [# L6 \+ z            DFS1(v);
    8 m' L" F2 ^" e) c! ^# C    }
    . i' K  n: S4 k: }6 }6 ~}
    0 u; s& V3 U8 w2 l  O9 btemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()$ c1 d4 h4 C; C1 O  T( {5 N
    {
    & c7 F* `2 c' n4 p& Z: f1 }. c    stack<int> s;
    : ?  n- C2 L+ p) G7 V    int tmp;
      ]2 U0 V) L% @4 T* A    MultiAdjListNetworkArc<WeightType> *p,*q;6 t( A2 Y' u4 `
        for(int i=0; i<vexNum; i++)
    , H) B0 j4 B5 u+ g8 ]% x        tag=0;) p* O! C& D* D. F- f. t
        for(int i=0; i<vexNum; i++)
    4 u, b/ T, d3 }8 |; t1 n    {1 q& K- ?2 {' F+ J
            tmp=i;7 Y" o$ f+ {/ U' ~
            while(tag[tmp]==0||!s.empty())
      N3 ^; l) }; i5 e        {2 u) n! ~0 G3 q2 K. B
                p=vexTable[tmp].firstarc;" R/ n0 f0 V2 {5 @
                while(tag[tmp]==0)
    ' E; f- d0 H# `/ q" c4 a9 m" `            {
    2 x; ?0 K5 M% O/ h( T: C$ E! c7 O                s.push(tmp);% b% y# N+ [  R! N- g9 ^- R
                    cout<<setw(3)<<vexTable[tmp].data;
    9 Q0 @4 y4 \0 N7 a                tag[tmp]=1;
    ) ~/ |7 g8 {; r6 w# A% V                p=vexTable[tmp].firstarc;7 f8 c/ U2 W& ]" ?" c
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for" P9 F- N/ b) `: R" }
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);+ u$ i' X5 e2 X8 p9 y3 q
                    //cout<<" 1st     tmp="<<tmp<<endl;: E- b& g' ?$ Q7 w' P/ z2 z
                }
    3 ]& M( ?  E  B1 J' Y            if(!s.empty()); i, i; X5 X  m7 q
                {
    - c6 N2 Z$ N9 p4 m                tmp=s.top();4 x* @) t. X2 Y1 ^4 ~, j9 X
                    s.pop();( P3 N/ u# n/ e& F
                    q=vexTable[tmp].firstarc;+ O" Q4 ~( ^* |( \
                    int t=tmp;
    6 z, W1 B1 A+ I- ?* ~                while(q&&tag[tmp]!=0)
    0 I2 A' B' e: R" B  z+ _                {
    - N$ X2 I6 Q, w+ |. @7 R8 Q                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    6 F" d9 N) V/ T$ ~# T: f! J                    //cout<<" 2nd     tmp="<<tmp<<endl;; V, X( i( c# K
                        q=NextArc(t,q);. c8 z! Z/ K3 T4 T2 b( c; i2 \( q
                    }$ y* V1 ^# W& j5 ]: ]! q% ?
                    if(tag[tmp]==0)1 l) u3 ?& E( u0 X- C' F- p
                        s.push(t);
    7 i; h! S6 V% W# K. T  j                ///1、对应上面连通分支只有1个点的情况
    , f1 Y* v! C( V- B0 G* r                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈# H. S7 B" b5 J6 n7 q/ {' t# w
                    ///tmp要么等于找到的第一个未访问节点,  Q" z  ?& V( K4 T
                    ///要么等于与t相连最后一个点(已被访问过)
    7 \6 F* O0 P3 d% _6 A1 V: V                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    : ~0 y9 F3 z3 S2 D            }1 F! p% D! @0 E4 B6 y2 F) j; Y- [
            }1 f( W  A. a& X, T' _
        }
      m* g" z) b5 V}
    # c* f0 c2 d# ]) b9 U' Z  q//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1, E+ b' L0 H- K0 c8 i4 Q
    template<class ElemType, class WeightType> int
    " {! \, r, X% K- XMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    . ^- m2 o( S# c( N9 n" b1 R{
    / V5 ^* [. A0 P    if(head==pre)
    $ {; j% r4 E* }' B  i/ D$ K: s        return -1;
    ' [5 z: E% e3 a, f0 S4 c( M+ W$ E& M* G2 \* K
        MultiAdjListNetworkArc<WeightType> *p;
    : @7 }* ?' U0 ^8 C9 V2 x4 ?    p=vexTable[head].firstarc;
    9 c' l, I  G# e: O& z% }    if(pre==-1&&p!=NULL)
    3 G8 E6 j! C4 l8 P# v        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    6 o5 k, p3 t- G8 u- w0 O% C% `6 v) S    //pre!=-1&&p!=NULL
    7 G5 N0 k9 u7 m1 _6 n) G    while(p!=NULL)$ q6 @7 N3 Z+ v% I/ \& x, I) h, H
        {# E, g5 p9 a: a0 f+ h
            if(p->adjVex1==head && p->adjVex2!=pre)
    / V8 b4 X# c; J5 A0 r) E: }. {$ V            p=p->nextarc1;) T! I, `# {9 `  ?4 X8 \
            else if(p->adjVex2==head && p->adjVex1!=pre)
    * `2 ~+ R9 m1 n* |            p=p->nextarc2;  w! Z+ y# G$ m& E/ i5 I
            else if(p->adjVex1==head && p->adjVex2==pre)3 a% X; q2 x+ A
            {: R0 i3 Z9 P# [  W- w% t& a5 k* {
                p=p->nextarc1;
    1 G+ w5 r, L. {* [6 A            break;
    - V) Z: B7 Q: D, d1 s, \        }
    ! _( @; a$ c4 R) U. N- s        else if(p->adjVex2==head && p->adjVex1==pre)
    % {9 Y( U' w6 T  A        {% o2 m5 n2 J' I/ p* ]3 |/ N( K1 o
                p=p->nextarc2;& I) w* _$ W! h. K3 ~, u
                break;
      |- Z, [- k) S$ t        }
    1 k1 v: K: W! j    }+ q. H, D' S7 Q1 z( v
        if(p!=NULL)
    ! Z+ [" M# k: E/ L& _  g( D6 W    {1 h6 {) m6 R+ i0 C4 P+ a
            return p->adjVex1==head?p->adjVex2:p->adjVex1;/ _' A/ M1 J3 E3 f9 i9 c
        }
    ( a% Q, ]+ u) g5 b/ H/ V( L4 o    else4 a. Y1 X$ x( A  j
            return -1;
    % q2 r/ o3 B# r5 m' r  \2 q}
      y4 r5 l& h/ v! K" B& w( g# T# J) r2 i: Q2 {

    6 ?! ^2 [8 S- i/ O1 {' e# _1 o1 Utemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3(); f; Q3 W8 U+ L0 ?8 n1 X$ ]
    {4 S% E8 a! x0 [) Z3 Q  E$ c
        stack<int> s;
    7 E  r' r3 |7 e( h% w( g% y    int p,cur,pre;
    + Y8 R- i8 k8 a4 n    //MultiAdjListNetworkArc<WeightType> *p,*q;' {0 b" o8 B$ R6 {
        for(int i=0; i<vexNum; i++) tag=0;//初始化
    / I/ s$ F, D9 V7 p# ~
    4 X! j1 W  ?, S    for(int i=0; i<vexNum; i++)
    . T6 l- d7 s# W% `    {6 N) e5 i( n5 i* q# L( x2 H+ E& C
            cur=i;pre=-1;
    + W, ~' q3 E5 [7 `$ A0 v        while(tag[cur]==0||!s.empty())
    4 v) Y  R' J5 _. ^& ?5 d, m        {, w% k9 v6 ]: k/ S8 Z/ o- y4 h
                while(tag[cur]==0)/ n% W, Y  E3 w+ t
                {
    , _- ~3 p2 d" f& f  ^/ g                cout<<vexTable[cur].data<<"  ";7 b7 s# _& t$ {2 P
                    s.push(cur);: Y" Q+ ]) A5 \0 L
                    tag[cur]=1;
    0 ]2 [+ u( q( C/ Y               //初次访问,标记入栈5 s" S* C: E' Q& B  `5 a

    * \' y& y6 \, t* [               p=GetAdjVex(cur,pre);//p是cur的连通顶点
    7 x6 H& k- ]/ o  X. E               if(p==-1)
    2 |$ e. U" M1 W7 w# G' a% X! _               {
    4 N9 t( V- `* f                   pre=cur;s.pop();
    # O$ X+ ]% r$ G, {/ ?2 X# x                   break;& N2 d; \9 e: i' J
                   }
    7 G8 j) R7 _3 D% g               else' L& B% k: N0 ^+ ^1 y1 J
                   {- D7 t' Q0 C+ Y: w" q1 W' n
                       pre=cur;, B9 @  ?( g, X% K$ A; |" d9 \0 R
                       cur=p;/ K# l& }) S# n0 S
                   }
    - f9 D: {' \1 _) C. y/ q9 P1 a1 e6 r# C4 O' C3 R* ~; V5 U
                }7 q2 e1 ?1 o- [, m
                while(!s.empty())7 N4 T9 o( G! e* I- {# o* P" c
                {7 h2 }5 T% J8 i2 T: P
                    cur=s.top();. A: j: U, R/ C' m  z9 W3 U$ f& w/ [) l
                    p=GetAdjVex(cur,pre);, r3 X; T0 c6 f' r1 T% a  @0 D
                    if(tag[p]==0). Z8 M8 C0 F3 A$ g# N2 C
                    {2 P* D! o& k" R! V% b/ m  `' W
                        pre=cur;
    % h" ]* |3 z4 h$ N* Q/ g3 f' [* u* T4 {                    cur=p;( ^: w( G" R5 ]' b! t* k7 S
                        break;7 V6 ~6 X8 R- J# Z
                    }% {, W* J7 }, `( Y- A' M5 M9 o0 x
                    else
    , w2 A8 {6 O0 Q0 Q: Y, x                {
    * J' I0 W* A5 h3 D5 _$ J  o                    pre=s.top();& p0 I& y" n, q9 ^8 K
                        s.pop();
    2 W+ }8 J4 `0 |5 b7 Y& g                }
    0 H$ n% j0 [* g  h
    6 v% \: K& ]* }0 p            }- d: X. l% T) D+ P, J* g
    # P& R5 F0 u, L, e6 B. B& q
            }
      `: l+ M! w8 l; Y2 ]' A6 B1 u% \    }
    $ F; M9 A/ ]5 g; v, C- B}
    6 z$ Y4 L- G( w. d* Utemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()9 s' O$ |9 W. \0 y( Q  Z2 S+ m* W
    {
    6 n4 m. |8 q8 r4 b: H    for(int i=0; i<vexNum; i++)
    ' r  `: j4 y- i2 ~& a        tag=0;  U1 ^4 c3 a" A* N! n+ S
        queue<int> q;7 I( F3 s( d! W- o+ i
        int tmp,t;" H, J  e7 {. j8 F/ I& z$ s
        MultiAdjListNetworkArc<WeightType> *p;
    ' c9 O3 F2 `& C; I! d, i    for(int i=0; i<vexNum; i++)( x. l) s4 ]* S: S
        {" m4 S1 P5 v' S7 ^% ^- r
            if(tag==0)* P, R# j2 {" G  F, h4 q+ R/ v
            {
    0 J0 p7 ~" k, A1 }* W            tag=1;
    9 g% B% E- [( r            q.push(i);
    5 z$ V+ b  \9 V  q$ w8 s3 n            cout<<setw(3)<<vexTable.data;
    ' U9 j6 Z; M  A# _5 B        }
    . ~, V% n$ ^+ y8 c3 B( b9 S        while(!q.empty())1 F1 I9 y- |4 o, D6 h
            {
    0 A. `8 u  T! g6 V            tmp=q.front();
    & ^. |* I" I' _            q.pop();
    6 [7 k; v' l3 M7 Z* m! R            p=vexTable[tmp].firstarc;
    ; P  x. i' C" J& I+ F  v            while(p!=NULL)1 T' h3 v0 D3 n8 x* Z' T
                {2 O; }$ c( N8 N: L& g7 z
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);# V  ]2 H4 H: e# k4 v
                    if(tag[t]==0)! V& h) [, S2 N3 p
                    {
    - {' R; o) `- D2 l; V                    cout<<setw(3)<<vexTable[t].data;
    ) A" x( ^3 o6 s* c- Y                    tag[t]=1;
    0 g4 _6 K- s# }) T3 C  ~                    q.push(t);
    2 t2 T( j2 @" O' t5 h                }
    6 S0 L8 d' }+ ~+ D  o& K. i! d                p=NextArc(tmp,p);3 C+ b4 m3 }4 c& L0 \2 M
                }
    ! e6 q* ]' a6 X; S; L* F0 D3 L        }, U4 v0 d$ K/ i& H4 u* Z
        }
      a: Q  i% R9 i& q}! l0 }7 w8 A: F# C- |7 E
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()! O: `* _1 Z- v% w- {
    {
    6 k9 u9 y  I5 x/ N    MultiAdjListNetworkArc<WeightType> *p;0 a$ I6 r- _2 s; d, z7 z5 u
        cout << "无向图有" << vexNum << "个点,分别为:";9 d, F. }/ g0 l: T+ r
        for (int i = 0; i < vexNum; i++)! w4 `2 l1 [' b, Z
            cout << vexTable.data << " ";
    * O" V: e7 v% v& ], q/ Z" Q; W    cout << endl;1 D9 i* o+ J2 X- r3 ^3 S, w
        cout << "无向图有" << arcNum << "条边"<<endl;
    6 {# `, V! P4 X8 B8 r7 t! I    for (int i = 0; i < vexNum; i++)
    5 T- i5 A; J( @1 Y    {
      J. G( W& x0 r) C2 Y        cout<<"和" << vexTable.data << "有关的边:";$ g- y" n$ t' Y
            p = vexTable.firstarc;
    1 r0 `4 U, M- [0 U% K        while (p != NULL)+ L9 V6 [7 b# }; D, ^  V& E' k
            {" B) @8 `/ o# |7 ]! ~; y9 G9 z
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    4 h1 V4 n3 q$ X; w* h            p=NextArc(i,p);7 ~. j. E( N) g; F: k, G
            }
    1 z5 l: K: L! g' f' r        cout << endl;4 n) X6 Z' C7 c  ]4 m
        }
    . A6 k& R; z( U. {3 ?}
    7 s( V4 E( p/ `% u) Q. p6 k. E' E3 B7 g
    / o' C6 F: [9 i% y, t
    邻接多重表与邻接表的对比
    $ K- {% G5 J- i" v1 R5 f- x
    5 g: m, H# W# S5 K- Q邻接表链接' x6 n6 w. M; F' k2 L+ d3 J% P
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    - u* N; m( c: Y8 j5 `在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。, v7 b! o+ }* E& l9 Y
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    7 R9 Y+ w+ E0 s& L————————————————
    ; d3 I: |8 I. l4 w版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。5 s2 k0 _2 D. O3 d; _# X% P7 a8 V
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958, F$ J: h. u. ~
      Q4 A& c, M1 U& Q
    8 O9 `5 j0 U% [
    , V7 j4 [6 _. h4 P

    1 `- `9 y# x: ?————————————————
    ) W- s4 t! O3 J版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ! j' C8 r" b- h* U7 _! M- H0 p; p- H7 m原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669585 t5 e" G; b4 J% H) h9 M

    7 I. V+ u, ?# E7 y' C: v. V2 Q! d# z* O( ]
    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-4-21 12:53 , Processed in 0.411041 second(s), 54 queries .

    回顶部