QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1529|回复: 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
    4 l2 s7 d: [* S9 I$ ?& x
    图的存储结构——邻接多重表(多重邻接表)的实现
      @0 P& F3 _+ p5 ^7.2 图的存储结构
    % E  G6 Q! `- W( v" u; w3 p$ `4 V# ]) w
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist9 v2 H$ x1 \/ f* y# _/ E
    邻接多重表的类定义. I6 E+ _* z9 }
    邻接多重表的顶点结点类模板3 K, m9 b3 V: f
    邻接多重表的边结点类模板8 s' p! x' m( {# V% f# _8 ?& ^
    邻接多重表的类模板3 D- w$ z' D" z* Q3 v1 ?7 u# G
    邻接多重表与邻接表的对比
    - b2 z6 @7 n- Q! d, Q7 ?7 ~8 h7.2.3 邻接多重表(多重邻接表)Adjacency Multilist! i0 g4 G& ^$ ?, r

    2 H3 d( k3 I6 \  v5 {2 ]在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。7 E  O7 N& e1 z% M, z* A/ C
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    2 U' _2 w7 G& J; ]& q
    : y% P7 H2 p* }/ {: n邻接多重表的类定义
    / O7 x, g' \$ S2 H 1.png / i* w/ o: _3 Z3 k$ c  u% ^
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    5 p9 ?4 X: Z4 U" wdata域存储有关顶点的信息;( s, k1 }, q/ a# p$ r
    firstarc域是链接指针,指向第一条依附于该顶点的边。# G8 f& i% y- J/ e
    所有的顶点结点组成一个顺序表。

    ' S6 ^+ P" ]. J% x2 ^+ F8 x
    4 N+ U4 ]' N- p* R$ I5 s- w
    template <class ElemType ,class WeightType>
    * u  N2 y; M5 ?- l) q) Aclass MultiAdjListNetworkVex( @0 V9 {5 |& T
    {' \" g7 Z$ H' v1 t- @- W
    public:; [# a3 H* h: P, C
            ElemType data;
    ! ^8 b3 v: d2 r  e  B0 j        MultiAdjListNetworkArc<WeightType> *firstarc;& K9 u4 t/ C0 N5 O9 G0 c# H1 \
    5 V# B& r+ T7 m
            MultiAdjListNetworkVex()
    4 D+ R' _0 f  k5 N$ ~        {
    ) F; Q1 a8 [/ x( x1 d% `+ s                firstarc = NULL;
    7 v/ d9 N" F7 C* P        }
      r5 M, }! Q, B1 ~8 q        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)* R' w6 t, r! V' D( _" l: \
            {: |$ e; E+ P: @+ E" L
                    data = val;
    % o( z, f) N+ B' m* \                firstarc = adj;: m9 f/ Q' |3 k/ y. P) Y/ n
            }2 {4 v6 l/ \6 P7 x
    };
    0 m& b7 T3 _" b& b8 O
    , a- |1 r7 Y, b2 y& m& q1 ~! d7 `邻接多重表的边结点类模板
    6 [- t, ^8 j! ^0 D5 t" ^( t! ]$ M1 \7 A, _/ V4 C$ E* E7 E6 i
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    ) T0 v% ~1 Z6 b3 o7 ~tag是标记域,标记该边是否被处理或被搜索过;0 f7 ]  [( [; x
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;4 d; h) H& V' P! s" E0 F
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;/ H* k1 i2 o# V# H6 h
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。! P; i8 _+ h& O- q4 n

    # B6 N  g, |" ^& @# _! d6 \ 2.png
    % c6 W- X: w* E3 Y, b0 a: O7 m( Atemplate <class WeightType>, c( n9 E, K8 r, s+ [4 A: T. A
    class MultiAdjListNetworkArc  l! w- A  r, j' b+ P
    {
    " M2 _" t: J) L) Opublic:
    & \3 I) c- H% ?% O, y" Q! @    int mark;                                       //标记该边是否被搜索或处理过. e$ B; H" p1 k& C) \/ y: _
            WeightType weight;                              //边的权重$ w* u0 ^/ m& N3 I& d# u
            int adjVex1;                                    //边的一个顶点
    * \/ i2 L; l8 a* e! W6 w        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-12 Y6 S( s! }8 d: d" D: c
            int adjVex2;  B8 h! g! [6 b
            MultiAdjListNetworkArc<WeightType>* nextarc2;
    ! z% ~+ f9 R& |4 F4 b9 u  m/ C* X8 h4 X" z  [6 O
            MultiAdjListNetworkArc()
    , Q$ U: e* n4 Z        {
    $ l% ]# w5 P/ p- l, ~: U; N                adjVex1= -1;- b6 ?7 \" s& E0 d- H8 t' N3 t+ ^; }1 B$ a
                    adjVex2= -1;
    / H0 H' k# U* J* g; M1 a        }
    4 p3 Q& P. e! g3 @. Q+ |/ A- q        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    ' r1 L. ~6 n5 Z5 l6 z6 |        {3 D; A9 y" d; ]" l
                    adjVex1 = v1;       adjVex2 = v2;
    ) @, ]' _: ?! N: O6 {                weight = w;" A6 K) w) @! F+ j$ F# G
                    nextarc1 = next1;   nextarc2=next2;$ X$ d# q1 Z0 Y
                    mark = 0;           //0表示未被搜索,1表示被搜索过* O1 R& U# O1 U8 d0 i/ P
            }( o8 N+ n$ Q, B  }& `

    ( \7 S3 U/ ]6 e邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>$ ?) l% I  C8 q" S$ B
    class MultiAdjListNetwork
    1 F' l) O( o2 i3 {5 r' Z{
    + `+ N8 t! \# y. V$ Uprotected:
    3 `7 B$ [: q) N3 Q0 g    int vexNum, vexMaxNum, arcNum;
    / O$ Y+ o' Y3 w; c+ n+ z    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    ; `! p4 J- Y! R    int* tag;& A- m  {5 E6 h; }6 v; ]
        WeightType infinity;
    - k2 j2 ?( ]4 a0 L  g( s  y4 U( E, R2 [* L
    public:% l4 `" v# z" f, q
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);4 a# a8 m" q# j9 p9 x# [
    3 G* \$ J+ q5 g% W- n! r
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    ! F7 G9 b8 U' B
    ) g, i9 d* G. ~2 J8 J6 |    void Clear();) P' }! a% i& l. i- h1 f
        bool IsEmpty()+ k% C& b& h2 Z% y0 I
        {
    ; [+ T( D' z4 ]; f% L; F        return vexNum == 0;: r! l6 Z* I3 m' l' T4 ]( u. A
        }& ~- u9 o; ~0 X1 ^9 `  W( l0 T
        int GetArcNum()const
    6 a% n' H4 v' C7 m/ V0 ]    {
    6 j9 A9 y4 u% M, E        return arcNum;% l% q. L, b# s3 V9 z& W9 q
        }
    * |9 L$ k; u2 R% J; z+ h2 N2 B* L    int GetvexNum()const0 G* o& {) X& s0 K
        {
    9 V3 R1 Q) w: E$ ?2 I6 H3 N1 \" i        return vexNum;
    4 K" j1 E) P" c' R+ H- B7 d/ R    }
    0 d2 D- z& l  N* o0 B
    # a: e6 t+ e- \/ C4 e# Y: u4 y, s; c8 z
        int FirstAdjVex(int v)const;" y+ p2 u5 a2 u- l" I
        int NextAdjVex(int v1, int v2)const;6 r/ l- k9 m1 `
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    8 Y9 U" l1 i* U( w1 {7 i- l    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    6 u8 \  Z8 K* R: x' L* a" [9 o5 |* K
    * N0 P) _+ m. q! X7 |* E- |( g    void InsertVex(const ElemType& d);& q- S3 o7 q+ h0 p8 {$ w
        void InsertArc(int v1, int v2, WeightType w);
    9 |% r: D) f4 ]1 K2 e* X* L: R9 J; A1 Y
        void DeleteVex(const ElemType& d);) s- i) g- v8 I0 }
        void DeleteArc(int v1, int v2);
      I6 S9 |8 T) g1 p& d; r, L  O$ B$ Q6 L
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);* ~0 k: Y# ?- Z  ^: Z& p$ q) P  m/ _
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    - z& E  q* F# a+ g) C
    : {& ^7 s4 Z2 A0 @, o# d    ///深度优先遍历8 K7 _/ N7 Y, J" ?0 w: w
        void DFS1(const int v);
    ; e& W1 W+ X  B7 G/ s    void DFS1Traverse();
    0 Y9 m# H9 g7 V& m    void DFS2();
    3 m; |6 }( K2 W* N, O' j* ~) ~$ X# T# T- z1 P
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    9 D% G+ q! M" z    void DFS3();
    . {7 @' e* @! h1 O! j' s+ W
    & G5 v( G% p* C3 h    void BFS();
    # \6 i) L7 H3 q0 {" [) U    void Show();
    7 N$ o- ~0 t* N};
    ' p/ G. I- v  t$ m0 F# ^
    $ |5 h( K: w7 F! b7 g2.函数的实现. N' q' F+ ~  }$ |4 O
    研讨题,能够运行,但是代码不一定是最优的。7 h# p$ F- m0 i, ?
    ' p+ {2 O6 E: |+ |9 j" X
    #include <stack>
    + ?7 M' t4 H+ l#include <queue>6 }# [. z0 B7 w6 P3 c4 I: I, f9 b: N

    9 g# r% C; e' M2 n3 }; ^0 F. atemplate <class ElemType,class WeightType>9 ^! O9 L2 [2 l  k7 x4 c& `
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    3 _' h8 S3 e( H, f/ X{9 D. r! u% T6 {2 g3 u
        if(vertexMaxNum < 0)
    1 J0 m' w8 x8 c8 B        throw Error("允许的顶点最大数目不能为负!");1 A$ N7 E) q. V
        if (vertexMaxNum < vertexNum)
    - z8 U' v8 t. e8 M* O* B# ?" @        throw Error("顶点数目不能大于允许的顶点最大数目!");
      @1 N& L) `  s    vexNum = vertexNum;
    # `" {+ K+ D" H2 a6 D. A    vexMaxNum = vertexMaxNum;
    & ~9 p7 S1 _/ c5 a1 A$ ?1 H    arcNum = 0;
    1 l# i* g* M# |/ A    infinity = infinit;
    $ c. q" ~0 [3 G; b' R6 |4 K+ z    tag = new int[vexMaxNum];
    ) u; U+ ]! L$ ^* d. a- s    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];/ t: Q" F) H- C0 ?3 w
        for (int v = 0; v < vexNum; v++)
    ; X$ L4 o9 F' r9 a$ u. G9 E    {
    7 C5 l0 b; v4 \2 M$ i. h- L        tag[v] = 0;
    5 w" M: F& R( b' i  S        vexTable[v].data = es[v];
    ( A6 L7 G5 I4 m  @( S        vexTable[v].firstarc = NULL;
    1 u7 X8 V4 j- x# ~: S; u    }2 S# n, o4 Z# Q8 B. T  a+ X, d
    }9 a8 Q6 R' U  @' G4 U, }$ B  V) T6 a
    template <class ElemType,class WeightType>+ m/ a1 d6 s7 d" C2 [
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    : t! T( @2 {3 [1 L) a8 E7 c4 ?{( A! ]' \/ {. t1 E8 b
        if (vertexMaxNum < 0)
    * z; t3 Y* ~7 B1 q8 h4 x7 r        throw Error("允许的顶点最大数目不能为负!");9 V6 h! n$ e8 ~* d! Q
        vexNum = 0;
    / T, n9 {) c. d, Z% e/ p% v; X    vexMaxNum = vertexMaxNum;' O: R* b5 E3 f  R7 N
        arcNum = 0;1 b2 x  g2 ^  z; D" V+ b3 C- z
        infinity = infinit;
    + i" P7 d: B% x% I# \. Y" K% i    tag = new int[vexMaxNum];
    ) U+ C1 p+ l. @+ j% g    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];" F, \4 @6 b. [- B: A
    }! l, r( B% a) }2 Q$ {" i
    template<class ElemType, class WeightType>
    * h6 G1 H- @  g: k2 X7 lint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const. t( \1 J* K- I- Z# R- F
    {
    ) h) |" t6 t$ j! Z7 D, h$ g' F    if (v < 0 || v >= vexNum)  B, @, Y; ?; A8 k/ {7 H" s
            throw Error("v不合法!");
    3 R$ R6 p* L, ~  w    if (vexTable[v].firstarc == NULL)
    5 N' f. n% U. K- g        return -1;) F. g  j' P9 t& B/ Z
        else) R, t7 P  d$ O: ?; ]
            return vexTable[v].firstarc->adjVex1;
    6 b2 X& b# k* w1 k5 N, F$ M$ s}
      W; Z6 o5 ^# q8 F% I# Z/ l
    7 ~9 n- P0 }. d# z8 Z* h. [' @' wtemplate<class ElemType, class WeightType>
    & n3 [3 g# b9 t. j9 Bint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const* x( \; W% q% A/ l5 s9 C
    {% q$ D' S" {0 V/ o7 W
        MultiAdjListNetworkArc<WeightType>* p;
    4 Q  y& a2 P% |$ l    if (v1 < 0 || v1 >= vexNum)
    7 L2 I& E- G6 S2 T+ {        throw Error("v1不合法!");9 }" w9 P, J& X! X+ C
        if (v2 < 0 || v2 >= vexNum)
    ) [0 y+ h% r% \9 `+ E2 m        throw Error("v2不合法!");
      s- ^) K* a% r2 W- p    if (v1 == v2)9 a8 X- o4 h$ v" V+ n
            throw Error("v1不能等于v2!");
    6 F1 k5 `; d5 ^0 m/ |( r9 a) E' w    p = vexTable[v1].firstarc;0 T5 O. l- ^( X8 d8 E
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)) O- }8 o0 [- y$ G3 G. J
            p = p->nextarc;
    ' A+ [( @' S# V/ m' c5 N4 M; \    if (p == NULL || p->nextarc == NULL)
    , |& |3 ~: P- I9 ~2 b! l; n0 c5 f        return -1;  //不存在下一个邻接点
    ! w0 X5 H* H, a/ u& O& R9 N0 }    else if(p->adjVex1==v2)) ]- U: K# ^; l& z: r
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);7 O+ K7 L: X) V% a0 M+ Y' m$ @
        else
    : ^0 m- B$ h% ~        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    ' J/ ^+ @  h+ F9 j}1 m; B' B( _1 X# [" L
    template<class ElemType, class WeightType>
    + k6 a+ x( x$ w$ t  B  Gvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()
    8 U/ N8 v3 [: H7 B# _; ^{
    0 R$ t# K  j2 z; S; x- j5 K5 ]    if (IsEmpty()) return;
    ; C0 Z0 G6 h6 o; H6 O! S    int n = vexNum;4 n5 i( o+ C% N( p
        for (int u = 0; u < n ; u++)$ e8 ^3 n# Y- O% P
            DeleteVex(vexTable[0].data);2 {6 ^' Y" U7 T: g) Q5 \
        return;# i6 a# U% _1 z1 `& O# ]
    }: ?4 ~/ w" ^. d0 B4 H
    template<class ElemType, class WeightType>4 A  ~" J# x$ ]' U
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork(). d8 j5 ^/ j2 U2 ~6 l" g# E$ V1 J8 X- P* O
    {' z( o( a3 `7 H, f  P
        Clear();7 u: R, D: Z; W
    }9 U" s" T5 \6 Q
    template<class ElemType, class WeightType>* S5 H0 d9 u+ Q2 U- \( T0 i0 s
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    8 j) u+ }! d( F: T/ N9 s: o9 E{$ P2 Z( i* l' M2 k! x$ x0 p
        vexMaxNum = copy.vexMaxNum;
    5 j/ ?* S! m7 x1 {7 c    vexNum = copy.vexNum;; L, n9 \. Q7 W  D2 _9 x
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    & l0 j. R  i% I1 ^, V4 Q* L* D9 E    arcNum = 0;
    , G' C0 E/ h& M1 j6 y    infinity = copy.infinity;) y! u& o& M1 q1 O4 x8 ]
        tag = new int[vexMaxNum];) e9 M- Z. X8 u/ Z: P+ ?) J
    ( T* J, A, O& w* ~/ M
        for (int v = 0; v < vexNum; v++)
    5 j% R* t4 U  r+ \4 D7 }! R( S    {
    4 g$ ^; l5 R) p        tag[v] = 0;+ l: L3 K7 m4 l% m" ~
            vexTable[v].data = copy.vexTable[v].data;* A0 l4 q9 E$ s: U0 z: O! t( T, ^
            vexTable[v].firstarc = NULL;
    4 a6 b1 j. {4 U8 k, p    }0 V6 E5 p/ z, I( G7 P, f
        MultiAdjListNetworkArc<WeightType>* p;& h: s' _0 g9 T9 k0 P8 i
    ! @( ?: R$ x% |( E, v2 L( ?
        for (int u = 0; u < vexNum; u++)
    " a4 ?3 y- Z; \  _    {
    ( R8 p; s+ d! y, K6 S% B$ r        p = copy.vexTable.firstarc;
    " t4 |- h4 }! E5 U  N        while (p != NULL)
    ; v" Q) j2 T4 ?% z+ j( F        {0 u: u9 n! s7 i( A/ L$ N
                InsertArc(p->adjVex1, p->adjVex2, p->weight);5 t) m  e: _' M( R: o* Z/ U
                p=NextArc(u,p);* `4 V8 v7 X5 A
            }
    ' V: g. y/ G4 K    }+ s! ?- l- s4 @; [; T9 H
    }
    3 |! r+ Y. M7 Y6 w* P  c: z1 ktemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&8 S+ a* j! D0 E+ e! B. O% W) q
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)% ]& |& R6 U2 x% n% o5 s
    {# A4 ~* u/ }# x) B" @
        if (this == &copy) return *this;
    & E2 l( I2 A. ]0 Y1 G    Clear();
    1 N8 Y) D, X9 s+ L    vexMaxNum = copy.vexMaxNum;4 }  p3 h7 T  t( c: `
        vexNum = copy.vexNum;- R8 o) w* P1 f
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];4 T& X( ~3 q) ]$ _. G2 J
        arcNum = 0;5 O5 F/ Q' C) v" M
        infinity = copy.infinity;4 v( u3 M6 l5 t2 U: q
        tag = new int[vexMaxNum];
    , B7 U% p" i. f- }1 [' c0 X, F! b9 B: _/ o4 o
        for (int v = 0; v < vexNum; v++)
    : V0 K/ H& e' {  D  L    {
    1 w. i' z5 a7 |+ L        tag[v] = 0;
    : V% U0 _' U: O        vexTable[v].data = copy.vexTable[v].data;( Q7 y0 |. A: P. G; s8 S
            vexTable[v].firstarc = NULL;
    # e1 l4 m9 k0 {% p    }  L: g, b/ e1 x0 ^) F
        MultiAdjListNetworkArc<WeightType>* p;" r; }4 f, `  D9 N
      ~! }4 D0 d+ Z+ c
        for (int u = 0; u < vexNum; u++)7 i2 o% ]5 y9 {$ L
        {; x# q6 i  \1 c* I9 u1 \2 ~
            p = copy.vexTable.firstarc;3 P( ]) H" d7 Q& l6 L6 s7 |0 N7 T
            while (p != NULL)& a7 e" ~7 ^4 v1 I3 j  z
            {$ b6 G" m2 A3 c2 ?- E* a5 O- G: j
                InsertArc(p->adjVex1, p->adjVex2, p->weight);& v4 Y1 G$ Q! c2 J$ \5 B
                p=NextArc(u,p);
    0 x% K9 T5 e2 h5 B$ h        }
    + W+ w5 @, d3 Q0 k0 f9 b    }0 k3 |0 ]* y6 i( @4 e. n4 B, T' G$ `
        return *this;8 h' o% A% }3 v. b% F
    }; E  |+ i5 z2 _( E5 [0 G
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    ; X) U% Q* n6 g3 G% uMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const0 W. i6 x4 m* O: m1 V* }
    {
    / h; f! _( ?; I! R4 ?7 F, \    if(p==NULL) return NULL;
    : v; m+ |0 L& E; N: C! |    if(p->adjVex1==v1)% ~2 z: Z. E  T/ n
            return p->nextarc1;. Q% \7 s8 @/ `. C- L
        else& d7 V1 Y: O. l8 V& ~9 {
            return p->nextarc2;
    . k  E3 I: c3 W3 `}
    " w- K3 G7 d/ J+ y+ Ttemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
      ^5 `; ]2 N" a2 l1 mMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    ; s! E# i  ]( J# v0 E/ m{7 h% v9 P6 x- i. q
        if(p==NULL)return NULL;
    0 m8 f( P% L, R6 J" k& T# \. v0 W6 Z. ]    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    7 M. n: I& a+ x8 A. T    if(q==p)
    1 ]3 ?' O- j$ D        return NULL;
    ; j; D& K% P. ?    while(q)( S# W0 p' D+ a7 @9 a6 `
        {
    : U6 G  w/ v7 m  h! `        if(q->nextarc1==p ||q->nextarc2==p)
    . X2 n  l0 Q8 C2 D0 f+ B. c$ Q            break;
    7 w2 }; j- g) N3 n& S        q=NextArc(v1,q);
    * P9 v8 B. E6 {: E$ i  `9 s    }0 D0 N: L" h* B1 t5 \9 \7 o
        return q;
    $ \* O$ P! Q$ X& @}
      V5 r: l; z' [9 q) d* g* u( Btemplate<class ElemType, class WeightType>  b5 u1 R# E& C2 l
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    / |) ]4 O9 [% S- O# w: x{2 H) d$ c- K  o, e
        if (vexNum == vexMaxNum)
    6 i6 ^$ R! v  a& K' I0 }3 |        throw Error("图的顶点数不能超过允许的最大数!");
    ) A$ L5 J( B& h    vexTable[vexNum].data = d;
    3 P& ?/ f0 s" m' \- t$ y: q    vexTable[vexNum].firstarc = NULL;. @& P2 l$ |  V. K9 Q6 R9 [1 ^2 d
        tag[vexNum] = 0;
    9 I+ ]& ^2 M( f; N7 u    vexNum++;8 w" J& W4 [5 S3 r' A
    }  k# S4 k% {  ^/ j3 N
    template<class ElemType, class WeightType>
    * |8 J2 M& M3 Z1 P9 j& Yvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)5 z9 z  k$ s; O. N6 y
    {
    # U- ]- @3 \% K% g$ `1 e    MultiAdjListNetworkArc<WeightType>* p,*q;+ ^% ^3 N, a8 Y2 I/ R
        if (v1 < 0 || v1 >= vexNum)5 \& X+ J8 V9 r# a( {
            throw Error("v1不合法!");
    ! G" u: K$ m& n, [    if (v2 < 0 || v2 >= vexNum)
    ; f" [7 b  C( L, Q' r, W5 Z6 X% u8 L        throw Error("v2不合法!");
    % g4 F5 Z7 |+ B* i6 [    if (v1 == v2)
    ; i7 E5 P5 ^- F        throw Error("v1不能等于v2!");
    7 A9 h5 i/ J% b, Q& Y5 s    if (w == infinity)* n: Q. A3 D* D# C7 e! @; N
            throw Error("w不能为无穷大!");
    " X; @6 R. m% C% E8 F/ Y$ D* u5 H9 ?+ z: v6 U
    " X: W* e: b: O+ w; u/ \' ]6 a" [0 c
        p = vexTable[v1].firstarc;" ?; `' f: B. d" t) M1 p
        while(p)
    " J; H" M1 l( U7 M( Q2 }    {' }3 v( P' ~9 w4 w2 p( [
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    8 G' ]6 ]' C: d, t7 X- e" s        {
    ) N2 j" a. y- q) u            if(p->weight!=w)
    $ g" n7 q& ?# D9 l" Y, I                p->weight=w;, @4 b1 Z6 ~* m# h5 R
                return;
      ?; w& D/ l+ N( s        }
    ' F: a2 [  a0 {9 P) n
    ! P8 @+ {7 ~( C2 b9 x        p=NextArc(v1,p);/ F: q6 M* {9 |1 E
        }$ J. X) V$ U1 j0 q/ q/ O0 ], e
        p = vexTable[v1].firstarc;) Y8 W( _- k  b  P! o6 ?5 F
        q = vexTable[v2].firstarc;
    , ^. c7 T" K; D* `& A8 R    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    5 P8 K2 m7 E* b) `3 Z7 f; }( _& u    vexTable[v2].firstarc =vexTable[v1].firstarc;5 i& o2 u; \- N) H& @3 S/ L4 }
        arcNum++;
    3 Y5 [; N: q4 A9 H}4 E* n; I" H6 V! [% y
    - b  A- ^; c0 `, d+ @
    template<class ElemType, class WeightType>
      E" F! a( Y) N, Z+ u5 Hvoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)) k, f7 I' E5 V, q
    {
    5 Z3 U- G. C" J1 u) u  k# \& H& b, S# a
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    7 N9 Y6 G2 H! W* l$ {- ]% r3 q    if (v1 < 0 || v1 >= vexNum)
    , w3 l- P/ \  P        throw Error("v1不合法!");
    6 O. l7 O6 L4 R5 G( ^0 M+ o    if (v2 < 0 || v2 >= vexNum)) t- C4 B  z! _5 _! g7 p* G8 D
            throw Error("v2不合法!");# I/ b- C/ v; P  i
        if (v1 == v2)
    " [1 |' x- q8 ^9 @        throw Error("v1不能等于v2!");8 P/ j1 d! ?! w7 u

    ) h- D, n7 ~9 i% }, q    p = vexTable[v1].firstarc;. ]" T- x7 I# W$ q% E
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    + c4 f0 B+ |3 m  D8 G- B/ l    {
    3 z$ q7 R% q. P- {7 w: E        q = p;. G6 k5 z# S+ _/ d. Q
            p = NextArc(v1,p);2 R; m* K" D& C
        }//找到要删除的边结点p及其前一结点q
    # r9 E$ h8 N4 M0 y7 A
    ( g. Q* `$ S4 w% M2 n4 N& i    if (p != NULL)//找到v1-v2的边
    3 T9 Q% y& k( X1 R7 a8 ]6 S. g+ e# k    {% X! |( P5 N- D+ r1 }
            r=LastArc(v2,p);: Q& P! _- t! |: H2 o4 \$ Z, J
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    % ^7 p% [& C% A' V- ?9 z            if(p->adjVex2==v2)
    * `, s9 y+ x3 d1 E* O2 B                vexTable[v1].firstarc = p->nextarc1;
    & [9 t: [/ Q( ~3 F$ m! p# S2 P            else vexTable[v1].firstarc=p->nextarc2;
    : V, l# S( \5 K7 }        else//不是第一条边
    1 Z" X  ]$ Y4 b# r: U* V4 |+ ]        {- ~0 K0 A( V  K; t. v
                if(q->adjVex1==v1)8 E7 q# j( K' _4 P7 e* F8 g
                    q->nextarc1 = NextArc(v1,p);9 C1 s: s2 R  v
                else
    ) U2 d: o0 s# p/ o1 v                q->nextarc2=NextArc(v1,p);
    5 N+ @( U+ T3 f6 I: K/ {. w4 m9 O; C, N- F( M3 J0 i
            }
    0 J1 X' W, N! l9 a        if(r==NULL)
    1 o1 |: Q' O+ }+ |* x            if(p->adjVex2==v2)
    4 Z3 U& c$ k0 N; `9 s                vexTable[v2].firstarc = p->nextarc2;; {4 T" z  Z; u
                else vexTable[v2].firstarc=p->nextarc1;( i; H* k' c1 ~# C
            else
    3 A! Y, U0 q& S  f* H6 u        {
    % E! K& @1 b1 ]+ |8 P            if(r->adjVex2==v2)/ ]5 K) m1 T9 B3 A% c9 P
                    r->nextarc2 = NextArc(v2,p);& f2 j9 |: v* d
                else
    ; w) W0 N5 P8 i+ [6 J                r->nextarc1=NextArc(v2,p);/ R) c1 q7 n1 i6 ~( M( j! j1 y
            }8 Y9 B6 [$ b% o& \- k7 f
            delete p;
    4 ~+ F7 r6 ]- N        arcNum--;
    4 }+ {& A8 S5 ]& @7 B% Z9 `' |: w    }
    + G, S. G0 s* a& K5 r. S! d+ y
    " U* S2 \8 \: s- Q$ w& c}
    5 F' D: y+ M; v0 r- z7 ]template<class ElemType, class WeightType> void
    6 E) z) V8 F/ ^7 ^6 d0 iMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    9 E% W6 {7 j9 Y" a) |4 j' k* E{
    7 B) W! X4 G/ b    int v;" d+ w$ Z) z  N+ @* H' V
        MultiAdjListNetworkArc<WeightType>* p;
    7 s. _2 D3 u7 A9 X- h2 T: ~    for (v = 0; v < vexNum; v++)//找到d对应顶点4 N3 J3 V, [9 Z$ T
            if (vexTable[v].data == d)
    ( H6 Z6 B; V8 p- Q* ?2 G6 ?2 r; _            break;
    9 c% c; j) i1 P( @4 F1 H    if(v==vexNum)/ \( e" i7 p3 E
            throw Error("图中不存在要删除的顶点!");
      D5 S% C& L  ]
    # i$ `+ ^! H3 L3 B5 n5 [# S    for (int u = 0; u < vexNum; u++)//删除与d相连的边
    ) g% Y" D4 C0 H6 Y- g5 A' G        if (u != v)
    - \; b" l& m4 P! `" X$ M# n1 i        {
    ; w( I/ c& A& c% F+ M            DeleteArc(u, v);
    7 U* w( L1 F' w        }6 ~8 W% X8 Q% {# \
        vexTable[v].firstarc=NULL;
    " b5 {5 v- b2 K* ?) i* r, A
    # g7 r) t7 s2 ?- q  N% F7 B    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    ! r: H, d8 i; }    vexTable[v].data = vexTable[vexNum].data;! f; s7 m7 e" J* }* u) z+ u& q  P
        vexTable[v].firstarc = vexTable[vexNum].firstarc;
    4 g( C; u% n8 F$ X4 K% A    vexTable[vexNum].firstarc = NULL;
    & d& C, O. `( @! K6 B    tag[v] = tag[vexNum];
    + e; k  ^% [! ~6 g' f/ ^) L1 n" e    //原来与最后一个顶点相连的边改为与v相连
    / N% d. m5 \- Z6 a1 d    for (int u = 0; u < vexNum; u++)
    # m& P3 a; s! F9 ~1 T3 K4 i3 H' b/ c( T" B    {4 A1 V! q" p2 Z+ |
            if (u != v)
    * W- a- {2 `2 y* ]* V! ]( C; ~" O        {8 X' s* a$ P7 O, j; i) e
                p = vexTable.firstarc;
    : K! }! [# [$ q            while (p)5 ?3 K+ ?6 }' S1 @! m' r. ~: y  K# G
                {
    7 @* a3 r( \: x6 z4 a                if (p->adjVex1==vexNum)% M7 V9 Q* ^" A6 H, D, y3 l6 _
                        p->adjVex1= v;" U! Z$ P+ g5 _. v8 h
                    else if(p->adjVex2==vexNum)3 j& G& T- v$ m3 G
                        p->adjVex2=v;
    8 Z  W' S. E" D6 h+ q                p = NextArc(u,p);
    % [, v) F6 M" m' Y  j- Y& F4 {            }
    9 X/ j* D; g& ^        }( |- T" G) h" m( m: ^
        }! Y) C: \5 l5 u. s6 z  P( @
    }
    % P+ r" z8 o5 }% s+ l: ^///深度优先遍历2 c7 @$ ?* ]+ Q9 m, _4 `
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    ; B* N; w. d1 ]! S1 E{8 V5 [6 A( a  C6 \
        tag[v]=1;/ O! M  T6 ]- X! a2 S
        cout<<setw(3)<<vexTable[v].data;+ I+ ~) q" I/ Z0 \
        MultiAdjListNetworkArc<WeightType> *p;! B2 b. g- q( ]1 W: E8 h
        p=vexTable[v].firstarc;9 ~/ n/ ^, C1 M% Z( }
        while(p)
    9 u  A% V- b% c& t6 w( Q    {( O6 N+ k3 m6 S& X- |% _9 b+ z6 S
            if(tag[p->adjVex1]==0)
    $ V6 @* X$ O; a- B* B6 u            DFS1(p->adjVex1);
    2 q% n" s% C7 ^3 y( C        else if(tag[p->adjVex2]==0)
    / ]3 {% z! Y2 Q            DFS1(p->adjVex2);
    9 z. {* c9 I3 U. w        p=NextArc(v,p);2 O% j! n' r  `9 ?3 |6 b
        }
    , r* ~9 M+ q- D) W6 J}
    3 Q/ v% n/ V" z5 A0 {  Z$ vtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    3 ^: N+ n5 v  [+ D* t" K& F0 Y{- {/ s) z6 U) j
        for(int i=0; i<vexNum; i++)
    ' m5 c0 M  Q* p0 u$ c: k        tag=0;
    ! g, f! s  ~: k' G* ^5 j: r7 a    for(int v=0; v<vexNum; v++)
    3 u; Z4 H$ l2 K; w    {
    / ]8 E  ?# E# g& `' Z3 o8 s        if(tag[v]==0)
    , f) L6 E/ b& f/ G" r! u4 D            DFS1(v);
    / Y0 I3 h" b  t4 t1 I    }: s9 w9 V3 R9 U! `) E6 f
    }% s. O* o' ]& t
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    9 x! k2 J8 x2 Q4 }+ |: e{
    " }  J5 V  s( \: n: B' V3 Z0 J    stack<int> s;) E) z* O* {* g" J% H
        int tmp;
    . m' Q0 {$ q: F5 i    MultiAdjListNetworkArc<WeightType> *p,*q;
    5 \' A# z6 A5 b3 |7 t    for(int i=0; i<vexNum; i++)
    3 ?& v* @' d0 ~" U: }( a& _4 z2 s        tag=0;7 ?9 X* Q1 {4 d7 d! d: Y2 }
        for(int i=0; i<vexNum; i++)
    7 Q5 E; V. y% {5 B    {, t0 w7 e- G  J% o: B; U( {
            tmp=i;
    . J, ^1 p# w! E0 d: k9 b        while(tag[tmp]==0||!s.empty())  g3 W! V0 K: I7 w
            {) o8 n. G3 B3 Y8 P4 `4 l5 x# r
                p=vexTable[tmp].firstarc;1 I1 y/ j9 }6 O6 s7 k# A" d: d
                while(tag[tmp]==0)! _( A: ?2 n  N4 z( |
                {- b& A  Q1 s2 i8 x0 e
                    s.push(tmp);
    ! @2 B, N5 ^2 @, l% [6 x3 }2 b                cout<<setw(3)<<vexTable[tmp].data;
      E: y" ]1 _* T4 G( z, M                tag[tmp]=1;
    ' {- o$ C3 F$ ?$ s" ?                p=vexTable[tmp].firstarc;
    6 f3 F. ]1 w6 c" v1 P2 q0 M/ }                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    5 H( {/ H. r* ]/ N! H5 l1 x3 c                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    ) Z4 B* k7 }7 j+ [                //cout<<" 1st     tmp="<<tmp<<endl;3 s# n- l$ l% E5 x; y$ `& p  t
                }
    9 ~/ H6 G% ?9 b7 Y# D8 U) j            if(!s.empty())
    7 u; g  [5 w' U7 B$ Y            {4 n& e' G6 [4 w- W' y2 o
                    tmp=s.top();: B4 t& a; Z) m% R# R0 q
                    s.pop();
    8 Y% q' d2 Q6 Y& E( Q5 o* S1 u                q=vexTable[tmp].firstarc;% p/ l# [3 O9 U6 n3 a1 i
                    int t=tmp;
    ) l% r: G) O# m. I                while(q&&tag[tmp]!=0)
    + q3 m5 O3 E8 y1 U                {
    + h9 Q" `- l+ i                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);3 ?1 @, e& l) W0 X
                        //cout<<" 2nd     tmp="<<tmp<<endl;
    + t1 Y+ |  o! h) c                    q=NextArc(t,q);% n: [3 W$ s, J. H! |8 l6 l
                    }
    6 D, S6 R! f. m( l                if(tag[tmp]==0)) D$ Y2 z+ K9 ?" _6 o
                        s.push(t);
    " W7 e4 P  y8 q; `                ///1、对应上面连通分支只有1个点的情况# k6 ?5 F7 ]! f- Z: h8 s# V8 W
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    , o6 q& x" r1 D- G0 S! g                ///tmp要么等于找到的第一个未访问节点,
    8 m5 |1 H# \* {- t" X5 m                ///要么等于与t相连最后一个点(已被访问过)
    ( {5 N6 v: H0 y, K$ u) \7 \7 \                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    5 ^5 x6 [: j; u- s# b, m            }
    . _" ]( A, W1 W4 d& o        }. v* Z4 E, S$ B
        }( v0 P$ v- G% X& \' `
    }
    + Y+ Q2 ~3 t0 x//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1/ L' h5 u- l) M/ C! h! t
    template<class ElemType, class WeightType> int3 K4 @6 |* k( ?$ W- W2 t
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    ) R; C: C3 Z# m$ v4 s. L{1 \- S: N6 y7 [# c# H
        if(head==pre)
    # N4 K; T  e& ?7 J: C        return -1;
    3 g9 E# K1 A9 O7 l& |# ~1 J, B0 B8 Y, M! q" j, O' V- K1 U5 F. r* Y
        MultiAdjListNetworkArc<WeightType> *p;
    6 j7 [7 ?5 ~: z/ x' i" C0 F5 c    p=vexTable[head].firstarc;
    : [6 t! K; ~1 O/ l% I    if(pre==-1&&p!=NULL)7 Z8 A" h# I/ {/ {
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
      k$ y0 c0 k2 Y& r, d6 v( v) ^    //pre!=-1&&p!=NULL% E+ K+ Y- M0 x" b
        while(p!=NULL)
    / R* h, k' o) w( C1 a" U, a+ f    {
    ; z6 L* I" Q: o" V2 h% u! o        if(p->adjVex1==head && p->adjVex2!=pre)
    . g4 Y' V; s: K4 |/ w, ~            p=p->nextarc1;
    5 {+ w0 K5 ~9 Y  `2 G; L7 j        else if(p->adjVex2==head && p->adjVex1!=pre)
    % C  E* T- y- m# {9 G            p=p->nextarc2;
    ; `$ ]1 s5 `- |; i3 \* C0 J8 i" s        else if(p->adjVex1==head && p->adjVex2==pre)
    . y8 u8 D+ [% e5 G, u! R7 W        {. G- w" G5 a" |
                p=p->nextarc1;
    & |8 n% i0 d! [            break;- C* w/ F. L5 ~: @: F
            }
    , Q1 T( k0 T* i; X* f  _        else if(p->adjVex2==head && p->adjVex1==pre)6 e% E/ @6 M. }& [! ~
            {
    6 K# o  K+ U5 s4 V! {" {4 o            p=p->nextarc2;
    : a) z; O" C7 m6 I* w+ G4 e+ s            break;- G3 A1 G+ ]7 a3 h6 U# s
            }
    # p0 r6 [: ?& _    }' |, ^5 H6 \2 Q4 R- {2 `# v
        if(p!=NULL)+ ?9 G4 _5 U0 B3 P- F1 X6 G
        {
    1 Y9 i2 y8 K! W$ M* o3 I        return p->adjVex1==head?p->adjVex2:p->adjVex1;4 D: C5 {* S. |, T* u' \0 O) `
        }; {+ u5 w, F) w6 j/ q+ Z3 j. G+ h8 P
        else0 o$ ~4 V  w5 G, n% g2 U. x$ S
            return -1;4 ]' u  |; ^& w5 `
    }' G9 F9 P% u+ z" U  R* C# x

    " Y% j* d# q2 a/ \
    0 w* [- d2 A9 e+ u5 xtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    2 m& V* I) M6 v6 |) F( _{
    # P: z, q7 A( Q% a    stack<int> s;
    / w$ f+ k( Z7 \4 F7 ~( |* a6 k    int p,cur,pre;
    ) l+ ^% Y2 l' ~    //MultiAdjListNetworkArc<WeightType> *p,*q;2 Q* j/ ~9 A9 y3 S; r1 @; `: U
        for(int i=0; i<vexNum; i++) tag=0;//初始化: \" [- V6 O- p- T2 s6 Q
    2 g( h0 l# I0 ]2 Y$ Z: j8 Z% x
        for(int i=0; i<vexNum; i++)
    9 {- l/ j8 k; D& s' D    {" D; w. w8 r6 g
            cur=i;pre=-1;% o. L7 S( a1 n1 `# d6 h
            while(tag[cur]==0||!s.empty())4 M) y4 p3 K1 j  w8 y8 X
            {% @0 w; y! Q. C- o  I% p7 s
                while(tag[cur]==0)% @+ k- f% i+ e7 p  ]6 f
                {6 ^9 {' n5 ]* C6 }0 B  G# |- h; h
                    cout<<vexTable[cur].data<<"  ";0 J7 X6 d5 h; z! f
                    s.push(cur);
    3 r+ {3 l% N' s( K) D# l3 o                tag[cur]=1;
      a8 y$ k* b0 O2 x. b! u               //初次访问,标记入栈" z. `8 \& v4 X& V  p( {, |
    , r: F4 j8 K/ k5 @2 y/ C
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点+ l8 l: m% r- }+ a5 D& |
                   if(p==-1). N7 G( s; D. Y
                   {
    . D; f6 m: }5 B4 v3 O" k                   pre=cur;s.pop();
    3 ?$ [( G0 }3 B                   break;+ k: M) G3 C9 A2 y" f
                   }. ]$ g  X" g3 G6 u2 @+ F1 R1 p
                   else
    - N2 V9 ~) [9 r! J. z2 Z# N4 P               {1 Y% t- N4 u5 ]9 {! W- A
                       pre=cur;
    5 }, C9 l1 W; ^: K0 X                   cur=p;+ H0 j, A) `9 Z% a, r6 _# S
                   }
    , v, p0 |' v( C" r. C# V
    " b. {' Q! `( ^5 Y            }6 g5 o; C7 I" u% d* r
                while(!s.empty())( H# m& \7 a, k. Y
                {
    ; s7 }4 S2 C& d6 Q0 ^3 _4 l                cur=s.top();3 s. @- i) c' s: T% L$ u6 w
                    p=GetAdjVex(cur,pre);% j. ]* A4 p" _, X/ s. P9 y
                    if(tag[p]==0)
    ( Z' F% M3 w  y                {/ T# {, }. ?) P3 k: J  d1 g) H
                        pre=cur;
    ; y  w1 Z$ G$ [4 `, R                    cur=p;# s9 w7 v% X% ]% N
                        break;+ D3 e; w& s* `% G* p  `- d+ f
                    }
    3 P7 j: x( p2 i$ W" [" E: u# M                else" n; q: A" w8 @  @# d3 {
                    {
    2 P4 ]' F4 `* S5 Y                    pre=s.top();
    " L+ D3 Z# u' e- _# j( }0 A                    s.pop();
    ( N0 t% @9 B' Q+ {1 }- @( t; Z                }7 q5 C; b* c% @: H- e

    % \# b, k" t. T: G( }( ]            }" }$ X" T5 a+ @* Y% w$ O* _! G8 s

    4 H% y! [. a) o4 i# J( b        }
    ( R: J/ @+ D7 m/ h8 e" g3 F9 z2 R8 A    }3 G3 t+ m7 C- G& g, ?4 O
    }- U0 [) V; g4 K- m2 C
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    5 P4 I! ^& E) `( v. g# u{
    7 c9 B4 H2 E+ Z1 a! }: T7 \  V    for(int i=0; i<vexNum; i++)2 a. E3 O/ L3 }/ f! }
            tag=0;' [8 W9 T  L' h$ r: `0 S1 w+ \! R
        queue<int> q;
    . G# j/ K0 M. V6 U* v    int tmp,t;
    , b+ }1 U* M3 i. ?5 k3 U: u    MultiAdjListNetworkArc<WeightType> *p;8 l$ u% Z" k. B
        for(int i=0; i<vexNum; i++)& B- O& g. J+ k2 w5 u8 f' r
        {
    2 d) ?0 M8 {: \% [! [/ W+ i        if(tag==0)
    5 b% f! Y! R  J7 ?' M! G4 x        {% b$ z( T. E! i
                tag=1;
    ; `" c& }( [6 w# M1 m7 a, e: z            q.push(i);! k3 e2 r8 z7 K3 s: _
                cout<<setw(3)<<vexTable.data;; E  `( Z1 E. W/ ^! N2 I3 {# c
            }
    / j$ Z( a. n& B& t0 ?        while(!q.empty())
    6 A4 C  n8 _, {- \# M; @        {
      D0 ~3 O6 A6 r8 S9 w! z            tmp=q.front();
    . S' s2 a5 O, n) B- O1 ]$ l3 V            q.pop();7 b: h- v$ c4 S8 D2 u3 l$ S, W
                p=vexTable[tmp].firstarc;
    5 r4 @$ v, N! S$ \: Z8 x0 W; W            while(p!=NULL)- {& N% K. I6 f
                {
    " R2 h) y! @" z$ P5 m4 v: _                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);5 h& X8 u! R, {/ H9 H
                    if(tag[t]==0)  H2 B9 P4 y( I. v3 R6 i* e( c
                    {
    9 y5 r3 o7 U' n* S                    cout<<setw(3)<<vexTable[t].data;
    8 ?" e2 }, o, t" Z                    tag[t]=1;. M2 J1 o8 j* J) F# q
                        q.push(t);5 L0 B" U2 o. T" Z$ H
                    }
    * x. U' H) ]2 u                p=NextArc(tmp,p);
    7 w8 {; c2 |2 R7 b2 V+ X7 s            }. |- k- ^* d& t+ g9 U
            }5 e1 v: |; S4 t1 S  N5 Y5 x
        }
    & k/ S3 B3 N( @, F! t8 V}  N6 Y) `7 \* f+ c  x+ i
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show(): o, w8 @4 D+ E5 u% q* s
    {
    , Y, {9 [; D/ V; d9 _    MultiAdjListNetworkArc<WeightType> *p;
    6 B+ y) U; w3 d; Q+ w    cout << "无向图有" << vexNum << "个点,分别为:";
    - @; @" ?  k5 t. b% S0 Y' y    for (int i = 0; i < vexNum; i++)! V  |. x0 G. u7 Z
            cout << vexTable.data << " ";" g6 o9 J2 Y/ F' @$ [
        cout << endl;
    ; x8 H- A5 Y  V! o    cout << "无向图有" << arcNum << "条边"<<endl;7 F2 L0 K6 k" C
        for (int i = 0; i < vexNum; i++)9 ]- L2 V$ ?; i% d: E
        {
    7 \9 M4 m4 S" a        cout<<"和" << vexTable.data << "有关的边:";& U% P1 A3 b- f# Q# u' T$ f
            p = vexTable.firstarc;
    3 C: _, v! `9 X4 P$ g        while (p != NULL)1 \5 m2 ~) u3 l# ^5 T
            {$ _" {- U2 [4 ]
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    ; \+ y( q1 K$ |7 I9 z2 J2 X            p=NextArc(i,p);
    # a4 O  s- C2 i, ~9 }        }
    ! P. N/ z6 E. j  B* J: W        cout << endl;
    ! l5 I8 X% g/ W0 n1 Z    }  t! D8 ~( @# }) T* o4 L( v8 c% B+ h
    }& ^* i+ R7 J3 U( w1 `: c

    9 V, a7 B5 A+ m/ S& @3 b1 K3 @0 a! h- K( u8 N
    邻接多重表与邻接表的对比
    4 f+ T: a$ c; V% O5 ]( r7 A
    3 @+ j* e, d. ?  S% p邻接表链接
    # K1 B: E+ `) `4 C4 V5 y/ I8 U在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。! z( j' Y6 G% t- K* P+ n. o( H; |9 H
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。1 I* v7 C3 j1 v  S4 e% U' b2 J* Z
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。" l3 B4 k* H$ Y$ U
    ————————————————
    4 @: G2 b4 g# C版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。: L# Y2 u8 [8 ~9 X) ?
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    ; O, H( e& s7 r. C$ h$ Y2 ?3 p1 @# B! b/ I; i! s) c6 m3 N6 m! Y# |
    - Q5 }% b7 x5 W2 B+ ^
    ( g/ w* T4 r. g/ u& `
    + p) V0 ~# b9 g
    ————————————————
    - W) m, j* M! ?  a+ H. ^2 i版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    , w6 ~5 \" ^% x( n/ ~& R) c: Q原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669587 u) q' s$ e0 {! [# H7 O

    5 M' R+ Y/ c) R7 N6 |, W' t
    / V# ?% F* j5 I+ T2 F
    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-11 04:39 , Processed in 0.467473 second(s), 53 queries .

    回顶部