QQ登录

只需要一步,快速开始

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

    + R0 W, ]9 b' j: |) ?# g4 a0 }图的存储结构——邻接多重表(多重邻接表)的实现
    4 r. ~4 g9 ?+ e& N5 `* V. m7.2 图的存储结构1 D7 g: v5 g; G$ ?
    5 f9 P  L) N. s3 N% z# \' g$ G+ L
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    & a- R* T5 l: s邻接多重表的类定义. N) b8 e7 ]8 [7 w+ [5 t
    邻接多重表的顶点结点类模板% N$ h8 J+ ]4 m1 M' H6 y+ F: F3 \1 Z
    邻接多重表的边结点类模板& ?+ y, |5 x; r7 n$ |/ E6 ]1 v. d
    邻接多重表的类模板
    . p! r7 ?) q" g2 I, B5 T, ~  b邻接多重表与邻接表的对比$ h2 |5 ?! D, ^
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    ! X) |' C# V( R, \) q
    " e$ X* l; g# r. R在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    + U- x4 z/ G" n( ~4 Y$ }在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。/ P  W5 b# ]) N8 E* ?
    , j6 \0 u/ z5 ?* b$ _
    邻接多重表的类定义' g3 w2 P4 O9 x9 r  p# M7 Q
    1.png # y( ~- }6 n- `* \
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    5 I4 P  Q% e& ddata域存储有关顶点的信息;! q+ h( j+ `/ O) g6 a! @! A6 E  @
    firstarc域是链接指针,指向第一条依附于该顶点的边。
    0 S% P% s0 i; t  g% ~所有的顶点结点组成一个顺序表。

    ! G9 ?7 U& _, K1 Z* X1 {
    - H! B0 C6 g! R/ \' |$ [* Y
    template <class ElemType ,class WeightType>  y# s8 X8 D2 C1 G3 Y
    class MultiAdjListNetworkVex
    - t- ~# Q2 O2 ?$ r" g0 r6 f' |- \+ V{
    % @# X7 y7 f% x4 A- E5 Vpublic:8 R; ~/ D# @: Z( x' X
            ElemType data;! q  f. ~0 P! S* K% b5 V: v$ @
            MultiAdjListNetworkArc<WeightType> *firstarc;- w( F: d" e  R

    5 J5 ]6 a2 L3 H        MultiAdjListNetworkVex()
    3 k0 t* G6 Y) {  A& c* z0 C" u" c        {9 f! X( M5 G# d' B1 s! S  G, ?6 Y
                    firstarc = NULL;% X- c. O, A) T
            }+ W7 W, {2 u- D  ]
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    1 Q1 T# `+ |, y) k9 S# q        {
    4 N. G7 f8 ^5 s                data = val;1 j1 [+ ]0 Z3 y6 s. S
                    firstarc = adj;5 x7 K) k! r$ h
            }" l  ]8 V* G: N( I* p6 n, p: v
    };
    7 q/ v* C. T% v2 a& P1 o7 c3 W* }* X+ F! p- F6 [* a9 S- P
    邻接多重表的边结点类模板% b+ j) `- e: l6 |& y& i
    " G. E% \5 N+ U
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:; u  r3 Y* M4 T0 ?6 H/ y
    tag是标记域,标记该边是否被处理或被搜索过;6 M& @. g3 Z* }; Z4 \2 v" j3 k
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    . D2 o" |) \8 @& w. B- ^0 Qnextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;0 E. {9 g; w5 W
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    ( ^  Q: R. k" e1 C
    4 J8 S4 k5 a$ S2 r) M 2.png $ }: }5 Q( ^4 D6 m: q) S
    template <class WeightType>
    2 N( W; D( t, l+ t/ Cclass MultiAdjListNetworkArc+ s. z6 `; |1 k" B! w6 E1 B3 B
    {
    9 i$ a" G7 H. H$ ^. t) Kpublic:9 D1 W  ?4 t5 T1 `
        int mark;                                       //标记该边是否被搜索或处理过+ P; y! C- [# R: h
            WeightType weight;                              //边的权重/ C  i+ b$ a& ?
            int adjVex1;                                    //边的一个顶点9 \! G5 Y. z5 I+ p' ~4 ]. J( g8 X5 @
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1" z* {) L6 E! l# k8 N- P! t6 {0 f
            int adjVex2;4 y" S5 \# n! ~+ t4 O+ q
            MultiAdjListNetworkArc<WeightType>* nextarc2;
    1 j- i# H: o, s6 w9 K+ G4 f$ w. u' n6 h7 ^2 R
            MultiAdjListNetworkArc()* V. H, X$ P: \. o8 D6 j, u
            {; L' I+ o! \# I8 A8 ?8 S. w
                    adjVex1= -1;$ f/ m) D% d1 e2 X& ]' u
                    adjVex2= -1;1 p, |% n  A* t9 p1 p  A) q
            }2 e5 h2 i4 ?- @/ }4 M/ a
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    - U" r, S3 {8 `( i7 G* z3 |        {! ?# X  z9 K- d, \" E0 a8 \' h$ |
                    adjVex1 = v1;       adjVex2 = v2;
    ( C) u+ t) `% y6 b                weight = w;( M$ R4 ?5 m7 ?# T
                    nextarc1 = next1;   nextarc2=next2;+ A- n  e8 {, v& r5 T$ ^
                    mark = 0;           //0表示未被搜索,1表示被搜索过9 V: j) |; s; H; n/ @6 T3 T
            }
    ' _, Y+ A5 K5 Y: K) r; u& O' r+ q7 |; g4 \# V! G
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    " d/ y) }  {" W% R! w- hclass MultiAdjListNetwork
    # b4 E7 M/ o+ q/ X{
    % }9 @( ]: ?; k% o2 C; Wprotected:
    1 i" X& P9 G" b5 V0 ^    int vexNum, vexMaxNum, arcNum;& v7 S: W1 |- z) [( r4 V
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;0 S6 d" b+ L6 j( A$ j9 e& a2 c+ m
        int* tag;
    4 f  T, v; ~, p8 N    WeightType infinity;
    7 Y2 l* n/ B! u& {
    ' O2 k2 t3 V8 ~# j! Z' S8 x# @public:
    2 _* T( n$ ^1 b+ b" b; X    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);' M9 q" a9 E  M* O

    / q, e8 [9 L) r$ p    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    1 ?$ k5 y- y4 x: j; m! p$ J, r5 K
    4 h, c, S. ^9 ^' t& A' N) k    void Clear();& f" s# l! b8 H5 |
        bool IsEmpty()
    ( c1 X2 \: N* Y" z5 C0 w0 M    {- W7 L) H9 ]7 p1 b$ H( {
            return vexNum == 0;
    % W8 a/ q9 [. D& Y5 @: ]0 m: {4 K    }! y  q, p7 q9 O. v; u6 _2 J- `
        int GetArcNum()const
    9 `+ Y1 z& H  R0 b2 {$ g6 Q0 y7 T    {( e4 _  [  U( @2 {' W& F
            return arcNum;2 r% l3 m8 ~1 s( R8 k/ z
        }
    % l( ?/ c1 \. k3 X2 |, Q( u    int GetvexNum()const
    0 G0 y+ {; b1 Z# @' f' C1 [( I    {* l5 F7 J9 J: ^; \, G! o2 @0 W
            return vexNum;2 b- t& }9 l! r! f8 M
        }  O5 F4 }2 [$ H* `0 M" m2 k7 x: N

    2 k, i% L; }+ G3 ~6 m+ T* R3 v  f
    ' `7 q; L( z0 u$ i/ E    int FirstAdjVex(int v)const;2 Q! J! T8 R) w, h' b2 D2 u/ a
        int NextAdjVex(int v1, int v2)const;
    " ?+ Y4 _& |0 F    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;/ x" t! Y' ^. Z# `' f* y* z. U
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;. O- H0 X- P5 n  k0 a/ Z% c7 j6 m

    & i9 n& ^  c) O& S, x    void InsertVex(const ElemType& d);/ ~& N9 e( L# N6 V: ]" ~  h6 |
        void InsertArc(int v1, int v2, WeightType w);
    . u' g; L' ]6 z5 n2 P' w& D
    7 W4 Q. r$ E- C    void DeleteVex(const ElemType& d);8 T! R+ c7 Y2 K0 V9 f
        void DeleteArc(int v1, int v2);8 R$ Z# ?$ A! x( I: O$ C' n+ P

    - {/ W+ |6 @% z4 k    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);6 l. X! k  w' t) K, f. a, p* {
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);, N9 L+ L9 X3 e$ L/ x$ [% T/ `' n
    . n) v7 Z# S% `6 G; i
        ///深度优先遍历9 w; E; J' T& F! v
        void DFS1(const int v);% y0 N7 v- n2 u8 E+ K2 L
        void DFS1Traverse();
    0 {, U6 |1 z. x- L! `3 O. J    void DFS2();/ @1 W% }; \1 k& S4 d* W
    9 ~5 D8 m* w$ j6 m% o
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1" }5 w* g: o7 W
        void DFS3();; ?8 F0 G+ P: `" B3 t6 ]6 E

    ; s8 i( Q9 A* F    void BFS();' a" z& y" e* g6 O. J7 L/ G
        void Show();
    2 m5 G% ^+ x8 z6 L3 w. i};
    # \4 _. Y/ W2 h$ m6 M+ J3 f, Y0 K' |  T0 K. @! l0 @1 {
    2.函数的实现; B" K7 D& x9 a2 [* f: g2 p
    研讨题,能够运行,但是代码不一定是最优的。+ X6 P. t1 G, X' A+ f
      p, q5 C5 M8 @
    #include <stack>
    ; v7 V9 H! d& L/ Z1 s#include <queue>. o( Q5 R5 R$ T# n

    6 T3 F& f1 U0 k4 {6 Btemplate <class ElemType,class WeightType>
    * M, O) U; G  v( K* ~. j+ G& HMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    0 y( v8 K: J7 B, x{
    6 L; ~, U9 S1 ], p8 s9 V    if(vertexMaxNum < 0)
    5 L, M8 S! t% W6 I; \1 \        throw Error("允许的顶点最大数目不能为负!");
    & @! Q5 c) S; y% U( T    if (vertexMaxNum < vertexNum)
    * N0 w6 d* h; v9 p) L" w# N        throw Error("顶点数目不能大于允许的顶点最大数目!");
    9 _, o" ]  C$ y    vexNum = vertexNum;1 [( d0 s1 B5 R0 B( b2 P
        vexMaxNum = vertexMaxNum;
    % g( c# Y, ?! g' g; ~4 `1 P) `    arcNum = 0;
    ; C0 {7 h4 n; Q9 a/ i2 @" h    infinity = infinit;7 @1 B8 M& d, r- L# J
        tag = new int[vexMaxNum];
    2 X0 g1 V' l" y; p6 T1 @) W    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    5 O; `! @& a3 L/ L# L    for (int v = 0; v < vexNum; v++)
    ; X- O# i- R$ @    {- \4 m) O8 q5 I
            tag[v] = 0;
    5 s6 [, H7 G8 }& X        vexTable[v].data = es[v];
    8 c. q: Z+ c" |2 `+ _1 B        vexTable[v].firstarc = NULL;
    8 M+ o! i+ `* S6 |$ o    }
    ; P; \" J2 l6 G2 D& Q! ?0 R$ x6 O! O}
    : w" T& b6 d7 s) ptemplate <class ElemType,class WeightType>/ Q8 ~# H' @% C7 K) J
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    ; y' s# f% `4 M0 P  ?# y! Z{
      ?/ B1 X8 z* a$ ^# o( J5 d    if (vertexMaxNum < 0)8 Q4 `3 ^) w$ S- o* N! V( }3 o+ ^
            throw Error("允许的顶点最大数目不能为负!");) B6 `) N, v1 f' E2 M
        vexNum = 0;
    - [7 m9 k. [0 f    vexMaxNum = vertexMaxNum;1 v8 p% g. M* y- U  [" g
        arcNum = 0;1 E. A7 i. Z/ X9 L
        infinity = infinit;
    % d& u6 P* [, w  r( x    tag = new int[vexMaxNum];
    ! [; D4 f8 W& X' j    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    & u. s8 N2 P4 c) a4 Q0 h}& |+ Z9 f% l2 e7 v* e% a) v
    template<class ElemType, class WeightType>% V6 W% [+ m9 h1 y* l3 p
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const7 E9 ^$ E: F1 A
    {. W0 l. B" d" r9 Y
        if (v < 0 || v >= vexNum)
    & z$ X) i$ {6 e  x, R7 E7 ~' C        throw Error("v不合法!");: w# J  t7 r, _! H5 x! ~2 R
        if (vexTable[v].firstarc == NULL)/ L- ^! E% u8 ~2 P' z: v2 c$ n' h
            return -1;/ R, \3 O( a% d3 P7 `, \) b, X
        else- z& q8 Q8 g' j$ v  n, h2 S5 ?) K
            return vexTable[v].firstarc->adjVex1;/ L2 e1 W; N! o+ q' G
    }" h5 y5 _( ]- @( w, q% Z5 @8 Q( ]
      l/ q  y4 g% i
    template<class ElemType, class WeightType>
    4 [* [+ s- q" P, _1 Hint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const& G! Q7 Q7 _4 Y+ D3 M
    {
    ' K+ A' N4 K0 \1 x    MultiAdjListNetworkArc<WeightType>* p;
    ! \3 j4 D3 c4 v' P    if (v1 < 0 || v1 >= vexNum)7 R3 w# d6 |! A
            throw Error("v1不合法!");$ \0 z% L4 p# o3 x
        if (v2 < 0 || v2 >= vexNum)
    : Y+ V8 p7 _, t1 R: T) r        throw Error("v2不合法!");
    & Y/ w) D/ H7 X) D    if (v1 == v2)
    9 Q, ]# R3 P* k# i: z" p1 T        throw Error("v1不能等于v2!");& u7 V* s, d1 |& \0 [
        p = vexTable[v1].firstarc;9 Y" Q+ p1 D4 M4 c3 t8 ^. c- ^$ o2 r. v
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)2 w+ J; P! d; ^, M& [4 A0 E8 D% p. n# ~! [3 k
            p = p->nextarc;
    , T" c3 y6 {2 I+ _    if (p == NULL || p->nextarc == NULL)
    . E0 {0 i* a* L6 D* [" {; A        return -1;  //不存在下一个邻接点
    0 _" E; a  ]5 S9 T& L3 A    else if(p->adjVex1==v2)4 P* L4 O0 D0 O4 _: L
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    6 N2 o' I+ A& u$ n6 j2 O: o& Z    else9 d0 c; Q( Q0 R, G) w% u
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);+ A8 r; F3 g+ e- v! J
    }- \6 [4 g0 p8 L/ B9 I
    template<class ElemType, class WeightType>4 Z* W' v/ M( a# f6 p/ L# M
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()2 d% |5 q6 c+ I2 H
    {! P& R9 H9 ?9 {7 b. H" M
        if (IsEmpty()) return;
    9 U0 K9 {, \2 z' Z& n2 s    int n = vexNum;! @, O5 n: x3 V- G3 p
        for (int u = 0; u < n ; u++)
    3 v( F: a( |# t8 t        DeleteVex(vexTable[0].data);* p7 S! d( R- t1 b
        return;' D- P  j9 x4 z! f
    }
    ( w; X1 D: Q; G1 L  Y* H* Stemplate<class ElemType, class WeightType>0 }$ ~7 u( q6 \& ^) B" l
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()( L/ q; _# D* u
    {* ^: G8 u$ F9 j% P) a) q8 h* \+ o
        Clear();+ |7 `* ~, r' y, H. s" g
    }
    $ D% d" ~: i, @template<class ElemType, class WeightType>: z7 w+ a# c3 p) G3 J7 b
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)0 j1 A& a, I/ `( q4 Y
    {
    0 u3 P6 y+ x$ G9 A    vexMaxNum = copy.vexMaxNum;% [  D" b. X) g$ i" K# S; y4 I
        vexNum = copy.vexNum;
    . s4 j" l# [) P# s4 }" D/ D    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];( ?4 @3 y$ n) M
        arcNum = 0;4 a) }6 ~1 C9 Q: c
        infinity = copy.infinity;  x! `" Q$ |/ |* b
        tag = new int[vexMaxNum];$ E$ s) K' k( q" q6 X

    % ^) @4 I$ ]( Q* q5 O3 O    for (int v = 0; v < vexNum; v++)
    ' `* u2 x' W7 }' _8 `    {
    3 L" h. z! E2 N2 T        tag[v] = 0;( Z( G- P: s- ]
            vexTable[v].data = copy.vexTable[v].data;  u- l8 t, g; c" F, z( d% \
            vexTable[v].firstarc = NULL;
    ( N8 O2 R; x8 R+ m9 E    }; Q; v7 J: \) v
        MultiAdjListNetworkArc<WeightType>* p;
    $ I7 R4 G" \9 U; u9 q
    8 v* n% ~# Q7 M! L& c$ n, C6 b! k7 ^    for (int u = 0; u < vexNum; u++)
    $ g( [( j! n4 n7 `+ S/ }    {
    6 P# }- ~8 a& c: G, n0 V% y  S        p = copy.vexTable.firstarc;
    3 y/ T# ?+ D, T1 ^. ]        while (p != NULL)) h* r* Z. O9 }. E% ^/ a* i8 b0 [3 S! P
            {" J5 f$ t* y# D5 e" P
                InsertArc(p->adjVex1, p->adjVex2, p->weight);# A9 K! H* W. l, X, N
                p=NextArc(u,p);
    0 C7 Z0 E; @: s+ K" i& |2 ?2 i        }
    1 [( A4 j6 C7 x, N% e7 F8 K! L    }. O) r3 q0 E2 h: E. Z+ o
    }
    8 g! \, M1 L6 G) @template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    . X& L4 Y1 ]3 l$ P  EMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy), g7 n# }* V( F$ N; Z
    {7 @: W% j, U( ]- L& P" @/ I( [5 }
        if (this == &copy) return *this;
    $ S! H1 }2 ~5 R2 R1 i$ f    Clear();
    6 N, e+ T; c; l- D9 \6 Q& k; J7 C    vexMaxNum = copy.vexMaxNum;% j- ]# r3 D# r$ X- ?+ q. Z' U4 d
        vexNum = copy.vexNum;9 K) ^. L! ?, [( k; `' I- T. ?# t
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];$ s; z% s( a# g5 l% @1 E$ X8 V
        arcNum = 0;
    5 G! X8 ?! O4 I9 @0 n# u7 G    infinity = copy.infinity;* W6 L: A- [# A8 C- i7 C
        tag = new int[vexMaxNum];
    " T7 _- G/ r" j. K3 v" d& X1 ^/ V4 U% F0 a/ R7 P6 b2 `6 \
        for (int v = 0; v < vexNum; v++)
    0 W$ t8 k& s; J    {
    8 I2 I3 c5 U. H/ A1 C( D        tag[v] = 0;) V' C' `& z5 y
            vexTable[v].data = copy.vexTable[v].data;
    7 z( z, a  M' r3 U. r9 x        vexTable[v].firstarc = NULL;
    ' p4 c1 z5 U1 T$ W    }
    9 {( j1 L/ a! J, S( e$ G! R    MultiAdjListNetworkArc<WeightType>* p;
    4 B) I* D7 g2 Q# n2 H' u. Y7 g% h, s: `* u
        for (int u = 0; u < vexNum; u++), x: N! P4 }2 F  ~
        {
    * t/ H" s$ N  `/ D        p = copy.vexTable.firstarc;
    9 Q" g9 K6 s/ g3 A* A5 l' K        while (p != NULL)
    4 R* {; O, n  |        {8 h4 s$ }# z- H3 u3 h
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    7 U+ r3 k" J' x" R" B# p            p=NextArc(u,p);
    # b3 `! h+ W4 e+ a  i        }
    1 B' h  `) |/ R8 I! k5 Q- A/ ^    }
    7 v9 |  ]5 T# J2 l* b. @    return *this;3 ~% }% b- K$ `8 l. C' g
    }
    " Z2 D$ P9 K* {( j) Ntemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*3 i* t, a2 N" Y* K2 }
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const( ?3 E5 G7 r/ ]6 n  M
    {0 ^0 c' M+ `/ G, H  E- @
        if(p==NULL) return NULL;
    ! F2 g8 l5 O  U9 f    if(p->adjVex1==v1)
    6 Z0 I! C. }. b- P: A3 A5 i        return p->nextarc1;) a, C  w, |9 O/ i6 A
        else6 d* C* z. ?* x) x5 S. a' x: S1 b
            return p->nextarc2;) g: k( F& u8 J
    }
    1 ]- ?, n1 A$ S" C( r, @& Wtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    6 g! D; K5 c$ s2 ]7 BMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const6 \& E2 e5 t0 n
    {
    6 T) L9 t3 R2 J1 j6 o& X: Z: d    if(p==NULL)return NULL;
    " L7 X$ f3 i' D    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;0 Y/ {2 A, l1 ^7 I* S3 _
        if(q==p)8 f2 P0 `# _( @; A
            return NULL;, Y7 g: g3 V7 ^; {( Q
        while(q)
    . J/ p( Q7 O7 ~, l! `  a    {# Y- N3 J1 c. W8 B( F2 ^& B: \8 W
            if(q->nextarc1==p ||q->nextarc2==p)6 o8 b: x9 ~- q! ^
                break;
    1 d" Z( n5 h/ z# u2 [' k        q=NextArc(v1,q);6 Z; L6 s$ V' W$ Y
        }& I% T! M* m/ E. s% q1 o; z# p: Z
        return q;4 M$ m$ }# y$ }/ R! Y4 R
    }
    - J& S# g: y5 `6 l8 C2 ^template<class ElemType, class WeightType>
    5 Y! C; j, X3 x+ l: U; b! Fvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    " I0 @7 ]- L  ^* W! Z& L{+ u( |3 T" ^+ F/ w4 Z
        if (vexNum == vexMaxNum)
    : ^! q, V/ L/ f- W5 w  L2 ^        throw Error("图的顶点数不能超过允许的最大数!");
    / t1 `* i" j$ @2 o2 |: q    vexTable[vexNum].data = d;
    $ M+ j5 ^$ e8 o% o. f$ h4 I    vexTable[vexNum].firstarc = NULL;: `5 j! `7 H$ H" ]$ q" e  S
        tag[vexNum] = 0;
    8 ^& K% |9 u$ Y* P# U    vexNum++;
    9 F. N& h5 d2 `  z, P' U}6 V5 s- f8 d4 k, g0 W
    template<class ElemType, class WeightType>
    , \, y) m6 g. l. R, R4 A$ S( Bvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    4 E' S% d) @, y) d( |{
    : \% h- F( [' h    MultiAdjListNetworkArc<WeightType>* p,*q;
    , H) Z9 Z+ Q1 A5 F8 _+ h8 L    if (v1 < 0 || v1 >= vexNum): Y! [  q& [1 l9 L: E, l( X
            throw Error("v1不合法!");9 V* }. ]+ n; t1 ^5 [1 ~7 U
        if (v2 < 0 || v2 >= vexNum)
    & F- I% x* F% t; U/ \) W( e4 v        throw Error("v2不合法!");7 V2 i' E: j& m. D, [% i( X$ o$ L
        if (v1 == v2)
    # g& ^) W1 r* ^) V/ p        throw Error("v1不能等于v2!");2 D6 j* \( W( \, R: F; E/ I+ t( K
        if (w == infinity)) B# S4 e2 l; Z6 j# M4 }9 `4 O+ C
            throw Error("w不能为无穷大!");
    : s* S# d) o- Y# J1 K8 r3 P
    / R5 J2 ^3 w4 h2 ?! [
    " @/ X( e" p3 J    p = vexTable[v1].firstarc;
    * a# X% ~* F$ y: l7 l    while(p)* V4 p- [4 r* V0 Q* w
        {
      j2 i  n6 i- M# [# t3 @        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    4 s0 p, B# F2 j        {
    6 h) w) I, i5 z) ~! R; c            if(p->weight!=w)
    4 N. R! O7 m& K0 @! r* s                p->weight=w;6 c" v0 t9 p, w7 K! o* d& ]
                return;
    8 N& j7 E% u5 Y  N1 B+ B$ [: c. ^; ]        }
      @2 Z6 }  I' `: ~0 @& U5 K/ j' D9 s6 E
            p=NextArc(v1,p);$ h% z4 m5 l  x# G% {/ E( @; Q
        }
    8 v6 Q/ \, f  C6 J! S0 o3 O  ^% _2 I$ j    p = vexTable[v1].firstarc;$ `, o: u; g  l; Y
        q = vexTable[v2].firstarc;! y; i, J% V0 [& y9 P
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法+ \! `8 ]- J0 \. w" E* Z
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    ( V$ \6 D0 M4 I& O0 j3 Q" ^    arcNum++;
    3 a. [8 \: x" K1 B2 ?" L, M: T5 x8 l}2 r1 a* r  G) c0 L

    ! Q3 `- l  N2 x. Wtemplate<class ElemType, class WeightType>
    * l) \+ d0 P/ ^0 evoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    . ~8 P+ n0 g( s$ k{
    . x# c( U* V7 d. r2 R* r: F7 F- `. M8 l5 h0 L8 q, U
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    0 P: v* s4 F& X! \' v" _+ g5 q8 t    if (v1 < 0 || v1 >= vexNum)
    % H" {4 k0 J" S% P' T! Y        throw Error("v1不合法!");6 d* m6 J1 X- ^, D$ ~
        if (v2 < 0 || v2 >= vexNum). K/ A1 a" C2 g) u% n
            throw Error("v2不合法!");2 c2 s' x1 q/ L! A, E7 i( |7 ?: B
        if (v1 == v2)
    : y1 t: N' K% K        throw Error("v1不能等于v2!");4 R! A3 s: c( D+ H9 U0 Q+ q

    2 R6 o) Z6 ^) v) J    p = vexTable[v1].firstarc;* L! M. R% ^! ~0 [$ E$ R
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)! Y/ X* |: K4 u3 v  s$ u3 _" z
        {
    3 v# s/ u2 A+ ]# V. ?/ h: T8 G- P        q = p;
    ; N. ~; Y& }0 B6 L% k( N$ h        p = NextArc(v1,p);
    # X% n5 x5 e" t8 R7 V  b, W    }//找到要删除的边结点p及其前一结点q! Y* U# ], u1 Y5 ~- A$ {) m

    0 r8 Y5 h- G! d* e% a    if (p != NULL)//找到v1-v2的边& g" e4 e5 J  U6 a# c8 _( h# w: ]8 ]- H
        {
    + K% Z9 w  l$ s2 t! U% }1 g. x        r=LastArc(v2,p);
    % v5 Z, s) R# H- v        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL  l5 G: P/ }( H0 i. i1 M5 ]- O/ @
                if(p->adjVex2==v2)8 J4 t- I) ?7 b- K: [
                    vexTable[v1].firstarc = p->nextarc1;2 L/ y( H; I  A" ^1 d  p7 o
                else vexTable[v1].firstarc=p->nextarc2;
    " t+ v# f* H, B, z        else//不是第一条边7 @4 ?4 L) D+ F
            {
    9 F% `9 ]* ?. \" z            if(q->adjVex1==v1)9 o; \3 E0 j; o1 ~" w8 x
                    q->nextarc1 = NextArc(v1,p);, @7 `) ?- X, o; j" F7 a; z
                else! n( q$ L( Z* h, J; \; r+ |- o1 n2 L
                    q->nextarc2=NextArc(v1,p);
    5 o1 v: Y: y+ A% @1 h& S% B* O5 k# q/ M# i  _! _4 V. _, A
            }1 N( D7 x& ~- r+ b
            if(r==NULL)
    6 x: Q% P9 @- N& q            if(p->adjVex2==v2)
    7 P: u+ B5 J- u. ~9 H: q# [                vexTable[v2].firstarc = p->nextarc2;
    2 a' J& z; i# a+ z. n8 s6 J: f            else vexTable[v2].firstarc=p->nextarc1;
    : O. s" L" W# J* c; u+ a        else% i$ G: Z2 V( l
            {
    ) W- L8 V; X9 f& R, \0 y            if(r->adjVex2==v2)
    5 i& e, A) c, h& x1 x3 L. ?                r->nextarc2 = NextArc(v2,p);1 ]9 C4 r+ l1 V  G) H+ ^* [
                else
    9 N$ _- a" N  d                r->nextarc1=NextArc(v2,p);
    & a# V6 N! T  g+ O7 Q1 k        }& a9 _6 I5 \" J/ E
            delete p;" `2 I9 b3 _; B; ^' l
            arcNum--;; o: _! t  J: v7 ~1 F0 ^  u1 J0 O
        }8 H  F6 v- o1 \
    5 A$ ^, J) }* _$ e/ i& C
    }
    4 I$ G# Y! L" Mtemplate<class ElemType, class WeightType> void
    ; E; E* Z9 p4 n- c# Q6 dMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    3 C0 k; W3 f8 n{. R# ?8 {% r5 v& ?
        int v;% h4 u/ Z6 B, A" ^9 ?+ j
        MultiAdjListNetworkArc<WeightType>* p;7 y) T3 g$ `" I% h
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    , U! j! f% Z" j" U3 g        if (vexTable[v].data == d), H# x0 O; y; m4 }$ e: K6 `
                break;
    % ?+ A% K8 @" N. H+ U: `1 @    if(v==vexNum)
    1 K. Y% h+ p, ^2 ~5 j        throw Error("图中不存在要删除的顶点!");
    ( w% C! U2 w  f$ R1 Y8 E( e+ x6 V* R) r, j) V! l/ V5 w
        for (int u = 0; u < vexNum; u++)//删除与d相连的边
    , E* J; B1 B4 k  R* y) |        if (u != v)  t; Y, Y; Y$ h7 t; O
            {
    # n& f) [  j/ i            DeleteArc(u, v);; |' [) J& y9 V, G$ K
            }
    # w6 b  T; j' P' R: |5 ]' h( @  R    vexTable[v].firstarc=NULL;* F; q  l- b5 m
    # l9 ]/ g3 b! s4 d' q) Y5 N# f6 V! j
        vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置  l# ~( c2 ~3 ^4 M
        vexTable[v].data = vexTable[vexNum].data;* j% ]. N* V! d/ f( |3 A& y6 g0 O
        vexTable[v].firstarc = vexTable[vexNum].firstarc;
    % `  W9 q" E% C9 l$ f& o    vexTable[vexNum].firstarc = NULL;
    # C: b8 S+ S4 E' n4 m    tag[v] = tag[vexNum];
    5 u6 w$ |( ^3 m4 a$ H    //原来与最后一个顶点相连的边改为与v相连( l; R3 d5 b1 W% k2 h
        for (int u = 0; u < vexNum; u++)8 c9 f" q1 k- J7 @1 H" f3 f0 \
        {/ A' B' t+ C7 c: @* \
            if (u != v)
    - h; E( {8 d5 X: E2 {8 I" i! B, Y        {8 ]8 x, }2 r1 z2 f
                p = vexTable.firstarc;1 Y  S. B$ l, u2 U
                while (p)8 x, ~# `( g9 o' Q5 P8 t( L
                {! W0 {0 q% k- c& f" _1 l' B5 w
                    if (p->adjVex1==vexNum)3 ]) [* i) s$ P$ J" O% j
                        p->adjVex1= v;
    3 q) m7 R1 `6 w3 {. d                else if(p->adjVex2==vexNum)
    : b' K' F( ~9 V1 }" O                    p->adjVex2=v;9 S8 s8 P4 ~' G8 S1 ?3 j1 c3 z2 o. M0 G
                    p = NextArc(u,p);. |8 }) P, W$ V% k
                }
    ( _- `# b, ~! u6 B6 z) m        }: V% \9 g5 e2 b. t; L
        }) B. n& c3 V+ _! q8 h, P) W+ {1 T! C
    }
    $ @: X- C! r% C5 ^2 b6 X) `///深度优先遍历* ?$ A# @$ v( U/ A
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    % w/ i7 ^, Q, y{
    ! U1 Z3 e4 Q7 `1 `5 _6 r/ Z    tag[v]=1;4 o+ e8 Q* x" H) f4 B( f8 Z
        cout<<setw(3)<<vexTable[v].data;$ ^4 G8 d) S  u) E/ W
        MultiAdjListNetworkArc<WeightType> *p;1 T; b$ v) W/ a
        p=vexTable[v].firstarc;
    , R& ?" u6 p1 \1 p    while(p)
      O; L' }  f" g- r  n# S- F: j2 r    {% K' K1 i7 [3 y: R# C' a
            if(tag[p->adjVex1]==0)7 N% n+ X: m, P
                DFS1(p->adjVex1);) h7 k" H6 x" T/ ^# L6 e
            else if(tag[p->adjVex2]==0)
    3 z! N' B2 r8 ~2 s3 Z- R            DFS1(p->adjVex2);# j) w: V: I! L- c7 B
            p=NextArc(v,p);
    ' n2 D( ?. h( t6 b6 L2 u2 L- ^4 c    }2 e5 o2 z! C0 u" l8 I6 n
    }  s4 [3 c  c& I
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    ; a8 x2 X2 r/ a) K7 w{. Y- m: K6 r7 p- M
        for(int i=0; i<vexNum; i++); ^6 p, k/ l/ k+ z! S1 f
            tag=0;! {3 w4 m0 u6 ~  [/ @
        for(int v=0; v<vexNum; v++)+ z7 I- D, y' d6 n
        {/ _& h, U7 `8 V9 p; _$ X' ^8 k  m) Z
            if(tag[v]==0)* N% B( Z6 Q& `
                DFS1(v);7 y4 k+ ]0 b4 c; D/ H
        }
    3 i- N- t" J2 R' z' H* S}
    ; @5 J, c2 ^+ h% U4 n, }9 G4 q- D6 @template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    ; u  ?8 u; t& V0 Y; H' V$ y{
    4 {; D2 ~) B. S) i9 [    stack<int> s;/ u0 x" D* Z. j& a; R# T
        int tmp;- Q! ?: }8 f& W
        MultiAdjListNetworkArc<WeightType> *p,*q;
    , O" f5 D) b: _9 a    for(int i=0; i<vexNum; i++)4 J: \8 \( m# U+ K  @- D
            tag=0;
    $ w! o3 x  f0 f3 i6 R; s- m    for(int i=0; i<vexNum; i++)& Z. ?& g5 y4 J6 X# Z. B
        {6 L0 d, s; }+ H8 @  Q' ~
            tmp=i;3 i! q# i( u% v6 d/ r. j  W) c" `
            while(tag[tmp]==0||!s.empty())
    / Y  v" m# z/ Z+ @0 f( _3 \! j        {
    + q% J7 D1 y& W+ X3 m$ p            p=vexTable[tmp].firstarc;
    , q3 z3 @0 l+ ?: i5 A! Y+ ?            while(tag[tmp]==0)
    2 m' Z, e3 n" ^. c            {) F+ P& g- x% y  \  i2 M
                    s.push(tmp);" F0 e: s# Q" z: o1 @1 X" j; l" N& g
                    cout<<setw(3)<<vexTable[tmp].data;
    9 G" O  ?2 D" P0 {) _% i' _                tag[tmp]=1;: K: I4 u0 M0 I% _% J
                    p=vexTable[tmp].firstarc;& a; U( |) D% ?, @" {0 n& h6 t% p: C0 x
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for6 ~" L/ t' \, `" o& m% J  c
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);. K& ~$ ]! z& e$ O9 i
                    //cout<<" 1st     tmp="<<tmp<<endl;
    4 R- Y4 v! Q% E& b            }8 D7 f$ R" c! t
                if(!s.empty())
    / v& q3 K& j; a9 c# e& @+ O9 Y            {
    3 T. s4 J( _$ K                tmp=s.top();
    ! E6 a& `3 R: g* e' K6 i, H                s.pop();
    . T" ?( n+ t% S% o                q=vexTable[tmp].firstarc;4 u5 W" r1 D! C$ l0 s# @# V
                    int t=tmp;
    - P; V. Y5 _8 T  c8 K  J: Z5 c                while(q&&tag[tmp]!=0)5 H2 |" ?; ~2 J' K) Q
                    {( I8 O7 c3 l' q8 Y0 H+ F9 v7 B
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    + v; [7 j- o4 ?, l5 S7 E( M                    //cout<<" 2nd     tmp="<<tmp<<endl;+ Z" H; S9 i& [
                        q=NextArc(t,q);; ^& l# c7 Q6 |8 O! S
                    }
    0 [( k8 T) e4 l/ ?; c                if(tag[tmp]==0)( A# V& [, y' s# K3 }& n
                        s.push(t);: p: |$ \1 V/ |; B+ d9 m* I8 E, k8 S
                    ///1、对应上面连通分支只有1个点的情况
    2 ]; M3 J& ?3 m" T$ _% w: J6 c* `                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈( W9 |! c/ }9 I% f# o
                    ///tmp要么等于找到的第一个未访问节点,
    1 ~! q1 \- E+ |: k                ///要么等于与t相连最后一个点(已被访问过)
    / ^; z: V1 Q" M! u9 M5 F& `) N                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    1 }' S5 ~" v3 ?4 E- t! F; @            }& b1 t+ B8 p; z0 s5 x. h2 `
            }2 b$ J  ^8 S# T, Z- i# l# ~
        }
    ( l' E; s/ W4 j& ?4 a- C}# A9 F3 s- x! e5 r- N4 W$ b
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    / Z* z: ^3 V" ftemplate<class ElemType, class WeightType> int& d: }0 k1 u" d$ j
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    & C* y! a- k! r1 }{# ~1 A' B" y6 [: h$ J' Y. u/ c$ c
        if(head==pre)
    0 ?, w# _0 _& b! Y4 Y: q        return -1;
    ; `. n( K  W2 B- C3 E1 N+ ?) X! o  g  l' E6 |/ f9 ?8 d# C" ~  }
        MultiAdjListNetworkArc<WeightType> *p;
    9 H% G7 I$ H, c. J    p=vexTable[head].firstarc;" B7 }, u  z5 K, u! v
        if(pre==-1&&p!=NULL)
    % v: r7 d; {2 ^7 [        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    : t2 E, |4 Z& ~: X- d" R  }    //pre!=-1&&p!=NULL6 G8 q3 T+ y) q+ c$ ~. B
        while(p!=NULL)
    + `' R' R$ D$ `) K: d3 X, d. B# B% q4 _    {$ W( g; q8 }( F1 |
            if(p->adjVex1==head && p->adjVex2!=pre)
    + U. t; {: J$ P. \7 f% I8 e            p=p->nextarc1;5 F5 [0 y! V7 o0 ^4 t0 m
            else if(p->adjVex2==head && p->adjVex1!=pre)1 z4 e" ]8 A. Y1 l' i4 Q- c
                p=p->nextarc2;' w1 x3 h$ s8 j2 v0 \+ \
            else if(p->adjVex1==head && p->adjVex2==pre)
    " A* [( w, k) g0 E/ Z- I8 y3 B7 L        {
    ! ~) W1 G( E: Y7 @7 @3 D            p=p->nextarc1;. b1 N! u) \1 S
                break;% K3 R/ h# D5 |8 t$ I% Y0 W; y: i/ y
            }
    7 f& I6 x/ X! D5 H        else if(p->adjVex2==head && p->adjVex1==pre)
    $ [- p) m6 d6 y0 `6 w3 V& j* o        {
    2 D3 M5 N! Z( O7 W# w  e" P            p=p->nextarc2;6 V9 `  G& b0 j% ]# @$ B
                break;
    ; n, b% ?% |7 {  b3 ]. b2 V4 N        }
    & C2 w) {3 k0 _) \' J5 |/ a6 S" ?1 H5 a    }; v$ b; C; k. L+ _0 n
        if(p!=NULL)' ?5 s- a& }/ Z& v) T
        {$ z$ \: h8 y  b0 i, ^8 i
            return p->adjVex1==head?p->adjVex2:p->adjVex1;6 y6 t2 C+ X: d% {
        }, f; I7 s: R0 ?" ]
        else
    " E* U5 R& t) s( _( ]        return -1;4 F4 E8 c# p7 T; T% u
    }
    - s6 n6 L- l* i) t9 P0 ^  T. b/ I% T+ i9 Q* @$ u$ g

    : F5 K! P6 U% X; gtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    / r+ \+ P, Y) X0 D- b$ D{7 W; K* z" t7 i  W4 G/ O
        stack<int> s;
    4 U2 E6 d7 q( q" u; T# H" @    int p,cur,pre;
    1 Y8 e* A9 v% `& b9 k0 E: P5 M5 g    //MultiAdjListNetworkArc<WeightType> *p,*q;
    + j) c8 N* v4 k1 U    for(int i=0; i<vexNum; i++) tag=0;//初始化, [: Q5 q9 S6 h
    ) h- W" P  L* B- v5 h/ I
        for(int i=0; i<vexNum; i++)# _6 \% J% s" f4 b* B
        {  V  C1 J6 z2 Y# H! S- x
            cur=i;pre=-1;
    8 f$ S8 ^# d! q' t+ C8 X        while(tag[cur]==0||!s.empty())
    4 g+ J" W* c- V/ u6 V, F" i        {* j: Q; ]% b0 ?2 j9 q5 G4 x
                while(tag[cur]==0)! L; V7 ]: ^- U1 h  S: [
                {' p' T" n1 K6 h
                    cout<<vexTable[cur].data<<"  ";. t( D2 n6 R% P" S
                    s.push(cur);
    2 ~, I+ Q. j9 R) \# _. e                tag[cur]=1;& |9 P6 ~0 g! Q  F3 B7 @. P2 k
                   //初次访问,标记入栈
    3 l# Q6 v; d% ~" w& s. l( D! T+ J; Q7 R3 b& k
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点9 C3 B2 G4 J: M
                   if(p==-1)% G1 W, `2 q; J+ O- K
                   {' T! z0 z( g1 t+ `- Q
                       pre=cur;s.pop();
    1 |3 g2 j  {. F1 J2 k) f$ k! h! w) k6 T2 P                   break;
    " e  [/ J/ p# _# Q0 e0 c9 X               }
    & I+ G" v% y2 \+ N, e0 ?# \: i+ ]               else3 }. \' s, R& T3 n- a
                   {7 F$ i. M( i% d1 J- n8 C5 h0 J
                       pre=cur;
    7 ^; W  @' I; O$ P                   cur=p;
    ; Z1 Z, z% r% ?6 ?7 H2 o               }9 N! M  A6 \3 T0 N0 H  f( Y: R

    ; t! Q1 r9 A+ e3 k5 ]9 H            }
    ! q; t" e+ G0 L3 _            while(!s.empty())
    5 V. t, l* J) S* U  c( _            {( ^9 A1 y' ?; C+ ^; S7 r5 F: Y3 g
                    cur=s.top();: ^. p0 W; M8 M3 m& Q; H$ M
                    p=GetAdjVex(cur,pre);
    2 ~! ~. K6 R3 x8 p; k                if(tag[p]==0)" D) L) p7 C" m# Y* R
                    {
    : T3 V$ K  {! q, G" q, o                    pre=cur;1 }- D' W) F: F* l8 l) l5 }
                        cur=p;
    & Q, ~; T0 N7 M2 ?, ^; J, S% ]* |                    break;
    . ~9 q( E# ?1 P7 x0 d. }/ z/ g                }; t, Y! l. c. `% D7 @* S& ]1 R
                    else+ s2 E# |/ V' l/ r# [/ N! O$ t5 W
                    {1 F9 @5 V0 b8 J- X9 |! O
                        pre=s.top();: _! _0 F8 f3 ^6 X, h$ _4 q1 s1 B
                        s.pop();
    / v6 W$ F( o% ?  ^4 `0 P- w- @                }3 X2 e% C2 T8 M! ~
    & d8 X$ A  [4 p" H( p1 E4 f
                }  l+ T! V! B, x% ^; S
    7 n- K5 p9 p8 O; K% e
            }
      f: \' q2 b/ T/ u: |5 f    }
    % _+ X- ~) U) n: i! d/ C# M}: E! q  @3 k9 y( X' ^* d
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()9 a6 i1 o0 B7 P9 ^6 F
    {
    3 J- T: j3 _' L9 a, X$ {1 E2 Q. _    for(int i=0; i<vexNum; i++), D6 @. t8 A8 L+ C& k2 m
            tag=0;+ x; J* R: _: N! D. n7 n
        queue<int> q;
    ( N8 a% z% F. e6 }6 F& h, X1 t    int tmp,t;
    3 Q: E* C% l/ q1 v) ~* N5 x' [    MultiAdjListNetworkArc<WeightType> *p;
    8 ?( e% c: c, |8 n  _0 R  k- Q    for(int i=0; i<vexNum; i++)5 Z1 u' ^# d2 {. d! \  _& H$ |
        {! |+ v; E+ g' i
            if(tag==0)
    5 ]: l3 W* U& P/ d: B0 X        {
    ) t  O! Y% J7 D& A! ?7 j            tag=1;- _9 f- B3 R1 G( m. ^
                q.push(i);
    8 v' K( h. [6 L9 r' e            cout<<setw(3)<<vexTable.data;  d) v( x. S& h( D' k: o, w
            }4 X- R0 f6 V- y' J: Z% u" A8 \
            while(!q.empty())) ?1 Z; s: w2 m- @% v- T
            {
    & P0 x+ H) E  H; n7 L2 }3 A, s  s            tmp=q.front();/ N+ b& m" R6 C- ^+ V: g
                q.pop();
    : L1 C+ P( J( e9 I+ ?" W$ N            p=vexTable[tmp].firstarc;1 A; b( j* _2 y7 |: u2 u
                while(p!=NULL)* L% B/ F0 I! K& P, }
                {( Y& \9 X) f) x, U  h& s
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    8 k% C: |9 i  l, @0 X- u                if(tag[t]==0)
    $ Q9 n9 M( l, h# t" N" `+ S                {0 y$ x) a4 N0 q3 I( C4 Y: h
                        cout<<setw(3)<<vexTable[t].data;
    , D5 L2 p0 q. V- L+ W8 m5 F                    tag[t]=1;
    ; n% ~1 m; d" a" [                    q.push(t);- ]0 o9 X$ O+ h2 ~0 t
                    }0 {4 {  U6 {* H. o% }
                    p=NextArc(tmp,p);/ }1 F0 k; n) J1 S
                }+ F3 Y4 x' {" g) g/ t
            }
    1 j: L* U4 E3 \/ k3 j! ?- X( l+ g/ t    }0 }# n  ]4 @0 h2 @# ]7 g" ~3 {7 W) M
    }
    3 Z/ f% c: N$ Z& ^7 }' A* e( ttemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    , L' O, T# p, m{
    9 D5 y# u+ T- w. _: l! J: O% {    MultiAdjListNetworkArc<WeightType> *p;
    - ?: o/ V, L% s2 v( o* ~    cout << "无向图有" << vexNum << "个点,分别为:";
    ! X) k% q8 W$ W' s! U( E  u    for (int i = 0; i < vexNum; i++)
    9 P* G% f" {- `( j  f( Q6 ~" [) ]        cout << vexTable.data << " ";2 Q9 e" {4 @  g) Y
        cout << endl;( a% ?2 ?% i: j
        cout << "无向图有" << arcNum << "条边"<<endl;
    1 d& M4 K9 R3 G0 ^2 o    for (int i = 0; i < vexNum; i++)
    1 Q# A& u  u. o+ L) E* ?' |    {
    # }. ?) O; X( _7 R/ m. U  p        cout<<"和" << vexTable.data << "有关的边:";
    2 k' }' z# X/ O: K        p = vexTable.firstarc;
    $ m' P  H2 Y, w% j* G. }        while (p != NULL)
    8 ~8 s9 g& E) Q2 K) L- o# O# Z" [        {
    4 ]6 w, v! S& U2 ?            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    & C+ u% G  a3 y( w- v            p=NextArc(i,p);
      Z% j4 Q/ d& t  o) [& h) }. P        }& r' p' E4 b& G& z( E
            cout << endl;( ~3 |( ?/ h1 h( ?% X, e% T
        }
    : [2 a- O) k- q}
    ( G9 X, v& r9 G& a" L9 s* b7 L5 C. }! W9 e
    7 X% o3 \" H/ x% v; ^# b* s1 v* u" c
    邻接多重表与邻接表的对比: y8 Q7 v% {! H; \$ l2 B

    " g& M! _$ F( ?+ l9 `3 p- _  T0 i邻接表链接! O4 D5 d8 M# h' f% }2 b
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    ' p7 I4 ^( J) Z在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    9 v( A& l/ C. c' O$ d  k" J9 P为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。% C9 |$ y! f( b; l7 X
    ————————————————
    8 I8 h- v5 z" ]1 ~版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。6 D4 y0 F9 m; S! t0 D+ f
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    , Y9 L& ]/ z( \! A9 N6 A& E3 [8 h& A

    8 f0 q; Q6 t7 E2 I& d7 Y  U9 Z
    - v. o' L" z/ d% Q' Z8 P  |4 k6 p( s% u/ E) N9 W7 _# ]
    ————————————————2 a4 n' Q# ]- z6 Y. M7 a
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。2 X  N' A9 L* G: [3 T. T; z1 C" F
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    * Z( N' ]2 o" }% n4 h" p$ r, [6 i$ r

    : N0 r. d8 o+ V: Z6 C
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-4-20 11:34 , Processed in 0.312758 second(s), 53 queries .

    回顶部