QQ登录

只需要一步,快速开始

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

    ( g. F6 f) O' I7 |图的存储结构——邻接多重表(多重邻接表)的实现
    + C  m+ F" Q  ]( F: F" E4 w7.2 图的存储结构3 `' j& @7 q; P" U' U# _; i' V5 @
      q5 W# }4 `/ N% p
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    $ G5 M3 _* p; C! e! \' `- a邻接多重表的类定义' K* u. Z$ i- k0 A- M2 g5 f) D
    邻接多重表的顶点结点类模板$ D4 K& E1 _0 d( Y" N5 g2 b% h
    邻接多重表的边结点类模板
    ) {- U* ?' U5 i) P% w' q8 @9 ?邻接多重表的类模板- F3 U" H$ P2 T; b2 k" U
    邻接多重表与邻接表的对比
    . b8 }8 p5 t5 d9 o% Q1 m7.2.3 邻接多重表(多重邻接表)Adjacency Multilist$ E, v3 ~1 l' P" p9 R
    2 |5 N* V- i9 a6 ?- \5 C( K' W
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。: P( r# a( L. i  G' b
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    6 J8 p$ |3 G2 B
    * |# W8 K' ]7 o, ?邻接多重表的类定义1 Y0 r4 G& z( _( X$ I. l
    1.png , L+ O0 e, a; P- i4 V# F. \2 k
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    ( \% A* ^; m3 Z& e+ U' Udata域存储有关顶点的信息;
    ) e" T( Z: c. {6 qfirstarc域是链接指针,指向第一条依附于该顶点的边。
    : U. G+ I, N* t! G6 G! f+ E所有的顶点结点组成一个顺序表。

    1 _" U' z0 B5 J* a# M7 ^& P

    * E# P- h! W2 {, u3 S# c2 Ztemplate <class ElemType ,class WeightType>, Q* ?- k0 S! S. Z) F/ [
    class MultiAdjListNetworkVex
    ; f5 l7 k+ `# {/ J{
    , p& t( z' z" [# @# apublic:
    3 E! d5 \2 J+ t- g        ElemType data;
    7 j# V+ a9 o  R; j  n* T( S        MultiAdjListNetworkArc<WeightType> *firstarc;# ?+ A: D3 X' E* m
    - L4 }' a, n' f
            MultiAdjListNetworkVex(), L$ z; D' U) x! c- ^5 [
            {
    % {; P, s: A5 R# k                firstarc = NULL;
    6 b1 ]2 P* j, o+ U+ i( k8 E        }
    . O7 m6 b) H, G& y! R$ P5 Z        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL), |3 h1 F' S/ P% w
            {
    4 H1 i0 L4 J  e9 P) U5 ?                data = val;
    ( W+ O! o  v0 q  b# W& A                firstarc = adj;9 \% `3 E3 y& r1 D
            }
    + ]/ b- P$ L$ b) U2 [* }/ I};
    ' z" F& u) S+ E. ^
    2 s+ a# ?2 \; }邻接多重表的边结点类模板: V$ }+ G+ G, {* T' S5 F
    % y1 H/ `3 _/ b6 t6 [
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    . l, Z  w: p" j4 [! ztag是标记域,标记该边是否被处理或被搜索过;
    8 p/ f# w8 O- Q  B2 Z* @" nweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;% }  s# O1 N# m5 m# A
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;2 f* p8 {% i/ m4 T. L  G" z# I$ t
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。, I1 y7 Q) l. q2 b. x% c

    8 h. F& \7 L5 K 2.png
    % k4 W2 k" b4 d, t- jtemplate <class WeightType>
    - |1 m' N* `2 T0 j9 Iclass MultiAdjListNetworkArc
    ; `% \2 b' R+ a% C7 ~{
    3 V' b9 b. |, A, U) ppublic:
    - B+ G  N7 L# w) [6 S* j    int mark;                                       //标记该边是否被搜索或处理过
    $ L8 {0 [1 F5 b. P7 C1 o        WeightType weight;                              //边的权重- x" `0 E3 r( H- [" ~
            int adjVex1;                                    //边的一个顶点! n  {) A+ E/ x+ Z
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-13 r% l% p7 D5 l# H
            int adjVex2;( r, K1 c9 X. i8 n9 k; x8 P! M
            MultiAdjListNetworkArc<WeightType>* nextarc2;4 t0 N& ~, e3 p. n; r
    & g9 C/ m6 W7 @! ]! I
            MultiAdjListNetworkArc()1 o# D/ n5 b5 ?+ ^. O, D" e
            {
    7 g! p2 E# U5 m+ F" }4 [                adjVex1= -1;
    ; x8 ^' h9 S# @1 H2 F1 W                adjVex2= -1;. H7 }  J! H# H' e$ c
            }
    / k. y! z6 M' f        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    0 E* D4 Q5 x' J        {
    - n+ W5 c9 d/ V3 x                adjVex1 = v1;       adjVex2 = v2;4 S# E; n# g3 n: q. e7 U
                    weight = w;) |" a* y/ d/ [" N6 X' R
                    nextarc1 = next1;   nextarc2=next2;
    $ O  J1 I$ c: O' u                mark = 0;           //0表示未被搜索,1表示被搜索过" @% {0 z$ H2 O' ]* P
            }
    8 i* c* ~  ~9 v" ?) v3 c0 Y6 `: e0 |0 h0 B, `
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    9 y# k, M' f: l' m/ Vclass MultiAdjListNetwork
    : \' H) [+ l  r7 ?$ [* }, a{& |# c# _/ ~; j2 E
    protected:
    * Q! B1 ^- d3 `* }2 S    int vexNum, vexMaxNum, arcNum;/ ~7 _: Y; x* |
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;6 K4 Y  J) R( j
        int* tag;
    5 g7 w# ~/ D- U    WeightType infinity;
    * j9 W) b6 V: [; U' V0 ^
    4 q5 J) a% e9 L5 p# Z: vpublic:7 T+ b( H" p5 g( k( ?! Q
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);# h6 B. k* y6 s" }

    + Q6 u$ N0 ^; s* d; X' ~3 \1 x8 i    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);2 C$ v; }" z, M4 j9 ^

    ' h! c) x2 t! ]% f4 B( R/ l    void Clear();
    ! G% d4 j/ M2 Q& y7 ]    bool IsEmpty()& O$ }0 `2 l5 |3 E& y0 E
        {
    4 k" _+ u/ W2 W6 R" b        return vexNum == 0;6 J( X: v* N( l- U) T% ?
        }3 U9 v8 o1 K3 a% B. F" [
        int GetArcNum()const. R; h% U0 r; s, i
        {
      O( x) f2 d/ E3 o9 d        return arcNum;6 y. A8 B& }3 x4 ?
        }$ u" G7 e8 S: B+ S1 j% L
        int GetvexNum()const9 X  l9 F: q: O: b) {, M! A. v
        {
      `6 E" X( q1 F. M        return vexNum;
    9 q8 g, c; ?* `4 T3 z$ z    }
    $ q' H  G3 \0 L- ^" V, y- o/ _" ]
    4 `' |3 F5 H6 ~4 ~3 D7 m  y% |. n- M5 I3 L( T; t* y% N8 N
        int FirstAdjVex(int v)const;3 J% V. @* X' Q
        int NextAdjVex(int v1, int v2)const;
    2 l, Z2 `% |0 y" X    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    3 U5 K1 T  K+ p" x: h) G4 z    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;2 n0 k$ O  o* M( J0 k; r3 T! `9 w) B: s+ v

    # q1 h6 M2 t3 Z' A+ m, w& @/ X. e    void InsertVex(const ElemType& d);" ]9 I6 t+ |8 z/ w: |
        void InsertArc(int v1, int v2, WeightType w);" V# ^" ~: o/ l, g

    6 x5 T  j2 ?8 s( I$ N    void DeleteVex(const ElemType& d);% @7 T3 e( s( ?+ b# V
        void DeleteArc(int v1, int v2);4 t% G! R1 J( c: b" {

    . j! ^; V7 b. ^) [+ B" q" A# k; m8 z    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    2 f8 E) M% ?; k( B5 B$ _! y1 V    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);* W. ?8 I' `/ i+ Z# J

    ' k+ }; [! l, L    ///深度优先遍历
    / u6 U9 f, n8 `5 ]. r9 g! j% D( t    void DFS1(const int v);7 D7 ]7 f# B& [7 Q( `2 j1 f: }
        void DFS1Traverse();# m& Q' _2 y7 V" n6 |3 Z1 }/ Z, N
        void DFS2();8 \0 u1 d6 i: Y4 P

    ( _  s/ W' c7 k7 @2 b) ~% j" V. b    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    1 H1 ?5 y0 P5 Q6 S2 @    void DFS3();2 T$ E. V5 A* `+ v% @8 H, z' a

    / d* _$ L! g* K6 \( ?    void BFS();
    2 g% k$ \5 m1 F" s" B    void Show();- N6 U+ x- ^3 r+ \* ~) T1 C
    };0 `; s  ~1 W, k& I' X+ N5 |
    ) M( o# u2 T! \6 }7 @1 @& E" Z% O" m
    2.函数的实现
    5 B# |0 e2 d# D# L; C5 h' G6 T研讨题,能够运行,但是代码不一定是最优的。
    4 e) U; p. [( f/ \. D0 X# P, p
    $ s( Y9 p* z* \; F: E2 }7 T#include <stack>0 a! }" m- Y+ ]3 g& G
    #include <queue>0 n$ t) r! K& w

    " U( a. ?, w" p  G5 U* ~5 ntemplate <class ElemType,class WeightType>$ L  z9 t# q9 a3 v
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)% _/ u& x6 ]1 ]3 C/ p/ ~& y
    {
    % C& A) n$ _. U" v4 W- l    if(vertexMaxNum < 0)' H) V* f" s; _% n
            throw Error("允许的顶点最大数目不能为负!");
    0 {* I4 {. i6 G! q    if (vertexMaxNum < vertexNum)
    . D8 A' y  M4 c  R        throw Error("顶点数目不能大于允许的顶点最大数目!");
    : h( O0 q% y& D# ^& g. s    vexNum = vertexNum;/ x+ P6 N3 L& i' m2 B! j1 c! R
        vexMaxNum = vertexMaxNum;
    8 }; y: P5 [! ]: v+ k: n    arcNum = 0;
      y( r! @2 C9 a. F, O9 a    infinity = infinit;  I' y% N+ Y8 B9 ~& m: I4 f7 ]& @
        tag = new int[vexMaxNum];
    $ K1 y  `7 E5 o. G, {    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];* V: ?0 J% a6 m
        for (int v = 0; v < vexNum; v++)1 f" _3 }* Y, P1 K$ N7 o3 S$ C
        {4 ~2 i6 }; _$ n$ S+ {& l* v9 E
            tag[v] = 0;
    & M: _6 M; s4 P! Z        vexTable[v].data = es[v];$ q  G8 f  j  x1 B0 l
            vexTable[v].firstarc = NULL;
    # t3 r9 x. E9 C0 z3 H4 Y    }
    1 W+ e. O. d/ v; B9 ^6 R) H+ N}0 J# S  K# t0 x
    template <class ElemType,class WeightType>
      P/ x$ E& P( hMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit), d+ |# U5 M' |- y  V9 y
    {) ]: a8 A* Q8 T) P, R
        if (vertexMaxNum < 0)
    0 v' o* e; t. D3 S/ O        throw Error("允许的顶点最大数目不能为负!");
    ! i7 i3 `9 M" `8 d% _    vexNum = 0;
    & s  o  k2 `+ S5 W    vexMaxNum = vertexMaxNum;
    # T5 Q2 G! w6 W0 [0 L    arcNum = 0;
    # }, e2 U6 e4 p, ?6 ]1 u    infinity = infinit;
    9 d2 x9 F7 k$ @; ^3 K- }% R    tag = new int[vexMaxNum];
    0 @" `5 {1 A8 g6 c4 A    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];* _- B6 ^: ^) y8 ]8 x
    }. X. W( t/ K2 X5 g- ?/ a; Y- }$ o
    template<class ElemType, class WeightType>
    2 V! G8 d6 {1 ^5 J! oint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    . J- w3 u/ j0 b# s/ b' ^7 F$ `& t. f{
    2 T9 }; B7 Z* ?9 S7 Y+ ^( C4 N& ~    if (v < 0 || v >= vexNum)
    ' N4 R) }8 E0 s% `- Z% H        throw Error("v不合法!");
    2 x1 F. R: T) z8 O3 j9 V    if (vexTable[v].firstarc == NULL)# G, n& [, t- q$ z( \9 |! |
            return -1;- F# y& o/ t& X5 C- N, f1 o' K
        else
    4 z. p5 v; J- q! c( u, }6 O5 y. ^        return vexTable[v].firstarc->adjVex1;
    0 S3 ?1 Y* k! `}
    9 h7 K- N2 q& L9 x- z, z
    * i7 {2 G5 r& ~0 v7 X4 f4 ytemplate<class ElemType, class WeightType>
    * q2 _0 n9 B. r$ K- R$ S* lint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const2 k' ]6 r- S# s1 j% P3 m
    {' n  S: B( K( J+ t
        MultiAdjListNetworkArc<WeightType>* p;
    " e# q4 T, A0 I3 \2 `    if (v1 < 0 || v1 >= vexNum)
    $ a& v/ z6 n1 E* O* o+ @        throw Error("v1不合法!");* H* c8 ~7 V/ v) o
        if (v2 < 0 || v2 >= vexNum)+ K. [8 w2 O* v0 w
            throw Error("v2不合法!");
    3 m7 _# c: `4 _; G# a! E  n  `    if (v1 == v2)
    # [$ D' c/ i3 X5 k        throw Error("v1不能等于v2!");
    " w  b) F; K3 W9 z    p = vexTable[v1].firstarc;+ s6 y% _# n/ M! u  g
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2), Q, V5 O0 T. R- W- \% T4 o* [0 l
            p = p->nextarc;" M* ?  C# {. g$ E
        if (p == NULL || p->nextarc == NULL)/ B4 k. a  ]* u$ a$ Q
            return -1;  //不存在下一个邻接点
    * ^9 ~# n5 v; t, S" F) ?- z    else if(p->adjVex1==v2)1 {0 b7 a. F- j" J
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    ; u: R% q- u( w. [' t9 e1 m$ G/ K    else
    1 r1 v9 E  d, {( [, O        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    7 m, m( o0 I# [+ T}
    $ g, i& C# G" s" m2 Y  r2 Ktemplate<class ElemType, class WeightType>, W: l4 c; V, R. d; J0 j2 W9 i
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()
    7 j( z% i/ X* F' Z3 {- [+ B{- Z4 V5 ~) \& P9 H
        if (IsEmpty()) return;
    * q7 {4 C/ Y7 Z+ w, V    int n = vexNum;
    ! _) @7 X# A" M: w9 D    for (int u = 0; u < n ; u++)# d( R4 B( e, Q7 ^: \/ X% b- f
            DeleteVex(vexTable[0].data);
    ' X9 V* g& e  x- G9 i    return;
    . t: P! e7 D& K# P  m}
    6 X% e. \0 {% y( q6 h: o  ztemplate<class ElemType, class WeightType>. i6 x4 J8 c" W- l- ?
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()3 g  Y) n" @- v  z7 S& C, ^1 v! \, z
    {: |, e2 j' ~. v5 @; u
        Clear();
    ' _, b4 ~+ s2 p9 }7 }3 W9 L}/ B- K# n9 Z+ Z" o# t) u1 v
    template<class ElemType, class WeightType>, m, ?5 G2 s4 }) Y9 Z4 w! _5 [
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    1 U9 v) X3 ~  o. i( q* N- o* A# |/ N5 p{
    * d( `) o/ R8 K' L& q2 p5 k    vexMaxNum = copy.vexMaxNum;- C& ^$ i9 }5 m# @
        vexNum = copy.vexNum;
    3 x( U" I8 p# I" v# o* f0 p" X    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];& P1 ^+ \( y, N" E9 ^: x
        arcNum = 0;* J/ T  {7 ~7 {4 ?' F0 R3 M
        infinity = copy.infinity;0 f+ i/ K; ?2 y; F# z3 `
        tag = new int[vexMaxNum];
    * t( h0 j) x+ O4 `* ~8 ~* Z  h( K2 ?0 Y) d, _3 c
        for (int v = 0; v < vexNum; v++)1 j/ v( [( w3 I4 B; v
        {4 C0 I! w& M+ k- v6 b
            tag[v] = 0;
    4 V7 a: f4 A- m) b% z6 X; I        vexTable[v].data = copy.vexTable[v].data;
    $ E7 a7 c1 Z. D1 I/ q; ~7 q        vexTable[v].firstarc = NULL;
    * \/ X- r4 G  i( t8 ^6 F& m    }
    1 y& G0 i) o" {: m    MultiAdjListNetworkArc<WeightType>* p;6 W; ~: G1 B8 ^: k

    % k' E2 e% s, i7 J% b    for (int u = 0; u < vexNum; u++)8 C" p1 d$ \1 t% n. E
        {
    " c# G2 K5 N. W: H1 D! A' t4 R        p = copy.vexTable.firstarc;
    5 o* j" M& ]) L, w1 k        while (p != NULL)$ ]" L* C$ B- E8 l
            {
    2 ~: }% g( \- q! z- T( ?+ W0 S$ T            InsertArc(p->adjVex1, p->adjVex2, p->weight);! X+ v% p2 ~- P
                p=NextArc(u,p);. b7 \* N% p2 g8 b, p5 W- A1 `
            }2 ~, R! p, V( l6 {$ _& h
        }4 l* Y; H0 _1 L- T
    }
    , W* Y- Q0 r5 H9 Z0 o5 dtemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    # O* \2 C) a& U6 ^$ h; {0 vMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)5 W- T% q+ ?9 _9 Y
    {" N  G# A2 c5 R$ W
        if (this == &copy) return *this;
    . k; T0 f( ~( D$ y$ {# l# w    Clear();" h* D- n' y( q/ Q. ]
        vexMaxNum = copy.vexMaxNum;
    . Q6 g4 P! c# E1 `    vexNum = copy.vexNum;
    ( ~4 m  H' \! m+ v8 e* [    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    , W% c$ |  L  A    arcNum = 0;
    : [; G1 w9 ?9 y: Q% v, @    infinity = copy.infinity;
    0 k4 z$ ?- a) j/ p    tag = new int[vexMaxNum];
    % k  f. L& i# {* Q3 p: r2 Y. ]# s/ g
    3 w5 q! X2 B" V1 U    for (int v = 0; v < vexNum; v++)
    & V7 [0 f) h4 i1 Y/ x    {
    8 K* S7 Q! o3 W2 \/ k" u9 d        tag[v] = 0;. i! H5 u: `" z7 O: a
            vexTable[v].data = copy.vexTable[v].data;1 b$ C0 s8 o# L
            vexTable[v].firstarc = NULL;
    ' C8 L0 |0 P6 L% m    }! e" Q+ u9 b9 ^
        MultiAdjListNetworkArc<WeightType>* p;" Q7 m, u. M/ p4 s$ J' \

    , p: @9 m8 m1 c+ q) E, b    for (int u = 0; u < vexNum; u++)9 Z, R) ~" a" R5 ?( _
        {
    7 b/ K  y! Y* g0 w( @5 l        p = copy.vexTable.firstarc;8 r( o# N1 c3 _( S
            while (p != NULL)
    5 J- S. j5 s5 U" S        {
    2 T+ K. Q3 Y' `# M' s5 R            InsertArc(p->adjVex1, p->adjVex2, p->weight);* e6 G& k( ?! K% M) o9 ~3 D
                p=NextArc(u,p);
    2 x9 }2 r" |* W% b! _, \        }8 v0 z. q+ }$ v0 a7 F
        }$ H( C& ~& K9 x/ D0 L
        return *this;4 w" D. R& ^+ u
    }
    ) _, B: A. O6 n3 Z) itemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*, @, p, W; `; |
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    2 t* Z9 W2 ]5 U/ t& L4 {6 ]( }{+ O- v6 O, f0 w
        if(p==NULL) return NULL;$ i+ w) x8 I% |% l2 P
        if(p->adjVex1==v1)
    ; \: O. c  N; |+ F1 g' E/ }        return p->nextarc1;
    ; y; e+ y! E( L( y" v# K+ g    else: w5 s/ n" Z$ ^; v* y, P
            return p->nextarc2;
    1 Y6 K' Q  x; i# d* R0 @: L}
    : ]3 Y9 A$ o( }1 Gtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    7 O4 G$ x) M* @5 [( SMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    0 m; _' z) n4 L1 U{
      P# ?. O" \* V# v- a4 Z- {    if(p==NULL)return NULL;: w; }5 T$ k; _) j
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    6 F( I7 u# J# B% O    if(q==p)& s1 y6 |: x/ E0 j5 a, T' h' |
            return NULL;0 Q4 b) ], _( d5 S
        while(q)% H$ l# J) D! D, b" |
        {
    6 j' {9 J& ^9 W8 g+ F" Y        if(q->nextarc1==p ||q->nextarc2==p)
      g7 U" Y* c7 c( x1 b* u            break;" a1 D0 W4 B9 B# `$ |
            q=NextArc(v1,q);
    % a* p; r/ K/ Q& x( m( h    }
    2 |- b' r9 C8 C1 [, d% }0 ?1 w* W    return q;
    7 Y$ a* u! H; i( {# m) R2 p( Q}- [1 y6 |' k: k. x  e- P
    template<class ElemType, class WeightType>
    " g  S! C' V/ cvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)" O* }' [8 V3 N# O
    {) R. G# g9 y* n/ j1 [
        if (vexNum == vexMaxNum). E" }/ x8 w! k0 Y4 T( m
            throw Error("图的顶点数不能超过允许的最大数!");0 P# t5 U3 l+ h- H3 s- f
        vexTable[vexNum].data = d;7 q$ T0 W$ D+ D+ }; w% Q' F2 C
        vexTable[vexNum].firstarc = NULL;3 P" ?8 @: n# V2 g# b1 z& Z% C7 s
        tag[vexNum] = 0;" m5 G3 f9 i5 Q
        vexNum++;4 u, q$ T6 W% I+ K
    }& A* g2 g& }: I$ F: e, X/ _
    template<class ElemType, class WeightType>  |3 i. V5 {0 o& H6 t/ X* d; S
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    4 H$ N0 f& S% ]  e% I4 O{
    ; [- D! A+ W0 ]9 n    MultiAdjListNetworkArc<WeightType>* p,*q;8 J1 y8 F0 j4 x0 A" [4 r( D
        if (v1 < 0 || v1 >= vexNum)& N3 \7 ?( c+ ^2 a/ {' F+ L% A
            throw Error("v1不合法!");9 h6 ^: {7 A3 b1 o% h
        if (v2 < 0 || v2 >= vexNum)
    8 e/ f( P8 h5 J        throw Error("v2不合法!");
    ' y6 s2 Q: T) v3 t! ^2 s& S    if (v1 == v2). f( N4 c! j. A/ H
            throw Error("v1不能等于v2!");
    . Y$ S4 ?, L/ E    if (w == infinity)
    ! _- l; d8 |; [/ W        throw Error("w不能为无穷大!");
    3 G; \7 j+ \$ y+ A+ e- s( i' \9 c
    / I' `3 J2 a/ e+ r  B# u! z5 G/ Y# q' C! W
        p = vexTable[v1].firstarc;
    1 p# X& u7 F9 H" P' i) B+ O  c    while(p)5 o6 }3 b/ b1 c+ \+ v
        {$ O. y  u6 r# s' T0 d* L
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    : t5 C. I/ H- z+ u6 B2 z1 r0 X, x; u& I+ s        {" [3 p5 {9 O8 h7 c+ A; n! @
                if(p->weight!=w)" v7 V3 U) j  q  t( {. N& q
                    p->weight=w;8 ^+ F: O) W9 a* [. U
                return;& P3 Y5 l% v5 v( x) K) N
            }' X+ J2 x9 t* T5 g

    2 t) o) q. {) h" A- q* Z6 h        p=NextArc(v1,p);- P' g3 |! j1 G
        }. K, \/ K0 w2 |5 \
        p = vexTable[v1].firstarc;7 i* Y+ _6 [- a/ H- q$ a
        q = vexTable[v2].firstarc;
    / r0 y& s1 @6 O    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法4 i1 F, @& z3 g4 [% U# I+ H% I
        vexTable[v2].firstarc =vexTable[v1].firstarc;; t% h( U% @" r2 \% }
        arcNum++;! L1 E; K- [7 y1 Y! N5 P
    }
    9 j9 X) C( B9 `1 s+ t: r' a
    + L& s1 X$ P6 I# S6 L4 a9 [template<class ElemType, class WeightType>1 l/ n& @1 z! `! |0 p: \6 r5 a
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2): [, C; ~* s3 o3 `
    {
    ' @7 q+ n& Q3 z: o
    ! h+ [% {; m- C# w    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    7 t) s# A% X. @& W% \; s    if (v1 < 0 || v1 >= vexNum)& \3 S* n% Y/ [* X8 \
            throw Error("v1不合法!");; s5 @0 E- {0 F/ H( Q7 f/ ]  f
        if (v2 < 0 || v2 >= vexNum)
    7 h/ a& @& o  h9 U9 |        throw Error("v2不合法!");
    0 t0 B4 A2 m9 m" `* r" Q9 `* y$ D    if (v1 == v2)
    3 I& C% ~" d# y0 x7 e        throw Error("v1不能等于v2!");
    0 y; S; |2 I, l
    4 x8 z+ d3 Z/ Z" \4 F! R, S4 F    p = vexTable[v1].firstarc;. x3 B! P. b- L* a; ?! o/ a
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    3 p% |& r" v1 U. t6 i1 V    {
    ! [) i; L' q! x! Q8 a9 J0 e" M        q = p;
    * p; i  W2 A5 L1 e" U- G        p = NextArc(v1,p);! l% Y0 D' H7 w2 e( k
        }//找到要删除的边结点p及其前一结点q
    * c0 O2 i+ ?/ h, s# R9 ?0 e, F" K, B, ?- y+ L4 _
        if (p != NULL)//找到v1-v2的边! F* z9 c, R5 h5 X/ S: G
        {
    , W9 P8 n! E+ b7 j8 r) g* N0 n        r=LastArc(v2,p);6 H7 g) V3 ~# Q8 y  M* X
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    5 _' d& R  g& F- f            if(p->adjVex2==v2)4 N. ?+ S) e4 Z# d9 b$ r
                    vexTable[v1].firstarc = p->nextarc1;8 V' u7 b# @4 S5 V9 h
                else vexTable[v1].firstarc=p->nextarc2;
      E1 ^6 Q: ~; o, v) d# f        else//不是第一条边1 z) ~, \# E6 W: t  Z6 g
            {/ ?& I  O8 ^* T) k6 p) ?" G
                if(q->adjVex1==v1)
    $ J) P1 w3 ~/ u                q->nextarc1 = NextArc(v1,p);2 U" y& u) Q; m8 A' d3 Z
                else
    ) m4 d. W8 U, ^! X: x                q->nextarc2=NextArc(v1,p);( |6 }! M  B8 M. p: o9 u* H
    & L. g! d% a0 b/ o1 T+ a
            }
    0 L/ a& H9 t- H7 c& Y        if(r==NULL)
    - a+ d2 @/ r) C/ z. b            if(p->adjVex2==v2)- D+ Z4 f8 A( t, g6 Z  c
                    vexTable[v2].firstarc = p->nextarc2;5 k1 s1 {( Y5 H, a7 q
                else vexTable[v2].firstarc=p->nextarc1;
    5 g6 X( y0 z' }; f* r# g        else
    / \% V& E. i' w$ g9 _" G, ?        {
      k2 J# M/ |. F, `, e) i1 [            if(r->adjVex2==v2)
    ' ?6 L6 a7 s/ z- P- V& [8 `                r->nextarc2 = NextArc(v2,p);' V: h: C7 K8 c, S' C) ^& Q+ L! C
                else
    * E7 S# F- M2 p1 S/ f% S( o' x* @, p5 `                r->nextarc1=NextArc(v2,p);
    8 r" V7 T  `( s0 ~: L        }
    : J' w! z; @$ r: @0 W7 j6 g        delete p;/ w  V  v* I  D- G' S  I  k
            arcNum--;' I1 p0 ~3 b1 b! L# b! ^/ m9 b: l
        }2 ^) l/ E. q( \7 ~# q9 D  c# V
    3 k$ c  f4 a% H4 R
    }
    9 g% k* ~& K" }6 k& Qtemplate<class ElemType, class WeightType> void
    ) A' D4 ?- `) \5 @+ c. R" GMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    2 d$ D! B; O2 L( _$ f3 f' l# r) f{* ^# I# B! r0 w3 c* i, c2 @4 A
        int v;
    3 E+ u* K( A" \    MultiAdjListNetworkArc<WeightType>* p;& C/ |' e0 |( _/ }. Z( r, ~# Z) u; }* i& i
        for (v = 0; v < vexNum; v++)//找到d对应顶点" L" G8 l! R0 W
            if (vexTable[v].data == d)6 T. u/ s* n$ P- u
                break;+ ~0 @% S1 x& R/ M
        if(v==vexNum)
    & [! c; `- s" O. Q        throw Error("图中不存在要删除的顶点!");
    1 S' a: h7 ^. \3 o" z7 r. F- p6 l, G1 o, P1 @
        for (int u = 0; u < vexNum; u++)//删除与d相连的边; ~5 r* \+ a  w+ J% n3 e
            if (u != v)
    0 }& z8 ~; T( W+ H        {" F' _0 F: u+ H0 z, K
                DeleteArc(u, v);
    3 k7 X2 u6 J) j, I9 a2 B$ }; |# z6 ?! A        }
    + t# w: b1 K$ W# Y$ K    vexTable[v].firstarc=NULL;
    / f; B& x% J$ n; `1 T' v$ t. d5 e9 y3 ~0 J' m+ }( ]  I6 R; t
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置* M$ t& `! g/ M( z- m
        vexTable[v].data = vexTable[vexNum].data;( e6 V1 O6 Q; X" i, N
        vexTable[v].firstarc = vexTable[vexNum].firstarc;7 ?1 \: G  [# O, S. o/ |9 u1 G/ T
        vexTable[vexNum].firstarc = NULL;% l3 ~; X: L2 j' g
        tag[v] = tag[vexNum];
    8 L  b/ y' E! ~1 V3 P% B" K' h    //原来与最后一个顶点相连的边改为与v相连
    # s  X7 W7 w* x7 @% l    for (int u = 0; u < vexNum; u++)
    % V1 m: b! ^" e: s5 a6 V$ r    {) V4 A, I1 O# s! ~! ^3 N: Y
            if (u != v)+ Q" e# X4 p. E4 Y$ B
            {
      F. A9 o0 o  h9 F" c            p = vexTable.firstarc;( Y6 V, ^% D' z0 H/ x
                while (p)
    $ f1 V  e% J9 J  |; {% O            {
    * G6 a  U* b: U                if (p->adjVex1==vexNum)
    * X- Q: I$ v: C7 Y                    p->adjVex1= v;" C& {3 g3 m: A# X
                    else if(p->adjVex2==vexNum)
    / K- o# m5 j6 R, [7 k% k3 K8 M. t                    p->adjVex2=v;
    , x2 Z- p/ `9 r. [# A                p = NextArc(u,p);$ _3 t9 M3 S% h4 N- l
                }5 r* T, M4 E% Q  h  W# L
            }
    $ M& k6 z$ _: Q2 p: T3 g    }+ l# W' B# G8 \% f: G! X2 X
    }
    5 ^" k; O$ U# t///深度优先遍历' {7 P1 ~: ~/ x( o
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    ( [. f- X2 Q6 E0 b6 |  i; a{. R- e7 D: T5 a) m% n' c: [' O, a0 F
        tag[v]=1;+ i& J1 W3 h, e% C7 G8 p
        cout<<setw(3)<<vexTable[v].data;
    1 y7 E% n% _1 g8 H    MultiAdjListNetworkArc<WeightType> *p;! r3 b: i8 o  Q. [% E" c: c
        p=vexTable[v].firstarc;4 m1 x4 C5 \6 O' S! i! |7 q0 i
        while(p)1 I& m. A% W, ~4 d: h7 J$ B- [/ f: d0 \
        {
    ' ~# l  P  ?& k* o        if(tag[p->adjVex1]==0)
    / B' f* ~9 l4 H  `            DFS1(p->adjVex1);
    - C5 H1 l- r1 L/ X% |        else if(tag[p->adjVex2]==0)* R  u* E* N4 L4 M, X* P& `5 ^' e1 _
                DFS1(p->adjVex2);
    ; H6 q, e" z* B9 ^3 L        p=NextArc(v,p);/ b9 ?, y# Q8 w; N" b
        }$ C( R: {" o1 K1 A
    }
    ; i. x. y0 q' D6 \template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    4 t" R( o9 x4 t+ r{
    * \; u9 ^5 E$ R  M    for(int i=0; i<vexNum; i++)
    0 f5 I. u/ }3 ^; T9 `        tag=0;8 U7 @4 W+ I% C. }6 P8 n
        for(int v=0; v<vexNum; v++)7 F* A( K! v6 y/ _1 v+ [4 b
        {5 A* C% n* P( j2 Q
            if(tag[v]==0)" ]& N2 ?3 f7 b
                DFS1(v);
    # Y/ `: U7 @/ ~- {( N    }
    3 [9 C2 y1 a/ x) ]: v# k}
    0 ]" o) _# m( s' ctemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    / A/ Y& T; H' D# v0 l/ S, O{( \8 [( B) K. K8 t3 t7 X% B/ S! _
        stack<int> s;
    - i) k' N) d; H" Z    int tmp;, J+ {" A/ Y* c* @
        MultiAdjListNetworkArc<WeightType> *p,*q;
    2 J6 I: g! B1 y8 N% r9 `# l. e    for(int i=0; i<vexNum; i++)
    $ f3 c- b; l9 P1 {5 ]' l- X% R; B        tag=0;  L- ^4 G7 ?3 m. y: y, u/ z) J, {
        for(int i=0; i<vexNum; i++)
    + L! r  t5 j3 G  M( T- I0 g# k0 h* {    {
      x& U% s2 \! l7 G; `5 p  Y2 p1 c        tmp=i;9 B: u; Z! G* d* u9 s/ v2 @3 |
            while(tag[tmp]==0||!s.empty()), s, p1 M1 R$ U+ k2 p: n3 a
            {% Y) _# _( p5 K( p4 b
                p=vexTable[tmp].firstarc;
    , F* ~2 F+ N0 h+ M: @' T4 P            while(tag[tmp]==0)4 P& U7 \. \9 q" w$ {+ M1 M
                {: X& u8 f/ Z8 v' X; K/ }( |/ _
                    s.push(tmp);. W( n' z  Q, L& p
                    cout<<setw(3)<<vexTable[tmp].data;2 b) z' ?5 p; ]5 O7 n2 z
                    tag[tmp]=1;
    0 W! o0 r, K" X1 Q+ g; \/ E                p=vexTable[tmp].firstarc;
    8 O& R+ f* E! I, l                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    3 K% e- ~" g  o7 R* M+ C- M* p                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);/ t* Z0 Y: y1 `4 @2 W2 c
                    //cout<<" 1st     tmp="<<tmp<<endl;2 \8 `, z* }, v; [: x* z% x
                }/ U* p# \4 ~# U/ o" I
                if(!s.empty())* y6 D+ R# \: W6 I7 F' B
                {& m# j: s( {1 D& @; Z
                    tmp=s.top();( Y; ?! D. K) y0 m3 p
                    s.pop();) C- D9 w4 D$ P/ O: g9 b1 s( A
                    q=vexTable[tmp].firstarc;
    / R9 v) z1 y9 q1 g                int t=tmp;4 s- e$ m5 k7 N  D3 [
                    while(q&&tag[tmp]!=0); A" I2 x$ a. O! t/ V6 n
                    {
    1 o5 N+ H) \! n' K  j* ]) x                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);% v' r8 ^( A) C& w- l% X. F
                        //cout<<" 2nd     tmp="<<tmp<<endl;6 L& v1 y; R- k& y/ m' r1 `8 P; Q) c
                        q=NextArc(t,q);% l' n7 p& @: l3 H
                    }
    ! g+ x8 K7 C8 a: Y- X                if(tag[tmp]==0)2 D  Z1 e7 c- V$ a5 s( m
                        s.push(t);
    : V# e: Y0 B' \: ~1 [                ///1、对应上面连通分支只有1个点的情况5 p! n2 p  s' g& S& L; a& u
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    ( C! H  Z0 p" H1 w5 m. i                ///tmp要么等于找到的第一个未访问节点,3 N3 n% m. G0 Z0 ?# K! a4 Q
                    ///要么等于与t相连最后一个点(已被访问过)
    1 e# p6 X  A9 k6 O6 m1 J. |' [                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    0 X! R; F2 u$ X* a2 e/ q            }4 J; K8 p& }4 _; Y7 Y
            }. X4 ^; A+ j( u1 o
        }# E" U6 y) S8 s1 b" V# Z
    }
    ( X) Z& k5 [/ E* c( |; t//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    ; F# P8 |( ?1 L7 T; @& b8 o7 J2 Xtemplate<class ElemType, class WeightType> int8 q* G" c9 p7 K1 O4 ]% ~5 E
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    * i# \4 C% I/ _, }- G( k7 ]{0 o3 ?* Y2 k0 R& p* P. W2 L! s
        if(head==pre)" {/ T& X. j$ c. f( a) K
            return -1;
    2 y! x. g, n, l. q$ x8 N# b6 ^; B7 ]& r. B$ B" U' C
        MultiAdjListNetworkArc<WeightType> *p;4 h: Q( ]5 @- h0 m
        p=vexTable[head].firstarc;
    , Y+ [( o# ]( s; c! Z    if(pre==-1&&p!=NULL); J, i; q2 q, X* [  w- _& @
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    * y" D# I! S: s/ V    //pre!=-1&&p!=NULL' d( z+ @8 V1 o: d5 i$ G# u% r
        while(p!=NULL)
    5 y+ B; z" q9 x3 E2 p    {2 C/ F) N6 G2 _# o% f
            if(p->adjVex1==head && p->adjVex2!=pre)) m) X' Y/ z$ |# U6 S
                p=p->nextarc1;  X' h$ A, K2 p; b6 f8 G
            else if(p->adjVex2==head && p->adjVex1!=pre)
    : T8 g5 M; I/ T0 V, H            p=p->nextarc2;* L$ H  q3 l) p8 w7 c# N' j9 U
            else if(p->adjVex1==head && p->adjVex2==pre); {( L2 d3 L1 J7 Y0 w
            {
    0 F8 y2 s$ ~% o" f' d            p=p->nextarc1;
    & j! h8 ^: g5 I" l3 ~            break;: R' z/ x- R' V9 W1 p# L* h( L
            }  Q. D) Y- ~' W
            else if(p->adjVex2==head && p->adjVex1==pre)+ k" @0 i2 t. S
            {
    8 u4 n+ C7 I/ \4 H  k            p=p->nextarc2;7 d, k# p3 m, {1 q2 B; J6 r
                break;% p5 Q  v7 Q. o9 [2 N. I
            }+ p$ U5 ]3 R8 e1 [- o* s
        }
      d% W$ ?, k4 K( l& y7 M    if(p!=NULL)
    3 P+ e; q" @& N* h) `1 W/ ]1 b    {. J% X2 h/ |8 e- D/ i
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    - \+ J# p1 N! Q- @, ]0 \    }0 w9 j6 ?* y5 E+ l
        else
    # }2 t4 c4 B0 L0 |) r  q        return -1;
    : @1 [  W! f1 r: @4 S1 K! U}. _# K0 y& |1 T' y& ?* |
    6 n9 [, Y. e1 s

    ; q, X' I& `& D/ Rtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3(), @; _4 }" q! c- @8 {- Q
    {
    6 q, h- a% g! o9 ^: G    stack<int> s;
    / j+ o+ H1 z6 d1 h" i& \/ q    int p,cur,pre;: Z8 B2 L  W6 u6 f# Q
        //MultiAdjListNetworkArc<WeightType> *p,*q;
    * f5 ?0 {4 m+ R    for(int i=0; i<vexNum; i++) tag=0;//初始化/ T7 |4 S! E- H8 B6 H' Q/ e% U
      c  J9 a8 `* A: H! [
        for(int i=0; i<vexNum; i++)/ H- l( S( `9 S% ~$ G
        {
    # a7 Y- I7 J/ X6 u        cur=i;pre=-1;
    4 m  t, h9 m7 ]1 j        while(tag[cur]==0||!s.empty())
    1 _/ F8 q( T8 u' c        {
    * `' q: q1 t; p2 G% @$ d            while(tag[cur]==0)- @' g; K4 w9 m$ Z1 p' |
                {( X5 U6 W' |& b4 F( p, C1 {5 n& n: p
                    cout<<vexTable[cur].data<<"  ";
    ; ?8 l; U- _; n. l, H                s.push(cur);& j+ M9 Q$ E: `; ?3 z# _, `
                    tag[cur]=1;" ~5 D7 o& {/ @% t% w3 Z
                   //初次访问,标记入栈( F$ R# ^8 T. l+ r( m3 |
    , i8 u6 E" W. J' V
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点
    $ ~) M2 Y3 c& u  ?               if(p==-1)3 M. B* f0 B2 \1 {4 G: x2 l6 C& ^
                   {
    / B* {2 w! q$ K; @, N% F8 Q                   pre=cur;s.pop();5 G; ^/ b1 B+ A" y2 Y
                       break;
    # V/ M$ M6 p3 q2 Q! K* ^! N1 z# y               }) r3 i! v9 o) B! L3 z, n9 V% L: ]
                   else' z8 O/ B. o( C1 M
                   {( c) h  e# O7 y" B; U+ P8 S  h& j
                       pre=cur;
    . ?9 C# W' v- y( r- S                   cur=p;
    , T0 m+ w7 v0 {& k/ P               }
    ! N' Z- ^/ X. s9 D0 T- ]5 Q3 }. b- E  V6 t9 @4 E
                }
    5 d, ?5 Z$ U0 j2 }% l9 D& n2 {            while(!s.empty())% _; j' P7 z5 w2 `
                {# r" Z$ d  W4 K7 r; c
                    cur=s.top();2 }$ A4 ~# Y5 }3 R# N8 v4 N
                    p=GetAdjVex(cur,pre);
    % ~5 P6 a% X5 O7 J+ B; q# W                if(tag[p]==0)
    " v6 ~9 N# N! j/ q) T: m                {
    , H! b7 d& C: `/ ?                    pre=cur;
    & q5 B0 ]( [9 S" D4 f3 [                    cur=p;
    8 d. V# A( \/ R$ o  M: Y                    break;
    + I/ C4 P; h0 m; ~                }6 n6 a' n( f: {% [
                    else: B0 ?; O* i9 ?- W# I7 o
                    {
    $ T8 \: A' h$ I5 N                    pre=s.top();5 f% ^! g4 w+ F1 F+ i
                        s.pop();
    $ \' C% @, {( v; h2 _                }- B- ^% g# l# J) |

    - _6 ]2 g6 j! `+ [            }1 r+ r! B3 e! z  `2 {
    , J% f: y+ C- M# C( V
            }2 m: P" f& d% c# y$ s2 y5 l6 r
        }
    ( l. ~4 b. Q* `. H9 @}2 x" y5 y) _- x& _9 V
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()) \' q$ b2 H# X& Q" |/ K+ x
    {
    + D) F$ d1 _& X+ H5 S0 Y) ?    for(int i=0; i<vexNum; i++)* ?! |/ m  h1 z
            tag=0;* r9 J( i+ a" F2 I& y( f. f
        queue<int> q;6 R" O; o$ @, T
        int tmp,t;
    ' n6 c! F2 T  v# v& e$ `    MultiAdjListNetworkArc<WeightType> *p;
    7 g9 }% _4 I% q  I0 s% Z5 P    for(int i=0; i<vexNum; i++)
    : a; m" W4 J" [! o- p    {
    % C! K/ X: _; p7 c: ~4 u# G) I. _        if(tag==0)
    $ V. N$ ~  I1 i" h7 f2 A- X* A+ n" w        {
    - e" a) p- h3 u6 a4 O4 _            tag=1;" i; W+ L# q5 M/ R: \' A$ W
                q.push(i);
    ' ]/ a6 u$ U# U* J; O            cout<<setw(3)<<vexTable.data;
    3 M8 z, P  z/ A* B        }
    ) g2 W+ m- j' e        while(!q.empty())! O, Y1 I8 ^1 r9 t" j! m" U. c
            {
    . n. `  A5 h0 N4 E5 r            tmp=q.front();
    # \3 N" Q7 m  }* m  j: ~7 B! D            q.pop();
    3 W7 Z2 j( X' Q1 N/ i6 X            p=vexTable[tmp].firstarc;7 C/ Q+ u# h% s
                while(p!=NULL)
    4 K2 B7 L7 Q  W8 z: n+ o+ {            {
    5 Y# {  v; N& C1 ~                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    # m5 L  X3 j+ p( C                if(tag[t]==0). x2 n5 q  t9 Y, Y* A% h3 _
                    {* ]: K% `2 c, F* Z% v' [. l5 Z
                        cout<<setw(3)<<vexTable[t].data;
    ; s6 o# m/ t5 Z7 Z$ a; ?9 r- `                    tag[t]=1;, Y. S5 T; d% {/ N& G
                        q.push(t);& q& q' o9 s% U) H7 a3 Y) i3 c2 t
                    }; L) e( x- f8 ^. P  e
                    p=NextArc(tmp,p);! u4 {, [$ q' J- k, P) y  P7 u
                }
    " T! w6 Y6 `4 y: t4 u$ y+ x* z        }' e6 r8 G& A2 g* T4 ?7 \
        }6 _2 T% Y" n* R& V: G) T% l
    }$ t- h. w" u# `% X3 H) _
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()9 p7 E' d5 V! Q& b2 B7 ?
    {2 x7 X6 \, o; j
        MultiAdjListNetworkArc<WeightType> *p;" K- x- B! f( Q
        cout << "无向图有" << vexNum << "个点,分别为:";2 U- ?% Q# S, d# I. I
        for (int i = 0; i < vexNum; i++)/ ^  n, m5 O+ u2 [5 F- Y9 o
            cout << vexTable.data << " ";
    ( B3 }3 H4 I, r% {    cout << endl;! H$ [. n2 L# }) ]% S, a
        cout << "无向图有" << arcNum << "条边"<<endl;$ w% ^7 u: C  \6 v# ?4 H5 z
        for (int i = 0; i < vexNum; i++)8 K/ X  Y% ^  y
        {
    % C; ~6 |& h  N+ |6 F7 S  Y9 `2 I        cout<<"和" << vexTable.data << "有关的边:";9 L' p: V- a1 V- q( k/ ?# S8 Z! d
            p = vexTable.firstarc;+ L8 ^2 a  N8 g% P  y9 I, O
            while (p != NULL)
    # w; ^- A& D( B3 z* F, m3 U5 J0 a        {; E- l4 O8 p3 L$ r9 J
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    % s0 b4 e% d1 i; k. X" ^            p=NextArc(i,p);) d3 y  l- \/ o, L* N4 s/ m# G
            }# F5 ~, Y2 |( s( @  `
            cout << endl;" }7 F7 W* Z1 O+ i3 B" x" Q' a5 Z
        }) T9 w7 E7 ]5 f
    }
    . i' _4 B( |/ X* W& U$ x: j& h% N
    3 E9 N7 a; W/ x8 o' `
    9 U* d) B/ y+ m9 s" {. @! e邻接多重表与邻接表的对比
    4 G; r9 S" B) S4 U3 I% N1 m( B
    8 G7 H! F- \" D4 ^. ^( p9 }邻接表链接" g7 f( ^0 v! }0 r9 Z
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    0 k$ _: n8 j; S  }& l在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。# l. C, W1 x6 W( c1 |6 V! I5 q5 M
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
      t8 H  C8 n% U, I% g' I1 v) G& X————————————————
    5 T% n7 t7 e( g# M& S+ e7 ?& t版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    3 A7 W% ~* P. M3 t2 S7 p原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    : {2 U' _  b# n/ {5 ~3 ?4 m% I2 M1 X' N3 @

    $ L* u0 P. N4 ^& n4 A+ Z9 A' p/ _$ M$ p* b' O

    % ?+ z0 }% ^, L- ~  Q————————————————4 ^: w' v/ A" N) O
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。0 M8 u( v5 R- K- B; i$ t
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958; l0 f$ L* I  @: R- J" C& \
    8 r2 `/ F. T3 o* E

    # @7 T- g' z6 t8 }# T+ \+ ]
    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 11:04 , Processed in 5.476382 second(s), 54 queries .

    回顶部