QQ登录

只需要一步,快速开始

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

    $ @. m; ]9 k; J- ~$ [3 A* w图的存储结构——邻接多重表(多重邻接表)的实现3 X5 _8 J2 o. {6 O5 Q
    7.2 图的存储结构8 l/ b" N- {, J9 x3 P* u/ O
    ' p* y" S5 E7 ]  \$ o# k
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    ) R  z" t- M/ M; U" e# p/ |% d- \邻接多重表的类定义% G+ ~  e5 \! t; a9 t5 q  C2 g1 k( v7 I) `
    邻接多重表的顶点结点类模板
    6 c$ k8 [3 ?8 a5 u5 d/ y邻接多重表的边结点类模板: L. c0 B  `8 `7 _6 F) `- S5 L) M
    邻接多重表的类模板( ?7 d% x: n' M9 F! y5 @/ ^
    邻接多重表与邻接表的对比' Z4 D3 Y/ v& A" G- ^/ W  ]6 |# C
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist  {" a4 _( p: s7 s" r* m

    / n" W' a% y- P% w4 n1 |在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。6 A0 g; N1 G9 H1 ^# e) t5 |
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。' ^7 D1 i; b( g5 {- G$ |/ Z

    9 u3 E% l- v, t. r) d/ C1 X& G邻接多重表的类定义+ ~$ G! g, H7 U7 _! u
    1.png ; L  g4 l. X* S5 y
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:: m( \( e" T5 x* c  J0 b8 O* E
    data域存储有关顶点的信息;4 d3 C) N! B9 p  v
    firstarc域是链接指针,指向第一条依附于该顶点的边。! w/ p( K% F; a, n9 ^' G
    所有的顶点结点组成一个顺序表。


    - x9 A0 e5 d2 v2 r6 {. W" A+ |9 m# ]4 K1 K1 y  J$ i1 `
    template <class ElemType ,class WeightType>
    2 E# ]* o5 k* o! P1 ]  Fclass MultiAdjListNetworkVex
    : m* c- t. `% o+ `{& W; s  i' l  m; q( H! N6 M. M
    public:
      [2 t- v% V. u7 m9 V# H& ]        ElemType data;7 H- t9 B; B/ f$ C/ K
            MultiAdjListNetworkArc<WeightType> *firstarc;
    4 u3 L* p2 Q. A  F1 y6 r
    7 @$ Y7 y" ]3 ]: n        MultiAdjListNetworkVex()  ?) e0 G  F. R) q
            {
    ! i1 U7 }( l* m% w2 U2 f/ Q% p                firstarc = NULL;
    1 V$ E0 Z+ }7 m) c) ]5 k        }: }$ U, o! \6 N2 G( w
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    3 B2 a' K3 S7 t7 ?) l3 r/ `        {
    7 t/ b" g4 w1 S9 c. {  A8 A                data = val;* {$ g6 ]$ c! }6 a( Y) r
                    firstarc = adj;( l0 x% f9 {1 u6 I: m# t
            }
    & U6 z# s9 R0 n# V+ t};0 q4 f4 e4 d$ ?( L
    5 r! R& i, G1 T, P3 @2 `# r
    邻接多重表的边结点类模板8 J" H9 d' W8 y0 `

    . n# [' Z; E: K在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    ) b* F! q2 a! p: e' Qtag是标记域,标记该边是否被处理或被搜索过;
    % U; _/ M$ k% \  P; o- [7 hweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    0 u, |* m& c. x" h$ p. T$ J- r  O) B0 }nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    : X2 h9 z: A" t' A* u. y% anextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。! P$ L& C( g. J8 E' T$ P
    : T0 S, o3 b# ?: C' _$ ^6 d, Q
    2.png
    ' a  O# b% ?" m) A  ^template <class WeightType>
    / s+ r$ @8 Q4 Y1 W) iclass MultiAdjListNetworkArc8 n' ~# T# B9 z, M/ L) q+ ?
    {6 u! n, f/ r8 i9 W* d
    public:
    3 b0 R; M# w7 T! J; ~  q4 O8 t    int mark;                                       //标记该边是否被搜索或处理过1 l0 g8 }  d; e5 {2 B$ Y! F5 t
            WeightType weight;                              //边的权重
    $ Q4 {# i5 t3 m$ A& o  [! u: H        int adjVex1;                                    //边的一个顶点
    , ~7 \# G. n9 \        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    & b) k* |9 M0 q# g) W        int adjVex2;
    : I! U1 i- k0 [7 g1 p( w4 `, J* Q        MultiAdjListNetworkArc<WeightType>* nextarc2;, A, ]' n- h/ d( w
    4 I0 Z/ y8 d/ m* ]& W+ w
            MultiAdjListNetworkArc()! S/ `# f! ^3 T6 G. o
            {
    ; ]1 c- V1 u9 ?# \8 n                adjVex1= -1;
    2 j" X3 {0 |6 i2 i; i8 d                adjVex2= -1;7 T; I& O. `3 X1 ]8 S
            }! F+ u: P  W5 u* R
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)( S. O9 J- Q# Y+ D0 a" C
            {
    ; h( R8 w1 \% C/ s+ l                adjVex1 = v1;       adjVex2 = v2;; \% ~0 A5 g* @+ y
                    weight = w;
    . t8 t& z# \7 G: Q                nextarc1 = next1;   nextarc2=next2;$ M% `9 ]4 |/ Z% M, w, F: ?
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    2 i* R" V) U% L) L- ^        }
    / R( L% P  L7 ?  r  F& N2 ~+ D6 P/ B5 L# }, K' ~& i  k+ _" b  E
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>" L, ^" Z3 N7 Z
    class MultiAdjListNetwork
    * S: }/ W! e& s3 y: j7 T, w{
    1 ^# l- {8 P. ~+ S$ ~0 hprotected:- R2 y# n! c+ {$ i
        int vexNum, vexMaxNum, arcNum;! `8 ~: F* [  J
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;$ ^6 I4 T# ^0 L' h4 V9 v# |, Z
        int* tag;
    . M; d+ C  k: C9 [    WeightType infinity;
    ( J' f( w' ?1 x1 e8 F
    / n) V% A0 i7 Ipublic:
    3 F% z4 j5 N8 W9 O  h    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    ! T* p1 f/ N' j' [# e+ }- ~4 E1 R+ U7 [) Y8 V* p$ n- \
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    : U$ X; n, y+ `' `* S) Z9 G, @8 X& j& T2 H8 S, R3 j
        void Clear();: [* c: c( ?. |
        bool IsEmpty(), x, X$ I' \7 Q0 Z/ n
        {
    , T( }4 a$ P, N7 B) d. U        return vexNum == 0;
    ( G% c) |* P7 \# O! h# q    }
    ) ^- V. p7 n, [1 n    int GetArcNum()const
    # h, `$ i7 y3 p- g! f' v    {7 n( |2 a7 V9 z& z
            return arcNum;
    6 ~! W( ?* A" H    }/ r( Y$ f2 `9 f( f1 x. u2 `
        int GetvexNum()const5 b2 `* X6 R; `% V
        {
    ; E0 Z( m+ J  L2 z2 @+ ~3 _        return vexNum;
    / [9 t4 }+ f  V2 X    }
    / c5 T% R/ y6 A* U& y& d+ U3 g7 O- q% z- @8 z+ E

    . V' g, g  F1 d; d6 a# F! h2 y, F! g; Z0 x    int FirstAdjVex(int v)const;
    / i2 a) ^2 o7 F    int NextAdjVex(int v1, int v2)const;
    2 n' p& ], ^* x& }# [$ f" X    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;% S; b6 J7 v1 V* G! S* x4 m
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;; z: a% d* i( S) z
    . h/ ^& @  j' I6 u/ w1 R
        void InsertVex(const ElemType& d);
    " A. G* L9 g$ x+ Z' ]6 u! _1 |; w0 a    void InsertArc(int v1, int v2, WeightType w);3 K! ?3 \; [  G5 J
    5 w0 r% J& H+ I- H) H
        void DeleteVex(const ElemType& d);
    / T" o" x& d: e8 [    void DeleteArc(int v1, int v2);
    3 a' G" {; J4 }* i2 e
      |1 \8 u5 ^& r1 A+ E4 j+ K8 O# u    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);8 \5 e) \; C  {8 ~
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    , C1 m- }5 `4 t0 B" t
    " y' }- M: V. S8 N    ///深度优先遍历7 y' y$ f8 R0 P" @" u% f+ S/ X" e
        void DFS1(const int v);
    ( j% ~6 ~( G5 _+ i: l    void DFS1Traverse();; H/ r0 g* e0 P9 O% B7 ]+ r2 I
        void DFS2();& o5 Z2 b: u/ g9 v8 V  b# X
    % J8 b: v& O! A& {8 k9 Q; g- |5 X
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    ' I7 ]  j+ r5 F3 N* c    void DFS3();6 b+ w% q! B6 |5 d* b7 P6 W9 L

    3 M' J) s5 ]$ z4 \5 l    void BFS();
    8 t+ u: C- M# n8 u4 V4 {; d    void Show();! U3 N* @3 s9 M
    };% ?) N" [6 S6 j$ J% j  x
    6 l* `0 ?# ~- [2 J
    2.函数的实现6 ^5 a2 w# Y4 J
    研讨题,能够运行,但是代码不一定是最优的。
    1 t5 Q) l+ n/ B( \5 }1 F! Y
    * f7 ^- s2 Q8 u8 W1 x; K) r, I+ ]#include <stack>
    9 I2 O8 d3 i0 u9 Q# \; \3 ]4 b#include <queue>% ]8 L& c8 u6 _4 j3 }

    6 ?: w3 `4 u! _5 ]template <class ElemType,class WeightType>; f* _1 [) M7 h8 P' q0 y1 @
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit), o5 M" ^; c; ^
    {" n# G* f" B4 A/ p& ~) B
        if(vertexMaxNum < 0)
    / G# x* ^; `# |4 `6 x* U: v        throw Error("允许的顶点最大数目不能为负!");
    & [( k: q1 w+ Z# o0 p    if (vertexMaxNum < vertexNum)- e# M/ U  @! f; l$ j- \$ C/ j) t
            throw Error("顶点数目不能大于允许的顶点最大数目!");
    ! e, x7 Q3 T0 R* j, j: G! X5 h) T    vexNum = vertexNum;
    ! P# v8 f9 t5 C$ X! f4 O    vexMaxNum = vertexMaxNum;  N' Z& U) @7 G  x5 h
        arcNum = 0;( {  Q# [# v; l/ e% D0 z; m
        infinity = infinit;8 Q, J) u( e0 q0 A  I
        tag = new int[vexMaxNum];& W, V% V' \$ ^7 g0 O3 D# n
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    ( l$ Z; E" c9 \+ s: b) G* @    for (int v = 0; v < vexNum; v++)* p& D5 `" T1 s( j
        {
    " X8 ~. B( h, R+ K& M9 s; L        tag[v] = 0;
    / t) b/ X% u. A$ {5 c        vexTable[v].data = es[v];, ]' J  K/ G0 t
            vexTable[v].firstarc = NULL;
    : u3 ]$ A" L9 }6 D7 _9 ]' X9 h3 d    }7 e* X6 h. }# A& a
    }
    # R8 m% W& V# D0 d7 V. S# ltemplate <class ElemType,class WeightType>% o: e( s" D2 b8 W( s
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    & Y) R. K6 Q% u3 `; X2 `; b% \4 ^{
    5 Q3 N5 b+ z6 V& C3 |    if (vertexMaxNum < 0)- z+ v5 C/ ]( r/ s: B  c# G
            throw Error("允许的顶点最大数目不能为负!");; s- n, e4 w/ o( V
        vexNum = 0;
    ! u, u  {! q# Y$ `7 l& B& e    vexMaxNum = vertexMaxNum;7 o# v5 P2 w+ i; ~
        arcNum = 0;
    6 M: V3 h8 R2 {. X; o" i6 C  a    infinity = infinit;
    . u5 J6 @6 }- k" E' `    tag = new int[vexMaxNum];0 e+ Z7 g$ S1 M
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];9 v; Y2 Q( d. n8 B8 P; B
    }
    % o0 R' C; l+ K3 G/ vtemplate<class ElemType, class WeightType>2 |, V! b; ]4 ]1 K5 ]$ U
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const8 t6 k5 \' K/ t
    {
    1 Y, ]  p: w. p0 v1 r+ Z8 C    if (v < 0 || v >= vexNum)+ K) G' s3 n4 u+ `/ L# e
            throw Error("v不合法!");. ?0 {3 D# Z+ [3 W
        if (vexTable[v].firstarc == NULL)
    , ]) ~  T. k' F: F        return -1;$ j8 G. L1 E' o% o9 I0 N5 t9 d
        else
    ( x0 i/ b3 A' f        return vexTable[v].firstarc->adjVex1;
    8 I3 P  ]1 v) {) I8 j) p; |7 u. B$ T; `}; Q4 t; ^) s9 V( f# {4 @
    . [1 H, F. E4 {  P* C6 a6 s
    template<class ElemType, class WeightType>% @# {& n' _+ Y3 K6 y% w
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const! \5 k6 t5 v( o2 [; R
    {
    $ j# g, l' T' }6 {9 h& p' v    MultiAdjListNetworkArc<WeightType>* p;* P3 c! ~! I. ?
        if (v1 < 0 || v1 >= vexNum)) ?% N$ L6 f6 t2 ?/ J
            throw Error("v1不合法!");" R" o7 }: Z. X& Y% v7 m& z
        if (v2 < 0 || v2 >= vexNum)
    4 W7 c8 v5 _6 X' R        throw Error("v2不合法!");
    ! x# X' {# o/ @    if (v1 == v2)$ U. b: Q3 c5 }! z
            throw Error("v1不能等于v2!");) ]! @. |) N2 G' ^) P5 Y2 Q
        p = vexTable[v1].firstarc;; v3 }' r: w; e
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)3 C. Y# P% {7 C* ~! V1 {- G
            p = p->nextarc;8 E/ B% O0 I% F$ R
        if (p == NULL || p->nextarc == NULL)0 ^3 S+ Z3 [' U# Y0 }3 u- d) A
            return -1;  //不存在下一个邻接点4 i. w# v- {2 u4 k, D5 O
        else if(p->adjVex1==v2), l! d) z. }+ X
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);# w) I8 V8 @+ t7 o8 F% S0 X2 l
        else) U$ O9 z% _" P8 G4 X" a/ s
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    # V; c. [/ a: E; ~}  L% y' q& O$ \# e- `
    template<class ElemType, class WeightType>
    , Q2 z: K9 H* B, F1 Avoid MultiAdjListNetwork<ElemType, WeightType>::Clear()& R/ W# C- p3 ?0 K& V; J- A
    {
    : q" p: P0 a$ {" X. {    if (IsEmpty()) return;
    6 P! Q( O& \- C$ w" h0 ?& I9 e9 V    int n = vexNum;6 B$ t% x2 \% i" z
        for (int u = 0; u < n ; u++). {+ z3 M& |" v# @* k
            DeleteVex(vexTable[0].data);
    2 q; c  H- [0 Z/ Z    return;  @* y5 X3 i" S! g( Z# U6 F. A
    }, r6 g! `6 X8 k
    template<class ElemType, class WeightType>, }$ Q3 P2 ^- k' d) M2 U% G
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()' ?; G3 N, M9 a0 O9 j! Z. J6 y; l
    {; b$ k. O1 V) F# ?! V
        Clear();
    $ W7 D- Y0 [9 {7 ]}8 ~+ X9 w1 A# ]2 h8 |
    template<class ElemType, class WeightType>: t7 G) d7 l6 E4 @) ]1 x) B( H
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
      B' z9 N- y! H8 s9 U" _- _: d{* P8 C: Q0 ~: l8 e: S$ E
        vexMaxNum = copy.vexMaxNum;1 c6 a- N9 h  h5 r- ^/ O
        vexNum = copy.vexNum;
    : C& v% W  m; W' i: h) ~, \, P    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    6 _5 o: }8 v0 g: e+ Y# x* p, n    arcNum = 0;
    0 s. J5 }' r* }4 P0 `. w! P1 J    infinity = copy.infinity;
    - m5 L& Q& j: i$ ]: i* K    tag = new int[vexMaxNum];
    5 }* |4 B: q0 M7 L; m! l% D$ b- U2 C! _* i  j( }: }
        for (int v = 0; v < vexNum; v++)
    " c2 T7 V3 I. B    {3 _+ y$ u+ z0 R  ^3 k9 @
            tag[v] = 0;
    ' s% o. S- V8 M' _2 K        vexTable[v].data = copy.vexTable[v].data;& b' S6 t# d% Z; b: H
            vexTable[v].firstarc = NULL;
    : T/ s. D% a1 f5 h2 f' r% T3 ~    }
    - `% ?0 v7 K9 U# e    MultiAdjListNetworkArc<WeightType>* p;
    ! s* l- v1 N+ P
    ' ^0 L+ m* G/ \. n) J: |    for (int u = 0; u < vexNum; u++)
    0 U7 G1 V% b/ @, \2 n    {% k+ k) T' b0 p$ U; H
            p = copy.vexTable.firstarc;
    # j# ^" N& x! S4 x- S# x        while (p != NULL)4 g! R8 r  Z- y1 [) H3 T& S
            {  x$ b) b# y! w: I% B; G0 k  r7 d
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    5 G: F1 [. L# n/ e1 p1 I) w9 E! f            p=NextArc(u,p);
    / H5 `8 Q1 B' A* L, C& n        }  V3 U5 L8 s8 G. r- c8 m  K
        }
      `6 w. s% L$ D3 x) ~) `9 D  N}% D% a$ v( D6 ^5 z8 J9 C
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&8 F5 M4 ?/ A& t# x0 g+ b% U
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)/ [6 ~! a; |7 c, h
    {
    / H: S. m: a* T, _9 a, V$ z    if (this == &copy) return *this;4 C; b; E& m# y& `$ {! N
        Clear();2 g. K* e, e( C. B
        vexMaxNum = copy.vexMaxNum;" k/ N5 ]& D* ]4 ]: ^
        vexNum = copy.vexNum;8 Z6 t5 r/ P% L/ Z! n4 d
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    8 @6 o5 Q9 l% N) ]( d, n; n    arcNum = 0;& g- B- w3 l" _
        infinity = copy.infinity;
    0 j* \9 ?* p( e, o0 i4 V; ]3 S    tag = new int[vexMaxNum];
    1 z4 _/ J4 H, c2 A) i& L; P
    9 @9 z( R) \4 g& J    for (int v = 0; v < vexNum; v++)
    0 V/ F( C* A. p6 D  V" |    {
    2 a9 C! b$ H8 x1 ]        tag[v] = 0;
    6 c* F, [8 P7 m        vexTable[v].data = copy.vexTable[v].data;7 U; A4 V& X- Z; B
            vexTable[v].firstarc = NULL;4 S/ j1 G. |& ~3 b+ X" h5 C
        }
    0 y( [4 K( L) i) \/ T    MultiAdjListNetworkArc<WeightType>* p;
    1 G1 S6 J. P9 i+ ~5 h& [, V0 V
    & D2 [! Q7 B, `3 x; ~: x8 M: v    for (int u = 0; u < vexNum; u++)$ P2 A4 @6 o& {
        {" z1 K! O" ?+ H+ \
            p = copy.vexTable.firstarc;/ o- n# Q' F6 E9 U8 o1 P. a
            while (p != NULL)
    1 _1 Y3 [+ _$ N8 s5 R" ~; n        {2 B4 J4 t5 |0 m/ i
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    ' Z4 |: w, P0 f# @, v            p=NextArc(u,p);, ~2 c" k# l$ h# s  y0 h+ D. k
            }
    # t1 A/ N3 b. z2 F3 t    }
    $ a  Y8 o4 y9 o    return *this;$ T- b/ [7 X1 ?7 E
    }" L+ Q  Q) B1 q
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*; ?. u1 G# q( a+ Q6 l8 i- [
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const1 X+ l2 i  F, G& G
    {1 J9 c/ R; w# {; F) ~2 L
        if(p==NULL) return NULL;/ j& G3 d2 ]/ S: f+ Q( g# F' k
        if(p->adjVex1==v1)
    # P2 Z3 r) ]1 ^& G& j' U        return p->nextarc1;
    1 L. P# [; g+ `    else
    4 C) C" m) o' R7 g) ?  i        return p->nextarc2;
    - Q6 n: E- H$ ^) ]: E' J/ i  l- P}6 B' h8 e; Q0 i+ {2 ]6 J
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*2 {7 n4 b3 C* }7 j- z
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const( ^  J9 Y1 {2 w5 v; l) \. [8 Q1 ^
    {
    - ~* K# z$ {( \1 l/ [5 ?    if(p==NULL)return NULL;# ]% G& P) u1 q
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;' R5 ~) L1 z: W
        if(q==p)4 X$ p7 z- O4 u* }
            return NULL;! W' g* t& @) o1 l! S1 H7 e% v
        while(q)
    7 J1 k7 |! D. P    {( u! D2 L6 L  C
            if(q->nextarc1==p ||q->nextarc2==p)  ^( a  f% F" i
                break;
    " R, u9 j' d3 O; Z8 A- A) x: ~        q=NextArc(v1,q);
    ( Q% d6 W/ D; R3 W* H6 K    }
    / v- [  m2 k8 U5 {' H8 O    return q;5 a' Y$ @5 p% E; M
    }: `* d' }* V$ m  F* o
    template<class ElemType, class WeightType>
    % i0 S2 P( D! xvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)1 A/ K1 Q8 Z; |8 n
    {- a+ J/ N- P" n9 D! j! M! ]1 I7 K8 [
        if (vexNum == vexMaxNum)( c  y8 ?- ]3 D/ Z" h) m. \2 V
            throw Error("图的顶点数不能超过允许的最大数!");- b! T. g2 J# Q! |1 Y
        vexTable[vexNum].data = d;
    0 c: d# I6 K' [7 V: r6 f: h    vexTable[vexNum].firstarc = NULL;3 w4 K. F% i1 s( Y" `  S; \; p
        tag[vexNum] = 0;
    8 h9 K% Q4 ?- t. `6 d    vexNum++;4 S0 f( s6 o9 H: B; h' p
    }
      [" {9 N* |& t2 x+ j: ]template<class ElemType, class WeightType>, u4 X! i! B. @# C6 s# P/ [. k
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    1 L+ `- y$ f3 @9 c0 n{1 p, K5 B; f: f; I  ]& Q  t
        MultiAdjListNetworkArc<WeightType>* p,*q;0 l1 m( f' @( O8 q7 E
        if (v1 < 0 || v1 >= vexNum)
    # ?) l9 J# i; F6 H1 P/ h6 ?        throw Error("v1不合法!");
    - U/ u$ @- L7 V$ N$ k2 u8 P    if (v2 < 0 || v2 >= vexNum)9 w& L' [" {6 N0 l6 H2 W  r
            throw Error("v2不合法!");
    7 ~" `% G/ B4 q    if (v1 == v2)
    / V0 O% c- o) o7 R" g        throw Error("v1不能等于v2!");
      q2 n# c+ y5 _. C4 I- Q2 H- a9 ]. b    if (w == infinity)
    . M1 p+ M5 L: s; B* l3 V# [2 }4 X" i        throw Error("w不能为无穷大!");
    . G5 o9 b8 [3 G5 d/ {( M+ [3 ~/ A$ O) g* e9 [% g* T0 k6 ]" y  h0 R
    ) x/ W4 \: Q% g9 A* z; \
        p = vexTable[v1].firstarc;
    2 ?( L; ?4 t! ?, N. S    while(p)
    9 i+ t' p; [1 j8 \- H    {$ a* O( \6 R, U
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中  |3 _" p: Q# |! z3 s
            {4 j7 F3 `* M  i6 |6 ^4 B$ K. B
                if(p->weight!=w)
    2 [/ w+ j# w- B+ [+ ]. I5 ^                p->weight=w;
    1 v' d! Q) ~( B6 l3 o            return;& [9 h2 X- ]6 _" `) y- o
            }
    / |  M5 v" Q* i% }) x9 V/ e' s0 N' ?! V
            p=NextArc(v1,p);: d# P! Q- B" o2 R! D' u
        }9 t1 M5 n5 b2 R' f$ p
        p = vexTable[v1].firstarc;( r. R  U( n5 P+ k) l3 l9 ?
        q = vexTable[v2].firstarc;0 {- V, N( {. m7 f, V, T$ L; u8 v& p1 x
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法5 J: Y  _2 T9 C+ P! ?
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    7 u" Q) c0 N6 x    arcNum++;
    8 N* m: B4 O3 q4 w# H/ V& D}
    , p" `( `) b1 A. N& |/ Z1 ?2 l, e2 e$ }. Q! {
    template<class ElemType, class WeightType>
    & ^; p# `9 B: k& R& Yvoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)4 H3 L# ?- F+ w- i; R) a
    {
    5 q( c$ d. ~8 J
    % I/ Y* t, g, o1 B    MultiAdjListNetworkArc<WeightType>* p, * q,*r;- R5 s, |# y( G2 b  l1 F6 r
        if (v1 < 0 || v1 >= vexNum)! {  ^: e* K, g/ k# ~) o' }( k+ ~
            throw Error("v1不合法!");
    8 K/ W7 r$ Q+ T. W: v. P2 A    if (v2 < 0 || v2 >= vexNum)
    " g4 W" b/ @' P5 R2 b0 E& m; U1 U        throw Error("v2不合法!");  {' }$ `$ o8 ]9 y, I7 D7 M
        if (v1 == v2)/ S' \+ \: ^& x3 D1 h
            throw Error("v1不能等于v2!");: v! E$ b6 A, Z
    , {7 j5 _. D+ v" T. ]
        p = vexTable[v1].firstarc;9 _9 g7 [  o; x. r
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)1 y) E& x! j+ ]; K/ ]. L
        {
    6 x/ O9 Z: f, P! C+ @" v$ T+ D& A        q = p;
    3 A8 I2 P0 {. J: E+ ?        p = NextArc(v1,p);# O, H/ X5 B7 k, c% b" l
        }//找到要删除的边结点p及其前一结点q
    3 `( Z0 s6 B! O, A6 b1 k: T6 q' m( D. u: q4 Q
        if (p != NULL)//找到v1-v2的边
    0 K$ v# ^* m$ o  o    {0 g; L  R. G$ Q8 _
            r=LastArc(v2,p);
    . Z( F# m1 z) p0 R3 r4 H        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL2 c0 E; r+ D. P. s
                if(p->adjVex2==v2)1 {/ p' M" l3 }2 |) ?9 v- m
                    vexTable[v1].firstarc = p->nextarc1;
    ! b$ X, a  H; s8 m$ U. Q. s( {: |            else vexTable[v1].firstarc=p->nextarc2;! T4 c0 p* w* n$ W. U% e
            else//不是第一条边
    5 r' R; X2 T5 n6 h& t# Z$ {        {
    & h% V4 \0 A) E  F" j  o            if(q->adjVex1==v1)
    % N1 M5 t, R; G  n1 E4 `  X) }                q->nextarc1 = NextArc(v1,p);
    ' o7 r! w0 E6 _3 A" g/ ^3 Q, ~7 l5 c            else$ @) `. H8 _+ |% i& t1 K3 B' c
                    q->nextarc2=NextArc(v1,p);
    1 {0 d$ d" o! }  @/ u5 s. Y9 s. R! c+ x) F
            }
    ! ~4 S0 E3 L% Y  X1 v        if(r==NULL)# I/ k$ Y6 d2 @
                if(p->adjVex2==v2)
    8 o  E6 a/ T5 `                vexTable[v2].firstarc = p->nextarc2;# {4 _% o7 Y; W2 z/ K0 x! ?" J1 `
                else vexTable[v2].firstarc=p->nextarc1;4 ~0 U* u. {9 r+ g' R+ H
            else
    , m+ V/ Q4 S, M. V( A        {0 g/ _' R- e6 u0 ?; l# p
                if(r->adjVex2==v2)4 j! j0 z- b. R0 k1 K  k2 ?
                    r->nextarc2 = NextArc(v2,p);
    % f; A' S, W% {3 L            else1 R/ I* X5 Q( p, Q. \3 T+ J
                    r->nextarc1=NextArc(v2,p);3 C( i, o! y8 L0 D7 K
            }8 N& `+ x2 W5 e
            delete p;
    6 u7 p1 k7 c$ v2 B, I6 q        arcNum--;& M) d$ [/ D# S$ g! n& e
        }6 v9 O2 d$ a  C: @" V7 @

    . @  O1 i& a% c9 ~6 d}; w* _" [1 D& h6 d6 ?0 Y1 k
    template<class ElemType, class WeightType> void8 a6 X9 q1 a7 P( u0 [$ v4 m, r
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    , _$ X  j+ y2 G9 S( l# _& b' `3 e{
    ' M) f" p0 b# g    int v;0 j2 Q2 C6 R" D3 v5 e9 ^
        MultiAdjListNetworkArc<WeightType>* p;* D" a6 d2 P/ ]. V$ z
        for (v = 0; v < vexNum; v++)//找到d对应顶点/ W3 O% l5 K8 [+ S8 J- w
            if (vexTable[v].data == d)# t& d  l' J+ Y# K* z  n- D
                break;
    , l  ~: t1 f4 {$ [. }0 [7 N    if(v==vexNum)9 e, ]3 o" B* S4 t. [& `
            throw Error("图中不存在要删除的顶点!");: Z* U& L! f& g4 R) l! L
    ) q7 z. [8 j+ ?' ]3 P/ C# \
        for (int u = 0; u < vexNum; u++)//删除与d相连的边
    ) ]( J8 F5 P- _* A        if (u != v)
    $ ~. e( m# O8 i4 x" V  ?! h        {
    # q+ l( M" l5 s% x! M9 A            DeleteArc(u, v);' Q9 e0 B- {2 ~1 {" I) W2 ]
            }6 x% K1 f, b! U, I/ E- X1 Q
        vexTable[v].firstarc=NULL;* Y  c+ `9 X6 k6 ?3 ?

      |) d1 C4 A- H3 ~    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置& ^9 D+ H1 T1 ]7 H( u6 t
        vexTable[v].data = vexTable[vexNum].data;
    0 Q' w+ S8 Q" M! a) R    vexTable[v].firstarc = vexTable[vexNum].firstarc;1 O' y  n0 {/ z  v: V
        vexTable[vexNum].firstarc = NULL;
    . B/ [7 \) q% S$ E/ ^6 i6 \9 D% y    tag[v] = tag[vexNum];
      \) E3 W# [! ~# U; C0 l3 {9 e    //原来与最后一个顶点相连的边改为与v相连. P# c+ z  B* h) \# V
        for (int u = 0; u < vexNum; u++)
    3 d# }1 [/ O7 {& p' i    {7 b' q/ x9 q1 Q6 X
            if (u != v)9 D9 c6 t7 n! ^/ q6 C
            {
    ! ]9 `% w9 J$ @3 g; E4 y& x2 Z            p = vexTable.firstarc;
    5 R  U: n: e" b. @$ O            while (p)3 Z& i7 c" F  C* H3 y& S
                {/ y6 G; q, @. u+ |( n$ w3 f, T
                    if (p->adjVex1==vexNum)
    . j0 ~( P. ?  `9 E! \8 e) j  J                    p->adjVex1= v;! I' a; g: B) b4 R! i# @; \; ~7 z
                    else if(p->adjVex2==vexNum)
    - N$ G1 U1 l8 C7 C# `: ^                    p->adjVex2=v;
    4 Z0 {' M2 X' ~3 g                p = NextArc(u,p);2 q8 V' O3 o+ x/ F% J( j# V* z2 u
                }! s( V- c& d5 w5 Q4 T1 M2 |
            }
    # ?: f1 H: F' X2 b0 n# m    }: q! h* i' O# Y  _1 Q& y$ V
    }: T2 {7 A" R8 x0 e6 E' q0 E
    ///深度优先遍历" _7 ^8 t0 ]8 ?9 f, ~* n( [
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    7 e4 T2 y4 V0 Y{/ d, k7 M7 @- V% M/ W
        tag[v]=1;  j7 ]8 v8 `$ s& k
        cout<<setw(3)<<vexTable[v].data;
    % x1 N+ H- a" k6 W3 w- A0 Q: t4 ]    MultiAdjListNetworkArc<WeightType> *p;
    ; M+ l1 g0 u& T    p=vexTable[v].firstarc;
    7 s( G0 a1 S) N( [    while(p)
    0 K. ]* d- P4 a6 C8 q: R    {
    ( I* M  S8 i' R- l- `+ d- {        if(tag[p->adjVex1]==0)9 p& a1 m8 j7 h1 G4 c; `
                DFS1(p->adjVex1);
    $ u1 T! K- J3 C) b7 h        else if(tag[p->adjVex2]==0)
    . y* g; L6 P7 W1 z- I7 v% C( x# ~' z            DFS1(p->adjVex2);
    # C4 V2 ?/ l0 [4 {        p=NextArc(v,p);
    3 F3 S- N# J# [( `& Y( r    }
    0 P# Z* p* `, a4 w* A' E}
    * F1 |& H; w* J. O' }template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    8 \6 p! z6 ?8 D' P{8 d4 l! v! F2 i$ }, c6 E% }( j" h# X. @
        for(int i=0; i<vexNum; i++)0 E8 B. ]! T9 n# t# B4 M3 e& n
            tag=0;
    : f6 i) p2 ^, k) e* X5 f- {1 a. u    for(int v=0; v<vexNum; v++)
    2 S( F6 b8 t# F2 N- V& q. q- @# |    {- u- @5 K6 w# k( q) {  t
            if(tag[v]==0)0 D- n' D; N! x3 U- [
                DFS1(v);. n6 A. P' q+ @- D7 Y- d% c; R
        }
    ) B9 N# o) |4 |5 C7 U}
    4 @( U# g% [, Q" X+ g. ]1 f; qtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()8 @+ L' o" ~: H& a2 ?, V* m
    {0 M7 B1 G* ^4 h
        stack<int> s;
    " H, C  W! F6 O$ K" t    int tmp;1 H% a% E) z* ], `! q  @  A  ^
        MultiAdjListNetworkArc<WeightType> *p,*q;
    ' K; {8 ~( @9 h    for(int i=0; i<vexNum; i++); P2 ]1 D' K& J
            tag=0;4 ?" d: q7 H3 S) N1 y' U+ Z8 {7 L3 d
        for(int i=0; i<vexNum; i++)
    5 ^% H$ ?7 z: P, D% Y7 ]    {. S+ f; Y5 E  h4 V
            tmp=i;: F0 q9 O  {5 z! K
            while(tag[tmp]==0||!s.empty())4 \, U5 v: z! ~+ }8 A. h
            {5 Y) E  ~' |  S; ^* l+ a6 ^
                p=vexTable[tmp].firstarc;
    . s! S- f* @: _- R            while(tag[tmp]==0)
    ' h2 y$ d" B6 S7 _9 g! _. Y) C            {
    0 i; X1 Z& B% O. k                s.push(tmp);
    , H' \& a; p: H; b6 w                cout<<setw(3)<<vexTable[tmp].data;  ?' c; |6 l6 u. }$ s; S7 x6 L, a
                    tag[tmp]=1;# r, G$ _3 m; v5 e) D# V5 C7 C
                    p=vexTable[tmp].firstarc;9 M6 n% _' }" j8 m7 L
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for. e* m  q* D6 C% y
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);$ D- k  E  f7 f. J
                    //cout<<" 1st     tmp="<<tmp<<endl;1 j( z$ z+ Q, R! |" \0 W) s$ k
                }3 ]3 B( L; t3 ?; Z
                if(!s.empty())
      P0 j4 I& e9 A4 ]            {
    4 Q5 c) d  c6 W                tmp=s.top();
    $ Q- l: C' |& q. }                s.pop();
    2 f7 E4 S( x* r9 e) x8 U                q=vexTable[tmp].firstarc;
    / @3 h; A; o# [8 P                int t=tmp;% \) D; U' c/ Z: q. G
                    while(q&&tag[tmp]!=0)
      p4 @0 _. b, J  j                {
    1 z+ r4 K! W. d9 Q5 ?9 a: f                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);6 ^; ^; M* q; R9 [4 J' O
                        //cout<<" 2nd     tmp="<<tmp<<endl;
    + s( a& M# b3 _# o& G  A                    q=NextArc(t,q);. C! a. r" N* _, D3 I5 F% w
                    }# i0 ~  y" C  W! K& I# ^
                    if(tag[tmp]==0)6 n+ D% x* @+ E/ |7 O
                        s.push(t);" u, K; g4 A$ W% |2 N
                    ///1、对应上面连通分支只有1个点的情况5 I% Y0 l3 a% h- u
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    : f5 e& @+ v2 ^' e8 o                ///tmp要么等于找到的第一个未访问节点,
    ( ^2 E. S% |9 @7 t! b9 f  z/ [                ///要么等于与t相连最后一个点(已被访问过)
    % t* p3 f3 ]$ d                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点4 Z$ h7 J) E' s+ l- A" g
                }# m' V( c" O$ B+ l- Z
            }
    " S% r/ J! N( w$ ?4 z; w4 @" S% {4 [    }
    7 c  p% t" L6 t$ Z  @( s! \9 t}
    - h- L! H, R4 j7 I: a//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    ) M8 ?7 l+ o8 G& A: Atemplate<class ElemType, class WeightType> int
    , Q# W3 Q; p* p2 r( g/ ~  j# b- CMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    ! x2 y7 e$ \* k4 B6 y# n{  v7 B5 y$ ]3 O  Q
        if(head==pre)3 f* j. j# U  e. d1 a/ a# x8 _8 c# s* H
            return -1;2 B0 b7 O/ B5 X
    8 L" u- A# `$ D; _0 z7 P4 r
        MultiAdjListNetworkArc<WeightType> *p;( B4 l! B& A, e- f$ O
        p=vexTable[head].firstarc;- c/ o& D1 M7 p' V/ G* k
        if(pre==-1&&p!=NULL)
    7 |9 K. ^! m: J* Q        return p->adjVex1==head?p->adjVex2:p->adjVex1;) z* h) G+ T6 |
        //pre!=-1&&p!=NULL
    3 L' c- v) @! B/ K( A- D    while(p!=NULL)
    / M  o9 S  x0 ?% D' Q' r$ V0 ^    {" v% @; l' x! p
            if(p->adjVex1==head && p->adjVex2!=pre)8 O3 Y* k+ c) m
                p=p->nextarc1;' S6 x) e0 W1 [% i0 F
            else if(p->adjVex2==head && p->adjVex1!=pre)
    - S8 u: w9 X9 {; A. B5 D            p=p->nextarc2;# a) ~8 }/ g9 f2 e( G4 Z2 B; [
            else if(p->adjVex1==head && p->adjVex2==pre). O$ @5 N: Y: e7 s  \: `/ Y1 D
            {
    5 g: O8 B+ g* Q8 K! m$ b0 T            p=p->nextarc1;- }3 H! i4 K9 i, W0 x3 G+ F: h0 J; i
                break;+ H6 J$ Y# i4 t$ o. v
            }
    4 X/ C5 r7 Q8 v        else if(p->adjVex2==head && p->adjVex1==pre)1 A+ s/ v" u5 ~* x
            {
    : o1 C# j* j5 [- e            p=p->nextarc2;
    8 f4 r1 |+ u$ R% n3 e; D% d            break;8 K( H1 f# P; M2 \8 |
            }4 o0 l- K& k" @9 x1 l) I7 I
        }
    ) b* `3 M1 t  O; Y+ }& {% M) t  Z    if(p!=NULL)
    * Q9 r2 {. d! t: p7 b" c+ O    {6 e" K+ Z3 _. c! [
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    , h1 C% {$ X# T) R% j! ~. U6 z    }/ |8 B9 X6 q4 K, r: r- `( M
        else
    $ l3 q4 S9 {/ P5 k        return -1;8 j! N/ A$ m# e' g. y
    }4 \7 a7 i2 T5 p' w+ ~. t# l# q
    6 ]+ s# N9 }& J2 o! ?

    * ^0 Q$ `8 s3 htemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()$ q+ w8 ^; G6 ?& A
    {
    1 Y) }$ U# U0 Q2 K& E# ^8 T7 b; m) g5 T) G    stack<int> s;
    2 q" s7 g( m- @/ F8 S( h7 M' u- ^    int p,cur,pre;
    & F. |8 q# C$ B5 q& c0 s2 j    //MultiAdjListNetworkArc<WeightType> *p,*q;
    : L# V# f: k& q. @    for(int i=0; i<vexNum; i++) tag=0;//初始化
    " L! @2 m# ?& X9 W; w) [0 {
    ! n8 q3 k' W) R$ P# t" K7 \    for(int i=0; i<vexNum; i++)6 x4 k! d) t" M: P$ Z6 [
        {# p; H# k; R" ], k, o
            cur=i;pre=-1;
    . i2 a* O# G  g# H1 e; e        while(tag[cur]==0||!s.empty())* D( K6 I9 R; D. [4 [! ]4 @) {5 B. m
            {
    - l0 v" p* L! b- |: e( l            while(tag[cur]==0)
    5 I* |2 A) H& M- m& M            {. c) l! N* x: N, O& q- L: G9 }0 A
                    cout<<vexTable[cur].data<<"  ";7 R3 |6 X% a! w. F$ w/ `: d  x0 q
                    s.push(cur);
    7 ?5 @; g; l9 ?                tag[cur]=1;
    & ]; ^( M! G8 {- i               //初次访问,标记入栈
    . ]) Y  c7 }/ M2 G0 k5 r+ I# R0 r
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点$ J+ q) o: e8 a7 e' t2 [1 D
                   if(p==-1)
    & Z$ M- C. L1 o$ I- j: X               {. ]/ z+ T  R8 a. T$ F0 u
                       pre=cur;s.pop();
    ; j5 Y6 O: g# d, N8 G0 I5 S' |                   break;& K! l9 h! r  ~" T5 ^6 b
                   }$ [0 [" o3 T* z/ c% Y
                   else
    4 `, E# `3 W8 L9 v8 q- a               {& X( e+ x& X# K% C4 R
                       pre=cur;0 w0 W( ?2 F% D. X
                       cur=p;
    . g, ]  D9 D% w               }
    ; c% v4 i' ~1 o( q( F
    % R5 ?) }. E$ B            }7 x3 G, G2 N- ]. s' e, m
                while(!s.empty())
    3 T' B  Q# d% P2 ^, s2 e            {
    % R8 [. c$ a9 H% u5 u% [                cur=s.top();0 C. s) l' H( R# D5 T7 }
                    p=GetAdjVex(cur,pre);
    . v& x& Q2 ~0 Q: [                if(tag[p]==0)+ i( P  C  Z" b2 |' I: \  C+ u+ S5 K
                    {
    3 W) t% Q7 E" m$ w                    pre=cur;& E" Y2 p+ z9 n0 Q1 C
                        cur=p;' L' h+ F2 p$ q4 [3 h* ?8 J
                        break;- j8 F# \: d' z4 w) d$ {6 e
                    }0 p9 \% R7 j# J3 G
                    else
    5 v4 O4 S+ L- J; l; k  ?                {) `' J% @: Z1 h6 A, A7 n/ _
                        pre=s.top();
    , N6 L# _& `1 F5 ~, B3 U+ B                    s.pop();" z7 [( h' B  N, ]- I0 D9 i
                    }* g4 W( X3 W/ ~

    1 W  I6 o9 W+ ]3 t            }! E% z1 N7 q/ A$ Q9 ^
    3 a5 ^& `5 B% {
            }7 p* R8 }: n/ o$ p' h5 {& T: `9 t
        }
    + x. `& P* \: V8 W; K! q/ G! T}
    8 Q7 _( ?( y" q3 Z. t1 w0 atemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    * ]0 W( T8 h8 t{
    4 P$ z# ]$ Y$ \6 }( v/ Q% ^# x1 P    for(int i=0; i<vexNum; i++)
    - a/ ]9 N; d' |        tag=0;
    5 @& M6 ?3 b# l$ z3 {' T" `    queue<int> q;  [2 u7 k+ X' R4 |4 H7 i4 k
        int tmp,t;
    & k9 }" D  M/ ~/ F, H6 X1 I    MultiAdjListNetworkArc<WeightType> *p;' e6 Q% d, z3 W5 v* E
        for(int i=0; i<vexNum; i++)
    ; a4 B' Y% w) g% a' x2 O- ~* g& X    {
    # n0 G" T; Z7 \7 `8 q! R' M        if(tag==0)& g! i+ W! H; O  J- V
            {5 f) R8 U( v% H! `# J% J; A( ^/ `
                tag=1;( O& D9 \4 C( I: V3 S
                q.push(i);
    - q" s( V; h1 T8 y5 S0 {. I            cout<<setw(3)<<vexTable.data;. ?: s: f, {: V$ }  Z6 s
            }/ J4 X8 r( c$ u: J+ c
            while(!q.empty())
    + Y, G+ x/ n# r- k" W$ ~        {. S! F1 ]0 ^  f1 }" Q& z
                tmp=q.front();
    ( w1 G" \' y% |1 L# a5 }            q.pop();2 }9 g9 Z) h1 g4 s- t- P/ A% x  g
                p=vexTable[tmp].firstarc;- b$ F9 V/ @/ a( x) U
                while(p!=NULL). t0 W- s, Z4 F
                {
    - [8 T. N5 U/ s; z; d                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    7 `3 v* i) m  J. A+ O7 w' W# a                if(tag[t]==0)
    8 ^) H9 \% W' H6 Q( _% v6 q( y  H                {
    & ^# Y) f) z0 U+ i5 Z3 e                    cout<<setw(3)<<vexTable[t].data;
      b: w* {3 X" k/ V0 {8 E+ h& ?! O                    tag[t]=1;6 z) W" j) g) T0 B1 N7 D) i  l6 w
                        q.push(t);
    ' l, `0 n  z% E: @2 Q1 m                }
    8 [  k- a) @1 r" W! f. v. C! @                p=NextArc(tmp,p);! z9 t8 m' |+ T' z1 g8 N) C5 L
                }
    ) N* ^' p7 o0 _% B, k        }! a8 g: L9 v4 [' N* m' |
        }  d0 g1 v, z, X2 ]
    }* J& F4 b9 ]; ~1 L1 L1 v
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    7 ~  S* f: m2 i# F. e  ?* b4 O{' g% b2 w% `- m8 z
        MultiAdjListNetworkArc<WeightType> *p;! L- K5 x/ E& c  h. c4 O# Q$ L
        cout << "无向图有" << vexNum << "个点,分别为:";
    ' P. ]1 T% A' C% p+ M5 P    for (int i = 0; i < vexNum; i++)7 n$ C1 J. h1 R- Z; S% p* X
            cout << vexTable.data << " ";2 I: Z' v% W: f3 E3 V. N- j- O
        cout << endl;
    : O0 f" F4 p; K# M    cout << "无向图有" << arcNum << "条边"<<endl;0 L: u: ]% D1 j
        for (int i = 0; i < vexNum; i++)0 M0 I; @  n) J1 V8 y  c
        {
    # h7 ^/ B8 h* |0 U        cout<<"和" << vexTable.data << "有关的边:";
    / \% o4 D0 w* Z* K3 Y  d        p = vexTable.firstarc;
    + h9 d0 v! }5 S        while (p != NULL)7 C$ ~  h0 Q, k' ~9 z) a# F
            {
    4 \9 x& A2 n0 y            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    ; ~; v) S5 x; R3 Q) h; @; ]            p=NextArc(i,p);( }; V& V/ ?# P" \6 a1 g
            }
    : j- z- h% o# j. V) k& n  B7 i        cout << endl;$ |0 d, x& ?: ?% [  L, M
        }' }+ v% r) P3 R5 X- Z; c
    }  {/ d$ O$ s: o$ l' Y# s

    $ Y. r5 r- p  @# B5 [0 l- h% W% n' d0 A2 d/ ?( A8 F
    邻接多重表与邻接表的对比1 o8 Z1 K: L4 h6 d# X) E+ u& A

    / w" M* f9 g+ v, w2 f$ k邻接表链接
    / Z2 \6 o, [* N9 O" V# I' F在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。% H  e2 C( z( f; o' i
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    . V: a/ @! v. K/ z2 ?7 F为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。0 ?7 ^( K1 _  w( J" ?8 D4 ?: ~( g) F8 `
    ————————————————
    8 A/ b& p6 w) g6 m* C$ \版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。! P* _& C3 w: A* l# ?" D# F7 h
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    ! C" k$ n$ t! T+ X1 J& p( I: U1 t3 R7 I! Y- |
    % D8 }& |; H( S0 o( A
    $ _% H3 W+ r- Y

    " F( F5 [1 ^' ~1 l: W9 J————————————————
    + Q/ @1 `+ \: u# i" s6 x* a4 ^% K$ a$ \版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。6 Q( l: t8 \- u* J7 y
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    * o" D2 @% Y1 Q- z  x1 [7 z) a
    ( ?5 o5 F1 `7 }( U9 w9 e- L  J* `4 m3 T5 d' `0 V- G$ ]1 {4 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, 2026-9-10 13:02 , Processed in 0.321641 second(s), 54 queries .

    回顶部