QQ登录

只需要一步,快速开始

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

    7 v. f; a' O/ r- c; V图的存储结构——邻接多重表(多重邻接表)的实现
    ( F; c5 {0 ~" N' F! b' v7.2 图的存储结构- O( M, D7 z2 s1 {( s0 r- y

    ) X- ?' k7 k+ Y6 c7 v% t7.2.3 邻接多重表(多重邻接表)Adjacency Multilist  Z& x, i9 x8 k" w8 @: W" h/ n( ]
    邻接多重表的类定义
    5 K4 C8 c# ^. @" I' N邻接多重表的顶点结点类模板
    ; q6 ]$ i6 D9 L邻接多重表的边结点类模板
    : b$ E; F' S+ ~9 Q0 e6 g邻接多重表的类模板7 `8 I/ i0 X/ O6 r: L" @
    邻接多重表与邻接表的对比% F$ _/ G' d; ^5 M% m
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist" b8 u# \+ R# m* d1 f" b* O$ {

    7 w5 t! ?- A# ?3 U; N5 v在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。) [; _8 k* J$ N" W# G! h, q. [
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    * f, A- X" {& J, \6 N$ q" U
    6 V. a$ M5 {. I6 {邻接多重表的类定义6 z, w2 K9 t: |9 M7 d, v6 X: y
    1.png
    1 T8 h! |+ U' S/ R: Z邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:' Q9 P: c5 p& q& O& q' R
    data域存储有关顶点的信息;6 t& T, i3 j+ w) S
    firstarc域是链接指针,指向第一条依附于该顶点的边。7 N' y: ~8 w$ ], d4 D: E
    所有的顶点结点组成一个顺序表。


    3 k3 ^' i0 W5 f& Q! A; x1 j& f; Y' \% r% |: L1 r$ d
    template <class ElemType ,class WeightType>
    3 x; @( Z; c* `/ Q+ }class MultiAdjListNetworkVex
    . Z& \$ P/ z& y% O5 u3 L{+ R  u0 q; i: t4 F
    public:5 t5 O7 q% v' d8 p0 I& r5 R/ C) Y. P$ g
            ElemType data;
    8 Y7 n. d/ k1 ~9 `7 C/ U' U        MultiAdjListNetworkArc<WeightType> *firstarc;& T0 O1 C; Q) [; E' c
    8 f  s  ?. b9 U6 l
            MultiAdjListNetworkVex()0 B$ D8 @/ |. [, v- i
            {/ Y7 g( ~5 |# U" R( F
                    firstarc = NULL;
    ' J1 H: b, n# t2 j        }# W- O  W1 S. [( C# `; F
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    / v( F7 P+ W& X5 Q$ X7 k: U        {
    ! X1 l4 h, \# M1 e5 E                data = val;5 H5 o0 r. u- H, E7 r$ |
                    firstarc = adj;
    1 q5 Y, D; q$ M, S5 s        }
    $ N7 E5 J  `" E};
    " D5 a" i* M* @
    * u/ \6 E8 p0 j# n( Y& ~/ f4 q2 ^邻接多重表的边结点类模板
    ( d" I2 l9 h+ B! g% W( f3 j9 f# z) E9 H: ^( z$ H: Q3 y
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    * s* @$ a6 U8 Q( O! Ntag是标记域,标记该边是否被处理或被搜索过;, k5 J' p/ u0 Y+ J: `' L
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    8 }. c- u+ A( Enextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    1 m1 p1 f* d9 @1 K' l! ]9 ~+ j* unextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    + B* i3 f# g6 T$ D* F) |7 {* D1 I
    3 d5 Z4 D! Y6 Q+ x% C9 V* L 2.png - n# s3 J. n2 v$ P! V' J" i$ w
    template <class WeightType>
    - N7 f' L* ?7 B5 r5 ]class MultiAdjListNetworkArc0 c" u3 F! W- L% a
    {5 m  Z/ {( I) l9 H1 W. }: y" \
    public:
    1 x  [& D$ d" M9 G9 C; }/ |    int mark;                                       //标记该边是否被搜索或处理过
    * d' m" ~7 o$ Z# F2 d        WeightType weight;                              //边的权重& B3 T+ Y# s2 v0 }4 _- K1 v' l
            int adjVex1;                                    //边的一个顶点% X2 i" T1 M) I  Y
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    " k* {4 h! o. F1 O1 a0 ^        int adjVex2;
    3 @$ g4 [" [% R5 o+ H/ f        MultiAdjListNetworkArc<WeightType>* nextarc2;
    $ c& a& d& A4 V1 e7 f
    9 M1 B) h$ e' B        MultiAdjListNetworkArc()
    . n. w' o. p( D, h; P4 V        {
    0 H3 d4 h  u2 {5 J0 Z                adjVex1= -1;% [, l5 j5 \" q$ H# k
                    adjVex2= -1;
    0 f) S' Y* r4 o: z  ?" x        }% x3 @1 X2 B: t" d( n
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)' \% E! L7 g4 {. G. _3 e/ u
            {3 d6 F( K8 Q0 E6 K" e
                    adjVex1 = v1;       adjVex2 = v2;9 O+ b1 u5 Q2 i/ X3 F+ a7 v
                    weight = w;
    5 X! N* U% C6 ~) S4 z                nextarc1 = next1;   nextarc2=next2;; T% y. f7 X5 q9 P( z5 T6 j" e
                    mark = 0;           //0表示未被搜索,1表示被搜索过0 L4 L) J4 i/ Y$ l7 w
            }4 d$ o" M$ g4 S
    . C- b& X0 X6 |2 N: w; T
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    " ?! U  x* d% Z; v: T1 Tclass MultiAdjListNetwork  [$ f1 I" S! J7 N% ?' W2 q
    {7 Y$ q$ }0 E7 L, M0 o
    protected:: V, O* u/ w6 o2 Z" t
        int vexNum, vexMaxNum, arcNum;
    5 }& [. a3 v* X# h    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;% P* m1 K4 g# a
        int* tag;4 f4 H5 g6 ~( t# ^6 p* e8 q# x
        WeightType infinity;/ z2 w) n2 R! |$ L4 ~8 u/ n

    / |3 B/ @' N8 b" i5 K1 c! e( K5 L5 npublic:
    6 w2 T6 s- @; k+ L# U    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    3 \$ p" _; i4 n4 o+ B3 F0 E1 l, {& X% }' V  i$ L) M
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    " l' B5 H" R8 G. q/ V9 }) G
    * I. x% q( ^, w. B    void Clear();9 c: p9 L0 F( d) ~4 \
        bool IsEmpty()
    * n( u/ [( p6 K% i) w7 `    {! g7 a5 A% K  u
            return vexNum == 0;
    " k/ }" Z9 b. ], B8 Z) V5 \    }
    * j) Z$ z# e, L& s8 o    int GetArcNum()const
    . e6 i+ c. p0 P2 P    {9 X6 m' |! l) D+ \
            return arcNum;
    6 d4 D+ C( r# h# b0 ~& X+ o! Z    }5 E; q; O3 t3 o! d  @- J0 i
        int GetvexNum()const
    0 b" R4 J; n8 m/ ^. r3 z" S3 R3 ^    {
    $ f9 r, f8 x% ?* {4 a" l        return vexNum;
    ) G5 ?+ a: @; m3 L$ ]    }- x+ }# _5 R! r& @' ?# Y

    $ z4 p* P' Y# ]5 h3 ]7 f
    % ]8 F2 b7 m. S6 O) ^2 G  q    int FirstAdjVex(int v)const;
    $ u0 j7 I6 J' c    int NextAdjVex(int v1, int v2)const;0 F7 y- Y6 V: ?9 j( D3 L* L( Q& g
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    ( A" J% D- M2 a$ O; D0 a6 ]2 F2 Z/ D    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    * o' W; I/ v' m" p. T! Y% e4 D
    ; u9 `$ T% h- {) x+ t! m    void InsertVex(const ElemType& d);
    1 x- \% r: k! Z2 b' A& y; P/ V    void InsertArc(int v1, int v2, WeightType w);. H: u, W$ T" Z7 D6 p9 d

    . U2 g$ A* V9 H( D1 y% M    void DeleteVex(const ElemType& d);  K; r% H* \; q3 g0 U
        void DeleteArc(int v1, int v2);9 a* J' |' l/ H* I; W! c) @/ T
    5 _5 c' S% u4 T' J% }* P
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);% o( k& z- s+ z9 H4 i% B# E
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    2 l* {' {" q2 s- P- j: H% ]4 W2 U4 H0 r" l7 i8 X( @
        ///深度优先遍历: M9 g3 X5 |% s* v' \+ O
        void DFS1(const int v);
    / V0 c# q# R! ]7 b& w0 u    void DFS1Traverse();
    & P5 i  a6 a# @9 t( v    void DFS2();
      q8 y0 _) }* b& l  I9 S' F5 j  x; H5 x! l
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    1 j  ~' ]( t* q6 o    void DFS3();
    - ]! N5 J/ ^/ X- k  ^" Q7 l8 O, D8 m: W4 V8 [/ i# E
        void BFS();! A( b  w, N" D+ r
        void Show();/ p5 C1 h8 P! Y" U
    };* G( |7 [' W- a8 S" ]
    6 b& X- ]9 Z' n6 {8 l  C
    2.函数的实现5 N( c/ h4 H5 r( h( D
    研讨题,能够运行,但是代码不一定是最优的。+ F- `  u. e2 C4 C2 A! I* ^

    1 T" c! q6 Q( T  \+ W" N#include <stack>
    0 K" Y. c1 M+ K+ w, Z#include <queue>) r- u3 p) }" X, E$ i

    8 o! I' d- W$ i: Z% `3 Ftemplate <class ElemType,class WeightType>
    / S. Z7 k. p0 Q, N4 v; _: i9 e# V  jMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)! W) x' r% y+ z, ?3 I
    {+ F. N  k9 r! d
        if(vertexMaxNum < 0)
      I( W+ s2 g) k  _6 O" V        throw Error("允许的顶点最大数目不能为负!");
    ( l4 ~& e" g; H% l: C5 H5 z) W* R    if (vertexMaxNum < vertexNum)3 C( W& @- S. l0 O
            throw Error("顶点数目不能大于允许的顶点最大数目!");
    ' i  y2 O0 V4 ]    vexNum = vertexNum;
    - {4 `! ~& Y1 n4 R: U9 T    vexMaxNum = vertexMaxNum;, {4 Y+ l, J4 n8 n
        arcNum = 0;( r& u$ M# ~) S) J1 I
        infinity = infinit;
    , F1 O& Q' }4 N    tag = new int[vexMaxNum];6 s* T( x; ]: m- M
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];! L3 z# ~6 U6 ?/ p/ l7 k, A
        for (int v = 0; v < vexNum; v++)) |9 i# U  K  ]1 G
        {6 n& u& Q# t" E2 t& j
            tag[v] = 0;# y8 t! `- p$ P( A& N& [) G
            vexTable[v].data = es[v];
    3 G9 Z  z. u$ Z2 t. O& e        vexTable[v].firstarc = NULL;
    - q1 s1 k6 h. \5 ]* _  F6 E$ X: {' X    }
    & i) ~2 Z9 M' V}
    % E6 a+ e0 \. z' Atemplate <class ElemType,class WeightType>
    ; I+ F" J$ i5 a/ R6 d8 n3 jMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)' }1 W/ |5 g" z! i5 R$ ~2 y
    {9 l4 Q- ~, h) y$ Q
        if (vertexMaxNum < 0)
    4 P7 }) Q9 I- }# S5 D  |        throw Error("允许的顶点最大数目不能为负!");
    9 A& Z7 E3 J4 E$ r5 O( G1 L    vexNum = 0;+ b+ B% G) f& [1 X
        vexMaxNum = vertexMaxNum;# ~) P. E6 U% [
        arcNum = 0;
    3 E5 A7 R. `7 W6 q* M* S' E    infinity = infinit;: O  Y$ g- I+ c9 p  u
        tag = new int[vexMaxNum];
    4 r0 R  g+ t' @  |6 w    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    % G, C% s* \0 q4 E  y}
    - w: \  u  u5 t% Z" U/ xtemplate<class ElemType, class WeightType>& o4 A. k/ @- `) y1 i
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const9 U  W! f! _& s! z* N
    {' n* S& I* O6 |$ t3 l  q: b6 e( O
        if (v < 0 || v >= vexNum)' ^4 {/ b. w  T' \7 s. n: \4 @
            throw Error("v不合法!");; k  @7 Q5 h! j+ {5 B& Q
        if (vexTable[v].firstarc == NULL)
    / H$ |9 j  q5 g5 U+ ]        return -1;
    ) F/ d1 y% k% q& I* M    else
    3 A+ }5 }' c2 w' D3 N9 X        return vexTable[v].firstarc->adjVex1;
    0 k8 j% v5 A2 }8 G0 G2 S}8 Z% @! @4 T& x: C' M

    9 ], ~0 ]' ^+ N2 Y3 Q9 x. Ntemplate<class ElemType, class WeightType>2 [2 W, g5 k  @1 `
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    1 G$ y$ I* F% h3 R5 b{) o1 v% J* @9 X* {
        MultiAdjListNetworkArc<WeightType>* p;' F$ k' f/ Q% Q8 ?7 w: l
        if (v1 < 0 || v1 >= vexNum)
    + v1 ]4 U3 r7 U0 {        throw Error("v1不合法!");
    . T1 y( f0 B9 O    if (v2 < 0 || v2 >= vexNum)
    3 t( ?% J: B% I! j! A        throw Error("v2不合法!");
    ; c% V9 _. z7 l6 W5 p    if (v1 == v2)6 t/ G& S  B  K" n% {" y( o9 r/ _9 E
            throw Error("v1不能等于v2!");* F4 u- @/ h% g- D! X+ G
        p = vexTable[v1].firstarc;
    7 u5 `7 R2 J" v$ S  p+ G    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    2 s$ p& q: O% x- {5 C        p = p->nextarc;
    - z9 V. ?% {, o" b    if (p == NULL || p->nextarc == NULL)$ R% h9 @( J. d, H' A; ?: p
            return -1;  //不存在下一个邻接点! Q9 @4 V1 W( f) a2 N5 T4 Q
        else if(p->adjVex1==v2)
    ! E# j: d9 z* T4 V8 F1 i        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    # J, g/ h9 F4 v$ a    else
    9 a0 d+ S1 F. P/ l6 s" ?0 j        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);  |  J- X6 p' q4 J3 K+ W: \5 }2 Z
    }! r8 R# H, d8 h" F; Z2 J
    template<class ElemType, class WeightType>
    ; i0 I5 f  \" ?, Z0 _. zvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()
    " N# F' i2 C+ c: f! P+ p- J( R{2 [; F; {' s5 c. p- ]* k4 z
        if (IsEmpty()) return;9 [$ u- ?7 Q; W. w9 x
        int n = vexNum;
    $ k2 d' d  y7 m& e1 h    for (int u = 0; u < n ; u++)
    0 ?3 H' J+ ~. K- A3 G/ P; p, U. u8 ~        DeleteVex(vexTable[0].data);6 X, C1 w) h* b, [4 `
        return;9 ?/ v( q3 f- X( W- p- E3 v* J
    }
    ) G( U8 h2 W0 E! atemplate<class ElemType, class WeightType>
    3 A7 L+ D. d  p, W+ J7 S2 u5 ~MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork(): [1 c0 f) b9 Q! v7 \: L
    {
    " b- A' Y0 f" I9 F, F    Clear();
    * F9 r/ f, @& M8 N5 ~. h/ q}
    7 `- u7 ?& e5 m2 r& G* Q3 ~template<class ElemType, class WeightType>
    0 ~! m/ F4 m+ s) T. Z. Y. z% gMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    9 Z. v0 Y1 O& i+ m  \{& @7 K1 U5 _  D' Q9 p5 G  Z
        vexMaxNum = copy.vexMaxNum;# a7 i0 C4 u- ?7 _4 B2 I3 y- n
        vexNum = copy.vexNum;5 I. c* t" I2 N$ n; H/ Y
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    % I# V) j' C% {8 K9 K- ]3 Y- U    arcNum = 0;
    , l  Q7 {* w& l$ l8 `$ |% ?# b    infinity = copy.infinity;* t) f* r/ t) C5 \: M0 ?. K
        tag = new int[vexMaxNum];
    " u: A8 y0 l$ u, p8 K" p6 }' M
    : _* F* U  I5 V9 {' T  O5 e    for (int v = 0; v < vexNum; v++)7 O; J0 b8 I/ t( H
        {
    ; \, d/ n! m* r8 F8 x        tag[v] = 0;( R4 s  V5 q* v' _, b( k6 y4 u
            vexTable[v].data = copy.vexTable[v].data;
    $ N* d$ }2 {& C! T        vexTable[v].firstarc = NULL;- M4 B: d7 p2 M* O
        }
    5 g) S3 |5 A" ^- P* _% j    MultiAdjListNetworkArc<WeightType>* p;
    2 v$ x0 K! n3 l# q+ T# ]
    3 Z/ w2 G0 `8 f+ A+ S9 ?    for (int u = 0; u < vexNum; u++)! w. t1 i: D4 D+ ]+ k
        {
    # ^3 Q  _0 h0 @4 y        p = copy.vexTable.firstarc;" ?& q4 C; i' D
            while (p != NULL)" @2 v" g, V) D/ G- ~
            {1 |% f8 ~2 }7 H! w% g
                InsertArc(p->adjVex1, p->adjVex2, p->weight);4 n  _/ d$ _6 _, j6 X/ C: W3 t
                p=NextArc(u,p);
    & T' ?  I0 L% l6 }" L        }
    + t2 y( O, r' G+ J1 W% h    }6 P( \! b8 [. J6 l2 P; M3 b: h
    }3 K9 ^/ V1 N& G/ b" V: X
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&0 ~# n+ y8 o7 n* G
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)4 ]$ a& V; o8 I- _' D; J& Q
    {* h; n" h1 S- N1 h2 |4 ]
        if (this == &copy) return *this;% J- C3 V" G8 T8 S  s
        Clear();6 k1 `6 R; i& z
        vexMaxNum = copy.vexMaxNum;
    ( D/ a* b$ g3 s+ {; x    vexNum = copy.vexNum;& G. b" I! \% K. E3 F0 i7 J
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];0 j& @0 P* k- r3 W
        arcNum = 0;4 x, e. K: x' }3 }+ @2 _/ {
        infinity = copy.infinity;
    % c7 l( X6 z- x  _& P    tag = new int[vexMaxNum];6 @# j; n+ i4 G( ^
    + l% c. E5 d5 j
        for (int v = 0; v < vexNum; v++)* f0 n! R  e* H: v, p
        {
    ! c# v  i; P+ @        tag[v] = 0;/ f4 a0 q# V& b% a& R% |
            vexTable[v].data = copy.vexTable[v].data;+ Y/ e$ J% n5 M. x: Q: B  P& A) `/ b
            vexTable[v].firstarc = NULL;
    $ D. j1 ~* L* _; Q. f4 X& y    }2 ]4 X% {& Z) |  w. J4 u: {4 w; `7 R
        MultiAdjListNetworkArc<WeightType>* p;4 \* w0 N7 `# j; a) A% M& B$ h

    ! S- ?; O1 b  B. ~2 h( ^+ t$ K    for (int u = 0; u < vexNum; u++)
    7 o" }, P& i: o! h4 c. S  ]$ i    {
    % T4 b( a+ [6 M, ~& f* c        p = copy.vexTable.firstarc;
    / t& r" x! T1 q1 u2 g        while (p != NULL): @. p' J/ G6 c/ O0 J4 U
            {6 l$ G) E1 @' X; o; E3 f1 s" Z9 U
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    ) H. V# b1 u* U$ {/ Q/ V- ^9 t            p=NextArc(u,p);
    3 g7 y- F6 P! y) Q4 d1 w9 G        }
    8 y" t4 F  Q' j4 ]    }7 ?$ I9 ^# P5 P( ~0 d
        return *this;: P1 D( e' j4 }9 t+ @" A
    }5 @4 y' A, Y( a
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*. H  M) i  R% b0 H# Q5 i2 `& m
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const) T7 o9 P  o# w" R) F
    {" Z! K% S- G, [2 m
        if(p==NULL) return NULL;) N- h1 v5 g2 d6 _$ S4 m
        if(p->adjVex1==v1)
    1 G: M$ {' W' a7 o) A. \        return p->nextarc1;
    ' x1 o: l& P5 d8 b/ n8 w: [0 s    else0 W: u2 C. m, J5 y; p, _
            return p->nextarc2;
    ! u5 R- E, Z* |) @/ [) I}5 V: P% \0 ?) e
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    5 I2 d( I7 d3 I- j% h* eMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    8 w, k1 C& Y$ O% r% {) `; R{2 b' ?" x# C* y$ f
        if(p==NULL)return NULL;# v0 L- s+ R& P( N7 R( Y
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    & X% l: g3 A  S7 |+ v$ W    if(q==p)# `+ L1 {! t1 p# h3 p+ |
            return NULL;
    1 o( ?: M: a- S! t! R0 p    while(q)
    3 @* e* B6 x1 A8 N    {2 o4 s* s6 l! _8 O9 T
            if(q->nextarc1==p ||q->nextarc2==p)
    1 S* C0 U) ^/ U1 l& Q            break;) C1 R# D4 L) p; O0 I0 R) p
            q=NextArc(v1,q);9 U7 ~& Q& D# b8 _4 S4 Q$ K+ H$ F& ~
        }
    : p- V8 i) \$ g' V8 X# Y    return q;+ c5 e# _- S. ~4 s$ M5 _, [
    }8 m& _) p) n1 r; E% [  D1 o
    template<class ElemType, class WeightType>
    7 n0 M5 `# k  P6 T9 L4 {void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)9 G& F1 g' r5 I) b
    {
    + N' A0 U( `) O    if (vexNum == vexMaxNum)) _& h; c, m3 A8 c
            throw Error("图的顶点数不能超过允许的最大数!");* G% K/ k* |: f) a; y: L+ O# ]5 A+ i
        vexTable[vexNum].data = d;9 S* }: y" o# u) v
        vexTable[vexNum].firstarc = NULL;
    ! \. K) P, b: N. H    tag[vexNum] = 0;; e- ^# a4 H; M# m, w8 w4 y7 z
        vexNum++;
    5 [2 C, G; o  N4 z. k/ V4 H4 i, K3 T}3 ]/ @& W: p% R5 q- N
    template<class ElemType, class WeightType>( ^7 e" p! M0 J/ r0 {* Z" @- m- W% C4 l
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)  ~: k% T2 J9 s$ x# x
    {. x6 ~" O. @2 E! G$ q2 @0 N. h
        MultiAdjListNetworkArc<WeightType>* p,*q;
    ) N+ L/ I8 m7 \- Z5 R& q8 [& f# J) P/ T    if (v1 < 0 || v1 >= vexNum)
    2 h; S; ]2 d, o. W        throw Error("v1不合法!");
    9 b: t6 J/ a; T4 q1 \    if (v2 < 0 || v2 >= vexNum)5 T* v" z4 n! t- m1 a! x* \% \" H4 v
            throw Error("v2不合法!");! l1 I0 K5 N1 T
        if (v1 == v2); w% b% L( F) d& X. o0 b1 I
            throw Error("v1不能等于v2!");
    , q4 w- h7 A8 |) a2 z    if (w == infinity)
    & n1 C# B* `$ p! l% j' U( N# Y5 E/ ?        throw Error("w不能为无穷大!");( M! ^3 X' e8 Z, S9 v
      M5 ^6 h8 V' n* T2 ^4 O% \

      ^$ J. A% p+ K# e    p = vexTable[v1].firstarc;( a9 F8 m* t+ C: ^3 a' e
        while(p)
    & w& Y) d) N0 n# B    {
    ' M+ z- u8 x- F; O9 M        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    5 c+ u/ Z* h: P+ E: W# J        {
    # T  p8 v8 F; \- l5 |/ e( }: r            if(p->weight!=w)
    " S! G2 m, J) O! k) A: g* V+ B$ c                p->weight=w;1 X# Q2 l* `) v' ?3 o7 B+ @$ j) i
                return;
    , H6 t* {1 |- l& [( Z( S        }
    2 ?! |; L# A9 B4 X) o: H+ P7 y1 q0 Y( D/ n
            p=NextArc(v1,p);9 Z- p4 @! e9 |% g
        }
    " ~" ~4 @4 e( N  n' f* H, {, g, {    p = vexTable[v1].firstarc;+ O' z7 I5 I+ f5 }* z
        q = vexTable[v2].firstarc;
    5 j" O5 y! S- e- c, P' A2 c    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    ! j" @* Y) Y- |: K* K    vexTable[v2].firstarc =vexTable[v1].firstarc;* f* P' f1 H3 d/ [4 C
        arcNum++;. p9 B. z+ ~+ _; o
    }
    $ j% K# a: A! G# @  n& ^( W# Z, m6 e; F: h0 |
    template<class ElemType, class WeightType>  g+ {. F# _! d5 ]' i! J
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)9 Y+ K# Q# ~, }& Q- a
    {
    8 B1 i! K- a4 L; [9 _8 t/ H
      S2 \! o( h0 O8 W    MultiAdjListNetworkArc<WeightType>* p, * q,*r;9 E3 k; n1 o7 c# H
        if (v1 < 0 || v1 >= vexNum)
    # m; X2 A6 h/ j" F) I8 e        throw Error("v1不合法!");2 A) z! l2 I1 f0 g, r1 C# p
        if (v2 < 0 || v2 >= vexNum). h3 }  q2 Z' ~  T
            throw Error("v2不合法!");
    ) U8 ~! K' C% L, z+ V. K: O    if (v1 == v2)$ K% q% @5 G# j' R/ m* @+ c
            throw Error("v1不能等于v2!");
    2 v/ b- q- D" c% C8 R( c
    : m7 t! ?! W4 Y: L( o5 E3 U    p = vexTable[v1].firstarc;" R. E' z5 M& E4 E
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2): E- a: ~8 e5 O2 r9 Z1 h
        {% J8 J, g8 ~1 v, q8 J
            q = p;
    : }% F$ N5 E! r        p = NextArc(v1,p);# t4 y( s' p, r0 D9 K
        }//找到要删除的边结点p及其前一结点q' b- y/ s0 o* `3 Q8 _* p. W+ i
    ' o- q' M: F2 r, _% e
        if (p != NULL)//找到v1-v2的边
    % y$ s2 R, e, A    {
    4 A+ W4 U) F. `/ k6 D4 D: p: v        r=LastArc(v2,p);
    0 p1 f6 C; z7 B/ j1 P. X* i        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL; N' C- b) A, L4 u5 o2 A
                if(p->adjVex2==v2)
    ! |- l7 M; v* ]. A3 ^) ~                vexTable[v1].firstarc = p->nextarc1;1 F3 B* p5 Z! i6 x+ v* ?! R
                else vexTable[v1].firstarc=p->nextarc2;$ Q. H. X+ i% W' g* a
            else//不是第一条边
    4 F& J2 B3 o6 o+ |        {
    9 u' l9 }: f; r. J            if(q->adjVex1==v1)5 x5 l5 T" w( h4 l
                    q->nextarc1 = NextArc(v1,p);2 X+ v* t5 ^+ {; W- ~0 E
                else
    6 O( G' B% z5 w" T; x8 W                q->nextarc2=NextArc(v1,p);7 e8 I, T- |; S7 _2 P

    . ?/ N/ E% \9 `* t% M: x' j. o        }
    " q9 O& F% Y  V5 D- A0 D" C        if(r==NULL)
    : O+ ^7 ]- E& {* o2 \            if(p->adjVex2==v2)" G+ j# n9 b& i# u/ }$ B1 z
                    vexTable[v2].firstarc = p->nextarc2;
    ' A" v$ g8 C" J% J3 E, j7 s            else vexTable[v2].firstarc=p->nextarc1;: y! k8 Y4 L% f) C2 r
            else
    5 j* y+ G' Q! W& s" k. k4 B- k        {1 p$ s# _6 y2 Q( @8 E) N
                if(r->adjVex2==v2)
    ; O6 I$ Y1 }, R                r->nextarc2 = NextArc(v2,p);. Z& U8 [# z' F3 ?# M
                else
    + s7 W* g: R2 c                r->nextarc1=NextArc(v2,p);8 \9 L# L$ @9 P# w" y  d
            }
    6 d- ?% |8 j* k6 ]        delete p;7 m* Q$ i" T  U  q2 G# H8 F
            arcNum--;
    8 S2 Q# V( y# v# F: `) x5 k+ Q    }
    ) _) b  y* H4 s# \; N' L# c9 G& c+ R* {' p* H
    }
    - k; o  X" `# D/ E' d: Y( Ctemplate<class ElemType, class WeightType> void* X0 G* A& ~8 m  @& x
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d): t  g. m0 y8 Z- o( g6 ^
    {+ A" I8 u. F) h
        int v;
    ; R: M" `6 [; a5 A    MultiAdjListNetworkArc<WeightType>* p;
    ; `' N  g' m- E8 ]* n    for (v = 0; v < vexNum; v++)//找到d对应顶点' u2 u7 z2 F4 U) a, Y' `
            if (vexTable[v].data == d)
    $ O- _9 G2 t; L& S" g* l            break;
    * \& K6 Q! U5 o, p- K# A( ?/ @  J3 P, T    if(v==vexNum)
    4 G+ Q8 p2 `3 ~        throw Error("图中不存在要删除的顶点!");  R( C6 G& z9 c% f, Y

    2 |! x+ m. \- C1 @: V    for (int u = 0; u < vexNum; u++)//删除与d相连的边
    9 h# h  q, }, H+ e* C( _1 ?        if (u != v)8 f- g  a! b" T7 W  W
            {
    ( J/ l, O$ o2 K0 ^. U4 D5 k& q            DeleteArc(u, v);
    - H1 _  Q' }0 O/ r        }
    7 p) Q) F$ L0 A" T3 T9 Q8 G    vexTable[v].firstarc=NULL;
    # B7 _5 J; A' T2 \- f: j% R- B# O. l* J' {
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    ( T8 f" Q: S3 J, x' L    vexTable[v].data = vexTable[vexNum].data;. \- v! Z0 }( }) c+ S+ ]$ m8 b* Q
        vexTable[v].firstarc = vexTable[vexNum].firstarc;
    ( q# T- O3 i& J3 A# b/ i3 @/ f    vexTable[vexNum].firstarc = NULL;
    9 @2 `. a3 t; V# m    tag[v] = tag[vexNum];
    3 G' e3 V; [& J    //原来与最后一个顶点相连的边改为与v相连
    , B! B  r6 ~, n7 s    for (int u = 0; u < vexNum; u++)) T4 V7 {* q" S: F7 @# K2 u: U
        {! k* z8 R5 ]' z& ~
            if (u != v)% b' H& A: u7 _2 @% ~, j; `
            {
    7 f# Q' G) K" Y/ E; g            p = vexTable.firstarc;7 M0 p. |1 s' d! l
                while (p)
    , m) X' A. ?! u- {* [; C            {1 k+ C  L. \, L& n
                    if (p->adjVex1==vexNum)
    7 p! j4 w# }! B. J# a                    p->adjVex1= v;
    ) n' H7 T! x' y6 T) p                else if(p->adjVex2==vexNum)
    ; O6 _& F* @: e( X                    p->adjVex2=v;" u; m" n; w& B7 f+ W, d
                    p = NextArc(u,p);
    ' T( K. b% R8 B) K0 Y5 r1 u9 O0 L; u, c            }1 c5 {# f& K8 a2 D% v7 H/ o
            }
    . M: j# Q! t. `$ f# o    }
    ) Z0 B: Y" A1 T}
    9 @3 }  J( d* j' y///深度优先遍历7 J" Y& W, u9 M$ ^7 Q; B
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    - _- k3 h( g; Z' f9 c) s( a! V{& _# ]/ i, r  {
        tag[v]=1;5 {( |; S& x8 W) k3 s* J/ }
        cout<<setw(3)<<vexTable[v].data;$ M0 E! Q* N1 _  O, }/ J
        MultiAdjListNetworkArc<WeightType> *p;' j* O( Y- E4 @2 p4 {# [* c
        p=vexTable[v].firstarc;1 E; d6 [5 X$ v' U' W: k) I  Q
        while(p)$ @. h! }3 D% ]& c" J
        {
    ' }3 t2 F8 ?+ [/ j) t        if(tag[p->adjVex1]==0)7 U5 h! o" R) d  z! l' F7 @, D
                DFS1(p->adjVex1);
    & l) J. l6 d# R2 ~" C  Q5 m1 y        else if(tag[p->adjVex2]==0)
    0 o, X) R- B2 }% p! q" y0 G+ V5 K            DFS1(p->adjVex2);4 ~$ o. H/ P* p& n, P" L& a
            p=NextArc(v,p);
    ) g3 \+ `0 G$ i9 J+ `8 N    }
    ! @3 m3 H0 M# v& u' o}
    3 P2 Y' c5 [3 {2 E: Wtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    3 r) Z3 L) V; Z' e0 H{" I. ^; O, |8 I
        for(int i=0; i<vexNum; i++)5 j& ?( [8 D6 f: ?6 o/ `
            tag=0;
    0 q! f) d' C# t    for(int v=0; v<vexNum; v++)2 |7 `  ]* e: M& o  ^6 T
        {
    / ~  z1 w8 g* [7 ?5 ?        if(tag[v]==0)$ A5 u' d* z6 v+ A, ?( g
                DFS1(v);
    3 c: w; `: W& S# c( E) r$ g- \    }2 s! s* t" ^. ^
    }
    ; g3 e5 ~9 s5 N# ~template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()( Z! v/ Z) Y" n. N1 Z; A
    {
    " C9 g. C. H9 x# m    stack<int> s;
    * j) i& u7 _/ G$ L1 I7 z7 ]9 ?    int tmp;9 b5 ?* f3 ~$ T: U. q/ c
        MultiAdjListNetworkArc<WeightType> *p,*q;. w0 w- m' P/ j
        for(int i=0; i<vexNum; i++)
    + V. @& r- W+ [3 _        tag=0;& T$ R0 M. k. R2 q; a0 l1 R3 f
        for(int i=0; i<vexNum; i++)
    $ d, P- ^4 c0 R1 [4 N    {
    . n+ T4 H( F& b        tmp=i;
    & N. N4 a, D$ i        while(tag[tmp]==0||!s.empty())
      B- z; z0 l7 o4 o        {0 C1 E) b; _+ F1 H1 _3 }
                p=vexTable[tmp].firstarc;
    8 |8 A/ b( Z0 u! J% ^1 [            while(tag[tmp]==0)4 b' V0 }# f8 U; e" A
                {
    8 m$ J: \  w  I$ ^- s                s.push(tmp);; g$ {1 A9 f: z; X) H6 l1 s- g
                    cout<<setw(3)<<vexTable[tmp].data;) ]/ [: n: C4 r1 ?4 z0 ^; I
                    tag[tmp]=1;- D2 t9 x5 k7 K- O6 S
                    p=vexTable[tmp].firstarc;2 U3 ^; \8 U+ |" V
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    - X+ V& U* l  _$ f! U" q1 v  J0 y                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    # J. P* d  R4 C* l! e                //cout<<" 1st     tmp="<<tmp<<endl;
    ! y: |3 _- X) G# X# U! T/ w" k, w% F            }
    ) v' ]1 Y4 F6 r4 r% m- H            if(!s.empty())" m4 x& f3 s% T6 b7 G5 x
                {
    9 w" R2 V( N  \4 P5 @8 l& D* I                tmp=s.top();
    % l$ U1 j' M9 M7 H                s.pop();4 d, o. U. D7 K0 r# W! X
                    q=vexTable[tmp].firstarc;
    0 i6 }2 j* u' @9 Z                int t=tmp;4 O$ V* @1 D" g; i
                    while(q&&tag[tmp]!=0)' F% P* v4 T( b5 Q( M
                    {
    + `* |' `2 |7 j( W# J- D# [                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    8 t9 C$ h" g3 m6 u                    //cout<<" 2nd     tmp="<<tmp<<endl;
    / M" Q, u% h( a% q! q3 e                    q=NextArc(t,q);
    . C9 S" \! G* ?2 j                }* t5 l3 p! S( }5 @* \# T, }
                    if(tag[tmp]==0)2 I5 f/ w) G# s  _5 ]/ X9 ^. w3 y2 n
                        s.push(t);; `+ A  h- J. o6 b& W5 r4 I
                    ///1、对应上面连通分支只有1个点的情况
    ) g# W4 x0 C  M3 H$ D                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    1 u  U4 K5 V7 n, I. O                ///tmp要么等于找到的第一个未访问节点,
    . [+ u7 U. z# `/ F% _. q$ {( P                ///要么等于与t相连最后一个点(已被访问过)
    ( {& d& ]4 C6 f7 v8 C9 w                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点' q2 x9 N& H) W# {  K% `
                }3 d) w1 Q+ s5 F* ~
            }: g1 |0 {- B; }0 J' y
        }
    & z# e4 [) ]) z+ U( b5 i. D5 ?}& H5 J' y/ u7 w0 e! r# r
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
      y& j7 W8 [! Z+ Btemplate<class ElemType, class WeightType> int
    % I$ E1 R% N! A( G$ Z0 qMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    6 j# a! \) f7 J2 q{
    ' Z& l- \& d4 m0 i- }; C    if(head==pre)
    , ]' g+ N6 I% G) w* I' T        return -1;
    : @/ x1 z$ w. b( Z
    % n8 d0 h9 `) o0 V    MultiAdjListNetworkArc<WeightType> *p;6 E1 Y( r4 B" x1 _/ q% S, U' S
        p=vexTable[head].firstarc;2 ~8 [! V! ]- P: G- t' ?
        if(pre==-1&&p!=NULL); L8 ~1 |. T3 W# S5 f# L- f
            return p->adjVex1==head?p->adjVex2:p->adjVex1;6 m# z6 o3 k5 l+ `. J) B1 x  U
        //pre!=-1&&p!=NULL  T; F2 \  E0 t
        while(p!=NULL)1 u2 n( W8 {* V$ @
        {1 l2 N! J  j9 I
            if(p->adjVex1==head && p->adjVex2!=pre)
    5 o7 A+ n' `0 G9 ^            p=p->nextarc1;
    5 ]  v; C0 x3 `# H7 `: W        else if(p->adjVex2==head && p->adjVex1!=pre)
    * D/ X2 ^9 M  O) i5 v+ r  H8 a: \/ T            p=p->nextarc2;
    4 X$ b) D/ O4 F5 y        else if(p->adjVex1==head && p->adjVex2==pre)
    ; n# \. a) ~8 m- F1 H* g& G- Y- k        {# c0 t7 o8 |: i4 i
                p=p->nextarc1;9 `2 [, D9 ^1 b
                break;
    ! D9 e, k# H5 A! ^9 x8 L6 x        }
    , N! I: U3 F6 S5 k- c        else if(p->adjVex2==head && p->adjVex1==pre)
    4 x" _) V* }* _1 _        {
    7 [( J8 [+ o& ]( N; ^            p=p->nextarc2;4 z! I. L( ]6 p) u; R8 |
                break;
    , V  ?' ^- V" K: ]2 e        }
    9 l' a/ L3 r9 w9 i6 o3 x    }
    0 Q: k. s# @: m    if(p!=NULL)
    * x- N' N$ F5 q    {' h! |3 W* S, `$ V$ V9 @7 _6 w3 }
            return p->adjVex1==head?p->adjVex2:p->adjVex1;% W; g1 c6 @4 k
        }
    * R& U+ E! O6 \3 F    else* ]4 Z/ f% y, F% q( M6 n
            return -1;
    / Z5 G! W9 @! @* n& u  u! I0 _}7 q& v" j9 i; c7 S& y: ^' I; v0 A

    ' N( ?% F* m. e+ F
    & ~: ?& T, n- c" Stemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()! Z+ C' M+ l4 P- K  p3 B1 e$ m
    {
    & ^; P  D4 l! @" [  `) ~5 l$ }, `    stack<int> s;4 a8 I5 V7 b& s1 d
        int p,cur,pre;
    8 _& A1 R$ Z% b8 A* C; N    //MultiAdjListNetworkArc<WeightType> *p,*q;& n5 @2 i* }& U" V4 l( Y
        for(int i=0; i<vexNum; i++) tag=0;//初始化% r0 G+ N  o: M$ b6 [3 |& b. A
    # @. `: ]* p8 T% v" ]
        for(int i=0; i<vexNum; i++)
    ' d2 N  ?/ ?5 ~5 d    {
    ! s* X! Y( H; o/ ?        cur=i;pre=-1;
    ' L. g* p8 [! D) E2 h8 t# Q! O        while(tag[cur]==0||!s.empty())
    * m) K, _" {7 C        {
    + M( c! t8 n0 ]; u7 v" A- T% \            while(tag[cur]==0)5 T; U# ]# Q3 a6 m9 I! Z
                {
    5 G# y) Q1 X' v5 O                cout<<vexTable[cur].data<<"  ";3 d0 B9 R+ {: d+ L% g$ N
                    s.push(cur);2 ~3 w0 \# O* p, h" V' C
                    tag[cur]=1;- v* [$ j0 q2 b1 ~4 g/ [$ [
                   //初次访问,标记入栈4 A& u: c. j& _9 s: S/ h

    # o* \- `% y1 n( g# m$ ^               p=GetAdjVex(cur,pre);//p是cur的连通顶点, ~% Q1 b" ]/ A* D0 L8 T& G# z
                   if(p==-1)
    0 k/ C: ^  j- \& y8 x& j7 w% c               {
    $ \2 X: M5 L. p                   pre=cur;s.pop();5 G( G% z( Y% \
                       break;
    7 l8 f* v2 m( g- H               }, t' J4 D4 }) K3 u8 u4 D9 z
                   else' l, ]& f( O# n8 V! C  w- H  p# V5 \
                   {8 a2 W4 u5 u' b
                       pre=cur;3 A( J5 L* |0 x: z0 p, ^
                       cur=p;
    9 J+ M, b$ X/ z" ^; a. e0 O! ^               }) A* k8 C9 F+ F4 G5 |- ~* o
    1 f! L* J$ n; h) Y
                }
    ( F; }" z7 T6 T0 o$ ^/ T            while(!s.empty())/ H0 _& b; e, K3 }! I' ^+ ?( S
                {
    0 j& k6 u9 k; |5 ~) w                cur=s.top();8 J0 Z. p+ }% a- s
                    p=GetAdjVex(cur,pre);! l3 q: h1 r0 ~: _0 V1 q' I. |
                    if(tag[p]==0)
    7 {# G. w4 @. C0 `: A                {. |, P: c8 D3 v- Z* U8 j5 \; f
                        pre=cur;
    1 p" d. R4 E! b( @, y% C                    cur=p;
    ; C0 Q/ B( c9 O6 h                    break;
    6 ~3 j2 ^& Y1 Q* v                }, i/ ]0 x& \, B+ B
                    else
    2 z& n9 \; H" {; Y  H                {
    + O* K+ C5 p5 N$ W, r                    pre=s.top();+ v) I2 w7 G0 M1 P3 o& \
                        s.pop();) [! d9 Q' ]# t# \/ ]" l
                    }5 U2 m, T$ O* R

    2 v" M& M; K: t, i3 L8 Y( x            }9 \0 K4 r" g' p
    6 R5 [/ j' ^/ ^! @
            }
    0 \; ~% F- P9 O3 e" z    }
    - C& r9 f4 M% _5 ]9 z7 o& j4 K}, [8 ~! M- D: a
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()1 R8 x/ Z* q& a! T8 Y( D
    {
    ( M# s) N+ E: I) D0 k    for(int i=0; i<vexNum; i++)7 T7 W, A0 O9 j/ R1 k; P8 a
            tag=0;
    ( L' E; Z( z% Q7 a8 [9 O7 \2 P    queue<int> q;
    & i- r/ h, r# F- Y    int tmp,t;$ n7 \5 l) v; l9 b* W8 y
        MultiAdjListNetworkArc<WeightType> *p;) n/ K3 _, W' x( b( B
        for(int i=0; i<vexNum; i++)
    0 y6 L" o; F: A7 t3 t    {
    ! L+ F/ ~3 r6 f: J4 J$ J& I5 M  J/ |        if(tag==0). ^; g2 P6 l6 O1 k+ x: s1 W$ \
            {" t( O; k) }2 }5 x. R
                tag=1;
    8 v  n4 H- \$ u  {% b0 l* |            q.push(i);7 q: t) Z+ B# U6 p' Z
                cout<<setw(3)<<vexTable.data;# b. M3 G* O9 M
            }
    + p: L  S! V1 e, [, g) O  }        while(!q.empty())
    5 }2 J* X4 c# A        {
    : M8 E  b8 b( K9 K            tmp=q.front();, T: I5 x' b" X
                q.pop();
    % X- a  d# u, G! s! k3 n            p=vexTable[tmp].firstarc;; L7 j7 }# c- ]2 @
                while(p!=NULL)
    5 t' ~# |# q1 T            {. l1 M/ i- o# V3 ^# U. T
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    8 @* G8 ?6 I. J7 b4 E  }                if(tag[t]==0)
    & ^4 H; m; d$ {2 p0 ^                {/ Z/ U! F* A. X* a: u- j
                        cout<<setw(3)<<vexTable[t].data;9 j8 e- ?0 u9 M; O
                        tag[t]=1;( v# i3 h; E7 H
                        q.push(t);
    $ t1 s: e) k. l+ z- [( X- y                }
    $ ?7 @) \: O7 }9 I4 w5 A$ }                p=NextArc(tmp,p);% p- Z; {$ u8 j% ^9 G2 I- r: y
                }
    9 l" p, I% J0 ]# l: R        }
    % x+ u' [0 O9 [4 x1 ^2 o" v    }, X6 l. _0 k3 ?! \( _3 z
    }
    8 X/ Y: X) J$ i% @3 W" t6 Utemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()1 S$ x% V' e0 O" R% h$ f9 _
    {
    ! j* Z. w, A2 p6 W+ |0 c    MultiAdjListNetworkArc<WeightType> *p;
    4 L# G% m+ O0 Y) Q. q) e, F    cout << "无向图有" << vexNum << "个点,分别为:";
    ( R/ a* O( j8 _    for (int i = 0; i < vexNum; i++)
    - @  A* k9 f) J& W( K        cout << vexTable.data << " ";1 m$ K2 i" o& n% H9 }, H( D: s
        cout << endl;
    ( r( P$ r; l' J8 p    cout << "无向图有" << arcNum << "条边"<<endl;; s% R2 a" O7 O+ _; V5 r
        for (int i = 0; i < vexNum; i++); a9 y  u. y6 ?5 S& Y* K) s
        {
    5 F2 }! \( Z/ C, v6 t        cout<<"和" << vexTable.data << "有关的边:";
    9 b, |/ e0 ~4 N# u: y4 J( C        p = vexTable.firstarc;
    $ {( a6 S' l! p0 J        while (p != NULL)
    * E6 H: w6 e0 K1 s3 a        {
    5 f/ z0 G: f( a            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    % |$ Y# |5 F" u* @1 \5 K7 M            p=NextArc(i,p);
    / a  A, I% A+ ]: l1 e# B6 K        }; D: L4 g# j$ E& s3 U
            cout << endl;
    8 {( m6 `/ e& F  ?6 o/ p' F6 ^    }
    / M5 H' ]/ O2 P6 \& ?# {. w% @}" @+ t4 i1 }8 Q9 t( I. P! j
    7 m, Y) `  s1 t

    0 d4 W' ]$ X8 C2 `; t/ Z, U8 y: {邻接多重表与邻接表的对比$ B1 q! X% _; |0 w
    7 ^  `/ j! N& ?* a
    邻接表链接
    % x; d) K! d2 E: U0 d. }在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。. ?3 g8 X. p: K8 F; M6 B2 I
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    0 p8 x5 {* r; [+ r; {- H为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    2 L8 F2 h/ `& _) m3 a. y; g————————————————: t; R$ X! r1 k! ~" {5 R# Q, A
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。; {# h, c; }2 j. L
    原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669589 Z1 z6 p$ `, k: z0 A) a6 w6 c
    . `7 I! g; ?2 Y) n
    ; u, u3 P- e+ ^5 O- i

    0 k' H# f2 B) A! `
    ( `; A! @7 W5 O8 I5 i————————————————
    , M& C/ Y* _% m8 h" n版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    . w/ S9 c" k3 @# b- x( j% K原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    * `% |4 j/ j+ l* a  E
    5 [. u, Q: i& Y2 e$ M% o$ D* X1 Q+ t* h5 ^! ^3 i3 _  H$ G4 }
    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-4 10:10 , Processed in 0.640004 second(s), 54 queries .

    回顶部