QQ登录

只需要一步,快速开始

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

    2 W* i% {4 }# C7 x& f  U图的存储结构——邻接多重表(多重邻接表)的实现4 M: g  t1 e* ^) O
    7.2 图的存储结构5 r3 R) p2 J. x' x; C
    : B* l* C' x( n. f
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    / j' R) p: Y4 i/ B邻接多重表的类定义
    % u0 T% c& F: G" B5 g$ Q邻接多重表的顶点结点类模板
    ' ?/ n+ E8 Y0 q' G6 S邻接多重表的边结点类模板4 m  T5 a6 `3 y# @( v8 _
    邻接多重表的类模板# [0 h2 @3 ]6 K9 j0 i2 |
    邻接多重表与邻接表的对比
    1 Q! i6 x. B9 D- `0 T7 P7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    0 a6 A8 e, Y- M4 T
    4 n* o" n( a+ [- e% Q* c6 W2 g4 o在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。* D- q; W& b( v3 P% o: F; J1 ~/ W
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    1 P- P: x& C7 Z( P; }# u; Q2 A# F9 M) X' j
    邻接多重表的类定义
    # V! T; Q' C* N1 c7 s- T) @8 C. _0 N 1.png 1 X& x* ^7 q% Z4 ]& j% d
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    ) e; i. C. d$ n  ~% tdata域存储有关顶点的信息;
    ) R! u6 X9 }& |! ]6 U/ b2 ]firstarc域是链接指针,指向第一条依附于该顶点的边。0 v4 }( N+ Q6 O: m! p  d
    所有的顶点结点组成一个顺序表。

    : {+ G% p1 ^8 ?

    - ?- I, {& v" b& t7 Xtemplate <class ElemType ,class WeightType>, `) L% N5 u& k! m7 K/ l6 o
    class MultiAdjListNetworkVex
    % ~* O0 l  q" t$ d0 J8 I, J- y  e{
    3 B2 b5 E6 |  ?, \# ]public:
    3 o2 x5 G  o1 c  |' ]- u1 ~3 t        ElemType data;
    % }! L; f' Q4 ^" Y% n3 _        MultiAdjListNetworkArc<WeightType> *firstarc;! k) S  y6 m3 N; q  T6 [3 G
    ' T5 D% D7 A; n8 _  c) A# [
            MultiAdjListNetworkVex()
    / [0 d3 f: _5 K# t        {+ [8 B2 Y4 r* G; p/ B
                    firstarc = NULL;
    ) H; o0 ~5 D0 v7 ]' ?        }
    ! Y' |3 }+ ?3 ^        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    % J: y( w6 Q* P/ c        {
    $ M; B- ^/ \& d: k                data = val;
    ! l6 m5 T. B5 u* x6 Q0 A; P: n                firstarc = adj;
    $ @  d6 y6 z1 ?; ]  c5 Z        }
    7 S/ E( p2 T% x" C* T! d};
    1 a$ P, A; I/ r3 Y4 Z$ i8 @. x; G0 J  U7 O
    邻接多重表的边结点类模板+ ~/ l; |+ J* `$ V
    # N  h7 |) l) t/ z* ~. ^
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:3 Y1 v- L% x; g& k
    tag是标记域,标记该边是否被处理或被搜索过;
    + [3 I( u* B# v  |% B& R- ~weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    7 U8 E+ w$ X" ^( H* ^. ^! F" {9 wnextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    0 k# U! S# k" F" s0 Vnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    5 J  g5 f  B0 m' }5 S8 ~6 i4 K4 y" G7 W) r# _6 U6 e
    2.png 0 ^2 m8 ~7 m& k; ^+ d5 ]  Q
    template <class WeightType>
    3 {: E1 v% q2 j/ b& |1 mclass MultiAdjListNetworkArc8 j' ?3 ?3 M7 v: b; D
    {7 I- H7 U: a; `" t+ ?! H% _
    public:
    / `1 r" w4 H! h. {0 O4 }/ b( `; \    int mark;                                       //标记该边是否被搜索或处理过8 h1 J8 ?* \) n* d* i+ N0 U
            WeightType weight;                              //边的权重0 _5 P. L; d; X9 N" J- i! d1 ]
            int adjVex1;                                    //边的一个顶点
      n8 C7 g: ]! O        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    : X; \$ A# d$ S$ i2 D- ]        int adjVex2;4 K) F4 g* i, w7 U! m
            MultiAdjListNetworkArc<WeightType>* nextarc2;4 ?4 r) Q0 `" v; e' a- ?; b
    6 W" o+ [9 i$ Y1 X" f
            MultiAdjListNetworkArc()
    ' a8 ]7 A2 J. c& H. G$ k) T+ o( B! {        {, Y5 O, T+ k2 C5 w8 r4 I1 N5 V3 n4 C, f
                    adjVex1= -1;" U: _: M+ A/ z; g6 P* D2 |
                    adjVex2= -1;0 j5 e% c* S. [
            }- V/ X2 n. u1 z
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    * h! e  a( c5 R1 L        {* R) {6 i) U: ~, u& H
                    adjVex1 = v1;       adjVex2 = v2;# f0 |* p* e) `3 F- {# P
                    weight = w;$ U4 O5 l3 W6 f2 X  E! x* c
                    nextarc1 = next1;   nextarc2=next2;- i8 R1 ^; w, H! r, ~9 y
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    * j; x4 \  s* R8 [8 w  a/ k3 j        }
    - K0 O0 x+ J( y! S9 y; y. }
    ; g- J4 q* A$ i" E4 v$ l: r6 r邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    ' n9 c$ J5 P& G  ^+ Qclass MultiAdjListNetwork7 K7 Z4 D1 E+ W, Q$ E3 z
    {% b- {0 |7 D7 i
    protected:
    ( J8 X& }4 ]# R2 p0 V# O    int vexNum, vexMaxNum, arcNum;
    1 l# R  j, i3 V% c: o/ o0 z- B    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;, G8 p8 ]5 @. t
        int* tag;' r& g4 l  m  h9 l& v4 {
        WeightType infinity;
    9 ^! ^/ Y9 _! i; ?- j+ W* Y0 }
    " Z( t+ J% A" mpublic:
      \( S4 ?( S: M* A$ l# P8 Y    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    7 N  Z( c. V; h2 H
    $ l/ G/ y/ y1 }    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);  y7 E: a; M1 I0 k- s

    , \/ |# F+ z" T6 C# [, n  X, L    void Clear();
    3 _$ e' U8 N* J; s3 p+ G) p+ I    bool IsEmpty()7 i8 p6 d+ J$ j# B) H, r
        {
    ; m9 O  Y3 j# O# n( H' w4 ]8 [        return vexNum == 0;
    . M) a+ E/ e/ z. J0 b" [/ S/ a1 q5 \0 b    }
    * [! [3 t  d% s# N    int GetArcNum()const
    % Q$ y* K7 n$ \, W" r. I    {) w6 |6 D3 o3 ^
            return arcNum;
    1 L( S9 F( Z8 ^8 L, z1 R    }# _4 B! w- R- S& n6 i. U
        int GetvexNum()const+ P0 q8 R( k- |0 W0 n& S5 X; z: X
        {
    ' \8 O- F# a  \        return vexNum;
    ' b" k" Q0 o2 j    }( k/ {8 v; }+ {. T7 }
    . w3 u1 y0 c3 v$ H1 T8 U

    % u+ Z) d* ]1 ]6 h  @8 l    int FirstAdjVex(int v)const;, [3 W+ `+ v6 U/ G
        int NextAdjVex(int v1, int v2)const;
    , g  ?$ A" e% q: k    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;* l: \- k* Q( X( ]! e5 D
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    $ w1 u2 ^7 {6 O  m* }" [2 R  a: [% q" o
        void InsertVex(const ElemType& d);4 h0 v+ H/ i& m2 j' C! {0 @; F
        void InsertArc(int v1, int v2, WeightType w);
    * Z8 h2 b  K6 Z1 G  b
    ' w8 L4 @  c2 C    void DeleteVex(const ElemType& d);
    * a' d, C' f0 N# ]    void DeleteArc(int v1, int v2);1 V( \) R; t4 Z
    3 X& ~. M5 H* \3 S
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);# x8 S8 L) y: D# k' p3 p
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);' E! K" b6 x0 [5 s

      L# f% ^" g/ q* b. B8 P    ///深度优先遍历
    ; y7 y( Z! x# G- p: i    void DFS1(const int v);
    ! K# @( ?* t2 f    void DFS1Traverse();0 k9 y* I8 R* X8 H
        void DFS2();
    " L, |  Y3 P5 O# o6 O, B. c+ A9 c& b) ?0 `! G6 d  S" u8 s
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    * s( b5 J0 R" N( n8 T# A& H    void DFS3();
    2 t) T0 D7 K0 J; Y4 Y2 a+ t
    & U2 e+ _/ W: ~  M9 D    void BFS();
    ' M9 L8 t4 W+ S/ n    void Show();2 V, q9 q- `. m5 M% X5 `* _$ M* ~
    };2 L" |. y6 r9 W5 O, V+ z6 I
    9 S; C$ c( P' W$ g/ n
    2.函数的实现; @0 c: s) q3 e0 Z! z1 Q7 t9 L' l
    研讨题,能够运行,但是代码不一定是最优的。
    5 ^% R' e; u" P
    + n, I0 T3 F- o3 {4 u/ z& h4 i" a#include <stack>
    , q  d* T0 A: a. r#include <queue>
    / s% v" d0 Y0 L+ j; V$ p
    % z- |7 r! r8 Wtemplate <class ElemType,class WeightType>
    6 r: N; k& H1 e& H3 m/ R- MMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
      z) M+ Q" w/ f& I: r3 A1 b# v{
      L: ~* i0 W; R& v* j, u    if(vertexMaxNum < 0)
    ( Q& z& [! m2 g5 Y& B" z5 \0 Y        throw Error("允许的顶点最大数目不能为负!");' X8 j! f7 V& B% P  R. z1 Q2 k+ g
        if (vertexMaxNum < vertexNum)5 l8 i9 S6 Z0 `! }
            throw Error("顶点数目不能大于允许的顶点最大数目!");+ A# P; t+ N  d& I6 O9 V' y
        vexNum = vertexNum;
    1 H/ ^8 J1 u8 u$ n( s    vexMaxNum = vertexMaxNum;
    " ~: n" u+ m6 u+ h% W7 L. L    arcNum = 0;
    . }% s7 b8 `! V! q3 Y) b    infinity = infinit;" _# x; }, T  ~7 r- L  d- E
        tag = new int[vexMaxNum];: q0 w* {$ _4 y. k9 N
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];1 d# Z" g' x/ O. {# c/ I( c
        for (int v = 0; v < vexNum; v++)$ c$ A. e0 R7 l# O; B( P
        {
    + |* J  u* F  L& T. Y1 B% p        tag[v] = 0;; i6 X1 z, T+ d% v7 n; ]
            vexTable[v].data = es[v];, ^+ G! q& V+ |; W2 E
            vexTable[v].firstarc = NULL;7 }' N  b) E' u) M
        }
    6 I& B4 w# z8 X1 C}4 U$ `. c9 p/ G  p7 J8 w
    template <class ElemType,class WeightType>
    + x* e% q, i% G) g6 u9 Z( f/ r3 @MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)* t/ F; U! E2 K& H  M) @
    {& s/ k' V, Q: _9 |
        if (vertexMaxNum < 0)
    5 y3 R0 B2 R/ T7 `$ K  a        throw Error("允许的顶点最大数目不能为负!");' u" |( I5 o8 l- b; D$ v* `" i
        vexNum = 0;/ d+ ?' N7 x8 h  Y+ y  U4 S' `
        vexMaxNum = vertexMaxNum;
    4 w/ X" z* _5 g  ~    arcNum = 0;/ m( z& p1 ?" @
        infinity = infinit;
    ) h) w) \- E# v: T( T& Y    tag = new int[vexMaxNum];( w( b5 U3 E) i& V6 B& V
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];; G, h' e+ z2 q! ?; R+ N/ l
    }! x* T) D7 O* D& S$ G! A$ s
    template<class ElemType, class WeightType>4 I1 ^$ f' W- C7 a
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    , @% A+ l- ?0 o7 Q! m$ ?{% }" g1 R4 o  Y1 S! v
        if (v < 0 || v >= vexNum)0 z! @) j' I! F) J
            throw Error("v不合法!");' _, ~; @! V) y% W3 T# u+ @
        if (vexTable[v].firstarc == NULL)+ n. k# u; O: o/ t  Y+ G" E
            return -1;
    8 X2 t2 }3 z1 p8 y! {3 ~% Q    else% ~6 S$ w; v( S% u4 i- I, x8 M7 _
            return vexTable[v].firstarc->adjVex1;! y1 M* g0 p% t5 A
    }
    ' ~7 S/ ]; H2 n6 {
    / ]/ g$ m" n2 R* I- r( Q2 Ftemplate<class ElemType, class WeightType>7 M, ^2 q% Z) }7 r5 X- s
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    0 p) T0 {# W6 O8 c, A2 ^2 z{
    + z' J  w7 a( ~; ]9 Q    MultiAdjListNetworkArc<WeightType>* p;
    0 |6 s# {% w8 m& m! g2 f( a    if (v1 < 0 || v1 >= vexNum)  ~7 L% d' n8 F6 A
            throw Error("v1不合法!");
      _' B0 z; C7 m. }/ L0 ^" X6 E    if (v2 < 0 || v2 >= vexNum)3 Z1 w- l; f9 m
            throw Error("v2不合法!");) ~2 ~' ~6 u8 b5 _2 L0 W
        if (v1 == v2)6 q9 J/ U9 N. c: u/ Y
            throw Error("v1不能等于v2!");
    . v& W, u. B% [8 d" U4 s) {1 G    p = vexTable[v1].firstarc;! T# N7 h3 `% a: v: U
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2). [: d0 Y0 M/ k, c
            p = p->nextarc;& X9 f( G) x) T* L1 p% d; k: @$ E
        if (p == NULL || p->nextarc == NULL)
    2 T) V! d3 V& ]* h7 Y3 m( s* z        return -1;  //不存在下一个邻接点3 S; V, x5 @" d( j/ D3 y
        else if(p->adjVex1==v2)
    " L- c/ T# X# L7 y) W; Q% G2 R$ _        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);3 X6 z. n1 [3 d7 ?
        else
    0 w5 r! U  ]# t* A$ {        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);- I1 n9 U4 k& q, ^" F1 ~1 M
    }
    6 b9 |7 m8 @5 \3 otemplate<class ElemType, class WeightType>- E: ^( x* |8 ?/ u1 ?
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()& Y1 e' q5 B3 n, F5 Y$ o, h
    {& k% N5 B1 P6 i$ m4 ^7 @9 G
        if (IsEmpty()) return;5 Y! _. G6 {. [
        int n = vexNum;
    6 f+ ^; X, i; ~$ k    for (int u = 0; u < n ; u++); k5 W. d6 m4 M
            DeleteVex(vexTable[0].data);
    2 M! ~3 e' E, ~% x    return;, i, ~1 z% m3 ?4 F3 n; ?# d
    }
    ' J8 |4 v$ j8 \" A8 |template<class ElemType, class WeightType>
    7 ?! w+ J/ b! B/ w0 PMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()5 u! Y" P  }* m, _3 G
    {0 F; h6 @' y( ?
        Clear();+ \0 r) y$ N2 d8 n6 L
    }
    3 Q$ [4 {8 S  H* [* Ptemplate<class ElemType, class WeightType># l# w* E; u. h) u9 ^
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)6 @: Q6 }  S. p  H% T( ~; @
    {% d& e4 R$ L" {1 I9 ]# h, H
        vexMaxNum = copy.vexMaxNum;0 g4 _; f  n! [$ }& e% ]
        vexNum = copy.vexNum;
    8 A' t8 i; o3 z% m) C    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    1 C/ t+ j9 t. h& n! g    arcNum = 0;7 `8 o* d$ U' U( K
        infinity = copy.infinity;
    * \+ ?% o/ R  n, \( ]    tag = new int[vexMaxNum];
    6 Q( X. H0 S6 L7 Q% u5 U6 y( K& R% {4 A$ B- l
        for (int v = 0; v < vexNum; v++)5 d  y+ b, p" p3 E8 m- f
        {
    + i0 x/ Z" e) T- T! X        tag[v] = 0;
    ( L" k$ ^7 R' B        vexTable[v].data = copy.vexTable[v].data;2 M" |: _3 `+ H) h! W
            vexTable[v].firstarc = NULL;
    1 M& H% }  }& M4 k    }1 W. b. f6 H! {
        MultiAdjListNetworkArc<WeightType>* p;
    / W* `; j( G* O& L9 a1 |9 u" {& t6 p" Y$ m! |" z6 v0 o
        for (int u = 0; u < vexNum; u++)' W% h) i; Q' I) N, l3 Q  k( T
        {4 ]. o2 W9 i( K: n1 Z& c
            p = copy.vexTable.firstarc;) u4 y% P( Q% R* a" p
            while (p != NULL)
    , T; ~3 {7 i; l( W7 C7 q        {
    # A% i0 x  Z" C$ \0 k            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    / d" ?. r6 Z& \+ Y$ Q2 C# U            p=NextArc(u,p);7 M! D" d8 h5 d, f2 S1 g
            }
    0 X/ j! `( v) p7 a  u. D* J# M    }
    $ c0 Z9 a6 R' `/ J}
    ) D4 N# r+ Q1 o+ O$ Qtemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    ' q! |1 R- b  Y1 `7 \9 WMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    ( N& a. z* G7 F  H: n{
    ' \9 u$ m3 I/ h$ C    if (this == &copy) return *this;
      q1 H4 n2 f7 V( R# |) o9 e    Clear();
    ' T3 L3 [' {$ Q" r8 o    vexMaxNum = copy.vexMaxNum;
    " t, V  r* G; D* T. n7 T    vexNum = copy.vexNum;/ a/ U: e8 u% e% b$ s$ X/ V( a2 |3 w# j
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    2 J$ O( K# s+ O8 c; y    arcNum = 0;
    % U& Z; p/ |2 F    infinity = copy.infinity;
    # r8 v3 v! ^! x; o& Z$ ?    tag = new int[vexMaxNum];
    2 ]0 x8 e3 y9 U7 P' q* ~6 t& {8 {2 D+ H* J
        for (int v = 0; v < vexNum; v++)
    - [) A! @% S2 r4 j3 s; B    {
    6 \  b1 r3 Q9 t( i        tag[v] = 0;
    ( U$ k, g1 }6 T$ |* ]% x        vexTable[v].data = copy.vexTable[v].data;9 s* U9 w- {1 h! T
            vexTable[v].firstarc = NULL;
    ( T5 B3 m4 G# ^+ [" E0 l- @0 G8 j    }1 x4 ?$ d3 I  _% |
        MultiAdjListNetworkArc<WeightType>* p;. o  m; P+ n4 a

    ! l! r! F9 A# w" t5 x6 |    for (int u = 0; u < vexNum; u++)
    ) Z; c  D' G2 n/ _) R0 J( g    {" B; M- r, ~% P* O" t" H, `" F& R
            p = copy.vexTable.firstarc;
    - ~- w6 g. }- @4 S        while (p != NULL)2 m# i% |7 @$ }( k
            {
    + ^$ |- l5 P) r/ o  Y3 w, _3 T, _" I            InsertArc(p->adjVex1, p->adjVex2, p->weight);4 V, u5 a! m. A* \, R/ k. T9 g% r
                p=NextArc(u,p);
    ' M: U! ~  L5 G) K        }
    $ K' b2 W2 J1 i: O# y6 R4 F    }' e$ S; F  G+ J" M8 |$ Y( L+ i7 `
        return *this;
    0 ^# e( y+ V& I/ F! a5 ~$ l}9 P7 \5 \! e# q
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*$ b2 M$ b7 G, K; r+ r
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const+ Y3 C6 K$ I3 U. U* {9 w3 ^: |# q3 p& U
    {
    % N$ [$ W1 d$ n+ H, ~3 [    if(p==NULL) return NULL;
    2 T2 `) F( N8 Z( W- v+ Y# a0 H    if(p->adjVex1==v1)
    . |! @3 x$ u& G3 o  L6 z        return p->nextarc1;
    & D: q) V: w5 L; D6 q! e- A2 ?, c    else/ b; v& Q. f4 P
            return p->nextarc2;
    7 H+ N9 K+ ?/ o# t}- |7 z* I$ O' ^8 O+ Q- W
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*( s2 q- G, S( R* e  v4 F2 G" k
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    ! u; t: }7 I7 C" q  _3 K3 e{# V% T+ K/ s( T
        if(p==NULL)return NULL;
    ; O! j, p: D1 H* {/ s    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;  a4 x" n- v1 O' \4 @+ i; q8 u
        if(q==p)
    ) D' S% E# \! f3 @9 C        return NULL;
    9 F" b8 \% B6 F    while(q)
    . p/ Z6 x# o2 z, k, F) j    {( |4 k( o1 Z9 B& [
            if(q->nextarc1==p ||q->nextarc2==p)
    $ i2 |6 x1 m5 f" B+ W4 B8 V- H. i4 z  @            break;
    3 v% c9 u  D" `5 n        q=NextArc(v1,q);$ z2 g7 [) m  Y4 F8 M
        }
    3 X# Q6 w8 j  w    return q;1 D" g4 O; B! P0 s0 H
    }7 ]6 h3 s' L5 o2 E* L% i* A
    template<class ElemType, class WeightType>
    6 V9 P, c; I- ]$ ~void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)1 Y1 h$ j7 t6 D/ J8 J
    {
    5 r4 A. N2 u/ f) u0 r1 `0 P; d    if (vexNum == vexMaxNum)3 L; D: B/ {) ^7 \6 t/ h
            throw Error("图的顶点数不能超过允许的最大数!");
    ' |) q+ D( ~3 z    vexTable[vexNum].data = d;
    6 ?/ U2 U1 _) i* Y9 E( B9 Y8 ^+ A    vexTable[vexNum].firstarc = NULL;5 Q" \- h' P8 ]9 T7 `( d
        tag[vexNum] = 0;! _* ~: ~% X, ^. {4 q
        vexNum++;
    ; F& _6 i3 j- m. e}# s- r4 u, ^( t
    template<class ElemType, class WeightType>3 a$ }$ F, w8 s0 ~- l* R" k
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    3 [. k) _! X; K& {0 a8 s7 Y8 O{
    % U2 T& `; d6 M( F    MultiAdjListNetworkArc<WeightType>* p,*q;; T2 v; h: l9 C  s3 C' O
        if (v1 < 0 || v1 >= vexNum)
    2 G3 @. u! Y! E  A/ Q0 I0 Z, n+ J, {        throw Error("v1不合法!");9 H1 C. D6 b' [: y
        if (v2 < 0 || v2 >= vexNum)
    2 N$ m; K# j1 q$ c9 b' t        throw Error("v2不合法!");
    * j/ O' h! X4 A$ G$ @5 S    if (v1 == v2)
    3 F( h  }2 y; Q        throw Error("v1不能等于v2!");0 O' Y' s) v9 _( Q! g/ \! i3 b% O* ~
        if (w == infinity)
    9 a6 H! O! M+ u! g, C  u6 s* v2 j        throw Error("w不能为无穷大!");
    " a. r) ?! v- C( p2 z4 C: j- x1 R, G9 P! R& _, c# F

    ! R: C# r3 P8 j  N    p = vexTable[v1].firstarc;
    ( c. Q2 S* D( W( J) g    while(p)4 \1 h9 M; l/ a
        {
    5 @4 Z2 E% K( d( ^7 z- k        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    2 N9 U% ^6 Q* P        {0 n) k+ D% c  O- o$ j" u
                if(p->weight!=w)
    : x8 `7 a+ q7 v' i8 m0 L+ b                p->weight=w;
    - j7 r) O" S" [5 z: i            return;
    - o% y4 R6 L. v+ J        }' R+ |( r  `' p, _* l2 R
    2 r" y  |1 d& f7 O. }, I
            p=NextArc(v1,p);
    / V! c) r3 g3 l1 |0 N" L' }    }+ \8 I- r' U! y
        p = vexTable[v1].firstarc;
    0 |& n% x: x6 A  }; O1 x    q = vexTable[v2].firstarc;
    ' E$ {, N2 U- \. Y( Y  c    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法0 ^% N3 C+ h3 y- k" \. c
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    1 `& v( o* ~, b* ~4 [$ E7 C) c    arcNum++;
    3 O9 i3 E# Y) a8 L, T( m}) z* ^6 @5 A5 d+ E+ n, d
    1 f( y3 G( y% T1 }3 w: P* ?
    template<class ElemType, class WeightType>/ p& v4 y4 i& w" e+ W
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)! _3 s3 J0 l, z) E
    {. E' k6 n1 a) B# C' @/ h

    % L( b. y& O& I  B/ V    MultiAdjListNetworkArc<WeightType>* p, * q,*r;  q. w' n2 F! q1 s
        if (v1 < 0 || v1 >= vexNum)
    # t) v7 P  b! @! [( A# Q. S        throw Error("v1不合法!");! n- D4 O  D: }, S0 h
        if (v2 < 0 || v2 >= vexNum)
    5 ?8 E8 e1 S, ]4 J        throw Error("v2不合法!");7 _  Q, S% D/ ~' n4 H% x  b% c* g: N
        if (v1 == v2)
    ) Z: p  ^  P0 M; i8 |0 T4 ^7 g, O' L        throw Error("v1不能等于v2!");
    % g; Z: Y+ c- a! y
    2 p0 v6 P+ Y( a/ g: x0 P/ Z    p = vexTable[v1].firstarc;& Z3 Y4 ~' S& r; {( l) B. p2 l
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    ) ?& x# d1 ^/ i4 W2 J    {. s. j+ Z  @- s( y/ j7 V: J7 y
            q = p;
    8 N, w4 B( d# T: @! l6 ~        p = NextArc(v1,p);  Z3 q+ Z8 O( m, G6 N
        }//找到要删除的边结点p及其前一结点q
    7 I& r# F% ?% c& \$ k' E* A
    2 i3 `% B" M# f2 R! ^    if (p != NULL)//找到v1-v2的边0 f8 J1 C$ D" D# v  Q6 ~
        {
    ) p4 G8 B# m( R8 ]        r=LastArc(v2,p);4 K3 c) d1 s$ x9 w/ G! a  l
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    ! b3 q' i7 H, G& ]- q3 Y            if(p->adjVex2==v2); Z. c: y# i! l0 {: v! e
                    vexTable[v1].firstarc = p->nextarc1;
    ( d" @7 K) M2 S            else vexTable[v1].firstarc=p->nextarc2;
    - ~- U& q1 B% S        else//不是第一条边
    ! m7 b- g9 w- Q1 [: v+ a        {. g4 a. J, X. k& z
                if(q->adjVex1==v1)
    5 {; j9 Z3 w0 n) S7 t+ h  j6 {) F                q->nextarc1 = NextArc(v1,p);
    7 V9 b2 V% O% ~7 N# s3 I0 G            else
    % c3 Q# {5 f" f- T2 u                q->nextarc2=NextArc(v1,p);" Z! l+ D. `! y7 A: s; j
    8 Q4 V8 L4 g( J7 l5 I
            }
    - m2 t3 F2 m, {2 h        if(r==NULL)0 @5 z6 Y$ S! J$ c+ H5 ^2 N
                if(p->adjVex2==v2)$ r$ _* S" \4 q& ^8 d4 ?
                    vexTable[v2].firstarc = p->nextarc2;# t# r  Q! W2 O4 e6 l1 X( x9 @
                else vexTable[v2].firstarc=p->nextarc1;
    3 k' D. `& P; u: Z& @        else
    . N7 S' M' B% Z) b8 y5 g, Z        {
    9 W. q# j8 b4 o. s7 {0 C! u            if(r->adjVex2==v2)* ^. U; `! W2 R( Y
                    r->nextarc2 = NextArc(v2,p);
    - S/ u- T3 q: s& S3 f& E            else/ i( `5 A* B8 R. L
                    r->nextarc1=NextArc(v2,p);$ L, M( P+ k( b5 O- L* y8 ]' M
            }8 S* h1 V) ^+ `' Z' `* Z. G
            delete p;
    ! x. K6 g- d. _1 S/ `        arcNum--;$ G* U) n" I7 }3 D% v# C4 \
        }
    9 d( S2 w. o6 e2 K5 V) L3 ]$ E. A$ [6 B) g* R# w$ M4 G! c, S5 V! p6 V
    }- n8 \1 P( }( G, A4 T
    template<class ElemType, class WeightType> void
    ' b3 k) G! V0 `9 a, U" z% EMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    " |* \4 w* t1 u" d{
    9 ?2 ~) g; E# G, |5 J, l5 `3 I7 e    int v;3 [( _- b4 I) f; D
        MultiAdjListNetworkArc<WeightType>* p;
    ' M0 A+ b3 z' b4 H: `9 ~! G    for (v = 0; v < vexNum; v++)//找到d对应顶点: o& D- q" I+ A4 ?
            if (vexTable[v].data == d)
    1 w! M# |& U* [+ T7 C! `            break;
    $ q7 j" t( L0 F: B  V8 @    if(v==vexNum)6 F2 J6 r" l) M1 ]' y( E
            throw Error("图中不存在要删除的顶点!");
    , p, ~7 z1 F- Q) W  f7 c& c
    1 q6 Y1 y: i3 U# X( h/ A' Y- t    for (int u = 0; u < vexNum; u++)//删除与d相连的边/ T! w8 w4 e! Z- K1 f% Z
            if (u != v): _; Y$ o; [& S6 S
            {* G/ `! b! @2 G1 {
                DeleteArc(u, v);2 k& `' ~' H+ f
            }4 C$ y  v$ E; ?& Q4 m* a% j6 {
        vexTable[v].firstarc=NULL;0 I  \- _6 g' F% Y
    : W0 m( ^* U. K/ {. M
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    : q& G6 I8 v/ j) L    vexTable[v].data = vexTable[vexNum].data;# d7 t5 `% ?3 M" I
        vexTable[v].firstarc = vexTable[vexNum].firstarc;
    . H& D4 \4 T3 d% a, R    vexTable[vexNum].firstarc = NULL;
    8 W' k/ |& t! j- \- `    tag[v] = tag[vexNum];9 d* q7 {& x: ^) Q5 T
        //原来与最后一个顶点相连的边改为与v相连
    ) |) Y. J$ N* ^# U    for (int u = 0; u < vexNum; u++), ~  l: H, `4 i( k* c. b8 N
        {
    / q, D, d0 G& M- L5 E        if (u != v)) o. X6 l" p: c
            {
    " H8 G# I- y( D4 u# M! r5 d6 N            p = vexTable.firstarc;- w$ B1 ]4 K4 ~0 D1 O, K
                while (p)
    4 H5 g$ M& Z  {0 a. n% S            {' w' `5 ^$ Q- L. `
                    if (p->adjVex1==vexNum)
    9 `8 q# C, m2 a/ y                    p->adjVex1= v;- f0 |) D- x6 W4 N
                    else if(p->adjVex2==vexNum)
    8 W5 E$ O' L2 ?- v9 t1 ?- N9 v                    p->adjVex2=v;/ O0 O- |9 G/ z3 m) S7 k
                    p = NextArc(u,p);) i+ x' x. i. E- F
                }" g9 z0 g& t5 s! z, G2 f
            }
    4 _3 Z% j* k3 {/ G    }
    ' f% ~3 d; N) @8 z$ @}
    ! C5 [+ Q' D0 p7 Z; ~- y9 P/ B///深度优先遍历7 U6 }& t4 U% v' t$ O0 {+ j! N2 C7 p
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    + p- {" P& ^0 a  [; y% o4 Q& l{5 f. d9 t/ |+ v) t
        tag[v]=1;
    1 E0 }- L+ c2 i" ]0 C3 r; |8 B    cout<<setw(3)<<vexTable[v].data;
    & f! c& w. C4 R# x' o; r6 A    MultiAdjListNetworkArc<WeightType> *p;+ g! ?$ `9 [) S' g' g& ]
        p=vexTable[v].firstarc;
    1 X3 I8 u" m) z$ j/ ~    while(p)2 e; L( ^- A  J( T$ }6 i& T
        {) ]0 c2 q# h( v$ X8 V9 X, J
            if(tag[p->adjVex1]==0)
    . s# c: K6 I% y$ ^3 [" c( k            DFS1(p->adjVex1);* A3 `; {! M  `; S
            else if(tag[p->adjVex2]==0)1 g3 J" H! U/ `9 M& ~
                DFS1(p->adjVex2);
    $ T& ?4 T1 E8 L' E- p% X        p=NextArc(v,p);! K9 u5 q) z2 ]1 ]2 ~9 `8 G
        }- l8 n" r. W: i7 u* w+ V& L2 H  @
    }% a% j4 I( r; h' i
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    # p" I1 n3 g3 ?" g: R5 v# B{
    0 J8 K2 W! _+ e    for(int i=0; i<vexNum; i++)
    % {  o2 ?. J: K4 u! r; G* N        tag=0;
    * u3 w6 s' H* l- b: O3 F    for(int v=0; v<vexNum; v++)' J$ P% D" O' p
        {
    . ~& _, T. a9 z# C& h        if(tag[v]==0)' l' N4 _9 d4 Z  j) K0 z) p3 W9 |; s
                DFS1(v);
    # {5 s! ^7 B$ _5 C( i& j    }
    7 V8 q2 {8 U* B}
    1 @( o7 j7 M5 h  ]template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()6 l% D  u) o8 [6 J, @2 ?5 I# ~
    {
    3 J) C2 X% m* _    stack<int> s;4 ^) p% i3 O6 d9 w2 s" D" W3 V4 k
        int tmp;
    . k4 C/ w3 b& g2 U5 o! w    MultiAdjListNetworkArc<WeightType> *p,*q;0 J5 v7 d& ^5 D
        for(int i=0; i<vexNum; i++)
    2 J! ~% Z! i9 s  o' X2 M        tag=0;: ~1 [  i/ c) G4 N2 c
        for(int i=0; i<vexNum; i++)9 U* J. \3 ?1 P0 h$ ~+ g
        {
    " p* J7 @# `4 T* Y, y2 ~+ R3 P3 ?        tmp=i;7 V9 x" r* f0 r3 ^
            while(tag[tmp]==0||!s.empty())9 B' h, ~1 G% }6 R: a. l
            {; K) ^' @* b1 ?& m3 }  R  S
                p=vexTable[tmp].firstarc;
    ' d+ w/ B( h* n3 c! b) i            while(tag[tmp]==0)
    0 c' X' b2 Y( Z, d7 U            {# j5 X( v% I( F; H' d
                    s.push(tmp);
    : s, W) k* S( _. T                cout<<setw(3)<<vexTable[tmp].data;( A/ }0 f" a! q" W
                    tag[tmp]=1;
    2 c5 U: V, ]- t3 X1 w6 }, Z                p=vexTable[tmp].firstarc;
    7 B; o5 }; R/ U' y# M; j8 |/ f8 u                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for! w  k, N$ K0 P
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    , r" R4 C# s4 s3 V$ @                //cout<<" 1st     tmp="<<tmp<<endl;$ E! [* b4 v' [' B5 a
                }
    # L4 O- A1 ]! r+ s  [3 W1 H) G            if(!s.empty())& Z- p0 `" z3 L( Y/ S
                {
      H) K+ J1 v( \7 U                tmp=s.top();
    0 O2 W+ ]  ]4 e' D                s.pop();
    5 B+ n: a5 R0 R  {2 e+ u1 V7 k                q=vexTable[tmp].firstarc;: L# b) [! _+ ^! ?4 i: z5 f$ {
                    int t=tmp;! G7 r: S, s* g& X
                    while(q&&tag[tmp]!=0)
    : y1 w; X$ V& w$ N1 |( P6 K6 }4 B                {2 Y1 d2 x7 ?9 y3 w3 D7 @3 M; s
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    $ v; b. M0 m9 k. [                    //cout<<" 2nd     tmp="<<tmp<<endl;
    % Z, W! |  o0 G9 R9 r: k                    q=NextArc(t,q);2 y4 {; ?1 \# P. V
                    }
    8 H" j4 `) J1 j" @/ F                if(tag[tmp]==0)
    . N4 h9 G* {, S0 N. ]3 ^0 S/ x3 Z                    s.push(t);
    : k0 |" Y8 v5 ?# e( z' K# Y+ d+ c                ///1、对应上面连通分支只有1个点的情况  K2 n# a- ^6 ]- t3 n/ R. @
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈+ T* j) J3 H/ {+ X
                    ///tmp要么等于找到的第一个未访问节点,
    ! T4 l  ?8 ]: ?* t                ///要么等于与t相连最后一个点(已被访问过)9 @. X7 s' j9 i+ M  L$ W+ Q0 h
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    3 g6 J% P8 D$ E: X9 Z            }( r0 ?$ S" x/ X! L8 G3 s
            }
    ' l. s* u- D/ M7 E    }
    0 V% Q7 E  O& O/ ~! @}
    , }2 |. X; N3 R8 J, [0 ?1 O$ l//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1+ D/ n' l6 X' L3 ]3 P1 a
    template<class ElemType, class WeightType> int3 m0 z  V) D2 K; _- O  b0 c, z
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    ) r5 g2 V/ Y+ q" q' I3 c{& p. t3 G5 f2 q( e, Y
        if(head==pre)7 X4 L1 F/ I* B
            return -1;
    ) k5 Y" h8 \" _8 }3 t# u. L8 w! Q. [* u& Y/ I9 W+ U
        MultiAdjListNetworkArc<WeightType> *p;
    2 f7 A# }" {. _, r1 C( q6 E$ h    p=vexTable[head].firstarc;
    * ?; x% W$ {, S8 _  u7 W6 [* g: k    if(pre==-1&&p!=NULL), f* O; ]7 P2 U
            return p->adjVex1==head?p->adjVex2:p->adjVex1;- L3 K( H6 h* |8 O  ]
        //pre!=-1&&p!=NULL. [$ m7 ~* ]4 b6 r
        while(p!=NULL)  `' G: r  W% y! Q+ D- B
        {
    & H( ^9 y2 [) B1 P: `8 y9 `        if(p->adjVex1==head && p->adjVex2!=pre). N+ T. H5 o; i  P2 z
                p=p->nextarc1;, `  \0 k$ `: K+ O% m
            else if(p->adjVex2==head && p->adjVex1!=pre)  k" i  @# U/ `) p, o
                p=p->nextarc2;
    - n# Y' ?5 Z% ^9 A$ |6 U+ Y& ?        else if(p->adjVex1==head && p->adjVex2==pre)
    ( u: v. Y2 h* R" k6 I0 @  `6 D) j        {
    ( D3 R4 d5 ^. a8 D  _            p=p->nextarc1;
    # h8 R1 r+ K8 Q6 R' @/ U            break;4 h1 Z' S1 y' ~2 @
            }
    / {# b: s# _; V* n        else if(p->adjVex2==head && p->adjVex1==pre)
    7 P, q4 V1 ?1 L+ ~" f+ n        {
    1 j) D& H; V# y) H            p=p->nextarc2;
      p% }8 D0 k) W1 G3 Z            break;
    / d: ^6 w, ?+ J0 ?        }4 \) T/ T! g# @! h( o
        }
    9 I+ R' K4 D/ W& g& H1 p. G5 e3 n    if(p!=NULL)
    : Y/ \' S$ x( ^  @    {
    2 p% r7 D) p& N1 V$ b        return p->adjVex1==head?p->adjVex2:p->adjVex1;3 S5 B: I( J% X  b9 n* C# |3 x
        }
    0 w3 U9 `* e9 n    else
    " k  J5 C" l  f        return -1;3 U5 T5 v6 f, {0 D$ N. ~
    }
    ! b& ?8 y4 {' q* _0 d) r, C* E+ P) q' N7 ?  y
    ' p1 O7 u! @3 \) M: ?: ^
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    4 j% r: d! o0 D) R# `  Y{7 `& b; f# T2 }5 `8 f3 Z( j" Y7 k" p
        stack<int> s;
    1 V& S" g$ {; G! Q0 T    int p,cur,pre;
    , W5 z/ b8 p9 [& c    //MultiAdjListNetworkArc<WeightType> *p,*q;
      s4 j* G' y- |  A) M* a$ {    for(int i=0; i<vexNum; i++) tag=0;//初始化
    2 S7 `' Z8 C: Z
    0 ^, l$ O9 H9 w" M    for(int i=0; i<vexNum; i++)2 g( o% A# l7 r' v+ R
        {3 X% `. m5 }. y# Z8 d9 \2 k
            cur=i;pre=-1;
    5 b9 k4 s3 [  M* E6 q4 z2 o) s        while(tag[cur]==0||!s.empty())
    * l. K( }* p* x* `6 J& b# V- \        {% d6 `& ^5 a7 A; H% ]
                while(tag[cur]==0)
    3 b8 t3 o4 L; P8 U. W! c. W6 r            {
    3 C. k3 O! B% m                cout<<vexTable[cur].data<<"  ";
    ! n# b2 ?5 N, w; m. Z0 G* C                s.push(cur);) b% E& Y# W; x6 C) p
                    tag[cur]=1;
    1 z( {4 q9 H# _: k               //初次访问,标记入栈8 ^/ z4 m0 F1 i! ~) g* o
    1 ^% n/ n* I& C" p
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点
    * b, Y1 V: z1 Q3 Y               if(p==-1)0 B$ e  l) o( \9 A
                   {5 {8 p9 }+ l- @+ M& g3 j
                       pre=cur;s.pop();
    9 J  Z9 _: Y: d0 t7 P                   break;
      `7 w; ^& Z& F8 V3 ]' x               }
    6 B* S: j. \" P               else# `/ {' n4 [7 w+ b
                   {0 \- u- x: \2 X0 Y: v
                       pre=cur;
    ( u+ I1 z* a9 m  l$ j                   cur=p;
    $ I+ R) i% O9 U               }
    % w3 t( r7 s# \5 p8 I) E" n2 N8 h3 t6 c
                }+ J; F& E* R/ e4 z
                while(!s.empty())
    ) }4 g( M6 z& e1 G  c            {
    . A# s& i* ^3 M                cur=s.top();* G8 ]7 f8 ?  r# b1 @/ @  Q. `1 ?
                    p=GetAdjVex(cur,pre);! b% c" D* P6 u1 O/ g
                    if(tag[p]==0), w4 b; U5 K+ {3 n# p
                    {
    4 W* i: b) R, Q0 S2 F+ ~                    pre=cur;# }; m. _9 z% P6 l1 Y
                        cur=p;
    ! U* I: f: O$ p/ C5 B( D                    break;$ b9 v; ~0 [8 g3 t% C
                    }7 D; Z3 J+ b; r8 _4 J: D
                    else/ @# G" T) s; }+ j2 Q" r3 g( g. f
                    {# v2 S$ I- `/ ]$ L5 u* w
                        pre=s.top();
    : d- y0 [% K7 u. p* y                    s.pop();: _0 }- a" t% x
                    }1 e8 e. y: S3 ?7 E

    & U) \$ C4 t! ~% i. Q. \            }+ W* a& ~3 z7 _; J3 D" x' U

    4 j" O& E& ]- S8 C" U        }
    $ S: K; J+ e; S5 C% d  ~6 a    }
    " \; w0 z/ }6 u, I/ j}) P! y1 P0 {) Q0 I0 O8 L9 X
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()4 L; R- V0 L7 m4 u7 @7 M: c" X
    {
    ! Q9 b; H* W8 q( Z/ p7 z, y* T    for(int i=0; i<vexNum; i++)" O# j5 m6 z/ Z
            tag=0;
    6 y& H: ^% g3 V    queue<int> q;
    ; ?$ H3 y, ]+ K. j# V    int tmp,t;) D$ @# S, H9 C# H
        MultiAdjListNetworkArc<WeightType> *p;
    # A1 j3 j8 v* V    for(int i=0; i<vexNum; i++)/ ]8 l" o2 I8 L  d9 X3 d  ?
        {
    ! e9 f1 r" t# |" x  d2 S/ I        if(tag==0)
    $ D2 P1 G) A8 q6 ~  h4 P        {
    2 m( I  D& N* s3 m& q  a% k) K            tag=1;
    ! q4 ~$ f4 S8 p7 Q            q.push(i);
    8 Q( \  [2 s: q. g0 @5 N2 Z  {3 `            cout<<setw(3)<<vexTable.data;
    3 j3 r* m3 i/ J$ ~. X        }/ ?4 W  q" E4 D8 D
            while(!q.empty())
    0 D4 Y# I6 a/ j8 B# A        {
    6 H* b5 |7 R7 _# ?& K9 W            tmp=q.front();2 E$ m- a4 W, W  ]4 u, X0 ?9 m  |
                q.pop();
    : I/ M1 n: X4 R1 U7 B            p=vexTable[tmp].firstarc;
    6 Y! f9 d) U5 E7 h9 o9 ]            while(p!=NULL)
    : M7 a1 |7 G5 i# N            {  I$ I% _( _5 P4 w+ ^( j2 K, q
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);8 n" G0 H& [# t1 L% d  A# s
                    if(tag[t]==0)% v3 P8 F/ y7 Y
                    {
    + ^  Z  t; ~3 X# y' e7 _                    cout<<setw(3)<<vexTable[t].data;0 L+ e5 `  k  d' h) E
                        tag[t]=1;
    + {; s% Q) i3 D* U' q$ S3 U                    q.push(t);# W% x$ B5 B# V! }
                    }/ G0 U( Q/ W  M
                    p=NextArc(tmp,p);' G# _  z3 d- B8 B! z; \5 n0 L; _. C
                }: v6 x7 e4 L5 }! V6 m. ^$ D
            }
    4 f: B0 \8 r; k6 ]    }2 S5 W7 a0 k; r. k4 [$ }
    }
    6 D; l7 Y5 [# s/ Ntemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()7 T% v9 \5 J, N% T
    {
    " [- \1 [7 t0 Z4 k    MultiAdjListNetworkArc<WeightType> *p;
    # Y# o0 Z+ z! G2 T, b; ]4 u3 M) U    cout << "无向图有" << vexNum << "个点,分别为:";! E* y; K, d8 |9 {! w
        for (int i = 0; i < vexNum; i++)9 W! d% c/ z4 T2 s
            cout << vexTable.data << " ";
    7 t, [! ~6 l4 o    cout << endl;
    7 x$ V9 x- A2 h+ }2 g    cout << "无向图有" << arcNum << "条边"<<endl;( p  M; P/ z+ C4 B  s  Q' r
        for (int i = 0; i < vexNum; i++)
    & g" N1 u, u; r/ D/ `7 \" c2 n/ n8 Y$ Q    {' z; C' O- Q4 {7 Y9 b1 _
            cout<<"和" << vexTable.data << "有关的边:";8 P% O4 U6 c. T3 F, r8 F; K/ p& s2 e
            p = vexTable.firstarc;
    ( e5 F- `6 d8 H2 f% P3 t5 {1 a        while (p != NULL)
    # b$ V2 a: ]. F        {( W& O+ T1 q1 V1 O$ {
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";9 G! u" I. j  b8 g6 T( C1 M
                p=NextArc(i,p);$ Z) b& j2 {2 ~, t
            }1 [* r0 H* g/ P* K6 n
            cout << endl;- o& I! Y4 }. j3 l2 f2 L/ V7 d. o
        }
    , O6 s& t/ t3 f5 }}9 B4 i& L. P- ~* N. N; w$ ~+ Q
    " p3 l7 T( ~9 m% B$ P. K3 D
    ; E% v& g4 n/ S. G+ p
    邻接多重表与邻接表的对比
    ( }$ d/ X" A$ g; d) `
    ; t% p% p2 q) E) |6 C) }% V邻接表链接9 n, Q& s# I4 m5 L
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。3 e. H* L4 e# o
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。" A: J8 `: F6 h1 Q0 v" E- K$ A3 i
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。; B* U4 T2 G" f) `& N' c
    ————————————————5 G$ g9 }7 F8 T
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    % w- W7 X. w) ~# ?原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    & o. |! \! S/ a0 B& j2 W7 w+ Y7 N

    4 L2 }8 _8 i5 U+ f$ d8 c2 Z1 \7 W2 ^
      p4 p1 E1 k0 t1 ]- a2 a
    ————————————————: H5 N- p: V+ ]$ R
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。. l8 i! R8 S1 @4 W) g8 U/ U+ e
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    * \1 e9 z, M3 h$ g$ @- K" U$ q" X
    , P: J6 f/ s. ~7 @/ m$ x  w3 k' ?+ c2 V( U* U1 Y  C7 i
    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-8 00:22 , Processed in 0.514104 second(s), 53 queries .

    回顶部