QQ登录

只需要一步,快速开始

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

    ' z8 q7 G5 r" s& r图的存储结构——邻接多重表(多重邻接表)的实现" ~! j, z5 D, x  \4 [
    7.2 图的存储结构
    8 g4 o% ?+ u+ X4 n& |$ C1 A2 N
    1 {9 t4 X. Y" q7 I; h, o7.2.3 邻接多重表(多重邻接表)Adjacency Multilist7 o) {+ p$ O* M+ a' C- o- ^
    邻接多重表的类定义' u+ Y+ t1 l5 k& C) @
    邻接多重表的顶点结点类模板# ^5 h: p6 j) e- Q4 v' P. m. [$ C5 ?# D
    邻接多重表的边结点类模板
    * @1 y% g, p( H" D% \2 t9 B邻接多重表的类模板
    1 v4 I- E! u( h  p3 P邻接多重表与邻接表的对比. t' J: g- l1 V% J' c: D
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    ' M6 J! z+ }. m
    & q% o$ ^  _, j- j/ }* ~; f在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。) M* Y% L7 w2 v7 v) E1 z6 L! X
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。, d7 {. L& ~. ^! {. d! f- f. B
    : o( I3 \8 `1 J  I3 f: e! k
    邻接多重表的类定义3 b; T/ b- ~6 ?" p
    1.png
    : [# F* U5 V( e7 a. M- n/ ^邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:6 b6 u; A5 ?) `4 |7 U1 L7 G
    data域存储有关顶点的信息;0 z) ?+ _  T& H# z
    firstarc域是链接指针,指向第一条依附于该顶点的边。
    7 E3 J( P# {! e" c0 |6 q5 {, }所有的顶点结点组成一个顺序表。


    ; Z' B4 k4 Z. n# O2 H! N
    7 O- Z3 `7 z- v' G' Itemplate <class ElemType ,class WeightType>$ w6 V$ Q( j( t" W/ m
    class MultiAdjListNetworkVex
    2 }# S+ A. }0 M: B0 {  m0 }{
    4 K4 P4 X) }4 _2 W# J4 @public:7 y$ N# e. q/ q
            ElemType data;
    : z1 h: M+ [$ T3 U        MultiAdjListNetworkArc<WeightType> *firstarc;
    + d) [) L0 F7 ]% r. ^; C8 _2 n5 g7 [1 X. X
            MultiAdjListNetworkVex()
    7 f. b4 Y" v( p" t        {5 I2 K$ c! J0 X: _3 _; h+ I
                    firstarc = NULL;
    & \, m' C. y" g        }! U' Q8 {! z' i) \$ ]
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)9 K% ?! E8 t: b" x) y+ ~% c
            {
    * z, `& c  }( J' z" r9 S  L  S                data = val;) K+ q2 y! j5 t! {0 @9 g" N" {
                    firstarc = adj;! C. c8 e5 g+ e
            }: w0 B0 k  V' Y2 l" [8 N
    };
      o- A% f2 e! A. \; Q: y
    2 l3 l. L) F( j; E3 i  q; s( A邻接多重表的边结点类模板; S, @& ?* p& T% f9 \
    , ?; D" c# c2 S# I; H; U
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:, x. k# t0 v- T  _4 @% V
    tag是标记域,标记该边是否被处理或被搜索过;$ Q0 ]( g5 T# M# [2 e' `' p
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    / [1 V+ S0 Q0 ~8 F3 q% ]nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    ; V9 l, A5 g1 R  A; unextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    ; `& n) y4 a: X3 [+ g5 d6 ^9 d; o2 P( n8 J1 U
    2.png - b8 j4 j0 d$ P8 v
    template <class WeightType>1 t2 D! u9 ~8 V$ J1 `
    class MultiAdjListNetworkArc
    , C  g- E. ?4 B/ U4 k$ ^{
    . Z0 v: V- ~$ b, Tpublic:* j7 U4 [& ?& k: `! G2 `# x
        int mark;                                       //标记该边是否被搜索或处理过
    ( o% d" ^$ ]! Y! L        WeightType weight;                              //边的权重# D- Z: k; N- H$ a
            int adjVex1;                                    //边的一个顶点6 h$ y5 d6 T# s. i
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-17 B! ]4 d. x! T( E4 g1 V! @1 C
            int adjVex2;. F8 S' K$ k, F! a" ?/ G- T# |
            MultiAdjListNetworkArc<WeightType>* nextarc2;
    " ~- {0 k, E- q, D0 H
    ) b$ f- `/ Z  z( R$ N" k/ t4 I        MultiAdjListNetworkArc()
    8 v3 G5 r4 u, K6 z$ ~& c! m        {
    & q5 C4 c# w% V  D$ j                adjVex1= -1;& f: g' s  P9 R: x4 }
                    adjVex2= -1;$ Z7 ^: f! z1 ?& z+ J" k
            }
    % e0 ?1 A+ u; Z+ a  O- M        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)" I6 H! N, m* H
            {. N$ F3 H; A3 ~, d+ y+ x2 N
                    adjVex1 = v1;       adjVex2 = v2;) a# A  K) I( {4 w* n) Y
                    weight = w;
    ( z/ u4 a1 d: {/ r, r# y                nextarc1 = next1;   nextarc2=next2;
    , l/ w3 u: u% e7 ^                mark = 0;           //0表示未被搜索,1表示被搜索过, `! B8 B" j# Y
            }; g" K# W- ~. T" d

    , {2 k9 D3 p$ t  R! B4 L邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    % ~* N' X$ u6 d  V- e2 T2 hclass MultiAdjListNetwork/ w0 w5 ?3 D5 D5 T. k+ t
    {+ P& r, R) R4 ^8 V7 [- `9 g
    protected:) S$ h  i3 L$ q& f# W7 E( s- @
        int vexNum, vexMaxNum, arcNum;
    # s- M1 f0 G: n4 p    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;% a" A) Y# b% ^4 q& j% l
        int* tag;
    0 q; K* e, ?: L+ @! p& }0 G2 o9 T    WeightType infinity;$ [0 [9 e5 A6 _, B3 e" B
    % |% Q' \* Z/ G; \; A$ \! N9 g
    public:$ D2 L' F8 @) V: b) o$ Y1 W
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    6 G1 l5 r& s4 ?& r' y" [
    8 P! e! ~: l( G4 f: [+ _- l    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);; C+ X* y; o8 O# `: G

    - \& e0 \3 O( p  u1 g    void Clear();" V1 `/ C& \. H2 u/ E
        bool IsEmpty()4 z, \6 i3 n/ h& }& g0 q. P
        {
    0 Y9 Q- Q; n" W5 ^  R+ A& s        return vexNum == 0;
    * P% J& G3 e+ `& ]5 R! l4 a    }
    % A6 o, w! M$ L2 ~; J! q( i! C. [    int GetArcNum()const
    ! x/ M$ f7 L, s' B: C" l3 v, N    {
    ; }) a# a( H. c9 D' L        return arcNum;; Y1 h' I  _7 b% L: l
        }
    : O# l  [$ i2 B  ^/ ?7 D; }    int GetvexNum()const
    2 [( x. {: B3 Z. Y. s* l    {
    * V% @8 Q  v0 E8 _        return vexNum;& o3 _6 T* r* ?  \/ n- U
        }8 N, m/ B" y. ]

    / b9 W2 x7 R0 g* I+ ?6 Y0 ^
    7 k, d. S) I+ [* s+ ~    int FirstAdjVex(int v)const;  J0 |. w6 W, x1 w
        int NextAdjVex(int v1, int v2)const;
    6 D: z. r" h) r' l    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    4 l+ N9 I1 |$ l/ g$ w8 m! l4 ^    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    ; H) l* E+ O  D" D) f; m8 q& D; Z/ v% X% B2 l: `2 ^: o
        void InsertVex(const ElemType& d);
    8 O" M& H" _2 A) Z    void InsertArc(int v1, int v2, WeightType w);
    : s# w9 I7 E! S: Y1 }/ `
    + K+ \- L' f* s* ?7 p1 p    void DeleteVex(const ElemType& d);
    ( t8 u2 R+ J% F2 C' Z    void DeleteArc(int v1, int v2);
    % q$ z) {: M6 [% I& q& T7 D3 u1 s  Y8 N3 q
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    ) p& g+ i: \$ q; n) c* w    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    , c; X' `4 Y2 U3 A
    / q. c1 H. G: I8 C% F' Q' h: l    ///深度优先遍历
    % a! J+ k7 ?5 _. z" p4 F- @    void DFS1(const int v);
    8 O5 }' o7 G6 n2 I3 r    void DFS1Traverse();
    ' j  ^9 Z( ?2 y7 w' Q    void DFS2();  {# y+ l0 F' s: Y' Y

    $ e! [% x4 G& q" O    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    - I% v+ D! h" `    void DFS3();1 n& ]: Q$ Y  i5 P& A

    6 S5 z" H& ]0 w    void BFS();% F& v. y: ^) g- C, M
        void Show();
    / q; N. Z/ |6 D' l* `, X};. B+ F  B2 N+ ]
    * q) ]; o) j& S
    2.函数的实现& I. L# S( n# L$ o+ J: w
    研讨题,能够运行,但是代码不一定是最优的。5 ?# A- `4 [% q5 c: V& Z. X# Q, B
    : S: Z. g( ?3 [6 [
    #include <stack>- f' E; R! N0 X  B  p" g
    #include <queue>3 J0 R) {! h$ z: B# |
    4 p0 Z8 ~, l* z+ v. @  w. T
    template <class ElemType,class WeightType>
      [/ r4 j1 f6 T2 f5 v3 C- M! r3 L. tMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)! c% P+ ~. ~) t/ S. `3 o
    {
    ' d' `6 }8 F/ ?3 V$ A$ ~1 R+ r0 ?    if(vertexMaxNum < 0)
    8 f9 R0 t6 [: |- N' V- Y, u        throw Error("允许的顶点最大数目不能为负!");
    $ H3 L" q: r1 D* @& y8 B1 r* t    if (vertexMaxNum < vertexNum)
    8 e$ I6 h! q1 q1 M4 d' m        throw Error("顶点数目不能大于允许的顶点最大数目!");. g8 n$ L2 {# G" P7 \) m/ e
        vexNum = vertexNum;
    $ w2 ?2 Q( x/ g; f0 D# t. Q5 d    vexMaxNum = vertexMaxNum;2 `6 h( d- J" e
        arcNum = 0;, \. O8 `4 j9 M+ `
        infinity = infinit;$ ?$ E2 l. e1 p- t* ~; g" J
        tag = new int[vexMaxNum];
    6 H( f4 X* O/ J    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];* q" j* }* h$ G/ S" [
        for (int v = 0; v < vexNum; v++)
    ' ]4 h4 D& c) N' L; P' L$ A9 I4 p    {
    , @% b3 l& v9 p% F/ e        tag[v] = 0;! J. s7 U) ?3 B0 C$ X
            vexTable[v].data = es[v];1 m) F! f8 g3 R$ X  g- C9 ]1 v
            vexTable[v].firstarc = NULL;8 b  i! d- J' @: M7 A
        }- R& A: R5 O) V. e0 ~7 W" a
    }
    1 `! O! B; N* P4 u, }5 ctemplate <class ElemType,class WeightType>& ~  T/ f: C, o" c3 R7 @! P  L
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    1 ?7 t8 F* N% ]& w{
    $ |0 e! U" N9 U- w" K    if (vertexMaxNum < 0)" w" Y7 v  a; f0 Z. ~7 |
            throw Error("允许的顶点最大数目不能为负!");
    : Y0 N- i# ~' r5 x  u' R    vexNum = 0;+ n9 M2 v; n) w, x4 s
        vexMaxNum = vertexMaxNum;
    4 b7 z7 s" @3 L( R9 o) A5 [5 L( T    arcNum = 0;
    " @* s) S" F) W! I+ m5 i$ q    infinity = infinit;" G$ P4 Q/ G8 u  O. [
        tag = new int[vexMaxNum];
    / |; t  E& Y+ X9 i    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];; c. t( L: {+ c5 h5 Q9 _" K& I
    }
    5 g6 Y1 f, k* H" p( Xtemplate<class ElemType, class WeightType>& j/ ^5 C, b7 a' u. s
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const% H! y! A5 G6 [+ x% }- [2 \: q1 a
    {/ l- a3 r  H4 M1 n' `  y
        if (v < 0 || v >= vexNum)3 x4 m& [: C$ \: y$ D
            throw Error("v不合法!");" S( T, W4 e% d' T+ |2 G7 w) `
        if (vexTable[v].firstarc == NULL)
    7 @. C- K. u7 l7 E7 u" s& b        return -1;8 @3 k3 |* m# E
        else5 V8 K5 I" f! s* l4 O4 e! `# @
            return vexTable[v].firstarc->adjVex1;
    & v% b# q# v: ]6 @4 J}( L0 U) ?  _; P  _) u

    9 S, U& p+ i" }' s& |( Ktemplate<class ElemType, class WeightType>
      a- h  B5 A; N& ?6 cint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const( w) h" y0 Q4 P; b0 n) W) ~! E
    {" {0 ~& C( [2 r/ ~+ I# F2 J6 ~
        MultiAdjListNetworkArc<WeightType>* p;# X- Z' d8 J' Y1 _: R0 C
        if (v1 < 0 || v1 >= vexNum)3 s8 f8 K$ \( L# q  d
            throw Error("v1不合法!");, c. X9 B0 W; V% |' p8 j
        if (v2 < 0 || v2 >= vexNum)
    8 Z' B8 @( Q* w2 C9 \* i6 G$ Z        throw Error("v2不合法!");, |* c  M* m& p/ h9 e. h7 q; [
        if (v1 == v2)0 P4 f. J2 W+ j6 Y
            throw Error("v1不能等于v2!");
    3 Q3 T4 n+ L; [' n% o& g9 k) w    p = vexTable[v1].firstarc;
    ( V8 x# J7 d5 F    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)$ G! U9 H+ `: m) y. Y
            p = p->nextarc;; G( l% \# {+ u- P
        if (p == NULL || p->nextarc == NULL)- z+ X; ]# E( A7 f
            return -1;  //不存在下一个邻接点
    & S, {/ ^7 r5 s% a    else if(p->adjVex1==v2)
    4 q6 S) b$ G% N        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    1 c" l# p1 ]" U% Y: V. x  k1 o- o    else
    + {1 R( d& Z/ e7 B# m( ^3 h        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);- H% V2 p5 e+ g
    }9 }& L2 S2 U- G$ h
    template<class ElemType, class WeightType>
    & E4 U: _8 k: K6 P, Kvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()/ W! o8 @. |3 }" B* O, j
    {
    ) P' n2 k5 |% A& q7 p. Q+ F    if (IsEmpty()) return;+ Z, I! X9 i4 ?6 A7 n- f( u
        int n = vexNum;
    5 \2 l& X6 N# `2 l6 e- ?) W    for (int u = 0; u < n ; u++)7 W9 R) E& x. ^
            DeleteVex(vexTable[0].data);
    - G8 v1 T  _4 B+ D    return;* J; i2 ?1 f" F; n0 h1 ]8 S
    }
    2 [! \, U, y/ b3 J" @# Ktemplate<class ElemType, class WeightType>: J3 s' ~+ T# `7 \* L9 \
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    ! W: ^$ T& ?# I9 [) D9 G$ r0 j{
    ! j6 h% e' n  l" x. W+ ^8 ~# ^    Clear();6 c; ?: [' X  Y; @4 F) F
    }6 _8 e0 l2 g$ u7 g) F
    template<class ElemType, class WeightType>
    1 _9 L/ C+ N9 L, e: ^MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    / \; @9 ^' o+ p- R- Y1 U{
    . l9 ]6 W' Q* _. I    vexMaxNum = copy.vexMaxNum;
    & n; l- n4 K9 x) t. G" E# r3 f  d4 Q    vexNum = copy.vexNum;1 Z8 u  ]4 f& l) T5 V8 Q
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    0 [" O+ J! B( A9 i2 A* P    arcNum = 0;9 c6 q5 s. K* Q! w+ k
        infinity = copy.infinity;
    : T! r: E5 }  _1 v6 t8 q    tag = new int[vexMaxNum];- W7 O( y; Z/ S
    8 m7 c$ r2 C# M/ `! {0 M7 m; d( z2 S8 N
        for (int v = 0; v < vexNum; v++); d0 C8 m# W' `' U* \% P- a
        {
    1 I/ x' K1 _7 h) H        tag[v] = 0;
    ' |/ J. @4 ^) X* g& `, k9 S        vexTable[v].data = copy.vexTable[v].data;
    + N/ i/ t; ]! S5 D4 S& \        vexTable[v].firstarc = NULL;
    8 `9 T* E* R- k& i: E    }
    ! A/ O8 x6 e, B& Y- B    MultiAdjListNetworkArc<WeightType>* p;
    " R* y9 o, p. S' z8 ~5 n( j6 }& E# l+ D  ~. R1 [
        for (int u = 0; u < vexNum; u++)
    ! D  B1 f2 D9 Q( J; f# j    {/ k- J5 r. w: R( j7 C6 M* m
            p = copy.vexTable.firstarc;2 E: n$ S8 X; s. Z) _5 C$ J( p# O
            while (p != NULL)7 H& p& ?- ?9 z& Q1 ^& [5 W6 x
            {5 e& T( I+ s( g6 u' X, ^2 F8 N
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    3 w0 o1 `) x$ t2 Q3 K6 D            p=NextArc(u,p);) Z* q5 I* ~( q% _5 U  t
            }: B) s+ Z  C# s. ]( {
        }, a8 c% R! p" \- `$ I- t
    }
    & D. \3 ?5 q3 H+ x9 Ktemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    # h  S% ^5 _3 o& @/ UMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)! M$ J3 b/ g) z( I
    {: F# k, Y1 f3 V# y! Z
        if (this == &copy) return *this;' }" L" a8 g" Q
        Clear();; j& d! c+ N! ], G
        vexMaxNum = copy.vexMaxNum;! Z/ q) Z$ K6 b+ ^' _9 i! h. m
        vexNum = copy.vexNum;. m) H7 Z( V, @" l1 `
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];% Z6 W% h5 K, K7 ^  I9 i7 b
        arcNum = 0;
    ' Y5 n* T& Z+ L5 A9 q1 l3 t) W    infinity = copy.infinity;4 n) {# s1 c& p
        tag = new int[vexMaxNum];
    / e3 h' ^* ^8 z- q( R: ~
    # B6 ~5 `  Z1 [, i( B    for (int v = 0; v < vexNum; v++)
    9 R, U2 q; V/ \3 n# o# `$ Q    {4 R; a! b% K, r' C; z9 m7 ~, m
            tag[v] = 0;
    - ^( K) l3 E, `$ u2 i. s% q        vexTable[v].data = copy.vexTable[v].data;
    7 g8 q5 _& H( K1 o" b        vexTable[v].firstarc = NULL;
    - i! U( {" V( e2 A0 |- ~7 [: v    }4 p% r( Y; e: |- s- P5 I) s$ m
        MultiAdjListNetworkArc<WeightType>* p;" R3 o, ~$ ]* ^) ^
    2 v0 l  q. Y4 ^. X# A
        for (int u = 0; u < vexNum; u++)$ H" d4 @: h/ _2 ^0 h8 d9 T
        {
    ) O: z% n* D) h' U& h        p = copy.vexTable.firstarc;. T% f& S  y2 n; }. \- |
            while (p != NULL). Z/ S3 |' e# [" I' }
            {7 K% F$ h( U+ j2 g+ Z; R" K3 q
                InsertArc(p->adjVex1, p->adjVex2, p->weight);- T/ Y3 e9 r, S
                p=NextArc(u,p);
    1 F2 I  v9 A! z        }
    3 h0 F% F% A; ~: @( d( q) O, \; n1 U1 |    }
    : |& F+ S0 o9 l" j( c8 q    return *this;
    : ^) J1 _0 S9 |- E( F; n}
    " X+ V/ }5 ^! c9 `0 W: Ytemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*/ W5 J) r2 s8 Z6 Y
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    7 h0 E- ^) A$ k) Q! ~) h{/ }3 k. |  U( C2 k& q
        if(p==NULL) return NULL;% b) s( j  R) l
        if(p->adjVex1==v1)' a7 @: n" ~* w( M
            return p->nextarc1;
    3 P# H; a* _! q0 m    else7 ]- F7 }0 G5 x* Y
            return p->nextarc2;
    , t# P9 a& \  ], @: g}
    . h, |7 x6 n9 C. H$ Atemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    ( _# P6 E5 A2 i5 c; t5 T  kMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    . y! D2 f" k, m: l) C0 s{/ Y# j; r1 E! y  I% h
        if(p==NULL)return NULL;: j" z7 W* T1 Z# a
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;+ `* T) Y' W! a+ x: I1 R/ F. |. D
        if(q==p)" S0 }6 N$ ?6 G% h5 u. \
            return NULL;! r9 D8 A6 m; Q5 W' Z
        while(q). A% i4 O$ M5 [. D/ G& A! y
        {) p2 Q$ C- W( Q
            if(q->nextarc1==p ||q->nextarc2==p)5 G9 [) q2 L! p
                break;5 |9 _4 L, P8 `/ Y
            q=NextArc(v1,q);1 Z4 A, [' q" M& O4 H
        }
      {& r0 L- x( {& w3 [4 y0 i" ^& K    return q;
    5 x3 A4 F( P( k8 v: C}
    " i$ w  q- j. P& |* htemplate<class ElemType, class WeightType>4 R( s- z. ]1 q7 n4 b1 k  ]
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    * e8 a$ M5 z0 Z6 ?% J{
    4 ?1 o1 @# P! ~0 k* Z    if (vexNum == vexMaxNum)
    ! N9 W6 _. b& `6 p4 O6 q        throw Error("图的顶点数不能超过允许的最大数!");0 W7 f2 [* ]+ l5 v  j
        vexTable[vexNum].data = d;
    , Z/ d4 t1 a8 S2 p' m2 w* D    vexTable[vexNum].firstarc = NULL;
    : w) v8 \( r; R    tag[vexNum] = 0;
    9 n' `9 e5 @2 S& M' c2 R5 C! I    vexNum++;
    - e+ e6 I8 Z" v2 }* M# `7 O0 q1 q}
    & n( U5 n9 l3 q* t" n! m; mtemplate<class ElemType, class WeightType>
    $ d' T4 L: |$ k0 J  X3 Hvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    5 l% K# ?& `9 n1 k{. t9 h- y1 w2 i3 K& y
        MultiAdjListNetworkArc<WeightType>* p,*q;
    % C: L" u8 K. X8 {    if (v1 < 0 || v1 >= vexNum). ]) ?5 ~3 X2 G3 ^8 c3 G! v
            throw Error("v1不合法!");
    4 _0 o. F2 \% l+ {7 C4 t  M    if (v2 < 0 || v2 >= vexNum)
    1 X. y+ f9 R! }) k        throw Error("v2不合法!");
    4 j0 C0 K* @  _3 w* F" j    if (v1 == v2)( ?, S/ [1 z0 g+ X
            throw Error("v1不能等于v2!");4 V, `$ j- j; U" F" P- r- r" N
        if (w == infinity)
    # G6 _2 z4 e( D1 P& ^) b        throw Error("w不能为无穷大!");
    7 c9 e$ y% T5 s2 a
    ) S( g4 c& }9 T9 F3 n
    ) H  U# x% F4 k. u    p = vexTable[v1].firstarc;
    0 o2 r* y5 p% P$ s. Q- \, i" T9 e    while(p)) s# G/ n& W1 ?2 g
        {
    ' H* `9 [! y' y' g        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中/ Z! F6 t$ m  b" _4 \1 v- \
            {
    1 U/ P# T# u2 D0 n$ N" R2 G            if(p->weight!=w)& h: F  h7 M1 ?: a/ C
                    p->weight=w;7 T% Z+ e  n. `6 |  M
                return;3 F0 }9 f# t- R9 G, A
            }) |2 s- D7 j$ r" A; ^
    / |( M* q) q1 Z' o* P2 ^3 _5 p
            p=NextArc(v1,p);; H0 I2 [# U! }' |+ N* O! R: {0 C
        }! u; ]+ d- ]" W
        p = vexTable[v1].firstarc;1 p) Q) e3 K) j* A
        q = vexTable[v2].firstarc;
    / J6 v. |! g; i. n9 J% D4 T: d! |    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法/ S* G+ |$ c" G9 y
        vexTable[v2].firstarc =vexTable[v1].firstarc;% U. h: G4 y/ c. b
        arcNum++;  v6 [6 m8 I& _5 I. I+ V" @/ N
    }
    ' X* h( p) B1 b8 `5 Y7 R3 L
    3 }; r* W$ D; {template<class ElemType, class WeightType>2 F# X: d9 y# K% g6 z. z  W8 `
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)3 ^  {1 A7 M6 ]8 n* U4 a
    {
    - u$ U" n7 Y0 A  i% U* m! M
    & F% M% |: M$ J* X5 F+ G    MultiAdjListNetworkArc<WeightType>* p, * q,*r;3 g) m% H$ ]6 r  @2 F" r
        if (v1 < 0 || v1 >= vexNum)
    ' m1 O* f! b1 {; b' R        throw Error("v1不合法!");
      l. @2 h8 ?, B+ X8 g    if (v2 < 0 || v2 >= vexNum)1 j: m/ H  ~% Y0 H+ p
            throw Error("v2不合法!");
    ) T5 k+ d1 q! z! {    if (v1 == v2)3 V6 r& t! K3 W
            throw Error("v1不能等于v2!");
    $ `5 \" `+ d3 @, r) f' R7 |9 |6 P2 a  e" Y9 g
        p = vexTable[v1].firstarc;. g6 y- x* j0 c3 J
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    3 k# [2 e" d: d- l9 b/ A- w    {, j& `6 H" ~5 s" k( l' Z
            q = p;5 B1 p( w+ k2 i& r: v. |$ d
            p = NextArc(v1,p);+ R1 [* V+ j/ S
        }//找到要删除的边结点p及其前一结点q: N, z3 l4 d  m# u7 n3 i1 p
    # @+ r( f) F" K1 u$ X0 q% B) c- P& z
        if (p != NULL)//找到v1-v2的边  p. }( H8 ]& }0 x2 y) a
        {
    3 Z1 t: G5 }; C        r=LastArc(v2,p);, |" X9 }. `8 e+ m- g
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL. B- }' m' e1 F' a- r& A  r8 B
                if(p->adjVex2==v2)
    & L7 M" H! w7 x2 n; c* j                vexTable[v1].firstarc = p->nextarc1;5 q9 l/ H+ d+ t
                else vexTable[v1].firstarc=p->nextarc2;
    * Z- I$ {8 v: @& |        else//不是第一条边) c  a3 Y7 `& A7 [2 H% a+ `0 N
            {
    ( H$ l8 [' t# x4 V( e            if(q->adjVex1==v1)
    - ~" ^3 c% `3 N& O2 x; P# Y6 R' P                q->nextarc1 = NextArc(v1,p);
    ; e& _1 _9 \* S8 S* [% c            else
    - _$ J* a) v, C0 o! F                q->nextarc2=NextArc(v1,p);7 z1 d& }8 \; \  Y: B4 }" n  [

    ; ?4 N' Q0 Y4 v; y& }$ ^/ E2 \        }
    , `$ C6 z" }7 @( t" M; i        if(r==NULL): O: [. B; j5 ]9 y9 M
                if(p->adjVex2==v2)
    + }/ m! h; Y% H  c                vexTable[v2].firstarc = p->nextarc2;3 K' x' K  ?3 w1 p. @  \" X
                else vexTable[v2].firstarc=p->nextarc1;
    ! G7 |8 a8 l& j7 v+ G6 \        else
    4 ^3 P9 n  O3 I: j( |        {
    ( ?3 ^' f6 _7 m7 v8 e9 l            if(r->adjVex2==v2)
    1 ]! c" z0 N- N                r->nextarc2 = NextArc(v2,p);$ c  @& S/ P0 y5 S
                else
    , R1 J( O5 V& M5 S                r->nextarc1=NextArc(v2,p);
    ; v9 j8 o- M% Z/ q        }+ i+ U9 Z9 ]7 O; K+ m& W
            delete p;
    : Z% y& N; o. q2 Q9 }: s0 s5 q# A        arcNum--;
    $ c! z  f9 a- }7 x    }3 `( _* g3 J! B3 D5 r/ j6 o
    ( ^8 Z; l' b" q0 r8 V; c# e" U  c# X
    }$ R3 S; L6 d  `* }
    template<class ElemType, class WeightType> void
    * [" |9 j& s; ~! s: LMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d), ]* r; h4 U% Z0 d# t
    {0 H; ~2 @% s, Z6 `6 @
        int v;  V" S7 X3 n0 t, H6 I" k
        MultiAdjListNetworkArc<WeightType>* p;
    4 d* E0 g2 T; K1 G% _$ d9 k    for (v = 0; v < vexNum; v++)//找到d对应顶点
    & X, V# x+ Z; P$ h. a5 H        if (vexTable[v].data == d)
    7 }# J6 j, R' \, @- R0 O" s8 y# \            break;
    ! S1 }' }  ]# v# C    if(v==vexNum): E- j  ^4 n/ T8 @  ?
            throw Error("图中不存在要删除的顶点!");
    2 a) q) \" n8 c/ G; i* O
    6 w$ H7 ^" i4 u% Y+ H    for (int u = 0; u < vexNum; u++)//删除与d相连的边* h! V, @$ d. c1 ?7 ~/ T6 i
            if (u != v)
    % P- h, U1 p. X# [/ Y: y5 @. w        {
    9 z3 {4 R* Y$ J  @& l+ Z" \; b            DeleteArc(u, v);
    , q: j8 o& I% s& i' c  L- d# K        }$ f3 h$ U& P2 `( [
        vexTable[v].firstarc=NULL;  s' [% b# _' Q% e* z
    1 Q) o4 u/ _" F3 R5 G( g" D0 O
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置8 L% x) t) `  `- a4 E, P
        vexTable[v].data = vexTable[vexNum].data;
    3 p0 d* k/ k- W$ q! O    vexTable[v].firstarc = vexTable[vexNum].firstarc;1 J4 Y! E! z, G1 w! A+ y
        vexTable[vexNum].firstarc = NULL;
    0 {% _6 S% r" p$ B9 x! B# o7 D9 [    tag[v] = tag[vexNum];9 C3 h0 Q' o- k2 B
        //原来与最后一个顶点相连的边改为与v相连
    6 j% k) f2 R. F6 {. c' e    for (int u = 0; u < vexNum; u++)
    9 E) `- d. H3 m/ V0 o& ~! T* ]  F    {9 P4 i6 R! V" s0 T% r
            if (u != v)  a5 F# O5 L) o) r9 O/ u( Z
            {
    % T3 s1 I5 g* b5 M, x5 m0 R+ }  o            p = vexTable.firstarc;
    . {8 q+ {- Z1 l/ v. ?8 x$ U' o            while (p)
    2 }2 U9 Z4 {" p  I/ p            {
    ( A' k, K4 J$ a6 i1 t3 K                if (p->adjVex1==vexNum)1 T8 A5 Y1 h" B/ H/ L/ s( F8 I
                        p->adjVex1= v;
    , x7 y: ]- H2 _2 f. `; q. ^' }' e                else if(p->adjVex2==vexNum)
    - `1 I: b# ^' U4 Q                    p->adjVex2=v;9 H0 w/ w' |5 [: _% Q3 ~& r5 a
                    p = NextArc(u,p);* |6 I# P8 z" I" ?6 N- j
                }6 X3 I. S/ H3 j; _# y
            }
    7 o+ j/ B0 t1 H    }
    8 b& b/ D3 L/ L; j1 O}  v$ @1 \$ D3 m1 k/ x8 j0 k) F
    ///深度优先遍历
    ! \9 a7 ~$ e7 G2 Q, [template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    ( n- W9 m* L% X{
    & k  ^* C7 u. Q  Y" @3 q  e, d2 t    tag[v]=1;/ r: i  b& j$ j6 m
        cout<<setw(3)<<vexTable[v].data;
    4 V/ Q7 S% c* }8 P  ^+ F- F    MultiAdjListNetworkArc<WeightType> *p;
    . y- S4 Y! u" E    p=vexTable[v].firstarc;
    7 ], \! Q3 I6 |    while(p): {# N! D7 V5 M! p" r
        {7 l( A5 N. l4 l! Q. F0 r: y
            if(tag[p->adjVex1]==0); T) M0 Z$ r) U
                DFS1(p->adjVex1);
    8 x5 S" n0 b& n. n        else if(tag[p->adjVex2]==0)/ L. ~) S) z9 |
                DFS1(p->adjVex2);
    / \& ^; H4 w: @) h        p=NextArc(v,p);
    * u0 Y4 Y/ \! ~9 R    }
    ) Z- Q! F: N# T( }, \) L}
    7 ?0 j7 g8 Y" t: b. @; i2 ?. b; H  ?template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    ; h5 m6 A: ^! ?- p! t1 Q{
    % C( p0 Y7 x$ G* b/ m. @) q$ X( l    for(int i=0; i<vexNum; i++)
    % L& u+ D. K, l" a+ V( a        tag=0;
    ; w& c2 _) t9 w) \% c, |* i    for(int v=0; v<vexNum; v++)3 B' V8 W0 l" W- C. W* E8 d
        {
    # S8 a3 y/ V9 Z2 ~        if(tag[v]==0)
    / a2 t" w. O0 g            DFS1(v);2 L. K" J4 Y# S6 h4 M! A- h
        }
    : {) ^) o, }# {" `: v7 U}" F' ]( q' s; V. N( _* ]3 X7 c
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    % N1 ?. r1 h- M: Q3 l6 w{
    7 K8 W  L! n$ _) A2 \2 L) |9 N    stack<int> s;( D- G6 m3 g- C
        int tmp;
    / `/ P) c7 u: H* \  r+ P    MultiAdjListNetworkArc<WeightType> *p,*q;
      G) L8 S/ W; P6 m    for(int i=0; i<vexNum; i++)# }, ]5 x& m9 U+ g
            tag=0;
    7 M# C" k! \- q" r/ v1 j8 |    for(int i=0; i<vexNum; i++)7 K, j5 e2 m$ h) q9 e+ Q
        {
    0 p* i) I; H( {, I- }        tmp=i;
    0 g$ _' X- n( w4 G$ Z* N; [* X8 d        while(tag[tmp]==0||!s.empty())
    & \/ @" O6 [/ a) g6 \        {7 C. z9 C% o  D" ~" X( N
                p=vexTable[tmp].firstarc;
    - O: f  E7 B( _8 ]3 ^* R            while(tag[tmp]==0)
    ( }4 i& h  ]) h2 a: v+ t5 M- r            {
    2 [' h* T$ A- M; |3 j                s.push(tmp);
    7 \, u! i/ |+ w& x                cout<<setw(3)<<vexTable[tmp].data;
    ) _) Q* T5 R, Y' _2 D                tag[tmp]=1;; k7 z" O- D/ n: ~$ _
                    p=vexTable[tmp].firstarc;) h% j& @( {# f, c" X6 P' {
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    0 a$ V! r( Z4 ~                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);+ e9 {4 D) |. V  i, q4 \
                    //cout<<" 1st     tmp="<<tmp<<endl;
    1 [9 q. J( k- ]  I            }
    6 o! i/ V* I% H0 g. ?8 L            if(!s.empty())
    ( R' f4 o0 a  c! i' w# U$ A  \0 y( @7 N            {  ~7 E0 Q5 T& d- T
                    tmp=s.top();
    / k7 j+ c0 X. x2 E  O7 E! D+ v/ |                s.pop();
    6 f1 g8 j; |& \& e                q=vexTable[tmp].firstarc;: ]  |0 A4 R" v! `. {. I
                    int t=tmp;
    ( N; q' H0 s, w2 _6 A: h                while(q&&tag[tmp]!=0)5 l9 |; T# _! N3 C; H' O4 Y! \
                    {# s! z5 K) e# Y+ u1 F+ X$ [7 _) I
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);0 Y9 A; Z" n5 c. e5 ]1 i% ?0 \
                        //cout<<" 2nd     tmp="<<tmp<<endl;
    & t. O' ]* j  ~/ Y6 L( c- N                    q=NextArc(t,q);. w4 f* I. X7 |9 x( c1 y
                    }5 u# O1 _9 r0 _! k5 R
                    if(tag[tmp]==0)
    # a* t2 g7 c- g8 H9 d                    s.push(t);
    + o+ K- r! d2 L                ///1、对应上面连通分支只有1个点的情况
    & k0 |$ G  Z' m6 F; B- ^, G. ]6 E                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
      q8 D  m& {0 B) p6 l                ///tmp要么等于找到的第一个未访问节点,
    ( ?- o# @6 y4 c) I: q" N8 U3 q( O7 L                ///要么等于与t相连最后一个点(已被访问过)% q: C" c& O$ g, q* a: j( W
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    + G9 l" ^2 l. r% A            }3 W% V; g* S6 P- {' c& N
            }
    # o- A7 e; i2 Z5 N1 u0 k1 I! B    }
      T' I7 Z6 U& J* i}1 h6 k: [9 x! |! }
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-12 |2 H3 l" p4 T1 [
    template<class ElemType, class WeightType> int  w+ }4 x7 }7 B+ F
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    . b2 ]. y2 @6 p, h( ~" }{
    4 C  {6 O% X& B5 Y) C    if(head==pre)9 \' E( a& s8 \( ?: W( L- L
            return -1;) }% B$ h+ ~5 I6 T
    ) k7 n+ ?5 I& l& E3 y9 ^! y5 P
        MultiAdjListNetworkArc<WeightType> *p;# N) o0 j( A  k0 n
        p=vexTable[head].firstarc;* K5 {% ^! u% Q, @+ ~! Q  j5 w
        if(pre==-1&&p!=NULL)/ j) G2 [1 C, Y; u. f
            return p->adjVex1==head?p->adjVex2:p->adjVex1;9 _9 r3 P: {7 I  d
        //pre!=-1&&p!=NULL0 j2 e/ @2 X6 R( s& U% ?8 P
        while(p!=NULL)
    & Q9 t$ O* Q7 Y! L    {# l2 m8 V( |$ B: b) B# V
            if(p->adjVex1==head && p->adjVex2!=pre): G' a3 c, y) U5 a, F  L7 }
                p=p->nextarc1;
    3 c: r5 n0 l/ k2 Y0 E( w) d" H8 t        else if(p->adjVex2==head && p->adjVex1!=pre)
    5 W6 Z7 P7 t# }4 W            p=p->nextarc2;
    2 F2 e* {5 V/ z$ q0 J- w; O; [        else if(p->adjVex1==head && p->adjVex2==pre)
    ! e8 h2 _9 m+ J  @$ m/ t( R1 p        {  ~9 T9 B* ]: m! @
                p=p->nextarc1;
    0 G# o- k2 i+ P! N: k            break;5 G" s& I6 w0 |
            }
    ; q( b8 g0 @. T1 B$ Y0 I        else if(p->adjVex2==head && p->adjVex1==pre)
    1 F/ L6 h+ O5 j  r" r" |. U) K        {
    8 }# m& }# K) m& `1 D6 o            p=p->nextarc2;
    ; x3 H/ [0 m+ w5 l* ], O+ y" S            break;
    7 b% T) A* R3 `; R4 B        }' y3 [' n+ M  a% q8 F
        }& K5 _0 |8 b6 ^0 K4 t) c7 G
        if(p!=NULL)8 p" {- D6 v2 Q+ I9 |, {
        {$ @3 O: T) r3 v/ v/ c
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    + r& L9 }" Y( s1 |    }
    $ o- A$ O0 N' j( ^. O+ T1 j    else3 C  q8 _: }3 \, F! P9 k
            return -1;
    6 w0 ]3 Q+ u( ~2 q7 J, j( y0 b$ I- \8 Y}$ E( y' c4 T1 D9 A7 W7 M

    - f6 W* m* @6 B/ W! t- O
    4 K" |. p; T+ E# U8 A: etemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()" I; _3 r0 ?' x4 i% o; M
    {
    / e0 Z, p! f, R% ~    stack<int> s;! A  U! V# \- J) {0 ]' i
        int p,cur,pre;
    ) P7 y3 P5 f6 K4 X- w+ s    //MultiAdjListNetworkArc<WeightType> *p,*q;% |4 `; d% X7 n0 F
        for(int i=0; i<vexNum; i++) tag=0;//初始化4 V; O- I0 A* k9 i5 R* A

    . p6 _/ |0 v* m/ q/ I6 }    for(int i=0; i<vexNum; i++)- z5 e  f- h& Q2 w1 b1 Y
        {
    9 Q7 i2 X- e( q        cur=i;pre=-1;& [& R2 U0 [. h# x5 _+ V% l9 C9 t$ G
            while(tag[cur]==0||!s.empty())
    $ `) M; P! M9 H) v        {* H0 P- n  M$ m: l
                while(tag[cur]==0)
    0 r9 a! n" l$ E. l* H            {
    . y" d+ o* ~( l; I( G                cout<<vexTable[cur].data<<"  ";
      i4 d$ K6 u# h+ q+ M$ q6 K                s.push(cur);  Q# g4 d& d6 X' S
                    tag[cur]=1;! l5 ?# h; Q1 ?
                   //初次访问,标记入栈/ x4 Z1 ], P% |9 r1 F
    * A! N$ l8 j+ Q# x/ ^2 D, r
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点
    " k5 Z; ?$ Y) M) T( D. G               if(p==-1)
    ; _4 Y/ Y2 `/ h               {
    . S6 `8 G6 j. s: Z, _& R, n                   pre=cur;s.pop();
    ; y( t0 m& S+ Q/ Z                   break;
    # s- C7 j! Q& l6 t# `( x  U8 P               }( o9 R) \- N# z3 h1 l. T+ i
                   else% y2 b" |! i8 H4 T2 n2 ]1 T
                   {$ o* m2 C% l5 q7 ~
                       pre=cur;/ K5 A9 l% B4 [5 v5 t& H; L1 c6 v
                       cur=p;
    ( c4 |) I- K; B  e               }5 w7 {- R# I3 `* A
      J" `1 Y- R: ~& b% x" v1 r- V
                }
    ! p; c1 _( @: J+ |2 ^3 E; q7 H            while(!s.empty())  j% z! P$ l7 o
                {
    6 L6 b" B; _& j5 e7 V4 @' R- s0 C" i                cur=s.top();
    ) v4 P) _/ ?; d, E) _/ k4 g& |                p=GetAdjVex(cur,pre);
    ; z+ u; e& Q  L. x                if(tag[p]==0)
    " A, h2 C* P* r0 U8 B+ h/ n                {
    ) n3 j- ^4 b+ L* |; f' r                    pre=cur;
    ) B" F3 ?" @' z6 w' D                    cur=p;# [. j3 M! Y% n* W
                        break;3 J9 g$ Q1 P# w7 k! a7 Y
                    }
    & f, i/ o. P& p  M7 m                else! @. k/ O3 o2 ]( T: O
                    {
    3 U( U9 o- T  d: u% J% E                    pre=s.top();
    - V/ V9 }# w$ c) w5 f                    s.pop();: |' D, A* Q: K% ^9 I% }) L
                    }, m" C1 X9 i' J" y. L; C

    $ r' \4 j9 n5 L" E7 ?; P. ~+ z. p            }& a; O! }4 |" @# G3 E
    6 B0 k4 w+ r3 a5 E% |. c" ~  s) m( [
            }7 E  z: u: P5 U  J, `* u& l4 }
        }, J/ u. q; b) d1 M
    }
    . S1 ?# H& K  Y. w( utemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()/ R9 }0 v7 O% b6 Y
    {
    " A9 ~" F6 L" X# z& J; k( j    for(int i=0; i<vexNum; i++), h# p0 |8 c' z9 g; p$ j
            tag=0;
    + e, t+ m9 [8 P& E0 x4 t( S& K. r    queue<int> q;
    , E& _) `) Q; ?    int tmp,t;
    ! u- H- o! q% E! {: [3 o; X    MultiAdjListNetworkArc<WeightType> *p;, v# K0 S% p4 K+ I5 H$ `9 i
        for(int i=0; i<vexNum; i++)9 b, {. e6 c/ A6 V6 x/ J# |7 j
        {
    " {; k; ~- t% r: @( |5 _        if(tag==0)
    % v  j9 O2 s, T) ~7 X! K0 }        {$ d( r: |' |& y: G2 u# m* n
                tag=1;
    . n+ o6 E# N) b$ H- C8 a            q.push(i);8 S- D5 J- c* {8 h, i, A: F
                cout<<setw(3)<<vexTable.data;
    , g0 y8 y6 U$ Q$ S( S/ A        }
    ( Z/ T5 Y9 Z* V" C4 L        while(!q.empty())2 v! Y: R" ^+ }  I
            {
    8 g1 K+ U$ F3 Y            tmp=q.front();
    8 o/ D( @" `9 [            q.pop();5 y% U( T7 Z8 {3 J- \; x* G+ ^
                p=vexTable[tmp].firstarc;4 r' J- r6 L2 h* y% {7 k" w
                while(p!=NULL)
    7 t% H& u4 n( B- p) }/ ]7 Q4 d2 y            {4 u' B; }0 V( z' V0 X8 r
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    0 p9 [1 @. C  V4 ]8 g8 q                if(tag[t]==0)0 Z+ ~% Z3 I0 S% F6 F2 C. P
                    {' U, V5 V# H* b+ p5 L# W/ `
                        cout<<setw(3)<<vexTable[t].data;
    / \7 D/ P0 w2 E1 A5 S0 x& L; ~                    tag[t]=1;
    ( ]" \3 A; K2 f# A                    q.push(t);- J: ^4 I8 G( Z! G/ W. L8 O
                    }
    ) ]1 F: ]( E( Q0 y* A                p=NextArc(tmp,p);
    8 _5 K4 y4 ~5 Y% N            }
    4 L% ~3 ]0 Q* n: K: `! C        }
    - f  Q( B9 {3 W, w    }
    + w" ]: [' B; H5 N}
    9 ?& x7 c/ I( t- H# E6 Vtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    ( Q6 i5 i3 c1 l& m, R  _{
    ' c" e! Q; J$ {& O( ]( X' N6 a    MultiAdjListNetworkArc<WeightType> *p;
    . e2 i+ D' v' J3 t7 h, X. a    cout << "无向图有" << vexNum << "个点,分别为:";
    / N/ E: i. {  P/ ~: z    for (int i = 0; i < vexNum; i++)
    % i6 v8 c, n/ H6 W" Q0 d% R        cout << vexTable.data << " ";
    ; u1 v+ C5 _! V    cout << endl;1 D; V" I3 n; E& S
        cout << "无向图有" << arcNum << "条边"<<endl;
    # r8 w/ R* o6 T; M5 D9 l    for (int i = 0; i < vexNum; i++)$ ^: Y8 ]8 {; J" ^* d4 Z+ p/ _/ \
        {2 \& H6 Q  E6 Z: ~2 ^6 d1 B7 t
            cout<<"和" << vexTable.data << "有关的边:";8 Q1 }9 `% l5 `
            p = vexTable.firstarc;  F$ L: x: O9 b" S4 p; S) B
            while (p != NULL)
    - X) {4 \1 h! Q/ ]  |        {1 _+ i  J3 q5 ^% V2 c
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    3 D1 K3 U: G% k3 I# [: z' T% Y7 M            p=NextArc(i,p);
    # z: }7 H# ~  \9 R4 s        }: t3 B9 K& T+ t. @. I3 u# i6 L1 F
            cout << endl;( V& m! F" Y, {: a4 K  e9 o! y
        }9 ]. Q+ `* z# y4 G: d- g
    }
    ) \$ T" t' Y2 F: M+ T3 `8 }) C& {  e
    7 L+ X5 e" q5 M/ F& H7 {5 Z# L
    邻接多重表与邻接表的对比
    + g( b% C4 {4 q1 L3 E% c# w& m; q. v
    ( A' k4 ]& M1 k% D  m" Y5 n  d邻接表链接
    2 N, g* Q$ p- y5 D$ O; @9 Y/ L在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。  a& d( O8 U& v* d# j0 A+ g
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。2 O3 Z7 b8 P, [6 Y
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。- H6 P  o, v& a
    ————————————————
    7 o! N. z5 J8 `版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ( u; d6 G' R+ o) W% E& ]原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669587 e0 w6 H9 x0 J( M

    $ M2 l) J: l5 j; f5 }0 ~  m2 ^" x4 c' l! s# R' |

    ) l; J5 Z/ j' H" v9 v" x/ m/ V2 X+ d; ?: P5 s
    ————————————————+ h  h) m0 C, P0 H
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    % h6 y3 A! w5 W9 i7 k- B; M原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    " h4 N& V$ z% b4 y0 c* A+ a; e. ^4 v* c0 x4 T# W8 j: |
    0 `/ K: \2 [( {/ q1 g! [
    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-5 17:08 , Processed in 0.866457 second(s), 53 queries .

    回顶部