QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1694|回复: 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
    ; [) y0 D! x7 A! r& Z  E
    图的存储结构——邻接多重表(多重邻接表)的实现
    + ?! H% \1 O, B% Y  l9 t7.2 图的存储结构
    + W' b" x. ?1 p4 ]
    ! f* Y( S/ X0 B* R7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    % c# p; [9 d# y$ U2 r1 y# w) U1 K! |9 ?邻接多重表的类定义1 \( `* S/ ^) H2 l' ?' k
    邻接多重表的顶点结点类模板
    ! |9 k  Z" c- L9 p+ l1 z* ^邻接多重表的边结点类模板
    5 @/ x" I# b2 ?/ e2 \邻接多重表的类模板  M5 \+ u4 P/ m, j" e1 p2 G
    邻接多重表与邻接表的对比% q7 B* ~9 E+ _4 d) W
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    % M7 [& q& d% x% L7 I2 q1 h  r7 a! ^0 M0 F9 q
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    9 {2 T+ Z2 d. U在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。7 G, t' }1 z- X
    ; H$ [3 {2 c1 j1 M% _& R
    邻接多重表的类定义
      X2 m0 ^0 o* A! h5 s% ? 1.png , v0 g2 L- ?$ \
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:+ T, P% |8 r$ I- ?. h
    data域存储有关顶点的信息;$ Y3 B" Y# d2 \% l* `5 y0 P! Z
    firstarc域是链接指针,指向第一条依附于该顶点的边。
    ( K  Z( N5 w  [% U! A# G0 G9 a' l7 Q; f所有的顶点结点组成一个顺序表。

    3 j& \$ e- W) Q5 B" o
    ( A2 m" L  C! l0 h" s$ C: U) ~
    template <class ElemType ,class WeightType>( A% h1 r9 X, N( {% C
    class MultiAdjListNetworkVex
    . Y, E: S  q: t! D& Z{
    ! H. N. S6 |( dpublic:' d9 p) i; l, @- a# I$ k5 T
            ElemType data;$ M2 ]+ D( t# [+ j. T
            MultiAdjListNetworkArc<WeightType> *firstarc;
    $ @' Z- @3 ?* N+ J/ J' t+ s3 w$ P  j. U
            MultiAdjListNetworkVex()4 J. j' y1 ?8 i! \2 V0 g
            {
    ( A8 L# W; z% o8 d                firstarc = NULL;- g4 G1 p' i( `3 h+ O- D
            }4 y8 M; F& B* i& p) U7 K
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    7 F& S/ p5 k5 m# ^0 @& k! ]' ^        {9 |" @# D  N: C; N% E5 y
                    data = val;- R5 _# y0 |. r% L6 C
                    firstarc = adj;0 Y3 ~  @( j) C. Q8 F$ d
            }
    4 R1 e: x& e* G};
    0 e$ o) j' ]! x8 V7 p0 x; t( n6 j& K; I4 _
    邻接多重表的边结点类模板
    + _/ M8 M4 @8 {
    # [! T/ R" {0 j0 b4 e5 {在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:, ]: B7 \7 j1 {* i4 y' Y: [2 U7 `
    tag是标记域,标记该边是否被处理或被搜索过;6 J; o- U2 ]3 D3 C6 s
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;+ ]3 ~+ ^4 M9 N$ r
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    4 w5 x/ u  s. O! [; S# _) pnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    + x7 |+ l3 S0 f* k! p" S3 x( g, S9 k' p
    2.png
    6 S+ z) x# ~* S4 W- @  ^' @( Ptemplate <class WeightType>
    - K2 t8 C1 [3 ^4 {class MultiAdjListNetworkArc
    2 M! ~; b0 w9 T0 j{
    + r  W  S6 b" ~, s+ S1 ~7 ^& C& jpublic:1 ^5 g9 c2 b& k6 W$ e, Q1 R- F; c
        int mark;                                       //标记该边是否被搜索或处理过
    1 |: P8 v- D! j        WeightType weight;                              //边的权重
    & ^- G" @' S+ M  C9 I3 S+ ]        int adjVex1;                                    //边的一个顶点# j! e7 `0 Y3 o% Q2 A
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-19 R' V/ n- [& @4 x: `4 d
            int adjVex2;% [% a0 x3 ?  w( J. F
            MultiAdjListNetworkArc<WeightType>* nextarc2;6 b" E4 [* B8 D* \/ I

    ' K! {. v9 q( ~! R( o        MultiAdjListNetworkArc()9 _& D* R2 a( U7 M
            {6 |6 q, E" K$ I: A: `, z
                    adjVex1= -1;
    4 \1 R( `0 k2 X5 a                adjVex2= -1;
    " p$ ^8 z1 t" M& @' f+ O2 l8 G: W        }/ m# Z" p4 |3 u3 j5 y
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)5 R7 a7 ^; z6 C" v5 Z0 e
            {: ~* A3 `5 F6 c& G
                    adjVex1 = v1;       adjVex2 = v2;
    - e5 C( q$ ]6 {, S5 v                weight = w;6 \7 i5 h% s4 r
                    nextarc1 = next1;   nextarc2=next2;+ \' b$ P7 M, W, X
                    mark = 0;           //0表示未被搜索,1表示被搜索过" ~) T$ p4 r  T! }) y( M
            }
    ; r+ B# S) Y0 q: f& }7 q& A' b- J# f- G* J4 W: S2 r+ f
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>: @/ \! ?: ~, X+ t9 s
    class MultiAdjListNetwork1 Q5 F/ B& U+ S
    {: i6 ^: n, x# s+ A0 C5 x
    protected:
    3 J# y: i) q+ q5 }3 K8 Q" j    int vexNum, vexMaxNum, arcNum;: N; \% a# N# \- X& L, Y& X
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;$ M& {7 Z1 V$ R7 J
        int* tag;
    1 ^+ G+ @! M1 v" Q2 F    WeightType infinity;
    4 n# V, ~! A. E7 K* l  e4 D3 e
    $ D8 k/ f) k" ?  s( w5 n& npublic:6 i( F. K5 X4 [( Q: k+ ^
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);3 }3 p8 @( ^. e

    ; P" P& j7 ~( o' T+ T    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);" s; O% m% y! L
    , |- T% f( a) I8 A  v2 m  r" J
        void Clear();
    . b7 s  A1 ^0 J8 |& c    bool IsEmpty()
    : R+ z* w8 p" o2 W    {7 o* ]+ ]- v% p0 f. q5 H
            return vexNum == 0;1 I" P+ P2 ~+ w: j$ c  G
        }
    , b4 d" n+ z" ?! Y/ {    int GetArcNum()const
    " S2 [: w1 O& l+ W6 ?. b! j$ {    {
    3 `4 w3 N1 L* _; h. Q% {9 ~        return arcNum;# m; K- c- L" |" X
        }
    1 F4 m0 o4 t* k: ]$ S' S' d5 |$ H    int GetvexNum()const" j  ], t/ x, s! ]
        {
    : F- Q% h  _8 ^' P! R, [$ q        return vexNum;
    ( y0 j3 `5 j" `: x4 @    }4 _8 V( O8 l$ [5 Z: J
    1 t0 w9 F/ {. X. x; f6 l

    ; |$ C. |- V: ]  U+ [) x* L0 x' o6 `/ V    int FirstAdjVex(int v)const;
    / T: r& A. _% c! a6 }    int NextAdjVex(int v1, int v2)const;
    8 G7 m9 x; l9 o    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;' A, D8 a; o6 S, d
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    $ @8 g2 k: v% W  O1 x# j* m" P6 Z# n9 }7 P* T9 c
        void InsertVex(const ElemType& d);: T4 m& c0 ?* o9 y7 z  E( w
        void InsertArc(int v1, int v2, WeightType w);" L0 ]3 F5 O5 n% v) g% V  \- d4 C7 n
    ( F; _  e$ V, ~, ~9 t6 O5 C
        void DeleteVex(const ElemType& d);9 S7 `5 g% i, S- `( N- s" i
        void DeleteArc(int v1, int v2);& D7 S  i) ]: P% f$ b0 g

    , n! m0 A% z" l    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    0 ]) D5 M4 K( Y5 \  ~0 a- h    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);  x7 F* l# O, P) \6 S9 ^. l) S
    * a/ v. J, |4 o
        ///深度优先遍历0 f) ?$ O+ g7 K
        void DFS1(const int v);3 P: W" _' z+ I8 z% S
        void DFS1Traverse();
    ) k) C2 c( M# Y8 P1 P    void DFS2();
    # Q& A: V7 I! v/ @2 H2 @" j
    ) G7 U: j. {! R* N- _    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    & M" X$ x1 x2 O* v4 ^    void DFS3();
    7 U6 {4 Z, L1 _7 x+ I* f; f
    6 f  _1 Y' s0 F1 J$ g5 E' M    void BFS();, e5 S6 d, @! U6 {& ]8 {
        void Show();4 E" a$ L+ N# |! p
    };/ y- `( A6 `" ?2 K" T2 S7 }
    1 v6 K0 n8 n" {0 I% V
    2.函数的实现
    : }* a" n- a( S$ @研讨题,能够运行,但是代码不一定是最优的。& l  H) [$ l4 t& R( @, V/ A4 {' O
    0 T# ~% G3 p+ V, i# X3 }* s
    #include <stack>3 c$ ?' u( R# s1 y/ r
    #include <queue>5 X2 M  g) V* p  f- h9 \
    # h8 r! A; Q6 ~/ F7 v; [
    template <class ElemType,class WeightType>! U' W2 h) `. K
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    / W& q! _, B4 z& Q9 V1 f& C{
    & U* [  X) \8 x    if(vertexMaxNum < 0)
    % m2 v% r& m8 C' t1 i        throw Error("允许的顶点最大数目不能为负!");7 U4 Q) Q8 u! {
        if (vertexMaxNum < vertexNum)
    ' R1 p7 N. P5 r" Z) {7 m- o5 \% F        throw Error("顶点数目不能大于允许的顶点最大数目!");
    & `0 R. D8 F8 r& ?6 P* c    vexNum = vertexNum;& G& L8 m  I+ o2 E5 ]7 c
        vexMaxNum = vertexMaxNum;3 i/ p1 D- o4 ]' z: K
        arcNum = 0;
    ' Z! J6 ?7 F/ z    infinity = infinit;
    $ D9 ]0 I" G* u2 Q2 r# \    tag = new int[vexMaxNum];9 m6 S6 S/ I+ f+ I5 g  Q
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    : [% j! y, w8 M; C- n$ I    for (int v = 0; v < vexNum; v++)6 q4 }6 g' K! q. Q$ r) R  [% }8 X
        {+ Z3 P& a; {. v- A) {$ O6 c
            tag[v] = 0;
    & i) [$ Q2 u4 U& m) X: Y' x  i        vexTable[v].data = es[v];9 I1 C! \1 d. N1 ?1 b" D8 y
            vexTable[v].firstarc = NULL;$ K- ~. z, q+ \; S$ N8 s9 u
        }
    ( i) U( y# S/ r7 Z0 K3 P* V}5 f! U4 M0 c1 o9 V4 u) P
    template <class ElemType,class WeightType>
    % U" E8 p7 x" o: S% J! X4 pMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    " v: E$ O4 F5 Z; R7 [6 ]0 C2 o2 O9 r{- O) W1 U  S: a) i
        if (vertexMaxNum < 0)' f+ R+ n/ a" y- e
            throw Error("允许的顶点最大数目不能为负!");
    8 O1 Q8 x- {  i1 x- \    vexNum = 0;
    0 V! C7 L; Q* P- G    vexMaxNum = vertexMaxNum;0 p& Q- F) i3 s) s" t4 Y
        arcNum = 0;# t- V) I1 i* [" E2 H
        infinity = infinit;
    0 X0 Y( R& A- m: p7 s+ M) g+ U0 a    tag = new int[vexMaxNum];5 g. N  E3 f/ i, P
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];! ~+ J% j4 D! w/ L9 `# {0 q9 v  K
    }! I' m; h6 w" {- z/ A, O8 i' h
    template<class ElemType, class WeightType># I! s" N5 n% p. z# _- X0 \
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    - C5 k$ P6 B2 J  |: x0 K{) `+ J& r5 ^; m: n+ Y& B8 ?
        if (v < 0 || v >= vexNum)
      w5 [- Q+ W1 X# D* _5 t& Z6 I$ S        throw Error("v不合法!");
    9 ]+ |  o& f$ w; j3 D% W    if (vexTable[v].firstarc == NULL). `" u. t3 \+ u2 p3 c
            return -1;
    2 S/ p& A- L5 ~    else
    & F" Z4 P! _1 \0 D' o        return vexTable[v].firstarc->adjVex1;( B+ n, {, Y$ w9 s; f: F* R
    }5 e: X$ c2 v8 j" @) @# ]

    8 H! e0 T1 c* w5 o" otemplate<class ElemType, class WeightType>
    / X: ~1 I# n4 \9 R9 B' rint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
      c5 u& L# M2 R" w{
    / _& {; l) c1 r4 V2 T    MultiAdjListNetworkArc<WeightType>* p;
    ) a6 V7 n% p3 z  [    if (v1 < 0 || v1 >= vexNum)+ m0 O5 {8 d( `
            throw Error("v1不合法!");& c+ H$ @3 ^9 L
        if (v2 < 0 || v2 >= vexNum)2 l- |& V; F6 m) ]) u$ d
            throw Error("v2不合法!");0 Q  f7 J; ~( V0 b+ H8 r7 _
        if (v1 == v2)$ g% \+ K" i2 l
            throw Error("v1不能等于v2!");0 h% {7 Z) V/ |* N: t9 N
        p = vexTable[v1].firstarc;
    : X! X5 Z3 Z. c  j. ^( B8 d) J) D    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    ! h- U: e. G0 [  i$ J        p = p->nextarc;& k! D" v) i% v
        if (p == NULL || p->nextarc == NULL)) V& K7 F: V+ L- w# V
            return -1;  //不存在下一个邻接点
    - m) h- l  @, V4 M6 s& w    else if(p->adjVex1==v2)( P3 z9 X" `! L1 J
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);: V7 n7 {$ d' k
        else
    ( x. c9 ~) }5 ?% w, a, T- v        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);$ z# e2 j6 T; x: c( s: `! i+ i
    }5 I& U* e- x' D0 M" ^5 o- S$ J
    template<class ElemType, class WeightType>
    ) E: A# n) j1 a% ~& Z* m: Svoid MultiAdjListNetwork<ElemType, WeightType>::Clear()7 |/ N4 q3 M# }. C1 r- ^
    {
    - b$ }' j7 U0 o0 T    if (IsEmpty()) return;# G# e: E9 C: d
        int n = vexNum;
    5 T/ j5 D. e& i" v5 m" ^  q    for (int u = 0; u < n ; u++)
    3 i$ l! K# i- a5 n        DeleteVex(vexTable[0].data);
    & x, W6 [+ H) |7 D" d1 ?    return;' w- P2 Z$ m3 x- Z% r5 a
    }. {( J% y- }  v* T0 s  u
    template<class ElemType, class WeightType>
    % Y; C* I8 x0 w& w& ^" |4 g, oMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    % \! y2 u9 y; ]6 z4 i; Y, z6 p{
    # ~' m  ^& A" z0 {9 k& }    Clear();
    ( Q( h' M' d# E6 G}
    7 A! j: f) b8 H% S  |  A% g( C5 xtemplate<class ElemType, class WeightType>
    ! i9 V/ x+ W9 m# a) Z# E: h7 ~MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)4 M7 ]1 |* W% a; e$ |
    {  Y3 v4 H- c* E+ o
        vexMaxNum = copy.vexMaxNum;
    4 m9 H# Q. g8 G    vexNum = copy.vexNum;- n- A$ ~, ?! N' ]
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];/ `* O) R4 q- H8 o# g+ t2 f" q
        arcNum = 0;( G3 }- B9 B7 M/ j* Z" K1 ?
        infinity = copy.infinity;' s. h6 Y7 W5 a8 \: X$ T/ y
        tag = new int[vexMaxNum];' O* M$ J9 N, N. `0 B
    ! l( ?" P9 y4 ]6 W3 r0 M5 ]4 n. p
        for (int v = 0; v < vexNum; v++)7 h6 n8 y  l$ M3 T9 C; f. U' y9 Q$ P
        {
    8 Q% c/ Z8 F; O1 x9 _        tag[v] = 0;
    1 ~: b$ n! {( a9 R        vexTable[v].data = copy.vexTable[v].data;  n$ S( ~. A& R
            vexTable[v].firstarc = NULL;  i: j2 K# ^! [: u9 Y" m
        }
    0 g# ?" `8 z) `    MultiAdjListNetworkArc<WeightType>* p;2 Z3 ]; H, W6 B
    " ]: T+ Y- }) r4 o8 z/ T9 O4 H
        for (int u = 0; u < vexNum; u++)0 g+ {3 h7 j$ u& b9 M) r
        {
    * ^$ \3 k# V- s6 Y        p = copy.vexTable.firstarc;. m; m9 r5 T; y1 H6 s7 t& }+ c* v/ r
            while (p != NULL)
    , [0 h2 c: L, r2 f8 U# E- b" Z% L- v' n        {6 D  M/ g8 x' J) Y( W% @
                InsertArc(p->adjVex1, p->adjVex2, p->weight);+ v, ]5 {- h+ Z& x5 F+ z+ y
                p=NextArc(u,p);8 [4 D$ y: X* g# |- F  H  v
            }" I" e6 b. m" @
        }
    , ~3 z8 k7 I  @}
    ( s  `2 |3 r1 e7 K0 N8 Dtemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    + v& Q! j" c2 D5 kMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    * I3 }  }' J% {! C4 O! Z& J{
    2 X1 Q- L' Q- G1 j( M1 j; d    if (this == &copy) return *this;
    ) u. E7 Q+ c: V" e    Clear();* h5 E; Q3 \1 n% A  I% s4 K
        vexMaxNum = copy.vexMaxNum;
    ; l: A- N  Z+ d  N0 J, V4 W    vexNum = copy.vexNum;  d* k" C3 c# G& D* e
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];+ V* s/ N: i8 r4 g# N! C; P: Q6 W
        arcNum = 0;4 ^  W3 E6 |% R7 [1 [5 U. r
        infinity = copy.infinity;
    2 z8 c/ e6 W- \) m' T- k3 r0 f    tag = new int[vexMaxNum];3 e: U( _: }) e+ A
    * t; {) X3 B. t4 k- P$ z* @& l
        for (int v = 0; v < vexNum; v++)" F7 R0 K, C8 Z! K. @
        {- o% k- y* m6 Q# c  D5 {5 @9 `. z
            tag[v] = 0;
      @+ o; T4 K( B* l- ]/ A        vexTable[v].data = copy.vexTable[v].data;
    " V: n; p, V$ v* E( x; @+ A        vexTable[v].firstarc = NULL;
    1 j4 c* O+ e/ _    }
    * o* _. C0 l! p" @1 Y8 `, p    MultiAdjListNetworkArc<WeightType>* p;
    7 p  l; a$ |" }- n, v  T% i" t0 X' T% q& m
        for (int u = 0; u < vexNum; u++)8 K, }7 m7 W/ K6 ?3 V9 i$ F
        {
    ! ^; ?- [4 r7 u6 z7 h- v        p = copy.vexTable.firstarc;1 H5 r# g& g( p! G4 Q$ J9 @! B
            while (p != NULL)
    3 C# a5 R: @: _8 [        {
    ( G$ v1 J& T) d. z% X            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    1 ^" |' f6 s6 Y$ A- ?            p=NextArc(u,p);
    - d, h9 D* _7 [) a. u  E& w5 i3 N        }& Z- J# C5 A/ a5 ^
        }2 a( R1 j7 H/ q* a- L2 K6 n
        return *this;- s: V( H8 |4 T. p; \
    }0 Q6 V  w8 J4 q/ G7 r8 M) Z
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*. S* l* Z. y2 w8 ]+ Y. K4 G. z
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const+ Y& [) V/ _1 I" D4 ?' B
    {
    , u, D" o( T5 e6 e" H4 j/ P, S    if(p==NULL) return NULL;
    ) b" S0 I5 a- l* |! Z    if(p->adjVex1==v1)3 t3 c, D& q/ K8 H/ p* V
            return p->nextarc1;( Y  i# v. T" F7 w8 O
        else
    " p5 a& H% ]4 K9 n" L        return p->nextarc2;: ]% u) ~( U2 X( l
    }# P% _, j; W# F( M" k- E
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*9 R' P1 Y' ?" n9 u  f; K( j
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    8 D) |+ l0 R" O% ^{
    2 w5 O8 M) V9 ^1 O2 v" H5 J; e    if(p==NULL)return NULL;
    5 @2 t. d& ?9 v7 F    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;' b: v, B' Q$ j5 \! e6 C" ]
        if(q==p)$ L" Z- V. S: g& {
            return NULL;
    2 O* t0 o7 C. T, m; s, S0 B) c    while(q)
    5 p# k0 H, U. @0 `    {
    + m: n1 r0 J4 @5 F        if(q->nextarc1==p ||q->nextarc2==p)
    ' @" @2 P* l+ E3 c! Z            break;
    1 K9 A! u4 a( a# i& p$ C        q=NextArc(v1,q);& W( D  |+ _7 ]3 p
        }, C0 }2 l. t' B1 C9 H
        return q;
    * ]/ {# y) b6 e}1 c" o9 j, j. x' K  s
    template<class ElemType, class WeightType>/ ~1 A# u. t# b8 @8 J+ p: G' {! g
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    " Q. j& H! C( z/ t( E" f! i{
    ' O. i8 T* L! E: v9 a  F    if (vexNum == vexMaxNum)
    % e# L! y# y9 @7 ], R2 V9 j. J        throw Error("图的顶点数不能超过允许的最大数!");
    ! s0 j9 G  _6 |# N; p" K& F8 @    vexTable[vexNum].data = d;) |6 J7 ^& x- D) J
        vexTable[vexNum].firstarc = NULL;
    0 N, ]! I/ x  {: x0 |    tag[vexNum] = 0;
      \+ X! M$ _( `    vexNum++;
    6 [8 a9 n9 h9 X9 g+ \}
    ) u2 l# Q8 e2 \( itemplate<class ElemType, class WeightType>+ I9 `- L1 ]- M4 A/ N6 U& F
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    # j. ~0 p: l# c/ y: |{7 d2 e, T8 {5 g' O
        MultiAdjListNetworkArc<WeightType>* p,*q;# y1 F2 d% |- U
        if (v1 < 0 || v1 >= vexNum)6 _! b+ ?5 K, y+ C) `+ X
            throw Error("v1不合法!");
    - s, g  `' X8 ?& l% s7 \/ y    if (v2 < 0 || v2 >= vexNum)2 g$ W0 k* Y5 M7 o7 w( ~3 b" u
            throw Error("v2不合法!");
    + o# g3 v9 G4 d+ E$ A+ i    if (v1 == v2)' n/ ~, ^- m6 G# f+ z# O) h7 t4 S0 I
            throw Error("v1不能等于v2!");
    # n7 {3 i, X# t4 W0 m  G% I* [    if (w == infinity)  T" ?$ A& O0 P
            throw Error("w不能为无穷大!");+ `' I! g8 k. B, e2 z3 ?

    - Q: b2 r3 d' u/ |" D% t( N" F
    ( g0 i/ e- A$ d; P: F    p = vexTable[v1].firstarc;+ K2 `: [' G: K8 B) D$ H( P. l8 n
        while(p)! C  F' [2 H2 t2 i
        {
    5 ~  y  U! G* ^  u* @7 h; l/ ]        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    1 h' y& Q. w- z) w2 y+ k% C        {% l8 q% i; _% Z4 ^
                if(p->weight!=w)+ W" f" p8 B% s. c
                    p->weight=w;
    6 |; {( K$ Y4 j3 _9 W            return;
    # p$ |7 V7 n0 |- F        }  d3 `5 T- U- I: n) P) u( X0 f

    ) k4 {) i7 d, t2 O! B5 R- u( `        p=NextArc(v1,p);, w6 E% S) g1 y6 e' ?3 k: g
        }  r: c% g0 B& m
        p = vexTable[v1].firstarc;
    2 `4 D+ [& L3 z    q = vexTable[v2].firstarc;! J, T) `7 L% [' T
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    3 V) C. `0 U& ~8 O; f. E6 R1 l    vexTable[v2].firstarc =vexTable[v1].firstarc;7 E# ^' y% ~( e7 h: `7 b
        arcNum++;: I' o. p* g, `! V/ Q0 ^
    }# f! `  c2 x0 _! a, X% y- V

    0 D1 _* H! x& @) ~  c0 ktemplate<class ElemType, class WeightType>" ~; v2 m% C6 h- S" v6 ]( W- i* i
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    2 z$ j1 a' L9 [{
    ) }; K9 a( ?2 O) V3 x% m4 V
    * j% l- h7 n5 p) c9 V    MultiAdjListNetworkArc<WeightType>* p, * q,*r;" V: {3 j. C3 s) ?+ w/ F' B
        if (v1 < 0 || v1 >= vexNum)/ y" Z$ ?4 \, B" I# L/ P, A' x+ k4 f
            throw Error("v1不合法!");
    6 D1 i% b. |! R) M# M) |+ J& s    if (v2 < 0 || v2 >= vexNum)( n0 o# C2 f0 \7 O# v1 M% m& i+ n
            throw Error("v2不合法!");
    * c9 @, A% S3 H  y  t" G, ]    if (v1 == v2)/ J0 x" n& X2 I+ \3 d
            throw Error("v1不能等于v2!");
    2 }( {+ ~8 u; z2 A1 }  j
    $ k7 k  S5 p) m& V( k    p = vexTable[v1].firstarc;6 N$ `6 ^- {  ~& f: m# d/ s
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)2 o5 J# |, `$ N3 |/ d
        {
    * z! F. [4 C0 a2 q# j        q = p;
    $ R+ |2 j8 x3 D6 D        p = NextArc(v1,p);
    " p5 H! B* v0 }- J8 @! c$ s5 [2 t5 E    }//找到要删除的边结点p及其前一结点q
    ; e/ i; a" o& o$ G" W0 f; C& m* \6 \
        if (p != NULL)//找到v1-v2的边: n( `' X0 N, E
        {1 }' t* h! K$ E% K& B' E
            r=LastArc(v2,p);$ l  ?5 ?9 I& m7 X9 A, L8 H0 M
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    8 u2 R. S- ]. {( i2 O            if(p->adjVex2==v2)  W0 @1 d" D' C. t% A1 p
                    vexTable[v1].firstarc = p->nextarc1;: x, b" |$ ^7 P( Y0 Q8 E
                else vexTable[v1].firstarc=p->nextarc2;
    " d/ V6 u6 @. ]8 y) K, Z        else//不是第一条边
    3 O3 n6 W; E6 m+ ^/ r% d        {
    : }& u0 H1 ~8 v6 _0 `. J- S6 Q            if(q->adjVex1==v1)
    3 Z+ Z! C4 ^: ]/ n4 \# ^9 ^                q->nextarc1 = NextArc(v1,p);# H( n: r  y& p/ L$ d
                else8 C( Z! I4 a4 [+ C. Q1 g
                    q->nextarc2=NextArc(v1,p);
    1 {  q0 v& @* i( X& U4 \
    , t- R, R  H9 j: R2 V/ V        }
    $ M" L) b0 o% L; s" l& j4 I4 P; j        if(r==NULL)  S) w3 O3 @4 e8 f2 t/ ?3 W
                if(p->adjVex2==v2)
    6 \- R5 y% k6 b9 e                vexTable[v2].firstarc = p->nextarc2;
    # d; ^6 O) I  {/ |, S8 Z            else vexTable[v2].firstarc=p->nextarc1;* P( S5 ?* D5 C0 e
            else& O+ Z) Y: t  _; @% m7 X
            {5 f( n, G7 C0 ^* L
                if(r->adjVex2==v2)
    ; D& r8 l$ T8 T* B                r->nextarc2 = NextArc(v2,p);! _: b6 f: v3 [' D$ r
                else: ?% v- s4 L! h. X
                    r->nextarc1=NextArc(v2,p);
    " G: {% }# \9 ]8 V        }
    * {. R( b1 b5 p6 K        delete p;
    ' q7 s: x, x( l% C6 o0 y, N        arcNum--;. T8 w( A' E, V5 H9 k, f3 W
        }7 x4 R  Y7 L& l8 N4 Q
    4 t% S7 c) p" K8 v; z
    }
    6 j; P" Z6 |' c$ ]/ d7 Y2 gtemplate<class ElemType, class WeightType> void0 v# K- [% w, m5 w. q
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    7 X; W8 f7 P0 k1 k: V1 _* x' X  y( g{; |$ I4 R7 t2 x. d2 b; p
        int v;
    * I. C4 o+ {# [! U, a: s    MultiAdjListNetworkArc<WeightType>* p;# q  c7 C5 S; j' \9 O
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    : M8 w+ s) V* H# [/ k! N, S) i        if (vexTable[v].data == d)
    . o  N6 J5 i& A# {            break;% Q4 z' Y* w9 D# ~- a
        if(v==vexNum)
    $ p' p- O% ?7 j7 q1 L        throw Error("图中不存在要删除的顶点!");1 c6 k+ z* d' ?; V: ^

    4 s8 q" Q) [  _! b) S8 w    for (int u = 0; u < vexNum; u++)//删除与d相连的边
    8 A; j9 {0 u$ |7 j7 q        if (u != v)3 `6 \9 k% O* I* B! e" w
            {
    * e9 [1 J& g! w+ S/ `6 W) |$ k, l            DeleteArc(u, v);, ?6 Y4 y3 f: `/ E* s1 |
            }1 ~/ e2 G( L" D% S0 O7 M9 q7 V: o4 r
        vexTable[v].firstarc=NULL;' x5 p9 `' ]6 Q; n$ i5 H1 n
      g* T$ [3 m/ X9 [9 H
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置, L% J! A: F& ]0 T2 c  y
        vexTable[v].data = vexTable[vexNum].data;
    5 W" X- A5 @+ n3 g    vexTable[v].firstarc = vexTable[vexNum].firstarc;
    # ^' W% h8 w" g2 P& j    vexTable[vexNum].firstarc = NULL;6 T0 H' @) ^3 n
        tag[v] = tag[vexNum];
    9 G! Q' d3 L, }3 l1 S6 A    //原来与最后一个顶点相连的边改为与v相连0 a8 _# A7 b) \6 J* F
        for (int u = 0; u < vexNum; u++)9 q' W4 f6 V5 \9 d8 ^$ q
        {8 O7 d  W4 S5 V, J3 d3 p3 q5 A
            if (u != v)5 e2 m9 K6 C( L: y& u/ p+ j
            {
    4 P+ J: X  l' M3 q2 g            p = vexTable.firstarc;  T  l+ f9 h2 O& a5 x% ^; v' ~: L
                while (p)
    : D4 ~+ J0 t% |& X: G            {
    2 Q- Q" m! O% E5 C" B                if (p->adjVex1==vexNum)7 K; @+ f/ w/ Q
                        p->adjVex1= v;
    - ^0 J+ Q: k( K- d" h3 F                else if(p->adjVex2==vexNum)
    5 U- E" c, x, m6 U                    p->adjVex2=v;
    * u/ V* J$ G1 a* W                p = NextArc(u,p);* T7 Z( V0 R' g) x
                }
    ! J: J/ a* e; \        }
    # Y9 `; O9 Q' _) }    }: E2 c$ l* U3 E) m0 h! ]3 w
    }8 ~" G; B, ]/ C
    ///深度优先遍历
    # C( A& F: S6 btemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    3 e/ e! G& y. ^{' ?0 g2 r% z" p4 w
        tag[v]=1;8 f) M. O$ \, P+ G6 Z. X- D6 B
        cout<<setw(3)<<vexTable[v].data;
    * r& q4 {9 |- c6 \/ d    MultiAdjListNetworkArc<WeightType> *p;
    & h* W% z  A7 r  \! s- J    p=vexTable[v].firstarc;$ N8 |7 ?  h" `  y
        while(p)2 w% J- H( q: v2 d
        {" d0 ^' V/ c/ Y; [2 A, M
            if(tag[p->adjVex1]==0)
    ( R. J) y  ^3 Z, h1 B            DFS1(p->adjVex1);0 N6 G4 O8 C0 ^& E) _- P. r
            else if(tag[p->adjVex2]==0)# k6 @: k/ R; H* @  K4 l+ {6 {
                DFS1(p->adjVex2);) C# N$ {5 c; c& `$ `
            p=NextArc(v,p);
    3 u* V1 {  `% d* T6 b    }
    ( X$ ~/ M  O. ^2 a}
    " R. w% z& l) I! A, g) [0 rtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()! V; u8 V' I" L$ J
    {
      E; V- [6 f+ k/ i( S    for(int i=0; i<vexNum; i++); z& {1 k# j5 o6 g0 L9 R
            tag=0;
    9 ^* _2 ]. ?+ ]9 o* D9 @    for(int v=0; v<vexNum; v++)
    6 j2 z. G3 b  [- n5 z    {5 q2 p1 p- p# ^* g  [" d0 e( f; M
            if(tag[v]==0)  l0 z' f. D& t
                DFS1(v);
    4 J: w3 ?/ @# B7 ]$ q2 y& u    }
    , \# v3 D2 f" T2 ~5 W/ F9 ^}
      P/ H, e  N" b5 z4 }( Dtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    0 I) {' S2 H: ?% n3 c{$ A; m, j8 Y" k; P( s
        stack<int> s;
    3 V3 v2 g. y. M% y# V% e    int tmp;# W# s2 Z% i2 W% P9 i  U
        MultiAdjListNetworkArc<WeightType> *p,*q;
    7 ?* R- E7 `& X3 }2 j) }9 b    for(int i=0; i<vexNum; i++)% T8 E2 N5 ^. \$ h
            tag=0;, l; o1 G  W. {. W; }7 Y5 a1 E
        for(int i=0; i<vexNum; i++)6 A! f2 v/ S/ V
        {
    5 a4 Z9 c: g  b% G' f! P! f% x        tmp=i;
    % c: H/ s/ k4 e" A) P        while(tag[tmp]==0||!s.empty())0 Z" X2 d( m- Z. n
            {
    ; R: E- O5 V4 j" e' s" h            p=vexTable[tmp].firstarc;( R/ d: L3 @! V; i* U! j. B
                while(tag[tmp]==0)
    7 S' t- i) I& F            {; L5 S9 {- L, N9 P
                    s.push(tmp);
    * n/ ]' Q! U8 n/ @                cout<<setw(3)<<vexTable[tmp].data;
    5 ?3 I0 Q+ u+ Y/ g0 }" E                tag[tmp]=1;9 {  _4 h( ^% G9 p7 D% T
                    p=vexTable[tmp].firstarc;$ H: q% c0 y7 K5 ]6 w
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for7 i5 |2 L. t) Q
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    6 b! l" V& ?: n/ E7 D                //cout<<" 1st     tmp="<<tmp<<endl;, B$ a% ?; [0 X8 K, m4 s( `
                }
    8 \( [! ?$ R! y; L6 H# f/ m            if(!s.empty()), p. V: d& Y9 N
                {
    0 g9 Q! [" u% D% L                tmp=s.top();% F: E2 n0 L9 O8 H
                    s.pop();
    5 R7 f; {# L4 i+ {& T( s9 T                q=vexTable[tmp].firstarc;
    ' Q+ x; @( Q5 i2 p( W1 ], i% f                int t=tmp;$ u' O( G1 E6 G- x% x4 X6 b  V* j
                    while(q&&tag[tmp]!=0)( [- x" B' `6 I* [$ r5 f) @5 O
                    {. O4 n3 R- j% c2 e4 ^, P
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    + _6 y" i1 U( i- p1 a/ f5 I+ l5 e                    //cout<<" 2nd     tmp="<<tmp<<endl;. k& }0 D8 Y+ a  w0 X  E/ B
                        q=NextArc(t,q);0 \; p/ R" e7 R) |. q
                    }5 }/ g$ `7 d, R; M( \
                    if(tag[tmp]==0)
    / C" E3 H$ [' r$ Q4 \                    s.push(t);9 c/ \0 b( Y* B, E0 P
                    ///1、对应上面连通分支只有1个点的情况
    1 Y: y% D$ o% u2 x                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈8 I0 r$ h) X9 L; N3 r' u
                    ///tmp要么等于找到的第一个未访问节点,1 F% E, h' ?* I: `" R: F- N
                    ///要么等于与t相连最后一个点(已被访问过)' ^) V' w5 G2 V
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点. G+ m, j7 o3 x0 _8 S$ ^
                }& ~+ |6 f; ~, X% z' ~
            }: ~. Z9 W9 L/ k7 D8 u7 T- J
        }1 g# P- G# _( J, r' i
    }
    + _" ?/ ~' x8 u, {//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    8 x, g5 K4 R+ P2 E" `template<class ElemType, class WeightType> int/ ^  q5 F3 l- J3 g0 U
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    - r$ r, B5 P1 s( I{
    % r: y: E& m& E1 _  I    if(head==pre)% Q! O2 s9 b5 W# u  V
            return -1;) K1 C" m3 ^/ E/ @; R# S; K

    ' |3 }; F% ?2 @    MultiAdjListNetworkArc<WeightType> *p;6 n* E. q- r- ^" ]6 ?$ s3 i
        p=vexTable[head].firstarc;
    5 E8 }6 O' X7 r) J    if(pre==-1&&p!=NULL)
    9 t3 g; W. @9 r4 y        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    7 ^4 ^, c  w" n    //pre!=-1&&p!=NULL
    & Y& g* D' K; K4 G# I+ {. H! F    while(p!=NULL)# V  |" A' h* R
        {
    % ?8 f+ |" z- Z! b6 k8 x: J; @        if(p->adjVex1==head && p->adjVex2!=pre)8 }. P' ?! e4 O" h
                p=p->nextarc1;2 T8 H! i9 Q4 g' n' G
            else if(p->adjVex2==head && p->adjVex1!=pre)
    3 I0 y" W0 V4 s5 R9 C7 ~            p=p->nextarc2;
    6 W( n3 e( U. P        else if(p->adjVex1==head && p->adjVex2==pre)1 C& `* @8 @4 X( G
            {
    + z/ Q; S3 F# W7 l. |            p=p->nextarc1;3 ]+ a& u, }! V  r) v/ g- a
                break;
    ( `9 D1 v6 n; S. m        }
    ! [) s" _' F' D( r+ s3 a* h$ j        else if(p->adjVex2==head && p->adjVex1==pre)8 D# N! E! u5 F! l- e8 B4 G7 y. N
            {' e6 m. P, `- h5 ~9 |: A: f' l
                p=p->nextarc2;/ |/ r8 _6 s: ^
                break;
    3 v+ a3 X9 o6 ^        }* I( l( l* F; K( Q/ y6 k2 p
        }
    2 v) g2 O; U+ ]( e    if(p!=NULL)
    ; u0 B* I* x9 Y5 i/ J0 d: A    {
    " P, p& l$ n% f) O% {9 F/ w8 G        return p->adjVex1==head?p->adjVex2:p->adjVex1;% y7 [5 j! p" ^! i4 Z5 U
        }1 @6 b: l- x, e
        else
    0 G1 l5 K9 l5 ~, x3 z        return -1;& `# h7 ~! N. d0 ]% o& h
    }
    4 n7 F% @2 u; X" a% f
    % }1 W; ~# `- F; l# s$ I
    8 w' K$ n7 D& `+ P! t, }& utemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    5 w  b; H' l* [2 ]' [% q{
    / p* M* F( j8 n' _9 J# q    stack<int> s;
    9 K; P, F6 T/ d9 m; k( @: |    int p,cur,pre;
    5 O+ L0 l9 K1 f; O/ M; A    //MultiAdjListNetworkArc<WeightType> *p,*q;
    1 K% |; c* L. S1 L6 b    for(int i=0; i<vexNum; i++) tag=0;//初始化
    9 q+ ^. W. K) V; O4 X1 J( C' m# F9 r( x0 ^. A! y
        for(int i=0; i<vexNum; i++)5 m8 c6 ~9 W3 _( s( P: x( M
        {
    & q8 u) F+ G( V! L  g        cur=i;pre=-1;6 c  k9 g/ ~! H0 R6 U, o
            while(tag[cur]==0||!s.empty())+ H7 ?: ~: m$ v! i- j6 @" t2 H" g: [
            {
    6 Q! p; m5 g8 E' G: `$ V. \2 ?            while(tag[cur]==0)$ N' Y! X  J  ]7 L
                {
    " X1 S  F" H: [, l! M* g3 E                cout<<vexTable[cur].data<<"  ";
    " q9 A5 ?* R: Z8 y                s.push(cur);
    4 _" j) s2 P/ g& v. C4 X( |7 F                tag[cur]=1;
    , t3 e" g7 z, @8 ^1 f# [               //初次访问,标记入栈
    : f3 j! @  _* [9 u# T$ T9 I+ U' t( D- n" H' @( K+ |
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点4 Q$ u2 P) Q" X9 c: U5 v5 {7 \
                   if(p==-1)  @: @: e1 K- @/ B) C7 J2 B
                   {
    " `& W* l* X# l  I% ^( ?                   pre=cur;s.pop();( \- F6 Y) U2 |1 Q( P
                       break;5 n3 `$ O( A8 H5 L
                   }
    % ~* b9 U8 t! Q               else
    % O0 n5 Y5 _4 A( x! I0 F$ z               {7 g4 p% j5 j; I5 U3 L6 y- p& \
                       pre=cur;
    ! x6 U# \; s" c! q) x7 j+ s                   cur=p;/ @* I5 d5 W5 m8 `' |2 F4 j
                   }) J, _; d- f9 j/ y# d
    + n9 j: t2 Y: s4 t7 \
                }" i4 ~+ O; t! V5 G- y: t
                while(!s.empty())! G- m! m4 f& V: t7 L( }3 Y
                {  V8 s/ D! u5 M# S& ^
                    cur=s.top();/ L+ ^+ I9 |" w7 j, }
                    p=GetAdjVex(cur,pre);. E2 N, W8 m) g. e; D9 Y
                    if(tag[p]==0)9 s2 e- n: @/ `) l% U+ G
                    {9 k  o% ^  j) p+ Q0 L
                        pre=cur;) f! M3 e3 {' |+ c  K
                        cur=p;
    # S' m% Y: K, ^, ?0 A1 a% D5 v! h% k; H$ a                    break;) @% [# m& w0 j* |  m! O
                    }* ]; \" M! O. g& B$ l
                    else
    : _# X, V8 P7 Y                {
    " f7 K! J' M+ t3 i                    pre=s.top();
    * h' J. B9 l% q8 D5 J                    s.pop();
    4 f: u2 w3 ?6 b, |1 ]                }
    2 l6 W2 v' a% i, L. v9 e8 B
    1 q# D5 [7 N$ X0 _            }
    " l  D4 v% ~+ n2 {: H# S& Z% N. v# D5 l
            }% Z5 N! Q; L$ g* @7 W0 [2 j* M
        }
    9 V1 R0 n6 u' M( W: s1 A. W8 k}
    " U1 X$ ]. `" ]  @0 H- I. Jtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()" E+ x2 b& G: s; E1 T2 }) c
    {" O+ D# }# J3 K* Q( i( S1 m
        for(int i=0; i<vexNum; i++)* v( H# A* R( h. Z
            tag=0;# K2 G" M9 m: W  e" M+ S# o* M
        queue<int> q;
    ' W7 G( ~" B8 `% a' K    int tmp,t;
    ' f, p' t& e- }    MultiAdjListNetworkArc<WeightType> *p;
    6 Y% x2 |' h1 V1 i( m7 ?    for(int i=0; i<vexNum; i++)2 ~# z/ b# w) G* R$ O
        {, E. O) T3 J" J5 f* g* ]6 N
            if(tag==0)
    ! M" F4 Y  g2 g9 C        {: w4 x6 p" k0 f' n, {4 b1 x+ |
                tag=1;
    3 v  ]; J/ ~6 \7 y! u( n            q.push(i);
    & l" e: F* U) S2 R# |            cout<<setw(3)<<vexTable.data;
    : D. J( y. u# V" |: W; i/ y        }
    7 n$ M0 }6 g) n        while(!q.empty())$ C0 z1 v# o9 ~6 |- s7 J1 Y
            {/ l4 }3 r; C/ T* r" [2 }
                tmp=q.front();2 n9 H( L1 ?# S8 p8 J
                q.pop();
    . ^5 j' E/ `5 q7 [; f3 c            p=vexTable[tmp].firstarc;
    4 E. t" t0 v1 n+ f4 w$ `8 F            while(p!=NULL)+ M0 q3 x/ q8 ~
                {4 I% S' _# y; I: I! B: X
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);0 @$ q4 a& ?+ m. z: P& y8 M
                    if(tag[t]==0)4 N3 p  c7 I) u' w* f4 u
                    {  m1 [+ }9 w2 K1 B5 v
                        cout<<setw(3)<<vexTable[t].data;
    / J) H5 r1 B1 y' H  @. \                    tag[t]=1;& N  q7 s" C' @* L( U% A- R
                        q.push(t);! o5 P* I0 o: i. a& O
                    }
    2 G$ j- H  _; x9 u                p=NextArc(tmp,p);
    ( d: h. m+ {. X; a            }6 T, A4 ^8 o0 c% l% Y# L# S
            }
    4 N, ]+ L  m$ }+ m1 U    }1 i( a* ^/ ]# M& j! z% {6 f
    }3 c5 @( B' Z  b3 |: C
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    . b; R5 v0 g3 a% K{: c' ^3 \6 Y; W
        MultiAdjListNetworkArc<WeightType> *p;  Z% O2 g7 C6 _6 j
        cout << "无向图有" << vexNum << "个点,分别为:";
    % _5 W- R+ s+ ~7 f7 K    for (int i = 0; i < vexNum; i++)
    7 R: t' ]* m7 @( V        cout << vexTable.data << " ";
    9 p' ]8 p: {' n    cout << endl;" ]/ K/ y6 J, s1 r
        cout << "无向图有" << arcNum << "条边"<<endl;
    . f4 t3 v# Q1 u3 T9 m# v. w    for (int i = 0; i < vexNum; i++)$ y; o3 D  J7 d( e( u( C
        {
    / f$ v3 p( ]& M! D, C        cout<<"和" << vexTable.data << "有关的边:";
    5 [/ k) U4 K( A$ ]- n) U        p = vexTable.firstarc;) G0 l0 g) O" Z3 h) u1 m( S5 Z& z
            while (p != NULL)
    9 _* V* h/ i7 I2 P; ?  k0 X        {
    " W) I9 D- D. ?3 z2 {1 E            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    ! E  n7 a, ~6 c            p=NextArc(i,p);
    5 V% d2 p( g1 t. O# w        }7 s8 F$ t% a6 J" R
            cout << endl;  [( T, W+ `, h+ v! Z* x
        }! t0 d* f) l* r6 B- c
    }4 ]8 d1 g1 o. V# S$ I7 n. Y

      W$ {3 e" D' @4 k% }; p% I5 L
    1 X, F- d! ]1 o" {$ F4 `3 [邻接多重表与邻接表的对比' z) x  D+ ]. y
    " \5 s: K4 L2 r# V3 X. m
    邻接表链接6 K! J' x3 }( r8 P
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    7 Q* ?9 A8 s7 ~在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。/ r7 q9 o  |, \) G4 z  |
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。+ }' E/ j5 E" b/ H" x- G5 f
    ————————————————
    . Q! Z- a; S4 n# ^: d. ~8 b- Z# X4 ?版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    % Q* i2 C7 w) _. ]" o; P  [+ A: c原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    # ?- n2 n/ x  n: e
    9 l9 y6 W8 ~$ W' X4 T) V  E, c, |) _+ B& S0 ]2 l
    # ]2 s( m, x" N& y

    9 ?( {/ b1 B0 r' E4 U————————————————% b* a% o# t  V7 w/ Y; t
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。8 j9 }: O* [  B( X/ \0 Q: W
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958/ c6 ~. y* m* u4 A# n
    $ N% P( H6 q% `0 @# Y+ Q
    & K; Z$ X5 M9 _+ l
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    fastpost qq
    收缩
    • 电话咨询

    • 04714969085

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-10-31 23:36 , Processed in 0.231344 second(s), 54 queries .

    回顶部