QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1544|回复: 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
    , ]* J! s6 V; |3 f, Z- g4 i
    图的存储结构——邻接多重表(多重邻接表)的实现
    : n8 v  D8 C  U0 R) T: {/ [8 k! G7.2 图的存储结构
    & M# a5 X* T& m& `& q8 B
    $ h2 G% z' d% s7.2.3 邻接多重表(多重邻接表)Adjacency Multilist8 r8 v* G; f) ^3 D
    邻接多重表的类定义
    ! t& @8 X& y! Z' n6 _邻接多重表的顶点结点类模板" A# M* }2 r; i5 X
    邻接多重表的边结点类模板
    ( M( H' e) c0 ]7 R邻接多重表的类模板1 ^  n& \6 Y% c: _% ?
    邻接多重表与邻接表的对比: d  N2 A' D; s3 S
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist4 B  O; l6 `9 P0 q0 c0 S

    2 D2 A  a( P  o+ k. s6 l  L在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    . Q9 G8 i" F4 _在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。* Z0 D5 }7 Q* q- M/ }# c) b2 o

    ; P. f( ~5 k/ z7 W$ k邻接多重表的类定义# l0 M% Q8 j+ W4 C8 d& u
    1.png
    4 ^7 C; ]# k. }3 J/ z* I3 t邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:2 D. p/ l/ d+ {1 d
    data域存储有关顶点的信息;% F1 p. {- {+ k7 q" Z6 n
    firstarc域是链接指针,指向第一条依附于该顶点的边。
    , r) {  U3 Q7 X! c- E所有的顶点结点组成一个顺序表。


    : d& v+ U- V: t  z$ V4 c' f1 P1 Y8 l5 g: |8 T6 `# Z
    template <class ElemType ,class WeightType>
    - Z; m: d* A5 E; R' z" ]+ ^  [! d. iclass MultiAdjListNetworkVex$ f$ L( \5 e9 g3 Y
    {: D9 U6 n( a5 Z6 Q2 q5 I/ E
    public:* X. Z6 s) E  C  K. E  Q+ ^
            ElemType data;% v% F) ], B5 x/ T- m
            MultiAdjListNetworkArc<WeightType> *firstarc;% t9 Y1 e8 S# h+ s

    5 q2 m  X% O) V5 \& w- c) x        MultiAdjListNetworkVex()% y" K* v; ]9 @  X
            {" ]0 V6 R; F' O) C) M5 M
                    firstarc = NULL;
    . W: E7 A0 F, [. O        }% r1 B8 a3 Y; F, d- l: i
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)/ s- S5 b* |$ l/ U2 X! k
            {2 S5 `% K* E9 Y; U
                    data = val;5 ^5 w0 e5 z* F; Z8 U  O2 @
                    firstarc = adj;" E% Q  U8 f& w9 J9 |/ E
            }: `$ ~4 I: \7 J" o. ?2 \
    };
    : x9 P# g& ]& q9 q6 r$ Q: O# D/ F% H9 n4 S
    邻接多重表的边结点类模板3 ^- x$ |) ]1 }7 G. d, r# f  G

    3 p$ E9 @/ I& b  b, I在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    4 I% P$ B+ l: _; etag是标记域,标记该边是否被处理或被搜索过;
    ) X& v7 G1 A. S! R/ @' I9 {4 vweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;7 Z' c! F, ]5 A/ a: E, g
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    4 ^7 j% ?, G8 w+ x5 q  o8 [nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    5 J1 T' O; m) S: A3 p7 Q% m6 g. w2 [+ Q& u0 ?3 t* F0 l8 c5 F
    2.png
    + Q+ b5 U7 {& rtemplate <class WeightType>! J  u0 Z) M/ ^6 E/ M  z
    class MultiAdjListNetworkArc
    * \( p6 u  |: H{
    : p2 A, X+ t7 {public:! [) r& q) i1 f9 f4 n
        int mark;                                       //标记该边是否被搜索或处理过) X( K1 b& D6 l3 `' u2 U& x* g' M
            WeightType weight;                              //边的权重
    / |% n, C* Q- ]  h        int adjVex1;                                    //边的一个顶点
    - E9 g. ^* ?0 ^; ~$ e6 R; s) F        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1: V, a  X" I% B; Z7 V) y* }/ L( Q
            int adjVex2;
    , H" E6 x" o+ ?3 k8 h        MultiAdjListNetworkArc<WeightType>* nextarc2;
    7 {9 L8 E( w, [" c/ B: Q* d) h  y- f+ \# L& e
            MultiAdjListNetworkArc()
    * K6 w' k: W+ l  X; D: B5 Q        {
    - A3 o# a) L4 Q$ H: L                adjVex1= -1;
    - M4 Y, |, m, ?( ^                adjVex2= -1;, w* |( v  g+ e% z6 R+ d' M
            }! H. Y2 \7 R" d; e' u
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)$ k$ @& r3 o, }" w% o, @! c1 r
            {4 W8 R0 M: [2 T) e! ]
                    adjVex1 = v1;       adjVex2 = v2;
    0 |+ ^0 \+ f/ M2 A+ ~                weight = w;; r& y  W: N7 D8 ]
                    nextarc1 = next1;   nextarc2=next2;
    + T  e9 {* m% p$ J: U  U                mark = 0;           //0表示未被搜索,1表示被搜索过5 o" u/ y7 K  y- S+ D) H. C
            }
    # f9 I2 H* b3 h( A0 o! V. X. \; N2 ?7 {3 X# u
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>3 Q) a: e3 t( `& j  L
    class MultiAdjListNetwork( x1 k: d! L4 N
    {$ p  w, T, N* h( ?' q8 I4 {/ D3 Q4 @
    protected:* t2 t; x) T! {1 s! _: x5 H
        int vexNum, vexMaxNum, arcNum;
    9 a9 i. r* |* |6 H- n7 j    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;- e; }. t# A6 j5 H! y/ j
        int* tag;
    / U7 L' ^9 [* A    WeightType infinity;( B6 A5 }8 b- f; m( E

    5 p  \+ _& S- t) E6 h" ~public:
    + \6 s) h4 B4 \) i+ Q# g2 C    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);& m: l6 S$ z+ ]7 n8 E, W& \( g
    " p. R  F5 t7 T) e2 [) ~! s& }
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    # F5 K0 C  L1 [3 o7 u; A. |
    2 B, U# U. T, ~, r( h    void Clear();
    . \' [- Z# Q  k: P7 r1 h1 O( V    bool IsEmpty(): \' Y' t& x8 q! ^. n4 ]
        {
    4 C  n, k/ v% J, p/ P6 `0 o        return vexNum == 0;
    5 K  U9 A) U  z) r; o    }
    . ~' `6 U. F$ R/ J. H    int GetArcNum()const
    ; k( g. K4 H: B) \( ~2 a    {
    $ H5 j: H8 [) X4 u0 K3 D# E) G        return arcNum;/ g+ f' |% Q: c) s& C" B2 i# O% s
        }3 L9 i. R  t- r5 m8 `' ?
        int GetvexNum()const
      i  v$ g! S! A. W' m. G1 q3 V    {
    ; t* x6 }! K3 w6 v: f8 `( M        return vexNum;3 o& q; I. c) [2 G1 K
        }
    3 J7 H' V; i$ d; N
    5 A: ?% m( A. B! u- I+ u6 X. y2 t
    ( L5 b: N+ S3 B2 N) Q2 p    int FirstAdjVex(int v)const;
    + s& t; v+ u% x) ]    int NextAdjVex(int v1, int v2)const;
      g$ O. o1 E7 c5 @7 W8 u  Z    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    , f8 k. t0 P, `: G5 w- @8 x  q    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    9 W) B8 ?- N( u0 a" A* P
    8 S, _5 f; |& d" x; R  z* s    void InsertVex(const ElemType& d);
      y  d$ r3 I% c6 ^6 s    void InsertArc(int v1, int v2, WeightType w);( F) P8 v3 W) H
    ! Y; A7 P: g" L. I' r' ]
        void DeleteVex(const ElemType& d);
    # @) e! B* `+ b% T! a2 L    void DeleteArc(int v1, int v2);  P7 g' Y- G$ d7 I1 g0 ]

    5 h& T8 b$ Q+ e* a) ?7 R    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);- M$ O0 P4 N( t/ d8 y# j8 x
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    2 k: Q2 W" ^' j; q" ]
    & U% }6 t: U: K4 z2 ]! g    ///深度优先遍历
    ( Q1 h6 r; a! e% K$ U8 @: ]) k    void DFS1(const int v);
    8 I7 l2 d3 E5 D    void DFS1Traverse();6 S( v0 ~0 B$ Z3 i! P
        void DFS2();
    7 o9 D: R7 Y2 F- X4 B. t. p, s0 c  F& u4 a
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    % T$ ?( G6 K) k1 O- F& t    void DFS3();
    6 Q& F* T# R$ s, h, ], V9 {; P2 ^! F. V4 f
        void BFS();+ Q% ?* Q* k3 G( ^
        void Show();
    $ w" {, ~1 z" Z) L8 Z$ {! Y};
    ; c) v# _) }" ]
    , V* \. g2 v' V+ i0 h4 t" Z2.函数的实现7 ]2 I& y% B3 C
    研讨题,能够运行,但是代码不一定是最优的。$ C6 @8 V/ x, R3 P: Y

    / |2 k' ~1 z+ C0 S#include <stack>
    2 n7 R. [0 B. y; O#include <queue>
      @; O- D# {) \: S4 I
    0 X5 S9 F3 n2 j6 M) `7 Ktemplate <class ElemType,class WeightType>. z& D: b+ S* f" d! L9 _& B
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)& K2 b% J; b0 w" O& _
    {
    5 y6 D- v3 W8 d& d6 s" N  |    if(vertexMaxNum < 0)
    ( a) Q4 s# N: T7 K/ T3 y        throw Error("允许的顶点最大数目不能为负!");% n, |) [6 @" G% H- G
        if (vertexMaxNum < vertexNum)% r: p9 M) B" g8 H. l
            throw Error("顶点数目不能大于允许的顶点最大数目!");
    ! \0 G" w, S% Q( P( ?  R' W; w    vexNum = vertexNum;) Y1 s% ^# k8 P, f2 M
        vexMaxNum = vertexMaxNum;
    $ }& D( O6 |+ M: G    arcNum = 0;
    4 l) L. i; N2 U9 s. X0 V$ A    infinity = infinit;4 s  X  D) }3 P1 ]. G
        tag = new int[vexMaxNum];  u0 u% Y1 a6 O0 u5 V0 u
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    # o" C6 z* h2 l& @; s7 g, y( T: ~" `    for (int v = 0; v < vexNum; v++)1 q1 m" `3 M/ M$ b. T4 S
        {: J% S0 Y9 g/ F, g
            tag[v] = 0;4 }7 Z6 I% }$ c
            vexTable[v].data = es[v];
    : r: \, r/ e! C2 s9 u* N        vexTable[v].firstarc = NULL;
    3 H: o& _  G8 R    }; `1 C, C3 S! _
    }
    % {: X# F5 t  g- [' Y3 Ctemplate <class ElemType,class WeightType>+ ~1 G; h9 C% S/ F' U
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)/ l: `% Z$ z: S$ ]$ J1 q
    {
    + ~! C# T1 K1 B/ |: s" Z2 @- }. k6 a9 H    if (vertexMaxNum < 0)4 J, A' k/ j( I. B2 D* x: Y- y
            throw Error("允许的顶点最大数目不能为负!");  R3 C/ L- t0 M8 F2 N! H
        vexNum = 0;, d) U- G0 n2 s! p: k' z& {6 c4 P! `
        vexMaxNum = vertexMaxNum;
    1 l9 P% M4 k' {3 P    arcNum = 0;% m" Y: I2 j# z! [0 b
        infinity = infinit;
    % }" F& G" Y1 T  @    tag = new int[vexMaxNum];2 A0 F6 S3 g0 W& \! Q& r) g
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    ! E; j9 L# p3 r5 ~& R8 l}
    9 u3 ^/ ^( ^. A2 Ktemplate<class ElemType, class WeightType>$ a; t9 m6 p2 X
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const- B4 N' d; X; y. ?; p! d9 C& R
    {+ Z" k3 h' C6 g8 }  K* |
        if (v < 0 || v >= vexNum)
      e7 v6 I! {; p5 ~4 h; ?0 F        throw Error("v不合法!");6 d# h( u; \7 I" b- r) `) m
        if (vexTable[v].firstarc == NULL). k; M+ q7 P/ c
            return -1;
      h6 s0 w. t7 u- n, v" e    else! j' q8 Z+ U5 i" v  f
            return vexTable[v].firstarc->adjVex1;9 N! ]' R( J# R2 ]/ _. f  R( b
    }
    8 |, q% ?8 L) D$ L3 v, x9 ?6 `. E1 F5 P; ]6 u# @
    template<class ElemType, class WeightType>
    8 S  n9 g7 q5 l$ I* fint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    5 o0 ~/ D9 F; G, e8 K  r6 ]{
    / `. z" j3 c, g    MultiAdjListNetworkArc<WeightType>* p;
    , U7 V& F$ k; ~    if (v1 < 0 || v1 >= vexNum). p( P! S# w1 C; V3 g4 f
            throw Error("v1不合法!");
    1 @7 O0 R# ~8 H# x    if (v2 < 0 || v2 >= vexNum)4 L; i# ]% W) V# c
            throw Error("v2不合法!");
    * x: x* A4 W: s; z; u2 f$ g    if (v1 == v2)
    & I* T  G! B) ^3 ]  q( x2 \; D        throw Error("v1不能等于v2!");9 p* ~- k  N  |& w
        p = vexTable[v1].firstarc;
    ; q7 Y$ r0 ], W- k    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)$ r/ O0 n3 O" `3 m) ]) V
            p = p->nextarc;) P/ _- I) a$ @% M/ P
        if (p == NULL || p->nextarc == NULL)
    0 T+ L+ P$ b& g7 ~9 j        return -1;  //不存在下一个邻接点
    6 e' U, r& C! u/ @    else if(p->adjVex1==v2)4 {* Q6 Y( |, p  F4 h/ p9 v7 W9 W
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);8 U( |% x) {% f$ E& O) ^
        else
    0 o8 x1 J, [2 T# \        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    / ~, f' ^: Y- ~% J; c}
    / ?$ ?( s6 M0 j# U1 C- Wtemplate<class ElemType, class WeightType>
    ' z7 r5 O$ o7 C$ Jvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()
    4 [  \  X6 l+ J5 ]. x{7 \2 Z0 Y- J! j. s
        if (IsEmpty()) return;7 G1 Y; A* ~, n3 k
        int n = vexNum;  f  [2 V6 o7 n% O5 v; Z" v. P6 z- e
        for (int u = 0; u < n ; u++)8 |2 E% _. Y2 J
            DeleteVex(vexTable[0].data);3 W3 z2 R9 e. t4 x
        return;
    % u1 C/ }& f4 c3 x( W  s. D! l: J}8 n, K; i% f! @3 C7 T
    template<class ElemType, class WeightType>. P" ?  E/ r( ]4 ]$ h
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()- A2 _" x: N. b) p
    {3 X5 L3 g% P8 A4 c, E  b$ L5 j
        Clear();
    6 T0 D  D- d1 P9 D* l( W}
    ! g. K9 I: g2 i% H. w1 \template<class ElemType, class WeightType>
    2 E1 V& U) x# Q/ k/ j( q7 }; zMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)1 L% k2 L! i* ?& k% T2 e
    {, j( A7 L* |! g0 W
        vexMaxNum = copy.vexMaxNum;1 x- M7 C9 x' B' t1 |
        vexNum = copy.vexNum;* {" @6 M6 o) L2 a8 @. f
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    ) S) \, P' k6 \) o+ K/ q    arcNum = 0;
      j( s$ A- @/ b: W6 S    infinity = copy.infinity;% F: Y. b. h0 X( J8 J6 H
        tag = new int[vexMaxNum];
    ) G; t) t% d# F6 Y! I6 H* l  D; T9 {( t$ ?& C6 T# i- i
        for (int v = 0; v < vexNum; v++)9 w/ ?: K) {% j% C: C8 u' W8 Z* ~$ \
        {, D9 W: L! @  v' g* q
            tag[v] = 0;' }1 @: ^$ s) l2 F* [
            vexTable[v].data = copy.vexTable[v].data;9 F* ~' z$ `+ V0 B/ w/ V4 y
            vexTable[v].firstarc = NULL;
      _$ r" s* N% m  W! j    }; V! b5 `( M9 C" g  m9 c
        MultiAdjListNetworkArc<WeightType>* p;
    + o, A# W" ~8 j6 S' F; J' X% d7 w' q- ^9 Y4 W
        for (int u = 0; u < vexNum; u++)5 M! v" ~: @; ^) S
        {
    : `0 c) t. f6 w        p = copy.vexTable.firstarc;
    & P0 {& R& ?8 B" _        while (p != NULL)2 s% C7 m1 s- H" A2 f2 `
            {7 K. T; A9 D% b& M( ^% g3 D
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    ; V: C/ ?, b/ o; n            p=NextArc(u,p);
    % f4 Y- y8 ?- X4 J# C- _        }  P/ B, N0 ?; w9 E
        }( P( o% V5 j; n6 e
    }# Q' _5 l7 ?3 T6 H' h
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&$ s* Y% R% M* S& V' f
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    , k$ q- S8 [, H( z  b* |{
    - B7 U. ?( {* W/ J( a1 Y4 N    if (this == &copy) return *this;
    0 W4 e. p' K% x+ b    Clear();
    . p7 ~$ y- P5 S# s    vexMaxNum = copy.vexMaxNum;
    ( H/ N5 s( Q- |& p    vexNum = copy.vexNum;
    * L* ?3 S9 ?8 W, B# r# i+ a    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    + I; V/ v, c, ^    arcNum = 0;
    : ^3 i0 A9 J4 B    infinity = copy.infinity;
    - l& Y7 w1 j0 f) X' T* Z" z4 a    tag = new int[vexMaxNum];( Y$ n8 K) |4 z% y$ F
    $ a; ~( H4 D6 z9 |  I' U, C
        for (int v = 0; v < vexNum; v++)
    $ P0 P3 |& x* D% w) T+ J. A) e    {
    7 \4 s  l. w3 Q* ?+ q% ?9 n        tag[v] = 0;2 \; m1 e% B2 y& Y
            vexTable[v].data = copy.vexTable[v].data;
    4 s6 m* R5 C+ p, D; h& F        vexTable[v].firstarc = NULL;! k' O+ ~- ]' E6 K% q
        }1 K1 P; p& @1 j' J0 n$ b
        MultiAdjListNetworkArc<WeightType>* p;
    1 V5 A" Y  V0 J0 K' Y
    1 V9 z3 M6 T, S) D    for (int u = 0; u < vexNum; u++)
    * I* c+ o$ j" y    {
    ' \% e0 K. @# K$ E3 {' b        p = copy.vexTable.firstarc;
    3 b# w! R) l8 m" ]- x        while (p != NULL)
    # K' w% M0 ]3 K) W; n        {8 ^8 E9 D2 O+ S
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    * z7 ?) R' @' c" p) {, v6 z            p=NextArc(u,p);0 |" ~7 {* A- L; r+ |. {: E
            }& `4 k$ X; x6 z, j
        }4 N/ Q/ |, S6 N/ a
        return *this;
    * a% W9 I! U4 [2 m) [}0 n2 R/ R( N1 S2 @
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>** [/ P1 W2 Z1 h& ]- C7 Z' C
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const/ M9 j% y3 v( A' L& |! d4 _
    {' ]3 V% u" R5 Z: v7 B* }2 M3 ~. [
        if(p==NULL) return NULL;; D* C$ n0 z; u& C) B) W% B) \
        if(p->adjVex1==v1)& g1 V5 R( V, k0 H  Y: L
            return p->nextarc1;- C) D& z* Y0 u, O6 |* v" n. I
        else( t% G; u3 W! Q5 Q9 T0 D
            return p->nextarc2;& T8 J9 Y& H- o& p; B9 Q1 J
    }: x6 e! C% F0 J  k
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    , d9 J, j! u% |0 VMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    , o3 L# E; {' D, W1 ^{
    6 g" ^9 l# b) ^2 }    if(p==NULL)return NULL;3 v- ?. y7 V, i3 O
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;' O. K7 U2 I; _7 M3 `. I9 g) i9 |
        if(q==p)+ `# f  B% G2 x
            return NULL;
    4 B* h$ l5 o6 E" ^1 M  P/ L% l( T    while(q)' Y' ?$ l6 @7 D2 G3 e# P
        {/ l# ^$ y* y. {
            if(q->nextarc1==p ||q->nextarc2==p), L  l1 F4 O; R$ h
                break;; T  Y. P' x; p* |# Q' ~& F3 D/ g
            q=NextArc(v1,q);$ t; N, A( @7 U) |
        }3 t- e1 ~! c! e# l% v2 c
        return q;
    ( q  [- G: S/ z! ~: f# [* U}( E: h. [5 }6 Z, N  c7 ~& H4 I0 |
    template<class ElemType, class WeightType>
    + {1 o& d! ~" I, F. gvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    8 c: _) P' J8 B- I! `" Y% H0 ?{
    ( e/ u/ w- ~2 P; W- `: n; g! A    if (vexNum == vexMaxNum)0 k+ D1 |- \4 I6 i, e" v
            throw Error("图的顶点数不能超过允许的最大数!");
    ; E: v5 G: H1 l' X! P    vexTable[vexNum].data = d;# Z& A; ^1 B! Y  t' j( {
        vexTable[vexNum].firstarc = NULL;
    - r8 s0 r, t! z+ P/ g2 m    tag[vexNum] = 0;$ R# k9 k  }1 L& {7 \& {0 d
        vexNum++;3 E4 x0 {+ F" O6 V  y# {1 ]
    }
    4 x4 _4 M$ }: Z$ Y+ Ftemplate<class ElemType, class WeightType>
    % o0 E8 j( h; g1 b, T/ c" }void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)- r% Y0 D. q% v2 ~
    {
    & s% l( z3 c! ?) [) s) f. w    MultiAdjListNetworkArc<WeightType>* p,*q;
    5 ?( f# l: U- H7 f3 N; e    if (v1 < 0 || v1 >= vexNum)
    7 q: c4 |$ a7 z: w3 o9 N- O! R        throw Error("v1不合法!");
    ' H, Q7 A2 a. K9 P: R3 K! B! ~' a( L    if (v2 < 0 || v2 >= vexNum)
    2 N$ O6 S5 |' p0 M        throw Error("v2不合法!");
    % y' g# d4 R. W# F! |, X7 C" O    if (v1 == v2)
    8 m5 }/ b; L. N        throw Error("v1不能等于v2!");
    0 ?  Q  p4 W( P' h( _2 z) U! o    if (w == infinity)+ z8 w1 E2 @3 x, I
            throw Error("w不能为无穷大!");# K9 }1 F/ o6 Y9 k2 k& g) t
    + I) z2 W* a2 q7 @8 H& [, `, E
    9 c3 M& `7 K, M3 Q  _
        p = vexTable[v1].firstarc;
    , m" ~: J' x& I' n    while(p)8 E2 x6 J. {9 h0 H' ?$ @; k
        {9 E7 [0 x7 `. d% n
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中. w+ ?5 R3 _5 m' V% ^- d) A$ n1 O
            {
    : A# k* c  b. a* G3 t            if(p->weight!=w)
    ! ?3 i, ?, ~5 U# I                p->weight=w;
    ( D" O1 u7 u( x; B" b* x/ p4 s6 R            return;
    - r/ v' q5 z" A7 S# c3 V/ b7 y# L+ z        }
    8 X, w# Z/ G0 O- T1 \
    $ h, ^  f' j7 X6 q/ }+ s        p=NextArc(v1,p);6 z1 i# [, e/ x9 T1 X
        }
    2 L0 S8 N  G( a/ b+ b2 k. }1 [    p = vexTable[v1].firstarc;8 k  J+ X, ?  @! A+ ]
        q = vexTable[v2].firstarc;5 \8 U1 \- ]2 ^/ S
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    % O/ a5 a- A# ?* m1 H/ N3 s    vexTable[v2].firstarc =vexTable[v1].firstarc;9 T1 x4 `0 u% T! p2 p4 X
        arcNum++;
    ! z2 y. y5 i+ U. {8 L$ x}
    + ]) h* O! ~0 D* t& d7 U( V5 ~8 \- r' q0 r. A& b# v
    template<class ElemType, class WeightType>9 h  C) }! }, o. }
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    & t6 n0 s0 ]. k" m% _; U1 V{
    0 M7 }/ {5 z+ ^
    2 a: C4 j% S' K( p& P: k- f    MultiAdjListNetworkArc<WeightType>* p, * q,*r;/ K/ t5 Y2 ~7 f1 D/ b4 B' S9 M
        if (v1 < 0 || v1 >= vexNum)+ D8 O$ N1 s& u3 T8 w1 i, y% c
            throw Error("v1不合法!");
    , \; L: H4 e6 Z    if (v2 < 0 || v2 >= vexNum)2 v9 g& q8 ^$ ?
            throw Error("v2不合法!");
    * P, M2 l. A7 R    if (v1 == v2)
    * Z* Y! ^. r# @+ C4 P8 g" l        throw Error("v1不能等于v2!");+ d0 t+ y8 |/ e+ Q, W; x7 m3 C8 x
    2 C  s7 @0 o, s. G; G
        p = vexTable[v1].firstarc;
    9 m2 [2 V1 o3 J" O+ m    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    / S* O2 b% _: D$ s( ]! v    {
    , v+ X4 g/ e5 @- \        q = p;. g. }  L. {+ u- e2 a5 e% a
            p = NextArc(v1,p);
    4 C% r0 g# y* [2 g$ Y( k* ?4 I( ?    }//找到要删除的边结点p及其前一结点q0 Q' L& O4 K( s& e
    6 [; }8 U6 w# \) Q4 {/ X- U6 H& f$ U
        if (p != NULL)//找到v1-v2的边
    $ w6 V$ w  ~- F3 z8 P) B    {
    0 R5 P. k" p- N! T0 }, C, R        r=LastArc(v2,p);
    7 o3 e9 L  c/ s( q        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    ( l  d6 Z9 F$ X% Y# o% u. e, i            if(p->adjVex2==v2)9 ]  O$ O  B$ T! U: o, R  K% h# I: j
                    vexTable[v1].firstarc = p->nextarc1;5 c# A8 g) ~. ^2 A) M  o6 L
                else vexTable[v1].firstarc=p->nextarc2;0 \8 F0 ~0 I9 l, L, e
            else//不是第一条边' L2 f+ r7 {, ], f' M6 _
            {
    # F' b' m5 m8 p  N5 {1 R9 ]            if(q->adjVex1==v1)" o0 J3 O* r0 D, t! z' g/ K5 p
                    q->nextarc1 = NextArc(v1,p);
      t( Y' s) w+ T5 p            else
    3 `3 _" Q; \! n                q->nextarc2=NextArc(v1,p);
    % o  d2 w+ C5 X% j- S- o6 e( F. _
            }
    9 \1 M) S! a) Y4 F/ }. q        if(r==NULL)
    4 f( y) _: I- h            if(p->adjVex2==v2)" h0 h; N* d( X& j* a2 a' {
                    vexTable[v2].firstarc = p->nextarc2;. \& d6 o% ]3 l1 x8 L9 D& t
                else vexTable[v2].firstarc=p->nextarc1;
    1 _0 \' O3 q- S3 E8 U        else" Z0 [! b1 f; H; y; x* c
            {
    5 V6 Q( O$ l' V8 ?! `" Z3 V            if(r->adjVex2==v2)
    5 B& m! K$ a8 w: ]2 \                r->nextarc2 = NextArc(v2,p);5 w0 A) W. V9 y+ R; J
                else
    : d! E7 |1 y: ]2 @* f! u                r->nextarc1=NextArc(v2,p);
    8 _+ n) w* Z  n" _        }9 q9 l/ Z# W3 u/ H* ^1 c
            delete p;6 m4 y9 [. b8 `; ]0 l
            arcNum--;
    . ]' `5 t- I! E3 Q9 W    }( i1 B/ |$ E* l$ }

    ! Z  Y5 q! r9 o" L) t}" U0 f2 \7 f6 T$ c/ z
    template<class ElemType, class WeightType> void
    , B  C2 I9 S1 O3 UMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    3 _8 D" E  N; k& e( |{
    ( \. l: Q1 @, R/ W, I4 R* s: j% }* h& c1 q    int v;3 O- L6 ?9 |/ a) g
        MultiAdjListNetworkArc<WeightType>* p;" i  y* K: ~" _# j, M. O" T2 o
        for (v = 0; v < vexNum; v++)//找到d对应顶点9 g' s" P8 r/ H$ x2 \
            if (vexTable[v].data == d)3 C/ D' U5 J/ K, }
                break;  ~7 }0 Z- m- O. x. t. a# `
        if(v==vexNum)7 o2 T$ V+ Y( U! @' i
            throw Error("图中不存在要删除的顶点!");1 K2 b: g9 Y' `+ I7 F
    / x* x, Y' a/ M2 l0 `& F- b8 z. E
        for (int u = 0; u < vexNum; u++)//删除与d相连的边. g3 n* V% @" F" J( L' Y
            if (u != v)
    % ]; V* f8 x; ]6 N) i, |8 l        {
    , ~* [5 W, x$ x/ B6 }            DeleteArc(u, v);+ r7 |  Y1 p( R
            }" n: \, [' f; N
        vexTable[v].firstarc=NULL;
    . w5 l. k! d" j8 B9 a7 R& t$ \# T# j3 ]3 Q9 a
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    * b- h' {8 x8 e/ v    vexTable[v].data = vexTable[vexNum].data;
    8 B, [* \3 V5 u1 i$ z' l    vexTable[v].firstarc = vexTable[vexNum].firstarc;1 }+ @/ Y# S4 g/ ^8 J% [
        vexTable[vexNum].firstarc = NULL;6 ~6 n/ B3 E  X: N5 v6 |/ r7 e
        tag[v] = tag[vexNum];
    ' r8 o0 m- x! v& b- l, e2 n- `1 F    //原来与最后一个顶点相连的边改为与v相连7 B# U# }# T3 e9 U0 g
        for (int u = 0; u < vexNum; u++)  \+ l% O1 r5 [) \6 x
        {" B7 F  v: P7 n, u' U" D
            if (u != v)
    3 e, [) X4 X: m- e        {" p1 r( Y2 V0 D! B
                p = vexTable.firstarc;/ _* S) {1 I3 p1 _  ]) \
                while (p)
    ; L9 ~% v5 R& o            {
    2 e: D* {7 W1 |( P' _8 K                if (p->adjVex1==vexNum)
    + q( O' [0 ?6 L/ p                    p->adjVex1= v;
    % C7 G3 s! F$ P/ e                else if(p->adjVex2==vexNum)
    ) |* X3 d$ V& ~/ }7 v: u                    p->adjVex2=v;
    9 N+ N. _9 n" [. _                p = NextArc(u,p);
    $ o6 J* ~. B. P& w. X% [' C            }! ^! Y" i, ^" v# w
            }% n8 J; S. H% t% e# Y& x6 V
        }
    * d3 G) `7 c# ~4 T}
    9 Z& l/ C! }0 O4 c! z" @///深度优先遍历4 r4 D1 e9 t1 F/ d, L
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    5 M' K  e# h* u4 M: t# z) Q6 i{
      `* Q7 t- |  y* G! p, u    tag[v]=1;& G& M+ \4 o  Y0 G$ n
        cout<<setw(3)<<vexTable[v].data;  Q* h1 q3 R/ ~3 h
        MultiAdjListNetworkArc<WeightType> *p;) h# b- i# V9 S) @
        p=vexTable[v].firstarc;
    7 i7 j) V0 S2 j$ ?; ?9 n    while(p)
    0 y* r: `; M# M/ u. @    {
    ! ?$ r6 M6 d6 c! |6 R: `. d4 Q8 }% E        if(tag[p->adjVex1]==0)
    % r, t3 b: ~$ d/ J: |4 B            DFS1(p->adjVex1);
    * g  J$ M& n  B& J: Z& w% x- Q" O& a        else if(tag[p->adjVex2]==0)
    3 D# H4 C9 Q9 F            DFS1(p->adjVex2);
    . L# q& _4 g; V6 i        p=NextArc(v,p);
    ' m" \. s0 ~& G3 M# e    }( {3 T8 ~  S1 z3 I+ n  y
    }
    . I  @+ |, T. _; r1 Ztemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    / G& k# S0 S; v, H3 |7 p0 W, N{+ \" b* I; C3 ^/ [
        for(int i=0; i<vexNum; i++)
    8 D2 g% W8 [: q9 C3 Z" e        tag=0;& d0 c3 V. A& c# @
        for(int v=0; v<vexNum; v++)+ q# L1 F  i  G3 ]7 {$ B5 _# V
        {, x8 v8 ^/ K+ X
            if(tag[v]==0)
    : v5 k" }8 V, Q* [" T            DFS1(v);0 k, `6 \  {# b9 \; T8 i/ G
        }; r, E, O' S9 H+ D
    }
    2 p- Q+ p3 M) q9 ~2 R& F/ [template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()$ v0 ]" m" e" k
    {
    / W1 g7 m" s' K8 |    stack<int> s;0 D* S; A0 d3 f1 t$ r# M$ c5 e
        int tmp;7 Y1 d$ _( @  c9 C/ I
        MultiAdjListNetworkArc<WeightType> *p,*q;
    + Y0 B  t" u* |    for(int i=0; i<vexNum; i++)
    - ?, u' C# ~: }        tag=0;
    " x/ i: D7 d* d) O$ N8 t    for(int i=0; i<vexNum; i++)
    $ ]4 S6 Y- [5 _3 h/ [1 u    {# O) I7 [. j1 p$ j
            tmp=i;! h6 k1 Z, L& K' j
            while(tag[tmp]==0||!s.empty())
    " P/ C; Q) O# p2 Q3 _        {
    * l, _" j* p( c            p=vexTable[tmp].firstarc;
    * C7 Q& T+ R, m' V            while(tag[tmp]==0)
    4 s  h% }( A1 B  Q; Z. n            {0 l, q7 |5 l8 L+ u: Y) k6 m
                    s.push(tmp);
    7 v) G# N+ C; u% G) @/ G- B                cout<<setw(3)<<vexTable[tmp].data;& w2 x! t* E5 ^0 J# e* T
                    tag[tmp]=1;" Y: R9 N6 V1 t# u6 A
                    p=vexTable[tmp].firstarc;) h2 {7 A! B. s" V% J  f* j; x: l
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for7 C+ S/ R& j! p) K/ C* Z1 Q
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    1 C* l6 Y. T' B" A% K! ^. x$ n                //cout<<" 1st     tmp="<<tmp<<endl;
    4 L$ P' W$ p1 ]$ ~# m            }( i4 G  `7 Q7 a5 T) {, ^
                if(!s.empty())  p9 X! t0 S# w& K0 N: Z- v. @
                {$ o7 |2 W$ W- t% A0 N* m+ }: H
                    tmp=s.top();
    7 q. U+ v; O* f' t: z                s.pop();
    $ b$ B1 E( p# J4 {/ S. P                q=vexTable[tmp].firstarc;
    * V* h$ O. ^3 |9 }/ X  Z1 y4 e7 L                int t=tmp;
    / q) r, k( `" H7 t: o                while(q&&tag[tmp]!=0)
    6 ]1 c2 d$ C3 Y9 ~$ l% A& W                {2 N" k: u, W2 ?* ?' N+ ^$ Z
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);/ P& H7 I5 y/ W7 q3 v
                        //cout<<" 2nd     tmp="<<tmp<<endl;( R1 T( {. ~$ w$ s
                        q=NextArc(t,q);
    # Q1 z3 d  v" I7 D% l  O& v                }
    4 u9 r3 l4 j/ U1 Y3 W                if(tag[tmp]==0)2 o" X" m+ b6 Z2 F# m3 l! [8 `
                        s.push(t);
    + {" r- @3 I1 K' X; w                ///1、对应上面连通分支只有1个点的情况
    1 L* G" E% p% Z& D                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈, \# i' x, I$ z4 U) c+ f, U
                    ///tmp要么等于找到的第一个未访问节点,4 s% G6 [$ e  [$ U
                    ///要么等于与t相连最后一个点(已被访问过)* f6 D" k0 D+ d7 c) I8 y' s8 y
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点- k0 |+ _- s- H. W; }& g! h
                }" s  ^- Y0 `. x; V! w9 j$ R  _
            }
    7 _* g5 Z. i% W% V    }
    . p9 r: [, M; n5 y  K, ~+ A}! I1 K* d! r' g% |
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-19 [+ {: I- J- m" `
    template<class ElemType, class WeightType> int# Y. T* i5 V6 I- a: j
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)8 R0 i0 ^$ J& ?" i4 ]. a
    {
    * ?+ e9 t5 B8 j8 Y2 v( [1 c    if(head==pre)
    0 w3 M% y3 C8 o        return -1;" S3 A1 N% D" M$ o% b# F# P! s$ ]
    2 X* {! q/ V2 {7 Y
        MultiAdjListNetworkArc<WeightType> *p;
      k$ x$ x( u8 ]! X$ G0 l7 w6 R    p=vexTable[head].firstarc;( A3 {. u5 P( Y  }% o0 I3 }
        if(pre==-1&&p!=NULL)
    1 m( v# I! {3 T) F5 x( q' R5 l3 `        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    % C  y+ \1 @" m6 `  s    //pre!=-1&&p!=NULL8 w0 {8 s* j9 G" C) E" q) W
        while(p!=NULL)7 Z2 ?* X3 b3 t( `
        {
    * f4 k5 N/ B2 j        if(p->adjVex1==head && p->adjVex2!=pre)
    ' k1 b  n6 d3 a( n6 m            p=p->nextarc1;& L- Z. [7 ~4 b
            else if(p->adjVex2==head && p->adjVex1!=pre)9 y9 a0 q7 W8 x, A8 e3 i
                p=p->nextarc2;; |. q/ u* i2 M4 S; P
            else if(p->adjVex1==head && p->adjVex2==pre)
    ! i, [: A- k2 u+ N        {) {* Y& |5 W, H5 g( J* B
                p=p->nextarc1;& ~2 c: A& z- R7 g2 ?3 W& g" E  J
                break;- B3 R, U' O( w) v" o6 }, a0 w" ?
            }2 z4 h' P; N" ~& `3 `; W
            else if(p->adjVex2==head && p->adjVex1==pre)8 ]5 o1 F. ^% e  m5 r% y
            {% D  n3 w0 O& h5 l) ~3 I# a4 h
                p=p->nextarc2;9 i+ P) a  c. X2 \. l
                break;
    - p6 l' Q( Z) x1 n        }
    9 ~! H) d, @" }1 j& o$ {' J    }
    & L9 }" K2 g, z6 _+ ~" D    if(p!=NULL)
    8 g+ f5 s8 k# J- u! s2 r7 l* w' F    {0 t* A4 e" m# v5 b2 @- N
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    8 Z6 q5 _$ {) n/ W. R+ O% V' Q; t: k    }
    ! {" u' z( V, |+ ~* }) f    else7 q7 i0 T9 u& F9 ]
            return -1;0 a) Z$ K8 v  E1 N
    }  Z' S9 E- k1 f6 ]

    1 X4 p% c( z/ D+ \# I) p+ i' S( s& X7 B
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    # r  }. y/ c- M8 h{
    ' `! c. ]& I( e/ J+ |% C: H4 Z    stack<int> s;9 d$ s; S1 U- n
        int p,cur,pre;. i0 _  p/ [, m, l
        //MultiAdjListNetworkArc<WeightType> *p,*q;$ r  T% P: c: c% w0 D
        for(int i=0; i<vexNum; i++) tag=0;//初始化* Q# a9 U9 ?0 ?; f# V' y9 E' i

    + @# Q3 _1 Y* S    for(int i=0; i<vexNum; i++)3 ]9 H' c$ Q8 i* ~  h* \
        {
    ; ]$ D/ d  Y& W, I1 _9 T* L- x: i        cur=i;pre=-1;' n- v; V  M( h& j* F7 u
            while(tag[cur]==0||!s.empty())1 L, J( x# T( W' r6 Z8 Z6 `6 ~
            {
    # E) F8 |( D! R4 ^; o) j. G            while(tag[cur]==0)) I: ~" O. T+ O2 ^5 Q* N
                {/ n7 ]! M  u: D+ l
                    cout<<vexTable[cur].data<<"  ";# c2 R; D# P7 _, a$ [0 l
                    s.push(cur);
    * V% A4 p9 h! m7 b                tag[cur]=1;2 e- C+ A2 R, C4 ~  K+ y
                   //初次访问,标记入栈
    , A$ S: S9 v! H; u
    * `8 T7 ]7 c' Z               p=GetAdjVex(cur,pre);//p是cur的连通顶点5 \! V; [8 k) I  X: m; {8 g
                   if(p==-1)1 @# Q. O- o% k$ s& N, w; U
                   {
    8 g' d- x4 B: W. j3 X9 \5 v. m                   pre=cur;s.pop();; c$ A, v9 N* l$ H
                       break;
    2 E, E- I* ~$ V  }4 P               }, t& x# _+ g" N8 f" [. u+ y! c8 W
                   else
    ( k! ?4 D  j# ?6 u' f% W, a               {# n( y/ R# N3 d" X  \7 v1 [
                       pre=cur;
    4 t1 I9 j$ Y# W/ v/ K                   cur=p;
    5 o' K+ R* T7 `+ M0 ?: ~* Y               }" d9 X  @/ e' e9 c# U

    . B+ h& v) X3 q4 t' `( x            }
    : m8 X* t! [0 ^2 q0 w! K            while(!s.empty())
    7 V" Q: B, n- E8 u            {7 f: \- V6 X/ R3 h3 `! q7 J
                    cur=s.top();
    9 V# ~& k* ^' P3 s9 ^                p=GetAdjVex(cur,pre);
    - n% [$ u! w" ]! r                if(tag[p]==0); _6 p5 v, a# ]
                    {
    " D6 Z6 z( C; |$ ~' M9 t) p                    pre=cur;3 d" `; J9 n' [7 B
                        cur=p;
    7 a( N" H2 F4 f) A                    break;, t8 A2 c+ o; B
                    }
    " U6 n+ `) j$ a                else* I) v3 ?8 `' ?% O& ]/ i& ]
                    {
    ( u* g1 N# w  l8 \6 I                    pre=s.top();
    - }. x3 Z$ ?( U                    s.pop();
    3 u* X% t1 X! p                }& s+ j6 a9 r7 @

    % s' ^' C( F  ?            }
    , w2 B: [2 k5 e$ b. u! l
    , e) ^" H/ q! E# j9 q0 N0 w        }# u9 R- q* {" P. K9 N8 ^6 t/ D' _, R
        }% R) j4 p+ \! B& L
    }
    & L2 m8 j# Y+ m! ~0 ~; O4 otemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    8 r8 Z) g) p6 R4 v; m, d{
    , N( L8 d, L% v: k    for(int i=0; i<vexNum; i++)
    4 `8 ^1 \& J3 h5 S; n( G: A        tag=0;6 H3 {: x* a& E4 [/ ]& Y- T/ e: a! w( W
        queue<int> q;6 y9 s. Y: j8 m; {" u0 D) i9 i
        int tmp,t;
    : n. E) |! B5 L4 F- ]# o    MultiAdjListNetworkArc<WeightType> *p;" b* q% D: A1 V4 H/ d4 ?
        for(int i=0; i<vexNum; i++)
    7 A, p+ P1 x9 W' D- z% u9 `# C8 }    {
    6 f) J0 T; t$ ~; k        if(tag==0)( e5 G# H5 v7 J; y6 a- J6 U9 U/ s
            {
    5 h4 \( I" L! ?: e* @+ ~% x            tag=1;1 p3 B. H2 b7 b8 D
                q.push(i);" e% n7 f) H: Q( [# \  W5 H
                cout<<setw(3)<<vexTable.data;- A7 H7 e0 V8 \3 O( H$ n& ]
            }# F" \6 z  R! E0 i7 n! U
            while(!q.empty())
    1 G  b% X* ^0 j; b/ J  |3 R0 P        {
    ( e9 W% ~! n; J7 P# x7 A7 f            tmp=q.front();
    * r  q4 a8 s9 Q1 `) ?# f            q.pop();
    9 A" e5 m0 }* H6 X% |  r            p=vexTable[tmp].firstarc;% {/ h, B4 D; ~! p  x- h
                while(p!=NULL)
    5 T1 r' Z: c1 Z  p5 M8 D7 H            {
    , O+ u9 O* z0 V2 O                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    $ C3 Y! j8 }8 k( j3 w                if(tag[t]==0)5 ^6 w8 G* M( G6 B$ o8 F
                    {
    . S* z8 Y7 @  t  h9 t                    cout<<setw(3)<<vexTable[t].data;
    # S9 D0 h0 ^( g4 O4 d) L                    tag[t]=1;
    ( R6 m+ X  X- c, q& Q8 E' V                    q.push(t);
    . K( s, F, C  n2 {/ {, l                }
    7 |+ A7 @& [2 P/ J  W' }                p=NextArc(tmp,p);) X+ `! U6 _, F( a
                }1 M7 r4 U) e* ^, F7 n: q
            }
    4 ^! H% _* x; T    }* o; P. I, e0 b3 C- X8 z
    }
    $ h+ Y* m# ~6 N  Y  Q2 gtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    * X6 h2 t2 [* A- P{$ p  d2 }+ _1 R% }0 s/ y/ ^/ n; S
        MultiAdjListNetworkArc<WeightType> *p;
    7 L8 Z) ^* A# B/ P6 p& ?" t+ K/ }  t    cout << "无向图有" << vexNum << "个点,分别为:";" f2 U1 Y3 I9 m+ s" k
        for (int i = 0; i < vexNum; i++)5 _' h3 l' ]; m1 l" V
            cout << vexTable.data << " ";
    6 F- w' R" J. I5 X& @3 e    cout << endl;. e8 z, V0 W% |* S, K
        cout << "无向图有" << arcNum << "条边"<<endl;( ]5 h8 f; A! D! _% [
        for (int i = 0; i < vexNum; i++)2 Y+ M) R: W5 Y7 C! i0 ^
        {
    5 N7 M" x* |) S, B' Q        cout<<"和" << vexTable.data << "有关的边:";
    ' a2 J) B( L  ?/ B- t4 Q1 s        p = vexTable.firstarc;2 W2 b' v3 v* z' P( X) L
            while (p != NULL)- c' e- ~% o" o/ K0 C  b
            {
    $ R% b7 v& O0 p3 N            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";, s: r* [3 q+ M6 ]1 T
                p=NextArc(i,p);
    " g5 Y( f' @  D% P5 C* e        }1 r1 v+ G+ `9 I
            cout << endl;' r8 Q. M% _2 t  |# g
        }' {: w; m) w$ n7 R
    }9 z& Z" w; ^# ^5 B: j1 J* a: D

    1 |2 m7 g- }: w! d8 r3 {# A: g6 Q$ w% W' M2 j
    邻接多重表与邻接表的对比
    ! A$ e* Q* f0 U$ c: D$ |7 @( j  g) a9 I" h; O7 k
    邻接表链接
    2 C$ d$ M& I0 }; t0 r在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    8 u6 o& G1 a; c4 d2 }7 H0 e) c在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    & K8 J* ?) y. i/ C# s7 a为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。/ B8 J7 r) f: o
    ————————————————+ `; A4 W% Y$ [
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ' ~6 {6 G3 v0 b  X7 W) b$ F# Y原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    & ?" Y( @/ ^7 k) G! ~  z. P8 C
    & [- j' F' W0 W, c. P' K4 t- Z/ D  D+ @4 @: f" |
    / j7 C7 {6 a1 X

    - d' f: k7 P. \( y, v+ {————————————————) B% p" y% Q' n) Q( o
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。3 Q! @2 E/ j% `% Y
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958  ^, `7 Q  A2 d6 t4 a' h  K
    , z1 _3 S- R* G- R
    6 ^  |1 [4 l5 j0 {% u9 M
    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-12-20 10:27 , Processed in 0.793759 second(s), 53 queries .

    回顶部