QQ登录

只需要一步,快速开始

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

    . C0 g6 {  O( O. u& l7 c0 `图的存储结构——邻接多重表(多重邻接表)的实现& [& Z/ \8 C% j7 ~
    7.2 图的存储结构
    * T' f) y5 A8 s; S2 |4 \& v% h, i! ~2 F. X7 i4 x
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    : C, z8 v: Q5 _& ^邻接多重表的类定义
    3 r; n) A) m: @7 j9 S7 m* }邻接多重表的顶点结点类模板
    9 H4 A1 X, }  S0 ~邻接多重表的边结点类模板! X6 s/ H: J* S8 t
    邻接多重表的类模板
      l4 Q; e5 l: K4 d; N$ a" J邻接多重表与邻接表的对比5 N2 `  z" U1 R% l5 D
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist; b* u: K' w* D, D2 R6 R8 z- x5 y
    ( L5 t- A. B3 N  W( m/ x' h
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    6 E0 I: U/ D. k在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。6 X, Y( ~( r+ y- @
    , [  m+ f" k0 i1 u+ \
    邻接多重表的类定义" G, _0 x5 a5 ^' R4 p4 E- u
    1.png ; }7 k4 w: R4 \: d/ A! A: z
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:1 N% x  T7 H4 L9 L( @
    data域存储有关顶点的信息;
    6 _2 y( m# o/ B% U* `) y$ ofirstarc域是链接指针,指向第一条依附于该顶点的边。
    9 n4 S5 m4 Q; z& E; {2 D* I( n. V所有的顶点结点组成一个顺序表。

    . Q: E: t8 B3 O4 y/ Y

    $ `" _# p; k0 d! G. Stemplate <class ElemType ,class WeightType>9 J) k8 B. c2 u5 l
    class MultiAdjListNetworkVex& B9 T  i: P% U; t" [; L* L
    {  x7 l- ]3 g8 I
    public:4 @; L% s/ |0 P/ e9 [
            ElemType data;* R" x, T2 t5 C' {  w, W$ e# ]
            MultiAdjListNetworkArc<WeightType> *firstarc;
    " F3 B1 G. T* ]; V, u5 ]" {$ @8 M" A( q1 M. y; m, n
            MultiAdjListNetworkVex()( i. t- i0 m+ X1 j% J1 ~$ f
            {2 }$ J' J; `+ }; D: B$ A
                    firstarc = NULL;1 ~5 G9 e  W$ w0 Z% Q  Z1 z- q
            }
    : |4 x# r$ Z! `3 [* ^        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    % s# o# @" d' w+ B0 `" C        {* K8 C0 k2 c( j6 m. v' y, e
                    data = val;
    , J. {4 ^" B7 E  t0 E( Z3 F9 o                firstarc = adj;+ u5 W9 x+ T( `4 g, ?% ?
            }- |2 M% G9 M4 N" v: l  U
    };8 K2 i" `% H) a. c* }
    ( c5 X$ z5 O5 i( Y* t+ c( d0 }  j2 \% U
    邻接多重表的边结点类模板
    ! M1 R( @8 T  G. }1 P3 W* Y
    ' c2 b" U5 A; {  l: _5 p8 f' B* M" l在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:3 Q( s0 N1 `% o. }# `
    tag是标记域,标记该边是否被处理或被搜索过;
    1 @) e- o3 m9 B8 sweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;2 G( ?  l5 c  |& D, U% E( B1 P& _
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    5 F$ p* }2 c# D8 q( j: W* jnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    & K( w6 U0 \$ l* |/ n8 o) m: L
    ! z+ D/ g7 y* S, O* q& n 2.png
    7 a1 Y; v3 a/ E- o9 @7 ytemplate <class WeightType>( X: y' p5 e1 o+ k* V
    class MultiAdjListNetworkArc
    ) b# B3 G/ t% l{
    1 u* X/ R, R7 U$ g1 p/ F  A1 s% npublic:* d  I& _0 m# p# |, w( d
        int mark;                                       //标记该边是否被搜索或处理过
    , Q/ @, g2 j5 O! L) E7 I) B        WeightType weight;                              //边的权重
    % V! W6 ?& r' x2 z) u& Q        int adjVex1;                                    //边的一个顶点
    , R6 ]% ~) {! ~: P        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    + z5 [* k4 x* e3 y5 p' M        int adjVex2;
    ( R" N  Q% X7 b6 z        MultiAdjListNetworkArc<WeightType>* nextarc2;
    5 \* W6 s: z& ^& J% e' D4 J( D6 H" s1 e- P' J8 x
            MultiAdjListNetworkArc()% o, L8 A" V% f$ Y. a
            {
    . m: O: L4 f  F. K+ M% ^. S# D% v                adjVex1= -1;
    4 H1 x7 D% o" I+ C1 Q. o                adjVex2= -1;, [, E1 n, R: d% p; j" D# ~9 a: `
            }3 P' \: }3 O; o+ R' r6 `& W4 }
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    + i! N6 C: q. j/ e, i        {
    ; o" g* a6 q8 r  l2 Z$ \                adjVex1 = v1;       adjVex2 = v2;) g! K4 X  T, V+ x
                    weight = w;
    4 @; {& s; \# V6 Y! i                nextarc1 = next1;   nextarc2=next2;3 K9 c" t* f3 ~' _* ~/ m1 C, b
                    mark = 0;           //0表示未被搜索,1表示被搜索过6 A- U8 b4 d7 I7 t( ?& B
            }
    ; m) T: F9 T! m1 H* {0 ?) Z* c- ~9 ]) A5 y7 e8 i2 z
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    ) i* k/ ?& J' s& k0 T5 Yclass MultiAdjListNetwork/ e. b2 n" K6 A0 H4 p
    {
    - [8 P" _0 B, a& }5 e" |* qprotected:
    6 f* j2 ^8 T0 P' x8 ~+ n+ R    int vexNum, vexMaxNum, arcNum;
    " |7 S% q4 e* M3 k, z( L    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    ' f7 T# b1 ~# W2 N; h+ K* B    int* tag;2 ]5 s9 v7 a5 Z8 ^/ t# }, h! ?0 c
        WeightType infinity;2 H) o- T" u  m) {
    1 S  `* ]7 Y* b- q+ f
    public:
    " k/ ~6 f+ a% R# |% L) Y    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    ' _! J3 M/ }0 I* g$ z9 H1 L2 c( \5 t! H9 K2 @
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);4 ^6 z: J6 L/ ]( a2 E
    # T0 X; y3 W6 y: N
        void Clear();# K( M& R3 s1 h; ^& ~2 V
        bool IsEmpty()3 ~7 d) V5 v+ m- k% c/ }
        {
    % t3 E  o# S) V# D        return vexNum == 0;* l; t' u' W' J6 w. S
        }% J, J) p3 ^5 {4 N
        int GetArcNum()const
    & X" b) B! g4 G$ Q! K8 O    {
    + ~2 f5 u7 ~; W$ Y        return arcNum;" `& V/ ~  m. x3 k- ^
        }
    " h. r& w' p$ j. e; T    int GetvexNum()const. @" D/ }7 G* U9 A+ @2 Y& h( W3 z3 J, Z
        {
    4 T5 x* L7 X/ {: N8 f' u5 D4 M        return vexNum;
    2 h5 }0 R. [. y# ^; O    }
    & j8 ^6 T/ K5 v. q5 V9 J+ k7 z( Z' Q8 ]
    1 l- c( v) N$ k
        int FirstAdjVex(int v)const;
    ( \3 [7 A0 v3 x$ |" s    int NextAdjVex(int v1, int v2)const;0 [  `2 B% v: i, d( r
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;/ _* }  V: a! D% q
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    3 k, E# H: A2 _1 a) c+ _4 V: Q. t7 ?
        void InsertVex(const ElemType& d);
    & q+ x* q0 d, J+ p! k    void InsertArc(int v1, int v2, WeightType w);* ~3 P3 p1 }) {0 `5 N3 A
    + ^5 z0 j% W; _
        void DeleteVex(const ElemType& d);; X2 u$ \6 V: ^0 t( i% |& A/ i) a
        void DeleteArc(int v1, int v2);" J, L: m' w- z- h& I' F) ^7 q" i8 C9 K2 s

    . e$ }( [/ M5 R    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    : [; r$ @$ t- M! z% l0 V+ X  l    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);; y% J" \5 \9 f- B, X' ?7 F6 X( o

    2 T; a& z( F/ a5 @! _    ///深度优先遍历3 \/ T: N- w; V' ?6 ^+ N
        void DFS1(const int v);
    ( |2 H1 Y% L/ v- e    void DFS1Traverse();! [& t7 ?3 o$ P4 w4 ]: l/ _
        void DFS2();4 G/ _$ i! V1 [8 ?* m5 w

    " S0 T0 S6 e" |: @6 B3 p; N* i* }' x    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-11 A7 f' y& t! N
        void DFS3();
    ! |9 G8 K& m& q9 O5 X' N
    1 _3 N0 f4 v0 c. c- J    void BFS();) C" |" _3 M8 L7 @& N  _9 |
        void Show();9 w7 ^1 d/ S- r
    };
    # z6 e% @8 j3 Q, k) d6 x0 W; o, _0 I5 f" R' E0 s
    2.函数的实现
    & j! O9 c% Z# Z9 R# K+ L研讨题,能够运行,但是代码不一定是最优的。
    / `' g) Z' N* R/ Y1 a% @
    & j9 j1 w) F( u1 Q4 j#include <stack>, j* Y7 l# i4 c/ P4 s# E
    #include <queue>8 A1 y9 I, l  Q$ I

    1 J, q+ r* q5 Z- ]7 F5 P: |template <class ElemType,class WeightType>6 u$ M8 _; d1 {7 M
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)) `* V! h6 K5 d( _
    {
    ( y6 t  N# G0 m2 P/ @) Y7 f    if(vertexMaxNum < 0)5 `& \; b. d3 l# Y
            throw Error("允许的顶点最大数目不能为负!");( W& G* c6 _) V
        if (vertexMaxNum < vertexNum)
    % E- e$ A, T$ _' R        throw Error("顶点数目不能大于允许的顶点最大数目!");5 a% \! ?; X$ r% R4 _( l1 z
        vexNum = vertexNum;
      i: m* a2 e% G; Z9 r  n  v- l    vexMaxNum = vertexMaxNum;
    # m8 H; g/ }4 s5 T& w8 G+ ?    arcNum = 0;" r, u  F# H; @+ t7 q
        infinity = infinit;
    ' H3 R! |  |: [! k4 h    tag = new int[vexMaxNum];
    " O. \: d+ D' Q( h    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
      U. D4 U$ O) V0 {" ]- U* I3 k    for (int v = 0; v < vexNum; v++)# Y9 z3 i$ G5 {5 n% e
        {+ g! B/ C. n* k
            tag[v] = 0;
    6 w1 T/ u7 U# x- [0 s% U" o        vexTable[v].data = es[v];
    / b" y; S2 J* v+ R4 z4 r% X        vexTable[v].firstarc = NULL;( A6 R$ b, P$ R; m
        }
    / W4 _; _( E/ G% l6 `+ x7 D}! ^, Q: y6 e  c/ N/ @) [' P# ~
    template <class ElemType,class WeightType>+ H1 i( D1 w- x* O& Y) F6 f
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)+ ~4 P# M% A: A$ h
    {
    ! @$ T4 |" l. o- k    if (vertexMaxNum < 0)  ~; V3 Z* K& q8 C
            throw Error("允许的顶点最大数目不能为负!");
    / y, c0 x2 F, E; O7 P5 y0 Q% C) G    vexNum = 0;
    & f' {' W: v4 \6 Q    vexMaxNum = vertexMaxNum;( R6 s! k" `' h# g8 W, S# z
        arcNum = 0;8 C) [$ s  n/ i- d- [3 o/ P
        infinity = infinit;. M: D+ l( r" p, y: }' @: f' E; Z
        tag = new int[vexMaxNum];9 |. P( N6 x& _
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    + ?  Z* ?. |. M9 w( J}
    ) t, F+ a7 R5 k5 O6 L: m$ g( mtemplate<class ElemType, class WeightType>
    : n( `! b- b& }- t6 eint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const1 D2 U5 B* L; u- U4 c, p: W
    {
    , t/ ]) F% n( a: q6 r# z    if (v < 0 || v >= vexNum)2 [7 @7 ?$ W- w- Q! e& u" \
            throw Error("v不合法!");
    % d9 N% B) e+ j. n    if (vexTable[v].firstarc == NULL). ^2 h: C( r+ z
            return -1;
    , o4 g  p! p% @    else. q# @$ I6 g" S0 t" K" R' ^! s- ~4 i; d
            return vexTable[v].firstarc->adjVex1;' h  ?; r; j) q3 h7 c
    }
    & S& A+ _$ ]. k+ d% F" w: d; i/ D) ?
    template<class ElemType, class WeightType>
    . ^7 `) D, h, y, h* zint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const. O, K. g* v) ]
    {: \8 |7 N) q7 h- \" J/ V
        MultiAdjListNetworkArc<WeightType>* p;
      Z1 `3 _# u5 ~) u0 w* q    if (v1 < 0 || v1 >= vexNum)8 J' v8 r. h3 j/ O. ]2 |% m
            throw Error("v1不合法!");/ \. }0 J+ K2 `( U1 t3 Q
        if (v2 < 0 || v2 >= vexNum)' d3 r# ?) J1 p, j" W& L& E* ^! f
            throw Error("v2不合法!");
    ) [. i5 R& s2 x4 n    if (v1 == v2)
    3 d5 f; D. R, {& ?' H8 ?( d- [7 J        throw Error("v1不能等于v2!");
    " t  v- Y# J( o, d  s    p = vexTable[v1].firstarc;2 N; u" ?5 P7 b5 j. q' w" i
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    % ~: j( X4 U) R        p = p->nextarc;; l) P2 L2 K; J; x
        if (p == NULL || p->nextarc == NULL)4 {2 F9 V3 \% c2 b! v. g5 P
            return -1;  //不存在下一个邻接点
    , R6 V$ u, z* z9 I8 g! b+ j9 L    else if(p->adjVex1==v2)
    ( v; @/ n6 w- ~& D9 T+ o        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);+ d8 G; S8 T4 o1 \, H$ v9 J; ^6 ]8 W6 [
        else
    6 j5 V7 d7 g5 @8 m        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);3 @) g% Q% q6 O
    }
    9 w$ D, Q" w/ O0 h6 c" Y$ J; `* Stemplate<class ElemType, class WeightType>
    , a% h" G) m1 j0 J" s- C/ Mvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()& x" I1 r" C4 w6 b! C
    {# N( x9 ~0 E# M1 a
        if (IsEmpty()) return;
    9 Z- Z% b; b/ Z0 C" l( c# ^+ z, Z, q7 @    int n = vexNum;
    0 B6 A3 N0 k* B/ x% {7 w    for (int u = 0; u < n ; u++)
    - U5 M* H: H. ^5 |. H; B        DeleteVex(vexTable[0].data);  m8 q, M8 Z. ?! q" j8 I0 U& h
        return;% ?- t2 _* C$ L2 y. ^* t
    }0 m* d* @9 Y8 o4 L: J3 ^" A
    template<class ElemType, class WeightType>' O+ C. s  o) F) c9 G
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    3 A2 m1 O( V& X) S7 b* J# v+ z{
    1 ~0 O. r4 M+ ~7 ]5 Y( r    Clear();
    * `# ]7 T" ?  s: ?. h8 |}
    # _/ Q3 O* C' {0 }: B6 \template<class ElemType, class WeightType>$ J" z; {1 q, ^: U9 C8 b
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)" N$ }+ B& p" S( n1 A3 j/ W
    {7 G/ A8 }* H- c" o, b$ _# w. N
        vexMaxNum = copy.vexMaxNum;! B+ ^3 N+ h7 ?+ Q
        vexNum = copy.vexNum;) x: ?6 N" l# \4 k: e/ h
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    0 v1 u" S  F: H+ D    arcNum = 0;
    0 X& `, Q' K. ^    infinity = copy.infinity;
    # U3 L  q5 f! j    tag = new int[vexMaxNum];& N5 q) l0 ?1 Q+ h

    ! O- N# `' ~& t: T, {4 o    for (int v = 0; v < vexNum; v++)( W7 ^7 B4 ]4 D. z* ^1 {
        {& X  G' h0 h" I& m9 J# Q
            tag[v] = 0;
    ! O  o+ A! @1 y        vexTable[v].data = copy.vexTable[v].data;
    " J+ o0 E; E) v) f# f4 J        vexTable[v].firstarc = NULL;$ @* f- s6 N# m1 }, |
        }
    3 V1 E  l& D: V$ i5 s- m    MultiAdjListNetworkArc<WeightType>* p;9 `7 U! X0 U: L2 a) G% b
    7 y, H3 R) M2 X- M: p
        for (int u = 0; u < vexNum; u++)
    6 l7 K' h3 E% p" Z+ G* U: ^' @    {
    5 g( A  |6 d7 Z6 _6 ^        p = copy.vexTable.firstarc;( V/ y3 n3 o. S8 L
            while (p != NULL)4 m% X1 b  E4 _5 E  c1 L1 N
            {$ G$ ?% u  L) t% j1 P% {
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    2 r1 _) S7 `  f& d            p=NextArc(u,p);
    6 V" N) `0 \% b% Z0 {" ^        }8 s% x0 L" M1 }$ g1 Q2 w- {. _
        }- D) L! A! A! V2 f4 V/ b
    }
    3 s  e3 Z% @* q+ r  \template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
      f5 M" o% v& KMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)! K2 \) ^! ]/ g# w9 f
    {
    8 c# a2 |5 f$ g/ ]    if (this == &copy) return *this;) T+ A% O4 ~- z- ]$ O
        Clear();
    $ E- z2 G* r# F: E) f$ q; V, |    vexMaxNum = copy.vexMaxNum;
    3 T' p1 c& [# H2 {4 Q2 L    vexNum = copy.vexNum;$ X- s/ a7 U$ ~; V' p( I
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];1 i& E' i+ X4 l0 b$ V5 k0 m; S  V0 p
        arcNum = 0;* t# v5 B2 {& m1 S
        infinity = copy.infinity;
    4 s5 K  h  q% x+ o; j1 u# l) x2 Q( I    tag = new int[vexMaxNum];7 V0 N9 A0 X: C' f1 @- K

    2 A: z) U8 |, G    for (int v = 0; v < vexNum; v++)
    # G2 {; L, x0 O' p5 v, Q    {
    8 V; v7 d# m2 Q" K$ k5 b" Y        tag[v] = 0;
    , e# U# l( G: r0 V" ]        vexTable[v].data = copy.vexTable[v].data;# n2 G% H& z5 {" {$ Z9 A/ w
            vexTable[v].firstarc = NULL;' [' L3 q. w! C5 m8 B  Y
        }8 f4 A* m& v7 \- r( V# g2 T
        MultiAdjListNetworkArc<WeightType>* p;* }/ G6 `2 D: i0 w

    / W: b2 c) f% D" G4 l    for (int u = 0; u < vexNum; u++)
    " U7 e" r4 r( [. W' `" q1 `: a' ?    {, h5 S. ~# ^0 ]
            p = copy.vexTable.firstarc;
    3 i) S1 l3 ]+ y: C: o- B        while (p != NULL)$ W1 m" Z& u$ M9 x, Q1 K
            {" E& p6 {5 N& l
                InsertArc(p->adjVex1, p->adjVex2, p->weight);) B3 L+ z  f; h
                p=NextArc(u,p);8 w5 j9 h1 \8 K
            }1 r9 _' m" J% s+ E
        }! D2 f, X' }8 T9 g: S
        return *this;3 W9 I+ c! t" U" @
    }9 A7 m4 c$ t# J* V) X  D& u8 g
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    $ d  ~2 M1 Y/ m7 EMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const7 H, X; V3 Q& h1 r# g
    {
    . R! s/ E7 A) A$ u    if(p==NULL) return NULL;. ~) a: n# d9 T8 [& a) Z) U8 S
        if(p->adjVex1==v1)4 y) m4 e7 J# D/ X/ Y
            return p->nextarc1;" V: [- H# E! W+ U
        else
      @6 d% F, I' V  [& V: b& c+ \        return p->nextarc2;- Z0 u( h+ @$ L+ m2 c! A
    }
    " N6 [( W% _& U" c7 S6 ]9 Xtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*- [: W! Q& W2 I; _9 M
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const* w7 O  F  O0 J0 M* c* _
    {
    $ i* v: y5 g5 v, X    if(p==NULL)return NULL;
    ( A( }" T* o* k6 ~  ?+ H    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;' }& E. P  v6 F) `! i$ ~. L) U" d
        if(q==p)8 o+ {/ n8 B, }! x* r$ V  b
            return NULL;
    7 r$ [; y' I% k& c4 }" ^    while(q); Z4 R8 f2 \7 N& I$ ]- m# S
        {
    , m. D$ ?" F! ^        if(q->nextarc1==p ||q->nextarc2==p)
    : q5 v  G* `* |( k' \: o: v, Q            break;( k) I' d, s0 y6 t
            q=NextArc(v1,q);
    # r. w& S$ G7 g% x    }! B( U# i1 n! d4 y$ Y- r- F6 F
        return q;
    5 M, [% a, [% D: X}
    & k. o% s, o" m- ~  @4 h8 |+ Z, ltemplate<class ElemType, class WeightType>  y% l/ |, q( W. P" R
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)! P: X4 ?, m* R% k7 ?
    {* H9 O  Q8 |1 V* @& ]: S
        if (vexNum == vexMaxNum)
    " s* D1 m4 J. ?7 i/ W1 ~        throw Error("图的顶点数不能超过允许的最大数!");
    / [- D4 W6 g/ k, Y. c    vexTable[vexNum].data = d;6 ~% I; H' r% K8 C7 h$ {
        vexTable[vexNum].firstarc = NULL;8 U9 h; l, D* N# K5 [& t9 \
        tag[vexNum] = 0;- d5 B3 ^( z+ Z2 l# y/ f
        vexNum++;, A5 l; E9 ^/ q5 a7 f! w4 [
    }
    / U! |0 r0 K3 |$ R/ Dtemplate<class ElemType, class WeightType>8 _/ P5 \# S. ]* x5 c
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    . o) F. t3 z, O; K2 j{
    2 e& B" F: P9 B3 F/ }5 A    MultiAdjListNetworkArc<WeightType>* p,*q;0 f' x$ a2 g" P5 [& V' G
        if (v1 < 0 || v1 >= vexNum)
    # G) A8 V( M- C0 F6 A$ O' O        throw Error("v1不合法!");3 L, w# x) k' ~: a* v, [' G5 W4 v& r
        if (v2 < 0 || v2 >= vexNum)
    ' ]) S, @" F# `5 t4 ^) _$ R& u        throw Error("v2不合法!");
    ( ~$ q$ N2 k- ?/ D- t2 @$ D    if (v1 == v2)
    3 i( A: n* v: ]& I+ Y" {6 H        throw Error("v1不能等于v2!");
    - A  \5 D& `4 c5 V    if (w == infinity)
    ! Y4 P( w  I1 Q8 q% F1 |/ A        throw Error("w不能为无穷大!");3 ?. M5 O+ z  n& b" g4 f
    3 M) i2 O# M0 Z, j
    . J% w. s/ X; S5 E. V
        p = vexTable[v1].firstarc;' P$ u# Y8 ]& q6 M
        while(p)% y# O4 C8 z. |" s4 j% ?4 H
        {
    4 `6 ^8 v- X$ l        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    " U" C( ~5 ~9 V3 H& v        {
    $ G# a7 ], D+ U' q, ^# F. G            if(p->weight!=w)
    2 n4 X* J' N* P3 R" [- k, x                p->weight=w;
    6 r/ H# |$ k" E7 h; z            return;5 [7 Q6 z+ G5 o
            }- p. L  ?& E( [6 C. c
    + Q9 f  c" b2 D$ K0 M& t4 {" L
            p=NextArc(v1,p);+ f' x. ?" H0 q9 m9 C' N' ]6 ?6 |) w
        }/ z& a8 `2 L0 Q; d1 m" ]  c, a+ R
        p = vexTable[v1].firstarc;
    * ~" y. {! x! y. U    q = vexTable[v2].firstarc;
    : w3 A. h9 i2 M, p    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    9 m' ?! @9 V0 q& W) m  M    vexTable[v2].firstarc =vexTable[v1].firstarc;
    6 h- q! z4 N0 C" Q    arcNum++;- H/ s7 D! y5 z$ F! i1 i6 j" v' l
    }/ c5 B" Y; s4 M* M( W# d# r7 {

    ( @4 b% t' Z' c7 Z9 ltemplate<class ElemType, class WeightType>! |: t% u4 T' S3 f
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    - w1 Z$ w# Z1 i; e0 d; A' ^{
    1 K/ K+ _) k/ z$ R! C% f
    / J/ O( L0 a" V+ z6 [  e8 u    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    ' s( d3 f. p1 B0 T8 W, i& I    if (v1 < 0 || v1 >= vexNum)
    4 j/ o0 d4 g: l2 C        throw Error("v1不合法!");1 j) r. D) g4 b, }) B* g, f
        if (v2 < 0 || v2 >= vexNum)1 b5 x) {* `+ y. s& G/ g( b
            throw Error("v2不合法!");- h' }- s, B( X! }) h
        if (v1 == v2)7 O3 b; c, T0 [9 E; x, X
            throw Error("v1不能等于v2!");7 Q3 d6 X, f4 U% b( e* O& Y" s5 V- h( u( G

    7 x1 ?: |" [) W5 m; R4 d# R) S; W6 w    p = vexTable[v1].firstarc;9 O# X' A" u  Q8 K. m: C# L
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)+ A& Q2 y) I2 W  b9 W( @
        {
    % F8 [$ u( p# p& x* ?0 g8 @        q = p;/ Y% `, ^! Y% `+ H2 V% c1 }
            p = NextArc(v1,p);  P$ a, d5 A; U3 e  \  Z$ @
        }//找到要删除的边结点p及其前一结点q4 ?& F9 X; j& H

    & M+ I9 w+ {( [6 ]( G    if (p != NULL)//找到v1-v2的边) E% L  R6 M, m
        {/ G5 X3 a' C0 C- W+ ?
            r=LastArc(v2,p);, s3 v% }3 k' v8 j! d3 D9 Q
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    3 a) D$ C% w% z; G) H% j+ t( I: t            if(p->adjVex2==v2)
    ( X8 B" S/ I* M4 A) s7 e                vexTable[v1].firstarc = p->nextarc1;
    1 e8 |0 `+ N- [$ M2 [* E& ?            else vexTable[v1].firstarc=p->nextarc2;) z, M' `9 |& E! m6 }
            else//不是第一条边
    5 i/ h% Q$ i* x' f        {$ b6 b$ I+ C' G0 j& M: V, v( ?
                if(q->adjVex1==v1). |- e& O$ G) N+ n  B- C, c
                    q->nextarc1 = NextArc(v1,p);
    , W  n( {# m5 l3 V            else
    $ T& o$ n9 L# l! m9 I$ j                q->nextarc2=NextArc(v1,p);
    ' d/ Z; ?/ l  l5 e. x1 m% E4 O6 r/ X* i0 y! e/ u
            }
    8 t8 B2 O+ r; m* X& t* E) A        if(r==NULL)
    + I! F/ b* d; j( K5 D4 e7 _            if(p->adjVex2==v2)
      z7 R0 `/ e6 |/ r' N( ~                vexTable[v2].firstarc = p->nextarc2;
    ; C% E" p$ G' r, O( ~8 X6 b            else vexTable[v2].firstarc=p->nextarc1;
    / f* K0 p4 n3 ^; l4 f        else
      r  l& P: ?# R1 k        {5 ~6 t$ I. g3 {7 ~6 _
                if(r->adjVex2==v2)
    5 r; s0 P0 `$ u2 W! [* ^3 X( M( m0 n0 H                r->nextarc2 = NextArc(v2,p);
    ) B# a: U! D0 e            else" z. y& C! L: z9 t4 o/ e6 l
                    r->nextarc1=NextArc(v2,p);: `. S7 S" d1 F- Q4 s" M
            }
    ; f% B2 Q* ]# M# a        delete p;
    , x: _$ V) O+ {  J: S& \        arcNum--;" }4 n( |. D' \- J3 p
        }; f- |# W% U; B( U: f( r
    8 O3 T3 S# f2 O5 @; F/ z
    }/ _" r1 [3 e  M& g
    template<class ElemType, class WeightType> void
    ( z! c- D- _7 FMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)' f  [6 s" c2 x& V
    {
    ( {8 W) i2 h( n# I  k1 y/ A$ X3 O1 {6 K    int v;
    3 c0 K3 [; L9 Y2 W4 u    MultiAdjListNetworkArc<WeightType>* p;
    * z% S& f; J  p, x/ z! g    for (v = 0; v < vexNum; v++)//找到d对应顶点
    3 S+ H% S" w! P% L- z- {        if (vexTable[v].data == d)
    ! d) I( Q5 o* j/ ]% }# c            break;
    ; L$ L9 `8 z0 Q6 \( J    if(v==vexNum)! |& Q1 G; R: f# g  ?
            throw Error("图中不存在要删除的顶点!");
    " d" d5 h; l, b  O
    ! c6 f5 Y: h$ }: K: e1 ]. m& N    for (int u = 0; u < vexNum; u++)//删除与d相连的边1 @+ G3 Y& \% n1 T1 |$ ^' @$ F7 v
            if (u != v)7 E) F1 q" n: o2 w4 j& r3 ?
            {$ a% v" i- [6 Y7 }
                DeleteArc(u, v);
    8 [" D2 |0 u% x  M  L) Z, ?7 E        }6 a) ?7 m8 r9 X) u/ Z+ t
        vexTable[v].firstarc=NULL;) d, Y& v" ^6 ~8 u4 l/ \
    6 o3 V7 i; D) |
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置+ b3 h5 Y' Y; P: _$ C+ n
        vexTable[v].data = vexTable[vexNum].data;% M- {7 }+ D9 ~1 Z7 Q9 |
        vexTable[v].firstarc = vexTable[vexNum].firstarc;! y! q& V9 y6 r/ |: l# r
        vexTable[vexNum].firstarc = NULL;' N# A$ X0 V' w
        tag[v] = tag[vexNum];6 M1 e" J5 H6 }
        //原来与最后一个顶点相连的边改为与v相连' f% F$ q& \& B4 q  @: p7 i
        for (int u = 0; u < vexNum; u++); c! y, o( n9 U. d% i" n
        {9 [2 t1 Z3 [2 D8 E
            if (u != v)3 @+ B4 k: r+ k0 W& q9 _8 R" ~3 g
            {2 p8 G/ h- _- g0 [$ A
                p = vexTable.firstarc;
    # N+ d+ w" `" G5 P5 X- `. l/ |# r            while (p)
    3 Z, d9 Q5 [( P            {
    4 T, W9 P6 F$ \8 k/ O) L  y$ X                if (p->adjVex1==vexNum)
    ' b9 x8 R+ @) ^- c8 i4 D                    p->adjVex1= v;
      G  \6 U' w$ H- ~0 r                else if(p->adjVex2==vexNum)
    ) u$ j, O) r* ~9 W  L8 ?; ~                    p->adjVex2=v;+ I  b8 T" k9 _/ }7 o
                    p = NextArc(u,p);5 ~9 ?1 F$ o6 @
                }
    - T, B, v' o6 z        }1 n! z0 d7 k/ t  h0 C- |' a
        }) s  \  a$ o- ^! X2 O
    }/ z) ~, v. p3 T- O/ b: V( w, E
    ///深度优先遍历6 p4 j5 f: O/ G0 W, M
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    ' u# v9 y  S4 n7 X# A+ X{# v: l# ^& L/ C; y) h9 t7 ^
        tag[v]=1;' T9 @1 k. i9 S6 a
        cout<<setw(3)<<vexTable[v].data;
    9 q$ f: d6 ^4 ?9 H+ y2 ~    MultiAdjListNetworkArc<WeightType> *p;4 m2 h* Z. R& }5 q% x
        p=vexTable[v].firstarc;
    3 G7 u4 q. ~# j  a8 R( w" W" ?' e    while(p)
    / I/ E2 Z* w% _0 y% i8 G) f    {
    6 p0 \9 P: ?. K+ x" x5 k% h        if(tag[p->adjVex1]==0)0 K9 X7 y1 p4 e& E6 q* ^; {& e4 p
                DFS1(p->adjVex1);: L8 t: T1 z" w# Z( t' ?9 X
            else if(tag[p->adjVex2]==0)
    8 S) m2 I' b2 ]# }3 A* b            DFS1(p->adjVex2);& v( V7 i$ S# c- D# P: O$ }
            p=NextArc(v,p);0 |9 Q4 r$ z/ J! {
        }
    3 z* H' R- G6 V. V( G}
    . g% V; i- E; d( v$ U% @template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse(), g: b" A4 j- \( }; G& Q' ]$ K
    {
    " J, _& X+ C: A( i# t, ~    for(int i=0; i<vexNum; i++)! X  a- @8 M0 u4 M( H8 F
            tag=0;) v: ]  F2 y" _5 ]( i0 I) p* c% A
        for(int v=0; v<vexNum; v++)
    3 _2 y1 w+ H$ R0 y* F' \    {
    ) T' c9 A  K7 {& x, p3 ^        if(tag[v]==0)  R/ L+ F0 ^8 L: m$ Z, L8 A+ O8 [
                DFS1(v);7 I5 c+ ?* U5 x* o1 E6 ]0 ?& p# @
        }  c* s4 n$ D* h" l- b; D' m
    }
    - u! U# n7 {' L! v6 E1 H: m8 P3 d. vtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()$ g/ k( O+ G) j
    {! d: }$ e/ K8 _8 G. x
        stack<int> s;
    , d" |6 I* d' ]  S. U    int tmp;1 o5 {6 w5 H4 l% }: E' _8 j: a2 m
        MultiAdjListNetworkArc<WeightType> *p,*q;$ f4 G/ i2 g# _0 Q1 M% T6 \
        for(int i=0; i<vexNum; i++)3 K& i5 K  H9 a% a3 V
            tag=0;
    5 _7 C/ Z/ b- r" ~1 O3 S4 t    for(int i=0; i<vexNum; i++)2 C* o" S( g# B$ v; ~3 I
        {
    * a( `& U6 w# S- ^! ?        tmp=i;
    3 Y7 h3 e  R6 z5 e4 M" o        while(tag[tmp]==0||!s.empty())
    ; M( _7 \% E- O2 M        {
    * H& a) }: A9 U; _; e& q& C            p=vexTable[tmp].firstarc;5 u4 d5 e6 S* U+ \7 O' ]
                while(tag[tmp]==0)
    ) y0 M% s# C1 T" h' q, c            {
    % C2 |" d+ H  X1 f" I                s.push(tmp);
    ! f2 W0 S1 Y* }2 r) _( m- ~2 U! j                cout<<setw(3)<<vexTable[tmp].data;
    : i* x  N5 a" h3 z                tag[tmp]=1;
    9 o4 T, }( \3 u  Y& c1 [! a7 e+ G                p=vexTable[tmp].firstarc;
    / h/ r0 N2 k7 x0 ]7 P" n                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    * k3 y+ {3 y( i2 l& s3 [' k  d% ^                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    0 i6 Y/ }6 f% Q# u* u% O& t                //cout<<" 1st     tmp="<<tmp<<endl;) k! z' k1 L& Z, G& o% J' B$ z" S* j- s
                }
    + w! d( {2 \) s! Z; s$ j) t            if(!s.empty())- ?/ r1 k' s2 C5 U& x
                {! |: z0 C0 K% `
                    tmp=s.top();* p: s5 N& [. d1 g/ p, f: f# S9 i( a& m
                    s.pop();1 J  F9 L! r: a
                    q=vexTable[tmp].firstarc;2 {: M& Y/ n$ f4 T" A, g$ C2 L
                    int t=tmp;7 p( ~- U6 E& I
                    while(q&&tag[tmp]!=0)2 Y* r. H& t. ~5 U) E, v
                    {
    $ @* |: r& J: v& X2 {8 C                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);/ C2 t$ l# _+ f
                        //cout<<" 2nd     tmp="<<tmp<<endl;8 |* }1 f: i+ h3 _) J' U
                        q=NextArc(t,q);' k/ @0 `6 E% G4 b
                    }
      r+ D- j' V/ A9 B6 ^                if(tag[tmp]==0)
    $ _6 d7 X, @, M6 V                    s.push(t);8 h7 J" @( P( ]$ }: K3 |2 ^; r
                    ///1、对应上面连通分支只有1个点的情况8 p5 Q% u5 d# E
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈% G+ x2 R* r4 E' m- C
                    ///tmp要么等于找到的第一个未访问节点,$ j. @, H; L! q
                    ///要么等于与t相连最后一个点(已被访问过)
    2 N9 e) D& `% s9 w  V                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    9 B" V8 I( s# Q! c, ~2 |            }
    5 D5 B4 B/ ]2 D* c# q        }
    9 P3 Z" ]" M6 j    }" Y7 Z1 f' M% |$ N1 G6 p- n# b
    }5 c# {3 t7 ?+ W
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    1 D5 o' V3 x8 g) o: l+ G# n5 _! [template<class ElemType, class WeightType> int
    # Q. M  N4 i2 c3 H% o- bMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    0 I  _% ]- a* O! k{
    + B$ M: T. B$ h& |; o    if(head==pre)9 o  R( u, e, A$ T7 T, R) r
            return -1;- W5 ~, c) u: A  A+ ~! E# i' p, _

    - N9 [1 b6 |4 z* o0 Z' j8 Y    MultiAdjListNetworkArc<WeightType> *p;' ?8 b# ~% B4 c2 z' O  z  U
        p=vexTable[head].firstarc;
    9 S- P* T: b$ a9 d    if(pre==-1&&p!=NULL)
    7 ~( b: e  x2 i0 \/ T! L3 W, p" S        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    ) s' d% h% `+ B* B+ |    //pre!=-1&&p!=NULL! U5 s1 I1 v  G/ e4 O3 [/ U9 P
        while(p!=NULL)
    * j! g3 Z- [, H    {9 M5 W- G2 A! r$ i
            if(p->adjVex1==head && p->adjVex2!=pre)
    - m$ z* K8 @" C8 H) X            p=p->nextarc1;
    6 p/ N' e6 V9 e- S        else if(p->adjVex2==head && p->adjVex1!=pre)  x4 b% Y- w4 O( T
                p=p->nextarc2;
    5 _& G- B6 e/ u, j5 C4 b6 a        else if(p->adjVex1==head && p->adjVex2==pre)
    , y# B4 B2 `3 V: K  U% w. J        {% j2 N3 {6 n2 J- h' M, n) T9 F
                p=p->nextarc1;
    ; H1 V* y3 k* p2 _* r            break;1 W+ U( k* \% Z, R' W( M4 V8 Z
            }
    3 G1 o7 \: }2 ?3 p2 e3 J        else if(p->adjVex2==head && p->adjVex1==pre)$ E9 H8 F1 g5 B+ ^
            {; J0 ~0 D2 ~/ E; A9 M+ C8 o% L
                p=p->nextarc2;
    2 r3 ]+ Y/ U& ?% A) K7 U            break;
    " ]+ ]# E( Y% b/ m0 X8 [+ X        }
    ' K) g1 Z$ h# N5 D" P, O    }# l/ K9 ?% ^$ r# E6 W2 g7 M
        if(p!=NULL)" i5 `$ ^! V) V
        {
    4 q. `6 A" r# k3 j9 V; o        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    2 z+ L0 Z* C. W1 `    }( c9 k: J7 b  w- K, O: F
        else
    2 Z+ q4 G, K' |$ E/ t        return -1;2 }- X" P+ g  `/ p* U8 ^0 v  o
    }
    0 y" N  c/ R3 Z3 \2 R
    8 B% o; W" f2 a2 u. M8 ^0 v5 e5 `1 g: z5 z8 p; J$ ^
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    ; ?1 C% W8 ~$ J" U{
    1 e  ~" [: c" w! o* U    stack<int> s;- ^' U# D; @( K8 A
        int p,cur,pre;
    7 s' z7 P: {& N) w  _/ X' [  }    //MultiAdjListNetworkArc<WeightType> *p,*q;$ l; e6 |& `$ O, q6 K( s2 f0 |
        for(int i=0; i<vexNum; i++) tag=0;//初始化6 X8 p1 p  ~* c- z& b

    % X7 ^+ y' q' U, x# L, y5 {0 D    for(int i=0; i<vexNum; i++)
    $ z" D, w3 ?5 A7 s& ^    {
    8 @. k; V9 Z5 T6 M0 Z6 A9 W! u& l4 O4 \        cur=i;pre=-1;
    , A! ~2 p0 F  y$ {, Y8 v7 ^) r6 x2 s        while(tag[cur]==0||!s.empty())
    1 [/ V# Y; y7 s: O& O, }! ~        {
    8 k/ }/ m7 K' l# @; |( L1 U' ^            while(tag[cur]==0)# s! M! q1 K9 ^+ h' w% ]/ ]
                {
    6 Q3 v% G4 z* E# S' e5 R- ]8 j                cout<<vexTable[cur].data<<"  ";
    ! {4 G: t, ~! x$ n8 R- S8 }# M                s.push(cur);
    5 N4 ^( H2 r$ A7 x5 K+ t                tag[cur]=1;
    / S0 q1 `1 O7 i. j: l$ _9 q               //初次访问,标记入栈. Y/ @" h) P$ ~' u( W1 e

      q: H# y- \! ~: E0 }6 N4 X" p3 ?               p=GetAdjVex(cur,pre);//p是cur的连通顶点
    0 C$ D5 A0 x0 O9 ]6 q               if(p==-1)4 x# p. k8 G0 ]7 H3 i7 K4 r2 J
                   {
    * [/ ?1 ~% n$ @; [& ^                   pre=cur;s.pop();
    - L3 z- V7 ]( `6 m( V) m7 I                   break;/ b0 g* Z7 n5 d0 A' ?
                   }
      d$ X# h: x; |( c$ K8 Z; o: C1 d               else  x4 z& s2 F4 n0 T5 j: W
                   {
    $ ~% }( h1 A& r2 y6 ^2 ?                   pre=cur;
    0 U5 P; h4 V% V$ v                   cur=p;
    ) D6 {1 @% E$ J" x               }
    ) F. `% D$ u& H: r
    / R7 V4 F8 F) k; j            }
    + m6 N' I$ Z5 l* H4 B3 n8 a9 U& U) }            while(!s.empty())
    . }- z) z" _9 p5 x" {$ |! Q% ]* p            {  R+ o/ F& @5 X% F' X( [6 M. s' m' J
                    cur=s.top();
    5 _0 ~2 @! Z3 ~5 q                p=GetAdjVex(cur,pre);8 Z$ n' @& ?. F5 t" Y$ `
                    if(tag[p]==0)
    ; @2 O0 y; }" M; i( E% S) a                {
    # I/ S9 o8 |: b                    pre=cur;* b: m4 m1 I$ Q# E6 `) M  _
                        cur=p;
    : T7 ~0 V7 }, k4 L7 u) U                    break;( ]8 P% j& ?7 f8 t; W1 z! R
                    }
    9 n! H& ]1 t( z! V$ E                else
    6 ~' w! `; M. ~: o1 t% t                {
    8 s% M: `- x3 }9 L                    pre=s.top();- a/ z  \& w/ V; N3 W# s
                        s.pop();
    3 O  I8 g  U( s7 o! k  j7 B, A                }
    5 ^! [& a* T/ N# s
    5 J3 l3 I5 X1 N! C7 K# c            }/ P, ?3 f; L. e1 `( o7 x3 r' ]1 O7 `* Z
    5 O) K% Q2 Y0 I+ [
            }
    ( D( q& `% d6 q- Q7 H; Z4 F    }/ w, X/ \* d3 ~4 {
    }
    4 R; b7 t) _  j7 D7 D! etemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()- r8 a& L4 o' q
    {* c. O7 s+ e  I/ Q
        for(int i=0; i<vexNum; i++)0 i& n  S7 W) I: T. d4 [% v
            tag=0;
    # l: s8 ?% X3 {0 x) h" q( Z/ ?# p    queue<int> q;
      j. p' {. o2 v  R. o    int tmp,t;0 R8 l: e2 s+ W6 f! @+ x
        MultiAdjListNetworkArc<WeightType> *p;( ]- j  J6 }. r0 i
        for(int i=0; i<vexNum; i++)
    # n! P: N: g# [, g+ e/ E* ~. S    {
    ) m. {) ?* W' L        if(tag==0); Q, T9 w! V. v
            {
    , z( N. f) ~' B6 y8 u  [, d4 c8 B6 b            tag=1;
    3 h( c/ G: u# E" K            q.push(i);
    ' `* `2 A/ ?: K" c            cout<<setw(3)<<vexTable.data;
    + R# V( ]( W, W1 N        }3 y- j( r4 q1 q9 _  f8 S9 p
            while(!q.empty())
    ; o- S& r; H, _2 @2 n. v        {$ o1 M8 H* [" d. N: u
                tmp=q.front();$ ?4 P2 g& u9 F: Q: T
                q.pop();
    ) g: g) r% B, ^( P; P            p=vexTable[tmp].firstarc;
    ) h. e& q8 w8 }3 q  }            while(p!=NULL)' m! u  }/ I0 X( |
                {9 R6 O$ f+ p( v# D; `
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);: o3 w/ S9 O( `3 N1 L
                    if(tag[t]==0)0 ~# h0 D# i, u  K4 F8 g
                    {
    3 n* F* c& c5 h7 U5 p, B* U                    cout<<setw(3)<<vexTable[t].data;
    , s- N- D2 {( x                    tag[t]=1;
    - x" b1 e1 i  q9 O9 i. b7 H                    q.push(t);# e9 W! m( h/ L) \) u* H% \
                    }
    ; ?6 N2 X% R  g9 y& F: s+ h& e& r                p=NextArc(tmp,p);
    3 L8 A! z) M6 k            }
    ) v, W" S# ]* e, U* ~) D        }
    * h% A, }0 S5 I' C. {; Y    }9 D% F$ K* p8 E0 _3 Y; M
    }* R5 T( a* Q7 ]. r5 f9 }
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()0 R" D! p" A! X$ j, S/ k
    {' X. `5 R  `; T7 y
        MultiAdjListNetworkArc<WeightType> *p;
    / T$ I) @! S4 j8 w    cout << "无向图有" << vexNum << "个点,分别为:";
    ; Y5 O1 L  ]8 z- Z3 P  D) U    for (int i = 0; i < vexNum; i++)
    5 ?& X6 s  P3 P        cout << vexTable.data << " ";1 r, ]8 N" }) t) t: `' i
        cout << endl;  {  o6 r/ x7 }; E9 t6 A: G
        cout << "无向图有" << arcNum << "条边"<<endl;# O& b$ _- M+ b) G7 C7 t
        for (int i = 0; i < vexNum; i++): N$ v5 v3 Z- U/ I8 f5 x8 e" [" C
        {' V  N6 D# `- V: Y6 q' I/ S
            cout<<"和" << vexTable.data << "有关的边:";2 C# e* t% @8 }. f! V4 ~
            p = vexTable.firstarc;3 i. `- m+ m+ M( b
            while (p != NULL)6 Q3 K3 w0 {$ w5 j1 ]4 B9 \
            {
    - z4 T; x% _/ _5 P! L3 y) S            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    $ |( S3 ?3 i' |( f& O6 ^            p=NextArc(i,p);
    ' ]! a" Q7 ~9 }2 H6 a7 K        }
    ( V/ o+ r) ~5 Z+ ~2 F+ S! k9 b8 _        cout << endl;+ t. U1 E& P! F+ d7 e$ o
        }/ j3 t5 d0 I( K0 h
    }* O7 |+ ]5 u) Q. C/ o

    - [. {& E3 T" B4 C9 v2 m* d
      T" [5 ~# `: N; K邻接多重表与邻接表的对比7 f5 N1 S$ m8 B
    / f' L% Z/ w: ^1 B5 P5 ^8 W
    邻接表链接) ~# |7 @9 \: c# U; k  }, H+ \
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    . [8 \$ u% `" h' o2 C在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    ( M# W! M9 J% i! h# I; v为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    & ?4 T  Y" n- P. G; I8 a0 I4 B————————————————1 e" i4 F3 @$ E+ F
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。1 v3 B8 v* X% j4 K: b6 d: u
    原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669584 @4 J7 u9 r2 u$ U
    ' A& b9 e& @( [; R! _
    & B  y7 }& I3 Y  P7 [
    % O+ S# J+ _0 e: j5 y$ j( |

    ' q' [' V% `& W- l& \8 u+ k! W% b————————————————
    ; H+ {5 t4 q5 F% \% |+ d版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    + l, k' [+ K6 l原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669585 l+ B% E' n  p; [1 Y, @
    * K5 ?8 m* Y: Y5 h( h/ o

    / v* K' P# y3 m+ n. P
    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, 2026-4-20 19:31 , Processed in 0.423126 second(s), 54 queries .

    回顶部