QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1520|回复: 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
    ) ?% p; M  v5 @
    图的存储结构——邻接多重表(多重邻接表)的实现
    / }' N: _( R6 p& ^& o' v7.2 图的存储结构
    3 N5 W0 ^7 \( A0 [: ?
    / w; n" I) r( U- [% F3 f  T7.2.3 邻接多重表(多重邻接表)Adjacency Multilist: ~( Z% f& Y  y& t# x( B
    邻接多重表的类定义9 A7 a  y* s8 `3 w- E. c* u
    邻接多重表的顶点结点类模板
    # H: n1 j3 \6 a5 z, c邻接多重表的边结点类模板8 n+ @7 e6 W3 ?5 G
    邻接多重表的类模板
    ' A* B1 X5 M$ x" K邻接多重表与邻接表的对比
    & U4 z! |- v; w4 W' |" P8 t7.2.3 邻接多重表(多重邻接表)Adjacency Multilist+ u! a$ O7 z0 L+ ^* J2 }

    0 k2 U6 t5 ^4 f; m/ s在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    ' b2 U+ p% l' Q' S! o在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。) I+ i. ], z: F$ h9 q  s6 W
    1 a' ^( W: _, k6 d
    邻接多重表的类定义
    ( W% k, F8 x7 t0 {* R 1.png
      j. F. Y  U% u: O* Z邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:& D/ t0 `4 G8 S" i5 ~4 c5 i6 l
    data域存储有关顶点的信息;) f1 S; t$ `5 F6 y
    firstarc域是链接指针,指向第一条依附于该顶点的边。- Z- S5 q, p+ w
    所有的顶点结点组成一个顺序表。

    , _* B3 h) ]9 k  ~7 L
    % I, h- j2 M. }' j6 ~+ s. ]
    template <class ElemType ,class WeightType>* |/ F! }7 M0 @& i$ d+ Z9 l+ M+ {& V
    class MultiAdjListNetworkVex
    + Y' s% w; K2 ?  W/ P. V{6 w; K8 d; [) P( `; n) I5 M& C: {: D
    public:" O1 w" ~* r( Q1 F9 e
            ElemType data;/ C; z6 w: B8 p
            MultiAdjListNetworkArc<WeightType> *firstarc;
    6 T6 g$ Z0 y8 W
    7 D0 A% o* r7 `& H$ o" s7 I        MultiAdjListNetworkVex()
    6 w0 d/ n5 T6 u0 u( a        {
    : T7 h3 [! J& K2 w4 f" u                firstarc = NULL;
    : A* J$ P/ @9 d' |% Z. w        }
    9 R# ~" z, {- j# z8 H' K        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    ; n. W9 d$ \4 D, p4 l, V        {. V# ^8 v0 t4 d. C- z3 b
                    data = val;0 R2 i5 X, d  s9 p7 N
                    firstarc = adj;  H* R1 ^  E8 Z) Y, H$ P* L4 u
            }/ t. ^( U: J* T. r( {
    };
    . Z; L1 F, p7 z1 E4 v; \* H% N! M7 m7 n. A. {
    邻接多重表的边结点类模板) f$ s2 d/ |1 F! J# {

    : Y5 F7 W" x7 ]. |# S+ O! h在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:7 o6 `1 X( J( I& m$ l% H* W' [( x8 P
    tag是标记域,标记该边是否被处理或被搜索过;
    0 j9 S+ K- l1 Z9 ?; b" V; y, Fweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;8 T2 i5 W! T$ I% }2 `! }& Z/ e* ~: O& I
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    # f( H7 l' M) O& ]2 x( inextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。* T  g7 a% z( Z% K

    3 q& Z' r. i& e3 G* U 2.png
    7 i1 h- Q- O. }+ A8 c' `1 wtemplate <class WeightType>
    # C0 X% @/ `. @6 v' N" a( i( rclass MultiAdjListNetworkArc4 v; a7 x5 k) \
    {0 c3 g0 C6 y) I) |2 |; [4 Y5 l7 S
    public:* X$ \( b% S" d
        int mark;                                       //标记该边是否被搜索或处理过" _$ E  l3 y4 p1 j: u1 V
            WeightType weight;                              //边的权重: z/ }9 O# Y/ j& x  N
            int adjVex1;                                    //边的一个顶点
    7 Q0 `/ m3 N+ ^5 _- S        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    5 z0 X8 k  O7 j$ }        int adjVex2;
    ! B9 w+ J5 F$ d, o  d        MultiAdjListNetworkArc<WeightType>* nextarc2;& Z) u7 J8 M+ R

    $ T7 e& z' k" ?. a        MultiAdjListNetworkArc()
    7 \- d8 s) l9 H- f        {
    - C, m+ M) K% `. j/ U( p                adjVex1= -1;
    + R+ j6 |* R" Y; g                adjVex2= -1;) @5 ?% G- t4 m0 B
            }7 j& s/ Z) K# R: a, Q7 M( ]
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL). {, m, J$ U. ]  D2 t$ a, X
            {9 C* _4 a) t/ J# j+ }8 e- l( p. b
                    adjVex1 = v1;       adjVex2 = v2;
    + e. G7 z, J+ B; e& m                weight = w;) G# B6 J: J+ Z( L2 H- H: T3 ^
                    nextarc1 = next1;   nextarc2=next2;
    9 B8 n$ H+ u) l+ f& z% o. v: B                mark = 0;           //0表示未被搜索,1表示被搜索过
    : N8 b' W! w3 h9 ]* k+ L! w" h        }3 E3 ?) A/ q( y1 e: ]6 ]$ Y
    $ y% @, R* E* O/ v8 @
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    ; I5 G( }7 x" {: |class MultiAdjListNetwork
    4 h" j- |5 {) P( Q{2 G: G  z5 j$ M" _' m
    protected:
    8 R, a& z0 [$ Y5 c9 M. B8 U    int vexNum, vexMaxNum, arcNum;
    5 K' S$ w3 p$ f# ]: W/ W    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;+ q% c, V+ p4 B0 u& u! L# I/ p
        int* tag;
    % Z- B. [& A. F5 O/ W% z    WeightType infinity;
    . r) d# w0 f. F! Z$ m
    ) _0 ^2 S0 \# ?8 T( O- epublic:
    " e; W5 B0 t$ ^$ S    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);9 l5 q9 r. N4 J  O# F
    ( n( e# _( Z9 z; r6 r4 P
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    4 a& ?; s" d4 P2 j2 O
    & g/ x  Y5 l2 s4 H4 j    void Clear();
      u% g4 r0 j: v+ T    bool IsEmpty()
    ' F2 @4 N6 k% {  |; W+ M8 ?/ J& a# p    {
    / g+ v$ U# O2 p5 |: d        return vexNum == 0;
    # [; N6 ?9 X  u9 d1 q    }; I! Q/ v  {% t1 m. K, w; x
        int GetArcNum()const- {$ B% h2 |! Y+ o( S. j9 C# a# \2 X
        {
    , S6 k& s' Y4 }$ c        return arcNum;( B( |; T' E" d) R. ]
        }% ~) k& r. N% t% v, j
        int GetvexNum()const
    ; s( O  ?! H8 \6 f    {
      C* r/ G2 [9 X        return vexNum;
    " K# |) E! y$ e4 J% W    }
    ' o1 j7 [3 G; d  \" Z+ R4 {" R! p6 \- V9 E0 S! I4 ]; m' }
    # p# x3 x+ F4 n; b, z, Y3 G5 ~
        int FirstAdjVex(int v)const;
    ) @/ C4 _0 y0 e# R    int NextAdjVex(int v1, int v2)const;
    + d; H+ n! I3 W' n+ U    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;8 v4 O* E1 V2 }  q+ B. B
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;8 s  d: H" O' t& P) S

    3 B7 `8 w3 [2 z2 \$ V+ |5 K) T    void InsertVex(const ElemType& d);
    ) f. I1 d( b9 a# K; ?# T    void InsertArc(int v1, int v2, WeightType w);( O( A9 R" m+ y& ?, }1 L# h! o

    ( P; d3 f! p* \, \  F    void DeleteVex(const ElemType& d);
    3 f' U* |" D6 n+ j4 o9 S    void DeleteArc(int v1, int v2);
    & Y; v% _& E8 z9 a1 p
    3 w' C( {4 \1 Q$ s" E    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);# P8 a+ H5 Y, ^; i+ k- Y
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    . }) h+ ]; z5 Z' H' G+ s: G; ~8 u" h/ w. O  t
        ///深度优先遍历7 N, |; m* R+ `0 o; v
        void DFS1(const int v);
    - q! F5 k2 @% P. t6 q( t: Q. g3 q) i    void DFS1Traverse();
    - H: z, S3 Q6 C    void DFS2();) J$ \- J, H$ c. \  v7 p2 Q
    ' D: q: ^7 A2 n/ q% L1 o# V
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    2 `0 [- _. h9 @, b' r+ Z- \1 P$ G    void DFS3();4 H, c9 w% T! _  G  r
    ( i# N% T8 B* w  h
        void BFS();( j1 |2 R& V+ d! o; a
        void Show();+ G3 j4 M1 b; r4 T( t5 M
    };$ ^- A6 f. o: W. v% Y  p
      }5 N# P) d8 @
    2.函数的实现5 U$ F; _8 o3 }  y3 Z* @
    研讨题,能够运行,但是代码不一定是最优的。  p/ q4 p# u0 P' ]5 Z

    ; b+ X& J7 ?) i: Z7 s#include <stack>$ i* _# P* e/ c5 ^
    #include <queue>: G. M9 P) V' ]$ L6 E
    ! d9 I0 B2 D9 v7 \  Q4 {
    template <class ElemType,class WeightType>
    ' `4 u" n) V$ `5 R3 _: j; FMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    ; j# ~$ b& H' x" }{: ]2 r& G. x! x' i1 i, `
        if(vertexMaxNum < 0)( I$ ]3 V8 P5 [3 |
            throw Error("允许的顶点最大数目不能为负!");' e) s! B) W! o! h! i0 E
        if (vertexMaxNum < vertexNum)
    & F: B* r4 J+ W; F        throw Error("顶点数目不能大于允许的顶点最大数目!");
    # G$ q& R# B$ l, a) {) y  A: M    vexNum = vertexNum;0 {5 E  b. X7 W
        vexMaxNum = vertexMaxNum;9 h7 t+ n4 \+ s9 U: @/ b* F
        arcNum = 0;
    8 _# b' s6 m9 z& E- E, p: g    infinity = infinit;
    % ?* _: U, F3 h9 ^    tag = new int[vexMaxNum];
    8 U# M) I& R- b9 _8 X$ F    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];+ f# ?$ l: t4 t8 Y
        for (int v = 0; v < vexNum; v++)
    & S3 R! e9 }) a5 j    {
    7 r. C5 u& a3 f5 |( W' N1 \0 f        tag[v] = 0;3 Z. l2 x6 e2 F6 ^  \
            vexTable[v].data = es[v];. [9 `5 b5 t, N, e+ F4 W
            vexTable[v].firstarc = NULL;
    " A: a4 [- ]- {: e# N( X9 E$ N    }/ Y2 G8 J1 d4 R! D* q1 |5 c; s7 z
    }
    " y0 ^% M+ O- j0 O. k4 ]template <class ElemType,class WeightType>
    " h/ O6 m9 b# WMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)1 r: b# _( t* h' \6 @
    {
    % I4 b# W3 e  G    if (vertexMaxNum < 0)
    " ^- N. h( D& {# d! |8 W! V; U% O( I4 Z        throw Error("允许的顶点最大数目不能为负!");% Q' R5 Y& r$ {) @; A5 W
        vexNum = 0;
    , r8 S( w: F- Z  Y    vexMaxNum = vertexMaxNum;9 M( L' s8 u8 i/ L9 H* E
        arcNum = 0;0 P9 R( H; D, z
        infinity = infinit;
    0 i3 ]7 E, H: o0 r0 m    tag = new int[vexMaxNum];: e& P9 @( d* Z5 p, H' d, e0 P) d. _% ^& ]
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    & \  I6 ^/ N2 r( I4 ^; O}
    ! N$ W/ W3 m) s' K6 }8 e4 ttemplate<class ElemType, class WeightType>
    * G7 g9 B- L% G7 Y. K4 G- {int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const9 |  P- `! [! q4 O3 m8 V
    {! i- M7 i% [* a4 X: B# |& s% y0 {
        if (v < 0 || v >= vexNum)
    / e5 p( o) [* E        throw Error("v不合法!");
    2 {' ]: T5 |1 N6 K5 n, u. V; b    if (vexTable[v].firstarc == NULL)
    8 o2 x  I" u- A6 z5 X        return -1;% j+ O6 F# r6 Z# f- \! @3 H6 L+ y
        else
    7 y. Y6 N) e# n  a% a& `. l7 u        return vexTable[v].firstarc->adjVex1;
    ( G6 _, E+ g" K! W}, s% ?9 b/ n. [8 _. A7 D4 _

    7 e" L% J2 x8 ttemplate<class ElemType, class WeightType>/ C9 d; ?% \- V- l! q0 l$ G  E! ?
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    : F0 G/ s6 J1 S' m{6 I: K6 K% Y+ w9 @6 R2 Q) `& y+ E
        MultiAdjListNetworkArc<WeightType>* p;
    ! v5 L5 Y0 G/ ]8 r* Q) b; p    if (v1 < 0 || v1 >= vexNum)$ I2 E# }9 n2 m; w1 ]/ V7 U
            throw Error("v1不合法!");1 J; x$ A7 [5 o5 B* ?9 `: a5 B% y
        if (v2 < 0 || v2 >= vexNum)  b. L, G2 V/ T. ?! u/ K
            throw Error("v2不合法!");
    ' Q7 @* R. c# w+ {    if (v1 == v2)1 |" L% U9 ?0 ?
            throw Error("v1不能等于v2!");; \2 l+ W; ]: Y
        p = vexTable[v1].firstarc;
    % C; b) y& O  k7 P* N    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    ; Y+ b/ a8 O& y% Y: F        p = p->nextarc;! Y2 S* y; Z: f
        if (p == NULL || p->nextarc == NULL): t7 c7 S, R6 N( P
            return -1;  //不存在下一个邻接点4 E. [0 S" ], P* ~3 u. e
        else if(p->adjVex1==v2)
    / [5 q. q- R" C, y  N9 I) g$ V        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);# D4 z0 h# [# q: M* s. X5 B. i
        else" g+ B6 Z6 T4 c
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    : T2 X+ B$ k# |, q9 s3 j  S3 \}' _; X, q6 f" a1 {; v9 @* t
    template<class ElemType, class WeightType># W9 H3 e/ m- r$ v$ {8 [. W
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()
    3 ^; e, k- |2 t7 y{# a- I% f' v+ u
        if (IsEmpty()) return;7 m) S" |# J* o
        int n = vexNum;/ V0 B* m1 k" X. m2 X; X6 Q. O$ ]
        for (int u = 0; u < n ; u++)! S) q0 `) p9 }( O4 V
            DeleteVex(vexTable[0].data);
    1 n, c2 f8 }* A; W, j( S' C    return;+ |/ H/ t; U+ ^, f
    }
    1 T4 v( O1 k8 J$ \0 ~* f7 ^# ctemplate<class ElemType, class WeightType>* v9 [4 m' [$ R3 L
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()2 _; s5 R4 _# r3 }6 h' I9 c! M
    {
    9 y4 o0 S& f: A0 \' a& ?    Clear();
    : e8 q1 b8 Q% c6 M5 d}0 p  n! z/ Y+ d% r" c% W, b
    template<class ElemType, class WeightType>
    ( _4 b! R8 |( u3 c* }( Z* TMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    4 r2 i- v; l8 r0 R5 F- J* a{0 [  `- w) y0 _. ?' j
        vexMaxNum = copy.vexMaxNum;5 }7 X+ u& F' x$ `/ |( X
        vexNum = copy.vexNum;* c  ^) u9 \, K4 d6 n3 t, d
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    * e! e9 w( d2 K: t& Y+ I    arcNum = 0;0 m& H! {# r; Q2 `) @* U* h
        infinity = copy.infinity;4 Q5 e5 B2 ^" J6 k+ x
        tag = new int[vexMaxNum];8 a1 ?- V3 M# S3 e2 J- \! b

    ' D. ]7 k* F5 G' l  ^    for (int v = 0; v < vexNum; v++)) P% D. }. c& J0 d7 E( q7 B# u
        {" X6 L  e: u, D# @/ E$ v% l7 a- ~
            tag[v] = 0;
    4 y( r& [, ~1 R        vexTable[v].data = copy.vexTable[v].data;
    , O: v8 C4 G, [. U. ]& A$ c        vexTable[v].firstarc = NULL;" M) q/ `, U# h$ f6 a
        }
    0 _  `+ l. z, a    MultiAdjListNetworkArc<WeightType>* p;
    7 o- D3 w9 p0 q
    0 |1 t& D+ s1 q( x1 f    for (int u = 0; u < vexNum; u++)5 ?( {* n4 h4 d4 L
        {! v* a5 ^+ p2 }" ~
            p = copy.vexTable.firstarc;
    . Z: P) {% I, O        while (p != NULL)4 {/ D; V# C: r, i
            {( W" ?; ?' f6 |. Y
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    5 N* P; o9 [3 e. W1 w+ d; s- ?            p=NextArc(u,p);- [  ]! Q; ?. B! K7 D1 j/ W# g
            }/ ~5 V/ ]" i5 D: T8 L1 ^
        }
    8 s' X  m9 }0 H- V) t}' R5 i: M5 X+ u9 ?! E6 `4 ^1 h
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    - P/ G- F2 P; A5 c& s' n0 R3 \MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    - \' A) \9 E8 E4 x{; o& R- s7 W/ B! ]
        if (this == &copy) return *this;. F9 C; _" u3 P! r5 s: _; ~
        Clear();% s" W4 w% I4 l4 C
        vexMaxNum = copy.vexMaxNum;
    # x+ ]* y; h% l$ k& s( j$ L& D    vexNum = copy.vexNum;( v: h, a( K- y1 ?
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];5 w. B2 E4 c( T9 a, C
        arcNum = 0;' R% |; N: o) A0 ], O; L& J
        infinity = copy.infinity;
    6 E/ C. h0 r8 ~" a    tag = new int[vexMaxNum];6 R$ V6 Q2 C9 ~8 ^* |% g# k0 J( R
    ( F# B7 c$ ^& B% N" L* q* ?. ]
        for (int v = 0; v < vexNum; v++)
    ( V6 \" x  |/ L% ~- h3 {# K8 v    {
    8 Y. G3 w  z! X' P. ~2 c: ^        tag[v] = 0;
    3 g3 l: W3 [; T: o% T  p        vexTable[v].data = copy.vexTable[v].data;
      @' v5 N9 z. H! s! \) Z4 M        vexTable[v].firstarc = NULL;
      {' _) h, a3 U3 c1 Y1 x    }& |  l3 ^: R% d- j
        MultiAdjListNetworkArc<WeightType>* p;
    1 C9 [4 s, L# z8 _( A
    - ?% |& e$ v0 Z/ ~    for (int u = 0; u < vexNum; u++)
      E5 f( M3 X, C  B' c! }1 G& `    {
      v) h: Y& f2 A% _9 O        p = copy.vexTable.firstarc;
    5 s; x7 P5 M3 b" v        while (p != NULL)
    0 H- O9 d% j3 N        {0 ]0 f# T% V% _! U+ L5 T
                InsertArc(p->adjVex1, p->adjVex2, p->weight);( e5 }4 o- P* ~! E. {5 @/ B/ \7 v
                p=NextArc(u,p);
    1 g3 Z, @, ~% R4 ~$ [4 [% d        }7 y$ u& e/ M4 s6 O: @: H6 o
        }2 Q% {0 m$ i* V' p+ ^4 f9 }
        return *this;' O# Z# c! Z4 |
    }
    - n' C3 i4 C0 [. Stemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    : s. F! Q& Y3 ^) m+ e: cMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const' W5 t% e  x  f) N3 @' q2 T
    {1 x7 I& p- a1 m: ?3 I$ x/ i6 y* }
        if(p==NULL) return NULL;! ^. z9 S; R* N" K/ U
        if(p->adjVex1==v1)7 Q" r  M; d) r2 i% Q8 `/ ~$ B
            return p->nextarc1;& _  y% B7 y( \8 m  z! [  p
        else
    9 E. |7 s2 g5 E9 j, b6 \        return p->nextarc2;. I" `) {2 Y1 X' l  P# l+ k
    }
    2 L$ d) T. _9 X) }$ w2 Ytemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    8 s+ N: u7 S* T7 o9 M) Q. }0 V9 ?MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const- M% Z4 l8 g  e& t! ^
    {
    8 X0 x) g6 P. @7 q    if(p==NULL)return NULL;1 j6 j% k1 t# @+ E1 D& D
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;- e1 t& I8 H2 \% p+ Z6 x
        if(q==p)& d3 M. m! d. ?" @
            return NULL;
    3 I' Y7 Q% S! z$ [. V    while(q)5 b% {  n  j& p2 i# _
        {
    5 K) Y; P8 ?0 z, p0 C6 n0 c( Q        if(q->nextarc1==p ||q->nextarc2==p)2 u* J% v4 w7 A) G
                break;6 c0 I! r/ m2 I
            q=NextArc(v1,q);
    * j7 |- r' Y5 y; U    }0 W) X  s+ R: g$ A. K) J
        return q;/ [' w. A7 X/ I: Q, s
    }0 S6 b  [# Z1 h
    template<class ElemType, class WeightType>5 s9 u! o4 y  C3 \! n. R& ^$ \
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    2 E2 h* ^# X. P. J# \{$ ?; C0 J/ K* m" O
        if (vexNum == vexMaxNum). H9 c- K, P4 C6 f
            throw Error("图的顶点数不能超过允许的最大数!");, H) c6 L3 A% }/ k" V; t0 @
        vexTable[vexNum].data = d;
    6 e+ _; @5 i* v  J% {! f    vexTable[vexNum].firstarc = NULL;
    2 e% [; M4 ?* h$ T0 g    tag[vexNum] = 0;
    & ?2 z2 W9 G/ _    vexNum++;
    ' `  `+ f0 b7 ?, ~( r& R: ^$ y. _}# T- ]5 R+ H# L' M
    template<class ElemType, class WeightType>6 M- Q8 g7 |& K2 B6 [6 X1 N
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    7 I7 G# o" \, v1 Y+ Z* w  N7 s{8 b# I4 ?0 i4 I! O% s; w
        MultiAdjListNetworkArc<WeightType>* p,*q;1 M- \4 Q2 O( y1 i% a
        if (v1 < 0 || v1 >= vexNum). O! y% Z  V0 v* r
            throw Error("v1不合法!");* |5 p, x  }* p$ s/ g/ \
        if (v2 < 0 || v2 >= vexNum)
    1 y" V3 t6 m- p& p1 Q' P        throw Error("v2不合法!");
    ) C1 n3 T; J5 p& ?% X$ g    if (v1 == v2)
    $ x$ }. a1 L/ V& P        throw Error("v1不能等于v2!");) _3 C+ y7 ?$ t8 @) a; _1 d* h
        if (w == infinity)
    & ^0 [4 u& [& u2 O        throw Error("w不能为无穷大!");
    7 k  }5 s3 J7 e1 }7 k. K5 W( E% K8 u

    + c, F2 n2 V' X) B) N1 v/ {    p = vexTable[v1].firstarc;6 |  Z6 M7 n5 T8 V- L- g+ {
        while(p)& j# ~/ n- R- z& y. L$ r5 X
        {- `' f, t" q1 u
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    " S/ q, D3 `$ H        {) B0 f6 F" c) x7 U! t! h" {. [: x: r
                if(p->weight!=w)
    ; N* D$ }" l6 u( j; c8 @                p->weight=w;3 m. f# x' j* T* {( F. K; s5 y
                return;
    ) ^# S" B0 \/ h        }7 o# B5 N& l0 q8 S

    9 u- L0 V' e5 o& Y# ~2 P1 V        p=NextArc(v1,p);
    + B  y! M, `8 H4 N: c0 F    }
    / N% q8 N. n' |. r  s    p = vexTable[v1].firstarc;$ v7 c, @+ _* \' f
        q = vexTable[v2].firstarc;
    , i4 K" ^' i5 O5 B2 w! ^- L    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
      X- ^) b% w" E2 E; Y7 {    vexTable[v2].firstarc =vexTable[v1].firstarc;
    % K2 i  p3 z* q" O5 ~    arcNum++;: T; t3 s- Z- |; v! P
    }
    ' K/ @1 x$ F8 ~5 V
    % G, \( V( W* u+ _4 W! k+ {; jtemplate<class ElemType, class WeightType>
    / T! K  d9 y! f) a& T1 N, f. Evoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)# C7 k: r* {8 A! E  c, g& [
    {
    ) O4 X4 s2 d5 C8 F" o
    # `( ?$ d: d  `' O! W/ J% _8 k    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    & n% Z! M4 w5 B" k    if (v1 < 0 || v1 >= vexNum)
    " p+ U# t0 j% `  l        throw Error("v1不合法!");
    / y% A; D2 t9 F: S9 U$ ?    if (v2 < 0 || v2 >= vexNum)
    & S( l; `  C* `        throw Error("v2不合法!");
    3 Q% }4 p! x& w) c. Z4 _    if (v1 == v2)
    3 y: O7 ~; X5 E2 O0 ?5 P) y        throw Error("v1不能等于v2!");$ n: d$ Q% k% e$ }' M4 [2 I4 G0 p3 z

    . Q. [7 V  J. k4 O8 j    p = vexTable[v1].firstarc;
    0 E' |: ?7 Z, x. j% Z    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    ( L+ M  D7 U2 _* x: V    {  v" l% V2 h. H/ v
            q = p;, \* @4 i0 w( g% v
            p = NextArc(v1,p);6 G- _9 I& i+ n5 `
        }//找到要删除的边结点p及其前一结点q
    $ S& |- U# _0 L: S- q3 L5 l" \' f- I5 Q7 v
        if (p != NULL)//找到v1-v2的边
    6 \  [8 y4 k% _; Y2 t5 k" L4 n& G2 W3 p    {
    0 h  Y0 s2 j$ b% Z0 k        r=LastArc(v2,p);
    ; C5 }1 J  w( O) S        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL8 {+ c5 ]$ z( N9 D8 B6 i2 E, i
                if(p->adjVex2==v2)
      @" |5 E/ |6 L! _                vexTable[v1].firstarc = p->nextarc1;
    3 N) O. ^: v9 B1 H3 r9 a% f! P! L            else vexTable[v1].firstarc=p->nextarc2;8 i( h6 }6 K0 v, P1 N# [! m
            else//不是第一条边% A& |/ h9 {- a) g
            {7 Y$ P, U4 C! n! _, r) ^
                if(q->adjVex1==v1)
    - y4 A- @  Z) v; U! q( A* K                q->nextarc1 = NextArc(v1,p);
      n5 c& A5 [  b+ F* N            else
    4 |2 U) b: k+ O3 `) `0 l                q->nextarc2=NextArc(v1,p);( ^$ E  J( n' z' f: q3 d1 j

    ; _! c6 s6 q$ v; @& c" @! k( }- W        }
    2 F+ Q# b1 O- R        if(r==NULL)7 I/ c' _0 n: z, S
                if(p->adjVex2==v2)
    2 [0 w: g$ h! j) x# T% N; ?                vexTable[v2].firstarc = p->nextarc2;
    & E9 g( K) _7 D% a            else vexTable[v2].firstarc=p->nextarc1;, b- P& h- _) c1 c" l
            else
    7 [, Z: n: O' ^4 n        {
    ! d8 i' _0 `# K- B- M            if(r->adjVex2==v2)' H: L, u: Q9 k  `1 r( D, @1 W- l
                    r->nextarc2 = NextArc(v2,p);! m' q" C5 M9 x5 T" H
                else
    2 H* g* a7 e- V2 e( W, y                r->nextarc1=NextArc(v2,p);* d9 [* l& M' `
            }
    * U8 |; u: h3 z; ^. C8 x        delete p;# f3 p9 L( p7 [% k8 a" P6 s
            arcNum--;
    1 I+ H: G$ Q. R6 |, X, C& f    }, k: b* c' m% M$ r6 H" k
    ! N( R7 I/ l- F8 J- `: A; I
    }
    ' W8 f# P( y" Q! y, W! E: stemplate<class ElemType, class WeightType> void0 B  J! `% e- u, v$ t1 g( U
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    * Y* I: k8 k8 E0 V{2 C6 e- _% G) @% [6 x, ~" t
        int v;5 q- r% B! e* R8 G8 o
        MultiAdjListNetworkArc<WeightType>* p;
    / I1 j$ ]4 e0 E3 H. V    for (v = 0; v < vexNum; v++)//找到d对应顶点: F8 v9 o1 O' D) V  _3 h% B: D+ ^/ O
            if (vexTable[v].data == d)4 [6 t; i; s+ a
                break;
    ; q) ~, N# h/ K! i3 q4 v) i5 Z    if(v==vexNum)
    " A6 q& a( C; w9 J+ H; j" v        throw Error("图中不存在要删除的顶点!");5 T4 `* j6 N" {

    ( z( g; X6 |8 @- q# V    for (int u = 0; u < vexNum; u++)//删除与d相连的边8 b' e- L/ Y: D  G, J- _2 I0 I
            if (u != v)
    " N8 O9 t  Q. a0 m& @+ q4 B5 t        {
    - _$ _1 q, |; b5 Z8 |; N! `            DeleteArc(u, v);
    ) g5 f0 O1 r( W1 z% s5 z        }# }1 J! Y# _$ U& l0 ^
        vexTable[v].firstarc=NULL;
    7 l+ Z7 x4 r1 ?# x6 n# L0 [
    2 v4 N& n  R+ M) k7 L    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    ! V) L7 I4 s/ K# |    vexTable[v].data = vexTable[vexNum].data;
    6 b  M0 h+ V; w. N    vexTable[v].firstarc = vexTable[vexNum].firstarc;% l/ N* [( R4 F; k, m  j/ k" T. S$ i
        vexTable[vexNum].firstarc = NULL;
    $ [( g; M5 k' J9 j. N  Q  u3 k1 O    tag[v] = tag[vexNum];! M( `$ o$ {& W1 ]6 X  x' Y5 W$ W
        //原来与最后一个顶点相连的边改为与v相连
    1 `$ ~) `. h0 ^- \1 g) I, ^+ Q: g    for (int u = 0; u < vexNum; u++)8 M/ i- H0 K  [+ _; ^" X
        {2 [. z5 g- Z$ i' g4 H
            if (u != v)$ E- l+ d4 [6 b/ c
            {2 N0 W9 s7 a5 @; i  k, o% V, [5 a
                p = vexTable.firstarc;* m; r. _" E0 F" v0 _
                while (p)7 e# j3 K0 _) f( b* E
                {
      H; y8 l+ |; y$ H) G7 [                if (p->adjVex1==vexNum)2 C1 M2 \+ F/ r
                        p->adjVex1= v;
    6 B; [+ G- j* s* A$ H                else if(p->adjVex2==vexNum): D# v1 N: F7 c: b; s
                        p->adjVex2=v;) ^/ B, c3 `0 y5 F4 x! e" ?2 \0 `
                    p = NextArc(u,p);7 J  t$ ^* |# a" x, z
                }
    . L, A+ u- Y, }$ J7 D' C! g        }7 ^# e( _6 ?! O/ H" Q
        }* _" I3 n# a) N' p' r6 ^6 d
    }
    5 R" l- i, u. l///深度优先遍历7 i* v% I/ r; v5 ?+ x
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)% N6 N; p) B2 Z- {. T5 g
    {! Y/ P# w  F0 b  l( y  i) a
        tag[v]=1;
    * d# F% }! i$ S2 o$ r; r    cout<<setw(3)<<vexTable[v].data;, E: V+ \) L% J9 P# |* R
        MultiAdjListNetworkArc<WeightType> *p;
    ; |; q1 H5 E- c    p=vexTable[v].firstarc;' u8 h0 b" }" y) t5 P8 V
        while(p)
    5 n  B6 `6 o7 A% O/ o    {7 D% ?) s/ O9 C5 F( m+ c
            if(tag[p->adjVex1]==0)
    . H" ^7 }9 j1 [7 `& v9 G            DFS1(p->adjVex1);
    / Y/ i0 d$ u1 }! F  }9 A        else if(tag[p->adjVex2]==0)
    7 D$ |8 r# O# ]+ z! X0 Q2 H            DFS1(p->adjVex2);/ ], {1 K4 E" v% S/ R4 J8 W6 G2 a6 ?
            p=NextArc(v,p);# ]0 G3 u- L% z: o9 M  e6 {
        }) a4 p0 O3 L0 U: @5 |. v, Z: N
    }
    . w2 ]% v) o' a  A- ~' z' T: utemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    7 \2 S" b- h+ V{
    / r6 z; ~% m3 @1 F' p3 b    for(int i=0; i<vexNum; i++)
    2 \; X4 b' [& O; C) R( |        tag=0;
    - V9 n3 }: q( @6 w- J1 ~) T    for(int v=0; v<vexNum; v++)
    / U! Q% j3 q2 w    {8 B0 Y/ S! g3 d0 \1 e7 w
            if(tag[v]==0)
    9 G* q1 i* k. J; _+ R            DFS1(v);
    # z0 E7 C8 B% |5 O    }
    ; C6 N4 O2 G2 G# m. n}
    ' ~; }1 `9 W' I' o$ Ctemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    3 w) Q1 r5 r' r! v! ~{
    : ^$ ]* _. z6 h& ?- r    stack<int> s;
    ' V6 r+ V) X+ ~5 A    int tmp;! J: F" N# D  _; ~. f
        MultiAdjListNetworkArc<WeightType> *p,*q;  F1 [  p0 _8 ^0 |  R; w, @7 d
        for(int i=0; i<vexNum; i++)% z! M( N5 G0 [/ `
            tag=0;
    . n& p8 X2 J$ m3 T5 a; B    for(int i=0; i<vexNum; i++)! p8 e- S, V# w6 r3 ]0 ^
        {
    $ S9 a# f( v7 T: J3 y        tmp=i;" Q5 t  M) E' B, V' n, [
            while(tag[tmp]==0||!s.empty()): B. k" t& v# h. x9 I
            {
    7 D2 }: Y7 M9 i! ?, [: h3 p' p            p=vexTable[tmp].firstarc;
    # x: D% H" Z9 D1 O5 K8 ^            while(tag[tmp]==0)
    1 v$ o: J* f) h            {3 M- i+ ^+ U& y4 z6 n, j4 ]
                    s.push(tmp);
    " x5 c9 F' d) ?6 A& ~' f. A                cout<<setw(3)<<vexTable[tmp].data;4 H/ j5 x' ^6 j" P4 p! N: E
                    tag[tmp]=1;. x6 O+ v* R1 M! q: N1 }
                    p=vexTable[tmp].firstarc;2 D" N" k  c" b: {8 c: i* _
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for8 P) X! o# i8 T& H
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);! Y/ M1 d3 _% l( m$ \2 \
                    //cout<<" 1st     tmp="<<tmp<<endl;. Q2 p: [+ T: r: T+ x2 g
                }
    & |! ]% _' {& V            if(!s.empty())3 m9 U# I4 y0 [% G' n
                {, z* ]" n; p4 @
                    tmp=s.top();
    + P  g! N5 g6 `3 ^) V' Q                s.pop();
    " H6 {/ {' b/ J6 C+ ~' {                q=vexTable[tmp].firstarc;
    8 Y3 G! f- S5 T4 ?# f  O! J$ \                int t=tmp;
    / f( b4 T; D5 J& k7 W                while(q&&tag[tmp]!=0)
    $ z% x  G' Q% G- Y3 ~/ z# h                {8 k* \$ k. o3 _0 x
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    6 A, m8 S+ Q+ z; Y. v2 Z, o1 ~: n# M                    //cout<<" 2nd     tmp="<<tmp<<endl;& e; D/ v+ w, ^
                        q=NextArc(t,q);3 |+ ^- M7 S2 _! w9 a* ]
                    }
    ! J' o( {. n% \                if(tag[tmp]==0)
    & W- ~# G0 e0 ?0 J3 N6 t7 q# Z                    s.push(t);
    ' l& l8 e6 z, G2 ?3 B                ///1、对应上面连通分支只有1个点的情况. c) W9 g0 r( N6 Q& }" V& {8 u( Q
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈( b1 T: \# m! T. d3 v
                    ///tmp要么等于找到的第一个未访问节点,/ ?$ p+ f# }" s" ?5 D( v" f
                    ///要么等于与t相连最后一个点(已被访问过)
    8 g' r6 {1 T* X9 v* c: Q2 Z0 h                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    4 a6 K; Q3 m/ Z+ R$ a& E            }  G4 q% d% y- o3 W/ c( }" L
            }) k' c5 y% [' O) X! M
        }2 N, |& x# ?4 p% X4 @
    }
    1 H/ R( q7 m/ d0 r4 \9 t( X//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    8 B3 R. X; ~8 a1 n) l5 wtemplate<class ElemType, class WeightType> int
    3 w9 g- s3 `' u- p6 N7 m% qMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)2 u$ ?0 n- M/ F" _1 j: J: F4 b
    {& w9 p4 u( m8 @) I4 r% e4 A$ y' N( H
        if(head==pre): g7 q6 ?* U8 G; I$ O& g- s
            return -1;
    3 |& w% ?. c& W9 n$ B: S
    3 d% q7 d+ y2 v& j& V, q: Z    MultiAdjListNetworkArc<WeightType> *p;9 l: `, O- v8 z; v$ E
        p=vexTable[head].firstarc;' _7 Z4 h! b- L, R! \- |
        if(pre==-1&&p!=NULL)
    . o6 ^) D1 ?. h4 S        return p->adjVex1==head?p->adjVex2:p->adjVex1;4 Z' V  o/ w6 I- a, Z9 d+ Q" T
        //pre!=-1&&p!=NULL9 r6 R) {+ r4 S6 [6 J
        while(p!=NULL)/ r0 O  Y! N$ Z& \& V8 Q% o
        {) e" n: Q- X) C$ s* {# U
            if(p->adjVex1==head && p->adjVex2!=pre)/ W% F3 Y0 v4 @( O$ x
                p=p->nextarc1;
    % R4 u/ }. I' O' }1 B        else if(p->adjVex2==head && p->adjVex1!=pre)* ?  T7 x& M: |" H3 F
                p=p->nextarc2;
    - u$ b3 z- [  A7 e! e, k        else if(p->adjVex1==head && p->adjVex2==pre)
    % z4 \/ z9 I; M$ x: o1 u" c        {
    ' d, w8 ^  a" Z$ g' J8 B9 U: W            p=p->nextarc1;
    7 o/ q& @# }! {" e* M9 e* R, s            break;# A: Z4 T* M8 c$ Y4 v
            }5 F$ k" ]. r! d8 y) A6 b) \
            else if(p->adjVex2==head && p->adjVex1==pre)
    + Z6 N1 N3 F* ]- _' J        {
    5 M+ }- b  g+ W" k            p=p->nextarc2;
    ' M7 b4 h& g4 @0 R$ w            break;6 J" K3 C& d1 G( a! m1 y
            }
    8 G/ H+ U  y" j7 F$ G# M    }) o/ k0 c7 ]; q$ ~5 g
        if(p!=NULL); k1 q5 \  V& q" }
        {
    ' ]4 a1 M+ j+ T% r2 U( ?        return p->adjVex1==head?p->adjVex2:p->adjVex1;5 \- U# [/ M' q0 S8 R
        }
    9 `7 ^/ k( ^: r6 I5 s5 b' E    else
    . \# ]" B1 q! f, q, }8 k        return -1;
    % h+ G* |3 a6 k' ~( j: [8 a2 \}4 L4 n1 l& S- K7 z2 n+ a0 }1 a, t
    9 G# g. {5 j# ^

    * [8 B) j+ T4 m  h; e3 U! Wtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()2 O$ d  J" G" [, Y& Z: f( [
    {
    ; b8 f" |, y1 B5 F    stack<int> s;. O! h2 w3 G# Q, f7 Y
        int p,cur,pre;
    1 P0 _7 k4 R0 s. p    //MultiAdjListNetworkArc<WeightType> *p,*q;0 g( V$ Y1 K) j3 O9 Y$ V5 X+ d
        for(int i=0; i<vexNum; i++) tag=0;//初始化- C+ N+ s; H! _6 G: e4 H- U% s

    " H; W9 b" w" r) r3 Q    for(int i=0; i<vexNum; i++)
    " U* q3 f# o( K: v2 F9 l7 {    {+ \) c3 ?0 m& O& b; b
            cur=i;pre=-1;
    ( w6 Z* o3 J5 k% n8 R4 a9 y        while(tag[cur]==0||!s.empty())
    - a2 L9 q% w! x- }3 I2 l  w        {4 a+ p( }# u% L0 ^
                while(tag[cur]==0)
    # p% ?: z$ ]( U) U8 G( d            {5 F8 L0 c. T. Z: `$ d: |2 }( H5 R
                    cout<<vexTable[cur].data<<"  ";
    7 _9 ?0 }7 }+ R9 ]                s.push(cur);+ B' j/ l+ ?5 N
                    tag[cur]=1;
    8 r; t. ?3 D6 r# \) U- L$ E6 ~; x               //初次访问,标记入栈! [  S: n2 T4 s/ p- x
    8 v6 N1 G' M4 D" x4 p9 h
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点5 n3 k: V* P6 \$ |
                   if(p==-1)& h" x  ?4 l3 R+ T: g
                   {
    * u9 ^0 u! x& E- h! z/ P6 S( T                   pre=cur;s.pop();  |$ z5 Y8 G5 {4 Q$ x) P& ?
                       break;
    ! p; [' `1 `- y* U( ^1 O               }, b" |% O; d7 ?* `
                   else
    4 r- F" z6 f( ^( ?               {
    / U, ^5 o' z* X# A                   pre=cur;: h/ c" W- N/ M( v; \
                       cur=p;
      `" V5 v. g# Y1 C, f" a: C               }% K/ E- J' Z7 h/ _8 }! C

    4 Q3 h$ Z2 l* s            }
    7 V% A3 z9 }9 u6 z& t3 F% b, e5 t% O" w            while(!s.empty())
    " i/ N1 q2 ~2 }( j$ _1 o            {; O+ x  a7 b0 j8 w& F# l
                    cur=s.top();
    * s" l: c0 E; v/ g                p=GetAdjVex(cur,pre);
    , ~. N0 p1 |2 S- C. J                if(tag[p]==0)
    , a" @( S, Q1 G3 u& Q" M, v0 S                {5 [8 r! G; _2 f* _! V  Y
                        pre=cur;
    % e2 d- r+ W( n3 Z                    cur=p;/ y4 C: U% B1 W' W+ h/ |: W/ V: q& m7 @
                        break;6 r9 I* X( N* e1 J! x% J5 [% W  y
                    }
    - c* ^( Q* m) s; S- V$ _& Q! P                else. Z5 s1 Z" w8 b2 @. \$ |
                    {
    3 r6 P9 M4 m7 }" `* ~, E# x: ~: ~5 m% |                    pre=s.top();% W, M! I4 k3 V# ?" q" c" Q  e
                        s.pop();: O' ?" v. P# U
                    }
    9 Q  ?5 y' i: [/ s* k( b" l
    6 q  X8 X& R* I' R            }  a' }; V- {" ^: P4 K6 H6 \. m
    ' z, |: Z$ n$ t1 f3 k9 c
            }9 D  A: G2 i6 u& w' N# l
        }
    0 W" u$ \: M1 J}" n3 s  z* w' h* d9 f
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    6 N3 {8 m6 Y& K8 Q" @{9 ^3 Y: k! g8 r9 Q9 V6 s# \
        for(int i=0; i<vexNum; i++)1 ^+ H! p( r( S- [' j8 }1 \/ S* c
            tag=0;0 L# x+ u2 U: R% @" \; }
        queue<int> q;
    ( i# x0 j' i6 ?" v    int tmp,t;
    1 N  x- g2 x9 g/ s' D    MultiAdjListNetworkArc<WeightType> *p;
    6 a0 S; ~3 S; E9 O    for(int i=0; i<vexNum; i++)
    3 f; [  I+ {7 v$ b    {$ @' P5 a2 {9 b( j/ _- `- d* F
            if(tag==0)
    ! E! c9 m2 c! }# k+ }1 K        {* {2 x7 y, @7 E0 j) v8 O; O
                tag=1;
    8 U" p7 D5 `+ b* U            q.push(i);, H; u2 h' y) N; H- N- n
                cout<<setw(3)<<vexTable.data;/ Z; h" i9 M0 a" v
            }5 z5 ~  h$ @. U% Z& ^
            while(!q.empty())
    3 _/ L1 J& T0 q- m: }        {# {0 Y- z; W& `( ^
                tmp=q.front();
    - q+ c' G) U7 F; c            q.pop();  X: N  @- o: ]) C6 u
                p=vexTable[tmp].firstarc;, K4 g( s  y$ [5 S& i
                while(p!=NULL), _6 n  v1 c  Q) C* L/ t: @/ i2 O7 j
                {3 K2 d' K$ h3 x1 N8 ?, x/ P5 o
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);2 {9 o8 M! `# I: g" U3 w
                    if(tag[t]==0)
    7 B# d' A0 R8 t3 v" B- S                {
    4 w& m& ^  Z/ E                    cout<<setw(3)<<vexTable[t].data;- g/ u8 W6 F" s2 I) G
                        tag[t]=1;" c7 o5 ?$ Q7 |! G$ u
                        q.push(t);
    7 p  t2 U8 h+ B0 _9 R* P( R! m; l                }) u$ \4 e8 R; o8 H# h$ `& _% D
                    p=NextArc(tmp,p);
    3 M1 o' n5 C/ ?! s& Q- O            }
    0 h- W$ e( v9 w        }# f; B, r9 z- i
        }
    - _( U/ F( _, N/ n$ P}" v9 U% A5 h( a" p+ j5 h7 f7 G3 a& E
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show(): h5 s; i- q  N$ g; L7 w
    {
    : I& h! F" c# O, v( ~. h    MultiAdjListNetworkArc<WeightType> *p;
    6 ?' U( r" a7 T5 R4 K    cout << "无向图有" << vexNum << "个点,分别为:";
    3 R6 D( _, D% a; W5 W, _    for (int i = 0; i < vexNum; i++)$ b/ s) F( F- [1 M0 t$ \# |
            cout << vexTable.data << " ";
    1 U. W8 j- E/ E8 z+ \+ `/ b1 y    cout << endl;
    ! ?3 T8 ~9 @, H" k3 n    cout << "无向图有" << arcNum << "条边"<<endl;
    2 g$ X4 \+ O% l( {% B    for (int i = 0; i < vexNum; i++)
    & b; e2 }4 o* N' j( B8 }    {
    , ]  G1 J8 A% U5 V# R        cout<<"和" << vexTable.data << "有关的边:";8 S4 m, c6 L7 y7 E& r$ F
            p = vexTable.firstarc;
    0 x. U" L' y4 r        while (p != NULL)8 h3 N: B1 t$ N6 B5 [
            {% i  a+ T: L. c! O
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    , N: N, n, g2 B1 E8 d            p=NextArc(i,p);
    ) s0 H# R- X/ _* K. d" _        }
    * T" \. m0 q8 V0 h5 Y4 X3 _# G2 M        cout << endl;
    ( y9 E2 W4 Q1 P  v0 D% ^    }, \1 @: N" ~& `0 u4 c
    }1 G: a  f$ {. }) T

    : L& ]2 X, S/ }4 ~3 @; |# F' M+ l0 B3 _4 z# @! [: Y. h+ [7 q. Q
    邻接多重表与邻接表的对比
    / x' W5 {3 X, ~/ ?) f. P9 I* [# L( f+ h1 K) D7 ?
    邻接表链接
    % n. M+ i" L% q) @在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。6 G+ }' P: b/ T! @! j* f3 Q8 d- a# G
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    0 W4 E$ R: r( {# ?" j, J为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    , k2 }: u, J+ m————————————————$ E1 P3 U; x* i0 N( Y
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。% }% E7 l& X$ I# }! }
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958- b# w* C! `& O' }& V7 w' H. x  _
    ) u5 t. W# c+ }! o3 L/ s' d

    # Z2 F9 b, J6 N; |! M7 s1 q) f
    : _3 _4 K: `) ^6 N+ g/ `) o; m8 o$ }" o
    ————————————————
    & H* I7 z7 R$ T0 B版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。8 e  p) K. @4 Z" R2 y+ o+ z
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    $ `6 e  s: Q, H4 ~: _4 c: P6 u
    % B1 t8 Z! O! b) f
    % u8 c+ s# k6 e1 q
    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-9 00:53 , Processed in 0.522530 second(s), 53 queries .

    回顶部