QQ登录

只需要一步,快速开始

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

    ) A9 Y/ a% d4 x, v8 |3 K图的存储结构——邻接多重表(多重邻接表)的实现
    . o* ]1 L. m! R% ^: h3 w" S7.2 图的存储结构
    " Z0 f2 [) J( ^* `
    3 C% K( p1 {# h% `/ g7.2.3 邻接多重表(多重邻接表)Adjacency Multilist6 o0 ]( L/ w8 |9 A& b7 x  c& m$ `& O& H
    邻接多重表的类定义
    ! s/ r* W" K4 D% g4 w! N邻接多重表的顶点结点类模板' B: u- j7 F% ]& U  |
    邻接多重表的边结点类模板
    ( ~( |8 ~8 |7 x: o& m+ B邻接多重表的类模板
    1 x2 v" e* J1 [" N邻接多重表与邻接表的对比
    7 K# W' g) G- T: G1 P7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    ' S: p- n: \! L" {3 A& K3 ~4 O' L9 b6 K, V+ S
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。& m4 V) z1 \- ~
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    0 t4 {7 U8 R/ f2 w  h" W
    . E* l/ g- N' x3 U" |" S' p/ j邻接多重表的类定义, p/ C$ Q8 y2 S) m
    1.png
    ; c- [% ]; A/ Q4 g邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:' G" N. n/ ^# s4 I  E
    data域存储有关顶点的信息;4 z' j+ [' Y4 P2 U
    firstarc域是链接指针,指向第一条依附于该顶点的边。
    , v: J, L$ {# |/ D所有的顶点结点组成一个顺序表。

    3 E! X; C) c/ X+ C
    ( B3 J' i/ Q; a( |
    template <class ElemType ,class WeightType>, D5 i- o* c1 ~
    class MultiAdjListNetworkVex! O2 G( F9 O0 V( t7 C4 d2 T* I' ~
    {/ a& {7 ^4 B  C( l
    public:
    * h4 S6 m- C: e  H" Q        ElemType data;) O: F- Y$ I5 m4 Z1 r: l+ I
            MultiAdjListNetworkArc<WeightType> *firstarc;* A- ~. i2 ?7 p/ ^) w

    5 l0 _& {& o: L: I7 R$ I        MultiAdjListNetworkVex()' i1 c# U, U1 T% C9 g
            {
    ) m1 d6 {# L9 B" k. p, }6 F/ \                firstarc = NULL;
    7 ^0 C  T) k/ ?- f0 |& \7 H        }
    0 A/ f. C2 x- S' X1 t        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    % y6 J* U6 L) \  z5 `0 P; g- [        {1 [; k  n0 x) [% d" k7 A) B
                    data = val;
    9 S$ j5 Z2 [! y* @, h2 v                firstarc = adj;
    # o  [: z( d9 o" Y        }
    , l+ }6 O' a& z, [. p) `' ^};2 [6 e" W! V8 }' h" J+ z$ t. Z
    9 z3 U$ A- A! G3 t7 v
    邻接多重表的边结点类模板
    & c' S3 ^* S$ X( V( L" n, c- t9 l6 @8 Z) k7 U/ P
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    - J  w2 e% l* W8 u9 v' mtag是标记域,标记该边是否被处理或被搜索过;
    8 I+ r5 r5 q8 }7 D: dweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    $ ?5 Y, p2 j) n! \, Qnextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    8 ], v6 |& J5 A$ T& R9 bnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。( F9 p$ n9 e+ K
    $ o7 {2 `) V+ Z! h. q5 \! W3 J; [4 J
    2.png
    3 I: }: Z, U& q+ |) R! j/ }template <class WeightType>& n, K' A- R4 x) E  y2 Q2 x
    class MultiAdjListNetworkArc
    ; Q) N. ~8 l) G8 d' A: K! G9 {: a{
    " T  D: Z7 _- W6 Q5 j; ?public:: Z' q) ]& D! e6 F# \
        int mark;                                       //标记该边是否被搜索或处理过5 C. l9 J9 u% w
            WeightType weight;                              //边的权重
    / o6 y( Z$ D' u* ~2 w; E        int adjVex1;                                    //边的一个顶点- k  ]& w" a3 p( d) {% V1 u2 }
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    . @- X4 r" |; l9 y. v' U8 t        int adjVex2;
    & ^7 D4 a) Z- q# {* E8 z        MultiAdjListNetworkArc<WeightType>* nextarc2;
    7 b( A8 e+ S4 a( @+ V* o& J
    ) }" {7 c& F; x9 H2 d9 d; q+ N        MultiAdjListNetworkArc()3 @' b" N# c$ L/ B* e$ o
            {
    + L5 V! F: F0 U% E1 G. c                adjVex1= -1;
    2 q& C  K3 E1 @$ Q* s                adjVex2= -1;
    " ^' V( \. t! o$ D        }
      g0 s6 W: o9 j7 |! r( G9 k/ X/ P        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    7 k0 t) g' ]/ f! w        {
    & l5 Y- i: n2 R0 H4 b3 A                adjVex1 = v1;       adjVex2 = v2;( E- O1 J5 X+ h; J. A& A5 Q
                    weight = w;" F, i; D2 s7 Y: R
                    nextarc1 = next1;   nextarc2=next2;
    2 k) C& {2 Q6 Z" S" {" P* n8 A                mark = 0;           //0表示未被搜索,1表示被搜索过
    2 k6 z2 Y% C6 r1 l, y        }
    1 [' b- i+ J/ e" j9 g  |, F9 r0 \( F6 ]
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>0 k/ H' O, [. Y
    class MultiAdjListNetwork
    - N1 H' l) C7 q& h{0 z# }% \% ^$ j6 }
    protected:
    ) Y; d- h. A  G    int vexNum, vexMaxNum, arcNum;5 @& l' C$ @( J9 l
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;2 E! [. |0 t# _) S3 ^
        int* tag;4 P+ j9 p/ v5 J- ~7 w; ]
        WeightType infinity;
    ! v% x  u( q, d  I# j- j! v* w& J, [; O# B
    public:" I/ ~$ l  S* t7 F2 @
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    4 @. d6 L1 B0 e9 W7 G0 L5 e+ x5 @2 D$ n
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);/ T1 c7 r- d- b; F5 i( \- \
    + ~. S9 ~( c  ?8 C9 z
        void Clear();
    9 T) ~# s* T. {    bool IsEmpty()
    0 P( i5 G% c* E- T    {
      _3 B$ k% E; M  ~! f; G) g        return vexNum == 0;
    ; c) w- t+ J7 Z& N8 \    }
    6 S( k# H% r# A) S: a3 n  R1 n    int GetArcNum()const; e+ R; J0 O: F! ?
        {5 Y" r0 C# B$ G6 J
            return arcNum;  Z: P6 d* K) R0 Q3 S
        }' g; B$ o) ]" R( z! y
        int GetvexNum()const3 Y8 g5 H/ b! [- Y) A
        {! _6 t' P8 |5 m# D! @9 }$ L' K
            return vexNum;# K; d8 A1 z% W% j
        }
    0 E* k( p3 Y0 ?! O- N) u: G7 @7 P, \! g* W, f& i

    , J1 D$ Z' B2 G6 V; n4 v4 ?    int FirstAdjVex(int v)const;
    % Z" x6 F! w8 g2 _7 s    int NextAdjVex(int v1, int v2)const;
    9 E- {' a! }: v* j! m0 N: I    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;+ g' i! A5 k9 Y4 Y
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;) l; a. }) \7 P# b) u7 O
    4 }3 n" W1 \' z+ z! @/ L7 w# U
        void InsertVex(const ElemType& d);
    ! K3 V8 x8 [; \; |" v! X    void InsertArc(int v1, int v2, WeightType w);
    $ U0 B9 `/ x1 g1 s' C' r; r
    ' O. m+ w- T# ?" z    void DeleteVex(const ElemType& d);/ a! i; ]  ^: Y* y, G, ^
        void DeleteArc(int v1, int v2);
    1 ]7 A# @; n" a" h$ b3 \6 w( l9 G" ?# \4 l5 h  f
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);- n! j  c# ~0 F
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);3 r" {* i1 {, P

    7 N- ^( G* k" e  I5 X9 r; n    ///深度优先遍历
    : a  Q% B+ ~* C9 z2 y/ [6 Y    void DFS1(const int v);% {" H: f( i/ }7 j
        void DFS1Traverse();0 D  [: v9 c  I& ?+ M* Y9 ?* C3 ^
        void DFS2();
    7 t( Q: y4 o: [8 R9 G2 u4 r: r3 C8 z4 r8 `; k; v; K, @. K$ n8 _$ \3 A* p# y
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    ! t* X! |! q: D) k$ Y8 q( {3 @, N    void DFS3();$ i  v& M# o6 C% r" e
    $ b. z3 p  O4 a9 y: ~% c4 K$ H
        void BFS();: Z  ~/ q3 K( A: g# J: s
        void Show();, H+ A% p: F6 n$ G
    };$ d5 U& B3 {& X5 E6 D

    + r# `% j/ D! y4 a* E# }: H1 W( h% V2.函数的实现8 n; Q6 M. _$ J' H. y7 ?0 D" K
    研讨题,能够运行,但是代码不一定是最优的。) x: `- q) S( {
    2 v3 k/ k2 K2 S+ l
    #include <stack>
    2 R; `2 s+ I, _! K& a#include <queue>
    + f, I# @/ e; S3 P. D
    # h9 s  I# H( P$ {0 c6 Ztemplate <class ElemType,class WeightType>% {$ h8 y% R. a
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    8 C$ _  w- h% [" R* g{, k2 R# ?+ S8 D' U. U
        if(vertexMaxNum < 0)
    8 P) D5 a0 W# d2 L2 ]* _) O% `( Q        throw Error("允许的顶点最大数目不能为负!");
    * O6 v4 s& d) B3 W1 x* |    if (vertexMaxNum < vertexNum)
    + D7 p9 G6 R6 \, y, |$ o        throw Error("顶点数目不能大于允许的顶点最大数目!");
    & D% l+ \3 ~  c    vexNum = vertexNum;
    ; |7 E: ]3 z7 ?5 @% \" f. T2 A    vexMaxNum = vertexMaxNum;
    7 O; C1 _. Y+ c, y4 Y% @    arcNum = 0;) v6 i+ Q8 m8 i' _
        infinity = infinit;) q8 n* i' g0 W/ H2 K5 m
        tag = new int[vexMaxNum];
    ! A: N% N: E, o- B, ]    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];4 {  H  r+ Y5 f1 A  I% k
        for (int v = 0; v < vexNum; v++)& Y4 |" m' [) m/ u
        {
    2 R) z& P) p! }  ^2 W/ L        tag[v] = 0;
    5 }* q, u& V+ ]9 k: l/ A) ^        vexTable[v].data = es[v];! K# ^$ M% B( }" n5 |6 p
            vexTable[v].firstarc = NULL;8 E8 x5 c9 k. d% e/ y
        }; L7 z8 M  D$ m3 B* G! N
    }
    2 n3 S: O1 P( A4 N1 ntemplate <class ElemType,class WeightType>
    & E: V+ _% U% ^0 A. i: v' r1 C# BMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)) P; {: w+ ?" D( V& ?) d
    {
    # ^8 l; K4 `* C4 p  _; h+ l    if (vertexMaxNum < 0)4 |4 b" H* J. v9 l
            throw Error("允许的顶点最大数目不能为负!");
    ( x1 I0 S  X. G    vexNum = 0;% V9 R& h% f0 b1 m; e
        vexMaxNum = vertexMaxNum;, r) m7 x( |- a7 R; B7 B
        arcNum = 0;
    . r1 o6 _& @' ^' g) J( o" S% S    infinity = infinit;3 X" {8 i% y) Y* B5 Q$ _0 c2 a
        tag = new int[vexMaxNum];
    $ w# \% A7 t* P    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];% W2 t# z; H4 m; ?
    }
    . o8 W6 S. G" o3 m3 f: y( B3 W) ptemplate<class ElemType, class WeightType>3 b; D1 l7 h9 {) _; h* f
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const& k7 |. X& k" T; B" d
    {* z# b9 n9 Q' w
        if (v < 0 || v >= vexNum)5 _+ r- Z& S. t' E1 p6 e3 k
            throw Error("v不合法!");
    + m* S6 d( S5 k, _$ Q/ p3 O    if (vexTable[v].firstarc == NULL)
    + ]& q& s. [/ j" I4 Q        return -1;4 Q1 {8 M" x5 u+ G0 c  [
        else7 w/ j0 n& L- d7 l& w
            return vexTable[v].firstarc->adjVex1;7 ~+ |$ a9 P7 h% b) V
    }4 L- n4 `' ~2 q% z5 u' ~
    - D0 o# x! a' _# t* e8 K
    template<class ElemType, class WeightType>, {- ]- Q0 t7 ^; f1 ^- M
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const% K% p6 M- W; x, M2 ^+ y
    {
    . m. k  @8 Q/ c# S    MultiAdjListNetworkArc<WeightType>* p;
    % R6 v' K7 f+ k/ d. p    if (v1 < 0 || v1 >= vexNum)5 E+ l& l* H- l9 L4 Z* _0 F& W
            throw Error("v1不合法!");: p+ y" }9 _  c* A" p- }) ?8 O
        if (v2 < 0 || v2 >= vexNum)
    ( ?* W* g: N5 {" J6 U9 ~# F0 m        throw Error("v2不合法!");
    " [  m* z5 R( B: }) H2 k    if (v1 == v2)1 J/ g3 a$ E" d7 [: X* d4 y6 N
            throw Error("v1不能等于v2!");
    4 ]3 ~3 ~( N. r* z& e$ Y    p = vexTable[v1].firstarc;
    " H8 p9 X& C  W2 q4 }6 q  @6 j, @" k    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    % Y3 C3 l7 d  P        p = p->nextarc;' w; E( e1 I( R' }
        if (p == NULL || p->nextarc == NULL)) H, T( k1 C# H
            return -1;  //不存在下一个邻接点: g) i3 O8 e! x+ ^/ S
        else if(p->adjVex1==v2)
    3 i# b2 W6 @' l# \" H$ K        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);  z7 D# m3 i9 `* N6 W
        else! n% x" R/ d+ c7 D) _5 J8 T0 {
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    5 l$ A/ \" d1 u! S7 \}" E6 p. @5 W8 y7 R1 a
    template<class ElemType, class WeightType>
    ; z4 N# N# A3 P! h5 kvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()
    # I, A% S# q! W1 E/ Y{4 e$ Q' v$ A8 t
        if (IsEmpty()) return;( _: J& ~- |' b, N: O! r
        int n = vexNum;
    : f" P+ L5 d' C4 M% c$ r    for (int u = 0; u < n ; u++)1 R: K: T, ]# i6 {
            DeleteVex(vexTable[0].data);! H( e' ]5 M& L* X0 B1 \( s
        return;3 b  ]2 ?3 {& B- `# l  T5 w/ S8 ?
    }
    , x4 M3 h- y4 t+ T1 Q+ M+ m' h- Otemplate<class ElemType, class WeightType>
    , D7 _3 e) s6 K# ]* V6 e  EMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()( {9 M5 n" q* v' i9 a& c- O) {
    {
    9 W- a9 Z2 C+ c' D1 l. Q5 m5 j1 S    Clear();2 C' P9 ]* B; C4 P
    }$ k( i: F% T% r& E9 J3 h
    template<class ElemType, class WeightType>; ]! ]: P' z+ ]% N+ ?. A5 D  c7 V
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)/ z* N5 w) |! d1 v5 M1 b
    {
      M4 O' m  o% q+ T7 s8 R    vexMaxNum = copy.vexMaxNum;( J& E& \8 Q/ s+ \' V
        vexNum = copy.vexNum;" W( [% `0 }6 f3 l# N
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    ! s* @4 T5 j& I  S- R    arcNum = 0;
    3 h6 G) `# S' Z- s    infinity = copy.infinity;% z, K9 }+ }2 \! C2 l4 s1 [2 P3 l$ z
        tag = new int[vexMaxNum];: O+ p/ p* ~% U- J- E7 X4 U& m

    + C4 ^" x8 |( t& m. a    for (int v = 0; v < vexNum; v++)
    $ n5 g" [" r; t' }4 S    {
    " V' ~* A% q" l& c7 M2 C+ {9 @: G- J$ r        tag[v] = 0;
    : p. a# D& G8 A! c& F5 X        vexTable[v].data = copy.vexTable[v].data;
    6 c. ~( P- g% p/ C2 ~        vexTable[v].firstarc = NULL;
    3 f  E1 |2 h1 H; t. f  I7 K    }
    7 p% r! B  t: h% ]    MultiAdjListNetworkArc<WeightType>* p;
    9 \. e  c+ x: X5 m0 ~6 X
      o( Y( G1 O1 }5 J2 h    for (int u = 0; u < vexNum; u++)
    + L3 k, _, u+ r    {' y: z+ |% a7 U
            p = copy.vexTable.firstarc;; P9 V2 }1 b/ ^* L2 Q* c" ]
            while (p != NULL), p, a$ n3 [' e- o: T& @
            {, `: W& a5 `; }
                InsertArc(p->adjVex1, p->adjVex2, p->weight);* ?& ~$ l# @$ W* _+ f% U
                p=NextArc(u,p);
    " [" l% S3 y" x5 J- a        }8 ?3 f: @3 y! w2 l0 r: S% C
        }
    ! L' x$ k$ {, i7 R5 J$ P9 x$ O}
    " i( I" ~+ F3 G9 ]0 wtemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    # O& f, g! ~- n% E; T8 @MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    & p& k! [: O) E{1 e7 R' ]& f4 T8 z. V( s9 j
        if (this == &copy) return *this;7 T& G! i% Z; _% A0 [; t5 a
        Clear();
    % M2 W! q5 H+ m, e- h, x9 d    vexMaxNum = copy.vexMaxNum;; p) O! `$ ], g) n, r: J
        vexNum = copy.vexNum;3 v  ~# g; m" W; ~6 o; ~( G
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];/ V$ N3 w# L* \. |4 @% s7 l
        arcNum = 0;
    . @3 W5 E/ P" b) A5 O9 K  [    infinity = copy.infinity;
    ) s% V+ J5 T1 |' G* z1 a    tag = new int[vexMaxNum];
    - C2 z; j) y# C0 `
    8 `5 h; A! j# r1 F' z: I) }    for (int v = 0; v < vexNum; v++)
    ( f7 }, n/ }6 s9 Y    {/ U8 R4 r3 a  J; q  g. T& s# m
            tag[v] = 0;
    ( I/ a3 m* f, Q9 j. J/ k! D0 F7 T        vexTable[v].data = copy.vexTable[v].data;+ x- o$ V! `) z
            vexTable[v].firstarc = NULL;  p; [& K% T$ i4 _( J& V% k
        }# i' P( Y) X; Z, d1 t
        MultiAdjListNetworkArc<WeightType>* p;( L, }- H- n7 Z6 H) t8 n+ d

    6 I/ I9 F3 [; d$ S4 `! C    for (int u = 0; u < vexNum; u++)
    : V& I) o8 g9 p! Q, A$ A  o  ?    {: C' F4 p1 {# e/ J1 [) [9 H5 I
            p = copy.vexTable.firstarc;
    9 k3 a6 D: }) |: m        while (p != NULL)
    3 b4 J$ L  ?; _0 t2 S  V        {
    5 a/ k) B( d! ?" ]: N" F            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    / L! h6 t* u2 X" N5 h            p=NextArc(u,p);
    . ]2 }- [. f5 B% P0 b0 `        }  ~. Y& j) ?. S, W# d, Q: t+ u
        }
    6 X- E: R. ?8 ^' n    return *this;- }6 m8 D' Q) \, i0 f/ d
    }
    , m: s* b9 A+ h' n) d2 Ztemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    & B2 D; W+ X) B* L* R  [5 B( zMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    0 ~% ?' J5 L& f. R: J7 K, N{
    , J3 C1 N! d+ K    if(p==NULL) return NULL;9 _- F8 e1 o1 u9 K" I* x1 v- E
        if(p->adjVex1==v1)
    ' h) r8 ?' _# K' m        return p->nextarc1;* S2 q% T( P+ R! F6 ~- N, x% B, |" r
        else
    & n& _- D% g" P        return p->nextarc2;
    2 a0 k5 n2 ^7 z; {6 b}) M+ N5 J+ c, ~$ U9 u$ f# I7 }
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    4 O  ~" o1 C& s* R. g( v, VMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const2 E+ l: `( K/ s( L, P& S
    {
    8 a4 v( `1 [) R3 X2 y- [+ Q& E+ S    if(p==NULL)return NULL;% J5 _5 M+ N% v* S8 h
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    2 [+ {, ]* Z3 f0 ^6 V    if(q==p)
    ! ]7 [- T1 {8 R! ?$ ]& `2 h        return NULL;
    1 \( `; |+ u! Q6 e4 a; C    while(q)
    * I: a6 T) O" }    {$ d0 D: n7 ?+ j& E& O2 A  S
            if(q->nextarc1==p ||q->nextarc2==p)* e$ K+ o" r# ~8 u; @, L
                break;) q' C) U5 p8 k; F0 _$ O; s, P
            q=NextArc(v1,q);. F) H. G# }% v2 ^1 W" P  Q
        }! ?+ `, P; b) n9 ?, H; g# J& v
        return q;
    + r' h4 c/ h2 t" B- o) Z; q  b0 H}
    - L# R+ \5 ?% W1 i+ s3 q* X5 m2 U4 P7 Jtemplate<class ElemType, class WeightType>
    6 ~* G8 j3 A6 `: A  ]void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    " B: V6 o5 e; o- d- |{
    ) }% e) L3 |% U    if (vexNum == vexMaxNum)) C% s% m+ h2 U3 z
            throw Error("图的顶点数不能超过允许的最大数!");5 ]' j4 q+ s, ]" X# W
        vexTable[vexNum].data = d;
    " Q3 I; t* ^% O- n& U0 A; C4 K    vexTable[vexNum].firstarc = NULL;
    2 i5 t2 T0 y( @0 {! u7 }: D    tag[vexNum] = 0;
    " E& X0 A/ Q3 g/ G- ]    vexNum++;5 B8 v( U$ u/ A4 Q
    }0 @# n( _3 F+ p/ Q
    template<class ElemType, class WeightType>
    ! I5 S% R' y( b* ?5 kvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    / `& ]$ k$ ~' ?. e" G" ?2 Q9 ?  v{
    5 ?( M9 j- i* J    MultiAdjListNetworkArc<WeightType>* p,*q;
    9 C: M2 j4 V1 v7 d! _: S    if (v1 < 0 || v1 >= vexNum)2 D- n+ `7 ?+ S/ M& j
            throw Error("v1不合法!");/ I4 ?5 }8 T: H
        if (v2 < 0 || v2 >= vexNum). I# Y# D* ?: {( s
            throw Error("v2不合法!");2 {) U$ f/ Y- H$ c- U7 y
        if (v1 == v2); B+ h$ Q- h  e; Y
            throw Error("v1不能等于v2!");* K2 m; g$ [4 D# v& h
        if (w == infinity)( B) u& P, {( G  z" G$ t
            throw Error("w不能为无穷大!");  G9 ?; v3 S9 p  O* s1 V

    5 y% [- C  f! P  v4 I+ B8 }* }3 ^( Q$ }7 V7 t+ Y
        p = vexTable[v1].firstarc;: E2 }, R; X+ l! |9 l% Q  N
        while(p)
    1 ]* _, u6 O0 i$ r% c0 H    {5 e& ~7 \! r2 [* n  C- A. s0 }* v+ S
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中: N4 E8 ]7 h2 x+ e6 g8 s6 C
            {2 b) J1 ^) i( y
                if(p->weight!=w)0 K! U, X, J/ J7 _- ]
                    p->weight=w;
    , ?! l7 V; Z. t9 K, x( u            return;
    " l9 y1 P: j# B8 k* L7 W* H# F        }( _( I- f9 z7 A; S( k3 [2 A- [$ u
    2 U  V  n) |* \( `& i/ @# ?
            p=NextArc(v1,p);
    + C% U" s6 j3 ?& j    }6 Y+ {" J9 P) m- ]2 B3 H" d) l: a
        p = vexTable[v1].firstarc;8 F  A! V% D5 O& |
        q = vexTable[v2].firstarc;
    / @: y6 U* J' B( A# d    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法* x5 z' R' B) r. N
        vexTable[v2].firstarc =vexTable[v1].firstarc;2 k+ k/ ?$ t* w  N2 T
        arcNum++;
    6 U9 X; K- O5 `: P& W1 @}& g* K0 N4 s! x/ v# B- p

      k; v- F% v" b! }& u, t$ H' L# dtemplate<class ElemType, class WeightType>. j+ ?9 M% M% ~$ M& d8 w
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)/ f2 {4 F5 |' W# p8 T# b8 b
    {, v3 _$ X% P0 H' d; F' |# C
    2 ~, S1 q% Z" }0 S
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    / ~: I' D9 [: R  e/ E' ^1 @    if (v1 < 0 || v1 >= vexNum)
    / \! G) v9 d  ~7 d. C        throw Error("v1不合法!");
    / v& B- u- Z& `! m  H: b    if (v2 < 0 || v2 >= vexNum)$ {( e# M( T- z
            throw Error("v2不合法!");
    , \! B. j4 ~9 [. ]& w: p    if (v1 == v2)
    1 N2 n- A; R6 ~. e! ~. a        throw Error("v1不能等于v2!");  p  W% c9 K+ ^" M3 i  S/ z/ M

    % s3 q! p" y( z5 p    p = vexTable[v1].firstarc;
    3 W9 G+ J3 W* `( Y! p! a$ G+ J. V    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)% y& q( h- t' }) T% {9 k( M
        {7 n1 S, \% ~9 X7 K
            q = p;2 N. U7 i5 y# ]' {- Y% ]" Z; F
            p = NextArc(v1,p);
    " `* ?! W* v( E' W8 p    }//找到要删除的边结点p及其前一结点q
    3 G6 [. W% t4 p% N7 J
      A9 ?/ |0 t& C! x7 x    if (p != NULL)//找到v1-v2的边& ^2 c  b: Y# Q# w
        {
    0 q0 x& q5 J( f        r=LastArc(v2,p);( F7 s  ?6 [6 J2 K/ K* U& p& s
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    - s- G2 n: T- ?4 {            if(p->adjVex2==v2)
    . g* j4 ]2 Z# w" ?7 J( O                vexTable[v1].firstarc = p->nextarc1;  S- ?- F- m) q# h- t: ]
                else vexTable[v1].firstarc=p->nextarc2;9 v0 \; o) z3 }& L
            else//不是第一条边
    + f6 T) w& U: i: Z        {
    # M1 o9 F! H, v! h" B6 n            if(q->adjVex1==v1)+ ]8 ]5 G  f9 I  b1 d1 y) W% o% V
                    q->nextarc1 = NextArc(v1,p);9 r9 D% V  `+ n. ~+ T( R  T
                else
    ) _, r; w, N; r                q->nextarc2=NextArc(v1,p);
    ) ?3 w* z. Y4 Z6 J3 `  O4 W6 @
    / Q4 T9 n7 @. H1 o        }% f' [, L$ n% ^' C3 }3 g
            if(r==NULL)
    8 I- a6 ]; m1 a+ T4 T* _2 |5 P            if(p->adjVex2==v2)
    ; W0 A/ n8 ~0 k0 u* D& ~                vexTable[v2].firstarc = p->nextarc2;
      D2 F/ g& y6 J, w; |5 M# _            else vexTable[v2].firstarc=p->nextarc1;- P, i+ G9 A, b6 L( w+ Y2 H# M
            else6 V% {* u; D0 M) P
            {
    $ e3 w/ v6 _) ~8 P" r9 K! Z4 h            if(r->adjVex2==v2)$ c, {1 e1 ?- Z/ e( P
                    r->nextarc2 = NextArc(v2,p);9 i4 z' _7 a! ?. t/ _! T1 l
                else1 x' I$ L: s$ V' k. N
                    r->nextarc1=NextArc(v2,p);2 r# f' y5 J' F7 s# e; S) M, r( z
            }, O1 \( L) f4 ~5 Z$ t2 T) c
            delete p;
    - s1 T. K' \* D% A2 p/ h        arcNum--;! O% s/ b: |( w3 }
        }
    : k- c7 v/ I  v, @& I$ x
    ( O! `3 k2 q. R8 K9 s! I& K}" N( t2 B7 x5 V- W: `& k! a3 o
    template<class ElemType, class WeightType> void: D6 Y, J4 {& Z7 \" z
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)2 k$ a4 E) D/ J
    {1 }9 }5 g/ u) ~# J: B: t
        int v;( \1 Q8 M3 |6 y5 G; a- q5 u$ |) `
        MultiAdjListNetworkArc<WeightType>* p;# ]- S" h, u- K5 J* t& s" y* D4 I
        for (v = 0; v < vexNum; v++)//找到d对应顶点. ]' h* D. X9 ]' X& Y
            if (vexTable[v].data == d)
    $ S1 Z( L0 {/ b) T3 @            break;% j0 u  g5 ]' W: z: ]
        if(v==vexNum)% W; ^: @  l7 H2 f/ c! w. L
            throw Error("图中不存在要删除的顶点!");6 t6 X/ V- Z1 H0 h; s. k* s" c
    / {) c3 I' }& l+ h. x! f2 i% r9 K
        for (int u = 0; u < vexNum; u++)//删除与d相连的边
    ' d! A/ u# x6 ^' E2 v" C( F        if (u != v)6 Z! p5 [6 k% t; L
            {
    ' K9 g: ?) N1 I; z# Y            DeleteArc(u, v);) b$ Z$ B' Z0 {% D% q/ F3 }! _
            }6 h6 M0 t+ k3 O0 I7 B- ^/ \
        vexTable[v].firstarc=NULL;9 V$ d6 S5 i  r

    " M8 d. d; g2 d  N8 R, c    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    . w3 I. d" f; l% @- k    vexTable[v].data = vexTable[vexNum].data;
    ) c7 d$ S4 Z2 J# k    vexTable[v].firstarc = vexTable[vexNum].firstarc;: s" G3 `, {5 H6 ?
        vexTable[vexNum].firstarc = NULL;& C6 |% d9 `' j7 w" B1 U
        tag[v] = tag[vexNum];
    ) |& B7 b% X  m( I# f5 P    //原来与最后一个顶点相连的边改为与v相连# J3 N$ G5 n7 b# r" v5 U0 n
        for (int u = 0; u < vexNum; u++)6 B' ^. S9 a: c7 u* @5 j* |
        {
    , |) @; L$ n8 Y0 v; y( P9 o" Y        if (u != v)
    2 A7 \2 F% f2 E) i        {& n2 ]) ]4 q; D3 K: X  w
                p = vexTable.firstarc;
    7 J; R+ W3 v1 P* {+ Q; V9 \1 e- k4 {! P            while (p)% @' v( w/ V- s+ d+ ]
                {
    ; t$ @/ r; z- n                if (p->adjVex1==vexNum)) N1 ^! l$ h9 b
                        p->adjVex1= v;# w( T  G  y7 y6 c& p! |
                    else if(p->adjVex2==vexNum), X; J) F2 [4 m# O+ x. w. j
                        p->adjVex2=v;
    3 Z- Z, }; M' w! r! w                p = NextArc(u,p);! ~. A: K: C) ?( T- T: @# Z1 x
                }& X# A4 w: B: ^0 B6 a1 v* c3 i
            }
    , u9 k; t& y1 E: s2 h3 q4 s    }% E' v* e- T  P# O0 n: z
    }. P- l: _" ]! t& f+ t" m
    ///深度优先遍历
    , k5 n  f% l( ~: \template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    ; K4 M6 H, i( e9 x) b4 }8 U+ K{+ w! M+ \8 G* m
        tag[v]=1;
    7 P0 i3 `& ^" i0 f, G  J( N: P3 `! q    cout<<setw(3)<<vexTable[v].data;* a4 B$ |" s0 H+ U+ \9 L& L
        MultiAdjListNetworkArc<WeightType> *p;
    9 ]1 d( D* E. F5 o: p( j    p=vexTable[v].firstarc;) J( o8 F9 e4 D0 o+ A' s
        while(p)/ z+ {- S/ U0 h. H
        {
    ! s5 A* G, L0 n) e3 T( x        if(tag[p->adjVex1]==0)/ ]1 Z+ N" g) {0 B! J' E
                DFS1(p->adjVex1);
    ; V/ q$ K0 y& K+ C* ^        else if(tag[p->adjVex2]==0)
    8 R# ^9 {/ \  O6 X            DFS1(p->adjVex2);
    . ^3 `# m7 F# {2 P, p2 b( h4 ~% _        p=NextArc(v,p);
    " l7 D7 p8 A/ y5 ^    }- x# \  o. I* H. E5 O: ]) P9 G8 `
    }
    7 K; X6 E5 o1 ~template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    ( @( e+ K3 l+ c9 W5 n9 N( F& o{
    " y; l5 Z0 p1 p# f& U" z7 R    for(int i=0; i<vexNum; i++)" q0 T: P; x" K# s% @* i
            tag=0;
    . Q+ n/ z4 E* h# f( X7 w( `3 _& h    for(int v=0; v<vexNum; v++)0 U! y% e! r2 M
        {; F4 M- ?0 l* J. @( m
            if(tag[v]==0)1 M, o' D0 @1 _3 |
                DFS1(v);7 p3 u- y. P6 [) Q
        }% r% d) d/ W. g4 i# H
    }; W  H# z2 w, F4 X! M
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()" ]! n6 }& J' w  M
    {
    / B5 N& l0 K6 N! r    stack<int> s;
    " \, K# E, s: j    int tmp;
    1 ^0 {- o: P! F$ P! H% [, m    MultiAdjListNetworkArc<WeightType> *p,*q;
    4 r  L( U: M' h4 u2 F    for(int i=0; i<vexNum; i++)/ r8 ?# P2 e) |, r
            tag=0;' [* k# v* J' d/ ~8 H+ L
        for(int i=0; i<vexNum; i++)' R, E- H( j6 e/ C4 ^, [
        {8 H  n5 x* p# M2 B
            tmp=i;; y7 o0 _: C# C7 T5 D
            while(tag[tmp]==0||!s.empty())
    2 k  ~. G$ ~2 a7 K! b        {
    4 e- D+ U. ^$ I+ P, F& q! U            p=vexTable[tmp].firstarc;/ k  f- A7 Q+ q$ J! R" j8 [' w
                while(tag[tmp]==0)' i- `9 C! p' {0 w5 C
                {3 m1 `2 V+ L3 J- c  C  V
                    s.push(tmp);
    ' ]: f5 L! o9 `: @# ~                cout<<setw(3)<<vexTable[tmp].data;- L+ y2 o1 L) `7 i/ L, T
                    tag[tmp]=1;
    , y, K$ `) o8 s' F2 N                p=vexTable[tmp].firstarc;& @6 }6 v( Y* x: D6 s  q
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for/ k) H# C2 x8 t+ J$ k
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    0 P( g! a! ?9 I2 H                //cout<<" 1st     tmp="<<tmp<<endl;0 @. z( t* z9 b
                }, c7 s/ ?" W3 p2 {! l8 w5 y
                if(!s.empty())
    8 |7 n1 v+ A- o2 ^5 E            {
    1 S3 P  i* l- E+ K                tmp=s.top();
    ( @2 Z' u6 I5 h                s.pop();  g8 r, w0 f* ]: Y0 p! P/ ?
                    q=vexTable[tmp].firstarc;
    1 G7 A' V" G2 K# x' g                int t=tmp;
    ) Z8 U( @# ^9 n& O: B* |& H& E                while(q&&tag[tmp]!=0)
    + N2 B7 D' R! u( }                {
    2 }9 [$ W+ f6 h0 ^                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);# F: K+ b% {! G$ Q+ x
                        //cout<<" 2nd     tmp="<<tmp<<endl;
    , A, ?( Q& ?  ?) k! H: y5 R                    q=NextArc(t,q);2 M! J: {) T1 X6 g1 W$ p
                    }8 @5 b  ~; J, U4 U7 a* R
                    if(tag[tmp]==0)0 }2 ~6 F2 b5 Z5 V  P* S6 c
                        s.push(t);
    ) `: U1 c5 B9 O' w, L5 H5 z                ///1、对应上面连通分支只有1个点的情况
    + G  P  W/ L: B9 O                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈+ V' L, O/ C, A
                    ///tmp要么等于找到的第一个未访问节点,5 w1 W) b& F0 p; I9 d
                    ///要么等于与t相连最后一个点(已被访问过)1 U# H- X+ E0 I' e- u
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点: `$ r+ d2 e- r; t: k  }7 j: S
                }
    $ ?: E- Z0 M: Q) i* q1 T9 W( ~5 M        }
    / p1 A: l8 [: i: h3 Y0 }7 Y$ _& C    }
    ! j+ r) |$ d2 H, u6 k}( H, l5 |8 D0 x1 C" n- E( N
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    0 l% {& u2 `2 h. f- s- ?% mtemplate<class ElemType, class WeightType> int
      h1 s; E0 \$ M9 lMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)4 e% G5 @7 ~6 l/ `3 [7 x0 _3 Z
    {
    , Z  E+ l) S5 ?6 R    if(head==pre)
    , K) Q; Q3 }+ ^+ g% d/ ]1 v8 D0 a        return -1;; l5 a5 l+ x5 w1 v9 g3 G

    # d) n& P$ ^  R    MultiAdjListNetworkArc<WeightType> *p;# \! i/ h  L+ ~! L
        p=vexTable[head].firstarc;8 o9 B5 a) o% R
        if(pre==-1&&p!=NULL)
      ]2 i2 H; M: |) ?        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    - F+ N/ }$ D" i4 `1 Q    //pre!=-1&&p!=NULL
    ! K! x$ @) u- S* S- L    while(p!=NULL)! ~" v1 ]  D+ `( s& J  r- ?
        {
    7 W2 i' }5 l7 x+ w- y        if(p->adjVex1==head && p->adjVex2!=pre)" M' R4 n  d+ K5 P, ~
                p=p->nextarc1;" f/ g" n( ^3 l3 l& D8 z
            else if(p->adjVex2==head && p->adjVex1!=pre)1 Z* }" d/ y- l% C/ c; ^
                p=p->nextarc2;
      K: L; {9 T' a7 _+ {, a, `) w        else if(p->adjVex1==head && p->adjVex2==pre)% h/ t- ?0 F: l
            {
    8 f" F5 f+ q8 O/ N4 M4 n            p=p->nextarc1;9 @6 F6 @! E0 D8 C% G
                break;
    : y5 _& U& k/ H5 }) B; n        }, M( _; W, z0 P$ v  `+ x8 |/ X
            else if(p->adjVex2==head && p->adjVex1==pre)8 r7 w2 ]* ^' u% n* B4 x
            {1 Y! S/ f# r( q8 C- g
                p=p->nextarc2;0 s* @& `+ N  Q7 q) D; K
                break;
    $ Z9 m" M' ?! w2 H        }
    % |2 I; A( P* y9 h* a9 Z    }- d4 H! s  b0 T  S8 p9 Y' J$ F/ H
        if(p!=NULL)
    " O4 Y) y1 f2 f% [    {
    % @& o1 W9 k& a. `% V        return p->adjVex1==head?p->adjVex2:p->adjVex1;, J' U! i0 H% a, W1 v5 K
        }
    ! e- o3 W% B7 b, u& Z    else$ U  t  j  L% H" x. g( _8 S% A
            return -1;; f) a2 V7 h. k9 Q
    }$ B1 l( M: u" _8 O) u# H$ D

    ; b+ r# O: O) p! I) P' R* x; [7 A# t  `6 U) ~" w, P
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    5 s0 |; F4 J8 S{
    2 L% D+ @" M: F: N" G7 t* e& F    stack<int> s;
    6 t& t( b# n2 w% \' H    int p,cur,pre;4 f( ]% x2 f' Y2 [
        //MultiAdjListNetworkArc<WeightType> *p,*q;
    - l. Z9 l3 a3 M$ a7 e5 Q" u1 a    for(int i=0; i<vexNum; i++) tag=0;//初始化/ Z: Y0 i) x- F6 f' R  z

    ' S+ s% j/ [5 ~) f& A/ w5 t$ n    for(int i=0; i<vexNum; i++)* ?& G6 J7 E/ T# |2 ~* S
        {
    ( N6 j7 R% V* z        cur=i;pre=-1;2 @- u7 y  v5 B' J4 r& N; A
            while(tag[cur]==0||!s.empty())) H0 _, u5 }" s/ B
            {
    3 F# J' B) Q( C2 x9 l            while(tag[cur]==0)
    ( w; ?9 D$ q+ F5 f$ m& A            {
    ; R. J$ ]8 `& V* h, K                cout<<vexTable[cur].data<<"  ";4 n! x' T3 T( D) P3 i5 m
                    s.push(cur);
    % q: U! B3 ]" s                tag[cur]=1;
    $ `+ L  p2 x- {: y               //初次访问,标记入栈6 {) H0 a; h* y2 {

    ' N5 l* H6 _2 L               p=GetAdjVex(cur,pre);//p是cur的连通顶点
    % F- N/ I( P, r, p( i  d9 D               if(p==-1)9 L4 _# Z( K9 N3 I
                   {
    # H. Y/ p$ B  ^4 r( A                   pre=cur;s.pop();
    - B8 \0 b) V5 a3 Z7 K/ K! m' @                   break;
    - G& P1 o3 R  W9 H               }  ]+ A0 i) t# |/ u5 f7 o
                   else1 J, ^* Y4 P- H8 d
                   {1 k6 J- B0 z8 c3 Y
                       pre=cur;& ]( C7 a7 A/ i* U( V* C
                       cur=p;
    # d3 k6 o  R& i4 Z               }
      t$ i% P2 b. A" v) |" U4 x/ z) b' ?2 _4 L
                }
    ! T, t7 R0 U6 R# R6 W            while(!s.empty())
    6 I( ~- E/ V. D, F7 t            {: u$ c+ a+ R5 g1 x
                    cur=s.top();6 l" ~2 ~$ ^% y2 P: ~  n
                    p=GetAdjVex(cur,pre);
    1 I$ L3 |; p6 M/ Z                if(tag[p]==0)9 |! H% W  R3 c5 `  o) f0 u4 @/ w* }
                    {5 I7 R/ |) H( a# d8 j
                        pre=cur;
    2 W% S- ?& F2 W" w$ w$ A                    cur=p;
    6 J- |. l/ P2 b8 I; I                    break;2 N/ ~  L; p) ^# M
                    }
    - _0 b5 q: D# q" [4 d; O  N. f                else
    3 \4 V+ H( Z) i( W7 q# L                {) t+ r* c/ e$ q4 u$ S7 i
                        pre=s.top();
    ' }9 B8 g3 i6 [3 g6 {! |                    s.pop();( B8 e7 f6 [) u, Y; M1 o
                    }
    4 h9 K- O: n+ @; j# H
    % ~, }- ^# y2 t& [: n3 v9 t- {            }, l1 A% ]% P5 E8 X4 ~" e
    1 ]  I: e% M$ g5 |) a; `
            }. n: ?; L" r% O( [' g5 a/ B
        }4 t9 P& H% N& L7 m9 o
    }
    ( `; G  K* Z* \* [. a3 i* @! M. Atemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    0 V/ m1 S" [. V& y{
    ! G& {9 {- }+ v    for(int i=0; i<vexNum; i++)% J- D4 H. \1 Z, D: ?* w- d
            tag=0;
    % S/ b4 K6 c. h$ w    queue<int> q;7 L  e3 @' U" X( \
        int tmp,t;
    2 m' i: g/ T3 b) K- N. c    MultiAdjListNetworkArc<WeightType> *p;3 L0 q9 x# ]4 U3 `3 h# e" @
        for(int i=0; i<vexNum; i++)0 T( @. ?( n- {
        {
    . y$ _, G/ `9 `- ~" Z7 R( P- @        if(tag==0)& A. Z- M& G7 C6 \. R
            {
    ; E3 C( `! Q& Y. R5 t) ~  {- F! S            tag=1;
    8 c! J7 v3 L6 [8 a3 I/ a' z            q.push(i);* o4 Q  \9 o1 d
                cout<<setw(3)<<vexTable.data;3 v3 J2 k: z/ a) m+ M0 S/ ~$ j1 \( ^' F
            }  p# Y$ m& K% G- G) b! I
            while(!q.empty())$ l$ E/ h+ R' a% i  d
            {  _7 Z& Q0 h. b, c
                tmp=q.front();0 R# ?: i/ i  v; n3 b) T; o6 k
                q.pop();
    6 H, ]+ G" h; r' P: ~            p=vexTable[tmp].firstarc;, K5 ~6 ~# I( ^6 H
                while(p!=NULL)
    / a/ A+ Q1 I: A5 O4 E5 b' ?            {- l; V# e) s0 |! k$ ~
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);2 Y) T/ @0 K( y2 S( c, C
                    if(tag[t]==0)
    3 L2 |+ s6 N& ~5 e4 B: G                {
    9 z5 U: }2 w: h9 ^+ Q; p                    cout<<setw(3)<<vexTable[t].data;7 {/ n( F% G( r9 c1 Q2 {
                        tag[t]=1;2 Q3 ]7 f& A# e* w" m
                        q.push(t);
    8 s7 C! @- W! q2 G$ X' V; x: r                }
    + o6 Q. s: C, n* P. C- \                p=NextArc(tmp,p);$ I9 N' u3 N6 a  v! v+ B2 T0 r% T) V
                }
    * M  Y0 A# @  O# q        }
    ; q: F& G+ e+ j    }1 ~+ h3 [5 g+ m. ^
    }
    - ^. m0 R1 c3 itemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()0 A; B. R1 q2 O5 m5 n: I
    {
    1 j1 p4 O2 E* R& [6 J    MultiAdjListNetworkArc<WeightType> *p;
    8 l/ Q  R& |  s+ y$ L    cout << "无向图有" << vexNum << "个点,分别为:";
    ; W; _, I) Z! `# y" a$ N* D    for (int i = 0; i < vexNum; i++)
    ) ]& f2 `9 X0 k$ |9 B        cout << vexTable.data << " ";7 |9 o9 v( x$ A; q) R
        cout << endl;; A+ V$ {' u9 }5 L5 v0 ~2 T! x' ~
        cout << "无向图有" << arcNum << "条边"<<endl;
      K8 f" `& |1 N# r; @% U* d    for (int i = 0; i < vexNum; i++)
    7 G4 Q; C5 m9 K    {, [9 f. j: M/ ~+ {, ~
            cout<<"和" << vexTable.data << "有关的边:";3 L8 N. j8 D7 {& b
            p = vexTable.firstarc;& |! _5 s- l6 b* E' t$ q, @- p
            while (p != NULL)9 q' m) n& J- w% }2 j
            {
    # M7 x; Q/ X* Z6 |            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    9 ?! w9 Q% M0 B9 K4 V( N9 x- D9 ^            p=NextArc(i,p);5 K8 G8 ~7 ?7 o$ P2 I% F
            }
    4 {, r2 H2 r- d5 M$ U        cout << endl;
    . T: j: v( n% Y! C/ t, s5 G    }
    5 V' `, h) P3 g. c}
    0 ?  I4 W4 o$ X$ B9 H2 u/ \6 i$ @2 P- r' U' W- O+ i

    , [$ n& Z' C5 v0 F邻接多重表与邻接表的对比! \+ o- H3 [, t5 n" O5 a$ U
    ) s5 c- p1 |, `( O  H) k/ a" S
    邻接表链接! F, f# X5 |/ c0 o* `% N
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。! Z9 H3 k4 Z% A" B
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    . }7 {1 j3 H$ [# E( e1 e3 P' O6 o为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    ) H. W" T$ p+ l: K7 W: o% r! [————————————————
    $ t, y4 c  N3 o# W6 n+ S/ ]# ~版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。. G1 ^! l7 N" Q( L4 ~, D, [* f
    原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669588 a8 T: J- a' R* B, R! j  c

    + O$ K% D( o5 e0 v' F1 C% S* R" \: z! A. I) H% \* P$ w% H; d5 L
    - I( c# j/ G5 a* x0 P( m' L! J

    1 p8 ~" @% y$ V; _& v0 J& b————————————————( }( ]) c6 H# P* i3 f$ C* {9 ?
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    # k6 R6 G3 [/ B原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    % U% a: w* C2 \; a7 e1 [% E" K5 o" r7 ~! ~7 e: L) T0 J" v/ E' b
    8 d! F) e5 a0 U5 w$ W% K8 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, 2025-12-10 03:27 , Processed in 1.126744 second(s), 53 queries .

    回顶部