QQ登录

只需要一步,快速开始

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

    . \- N$ P7 t* O' T4 o图的存储结构——邻接多重表(多重邻接表)的实现
    / K. z+ W" @8 S7.2 图的存储结构/ q: H7 G) k% i

    ) I  H, S9 |# }+ c8 J9 Q7.2.3 邻接多重表(多重邻接表)Adjacency Multilist, I5 Y1 V0 y4 O+ H/ S  s
    邻接多重表的类定义
    6 c4 J6 ?# U' a0 F2 ~2 i邻接多重表的顶点结点类模板
    / d2 V) S6 K/ t4 f* `. a邻接多重表的边结点类模板6 D# Y( `5 V$ q' x
    邻接多重表的类模板' [- }( a' F8 |: X8 R% X, k& P
    邻接多重表与邻接表的对比- I" g- _" ]! Z3 q2 c# P0 M
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist, C$ _  l3 u# E

    ! O! G% F6 G/ E2 b2 L: R# |, W在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    " X: g- z3 N- F2 a2 @6 |在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。) F' l9 V. e& ^  F# N2 M. @

    ' f5 s6 d: W) D# F$ C邻接多重表的类定义
    - u$ a! ^' J; e) l  Q; z 1.png + i) o1 x! A0 J, X% M
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    - N" ?. H- x! Z" mdata域存储有关顶点的信息;9 t  m9 P* i. d( ]7 L8 Y, U& P
    firstarc域是链接指针,指向第一条依附于该顶点的边。3 p4 U9 m7 V8 a( g0 ^0 ?4 E
    所有的顶点结点组成一个顺序表。


    0 C. Z' E8 G8 h' P' o
    8 ?2 I2 L- i! N0 ~; k2 Atemplate <class ElemType ,class WeightType>
    8 ?, d1 J3 U1 v1 m& Bclass MultiAdjListNetworkVex
    ! I, g" a0 Q$ p8 U. O& i6 Y{" ~7 ?( n& W5 [8 d
    public:
    * Z# O# g) G4 C! o        ElemType data;
    & t4 `# I/ u, q& \3 N        MultiAdjListNetworkArc<WeightType> *firstarc;
    + s& F; Y+ l5 [1 ~1 ^  w# e8 f/ Q
    / [$ b. Y# p( k9 c        MultiAdjListNetworkVex()
    . @: g: ^, g" ~        {
    . N# E3 R* @( C                firstarc = NULL;
    + A; G: R% R5 S/ |7 J6 u) j        }2 \# N1 r( c& d. Y& R5 ]/ Z
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)& T5 j0 s4 w5 L! n2 z
            {# l1 D5 u2 N1 w) Q2 z
                    data = val;
    0 [% @7 h) j- U- v, M                firstarc = adj;' ~  r. G( I9 M7 v4 c
            }( ~/ }9 b% d: c1 ]9 o! t- a( {
    };$ N2 N, S+ v$ Y6 b
    1 h, ]( S/ Q- {) h
    邻接多重表的边结点类模板
    # ^2 e* B# E2 E/ r- i. F% C( b# }, d. A% _' M- x  k
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    6 r3 d  m: l- ]! U- D6 }* h  Otag是标记域,标记该边是否被处理或被搜索过;
    % O: {" E! I- a6 ?weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    4 u! S7 x4 t. _. z' Z/ _nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    * g5 `# {) y% c& m8 Onextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    : E. z# h+ d7 F1 H( A4 H# Q! I0 k4 A5 M# n6 {0 V4 D
    2.png 4 R7 t$ w: Z: p* o" \9 q/ L
    template <class WeightType>
    0 x5 X( q9 s/ }5 Z9 M& T0 Hclass MultiAdjListNetworkArc
    " h. O2 Y" _& r{
    8 h+ t; r* M) o0 f! Qpublic:
    ' O' x0 A& N* \) y1 N    int mark;                                       //标记该边是否被搜索或处理过
    : @7 ?- J9 H, R& V) A' ?/ `        WeightType weight;                              //边的权重
    / F- J; `7 M4 w- ]/ i        int adjVex1;                                    //边的一个顶点
    ( B9 |. [+ w" T        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    - p' j/ {) N6 R% ?% f: Q- |1 {" O% h0 R        int adjVex2;
    ; o# R4 w7 K& B0 I/ f6 Q/ _        MultiAdjListNetworkArc<WeightType>* nextarc2;  L2 Z7 @! j$ L- U  s% L. M
    , e' a5 n* \  {" ~
            MultiAdjListNetworkArc()
    % y4 u9 g3 u8 S+ E        {& E) c3 I0 ]. P8 V+ i
                    adjVex1= -1;
    1 e% |' o! b2 j  q# U                adjVex2= -1;
    % w: e+ g3 S. t8 T) m        }
    8 ?9 A: {( B, v  U. w0 _        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)3 s9 _2 `1 p4 _" X/ l; f! O  a
            {
    % x4 s. w- T- U4 U8 s3 @; a" D                adjVex1 = v1;       adjVex2 = v2;
    , {! t4 A/ a+ F+ }+ u; ]3 V                weight = w;( |7 F9 y& n* }2 a
                    nextarc1 = next1;   nextarc2=next2;
    3 {: F2 ~/ z- ~* j6 q0 }2 T$ L! x- V                mark = 0;           //0表示未被搜索,1表示被搜索过6 d! U+ Q+ g$ K, {: A
            }0 U/ C/ b" h! u* [
    ! @- u& c3 ?" g6 Y
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    % C" q4 \4 f2 x4 i# y. Iclass MultiAdjListNetwork
    : p4 n; B$ [% U{/ I6 S: d4 p( c. b+ M
    protected:' [% Y8 d( w4 r9 a9 ^; K
        int vexNum, vexMaxNum, arcNum;
    ) W2 p) ?: |9 F5 D" d% B    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;; n5 J7 N3 T1 Q' H% u& s& v
        int* tag;1 b% l1 D/ x) [# Q6 M
        WeightType infinity;+ c/ h7 q; y' M% t( D
    ; e2 V: ]% r9 V) h$ X, c
    public:9 E* Q2 D! ]* b
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    : d: x9 @7 K: c7 a& e
    ' t" j% q$ [6 G    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    ) K9 F/ O9 [& ^' Z$ f; ^' v1 F
    4 D: q+ W0 C! i" o    void Clear();' l1 n% o6 |, x) K( Q
        bool IsEmpty()
    : L4 v, e  p7 W- X    {
    " h2 E1 F2 X/ t; B        return vexNum == 0;
    7 m' E( S9 O' K9 v* U    }
    % N+ B! V1 u, [1 X9 m( T    int GetArcNum()const
    ( r0 k- U  A! l" A7 N" G' _7 [    {) N/ i3 F, [; w: z
            return arcNum;
    : t# a3 U! C0 b( g% d4 a. R( c4 T    }
    5 i8 T2 ], |1 h5 `    int GetvexNum()const9 Y9 F, X9 @* M" ^) V& y0 x% u
        {
    5 k/ ~: z% _* P; V        return vexNum;
    9 {( V! ?5 Y' Z- f  J) _    }3 p. a+ U6 v) L! w; e$ p( u
    ) ^0 a/ E% i7 h
    9 L5 e5 n5 ]  S  g, K
        int FirstAdjVex(int v)const;: n$ v4 ?  c  j0 _
        int NextAdjVex(int v1, int v2)const;
    6 P1 ]* B+ U" k4 G/ Q' Z) J  b    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    5 W. {( a+ v/ q/ e/ [    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    - [, V* s/ X# O: `: z2 A5 f* I6 M- N8 g
        void InsertVex(const ElemType& d);) W1 N4 R" {' I9 ]5 ]2 Z- p
        void InsertArc(int v1, int v2, WeightType w);
    / z. M7 |6 R* x3 N5 Y% C$ C. J$ w: P. B
        void DeleteVex(const ElemType& d);' z! H' }  j' ~/ x/ I) C7 k
        void DeleteArc(int v1, int v2);
    : C9 a- x/ |, M% u' t, o! T
    4 W* u9 i! Q* h2 V, k    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    ) H! x. t+ C6 R3 {! {: f    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
      n  Q) C' V1 R9 w2 k
    ' e, F- A8 z+ _6 }! b    ///深度优先遍历# {0 c5 e) c1 {; P7 s5 F  l: i4 e
        void DFS1(const int v);
      z; H( l, q6 G9 u: s. _5 X    void DFS1Traverse();) w& A. K3 b! @! Q$ G' }
        void DFS2();- {$ c& W3 t: U" S( r3 c
    9 z! A$ s# m2 ]
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-10 s( z8 N7 P* v
        void DFS3();
    $ ?% j; H% g' |
    " _4 D" [, O$ e- Y    void BFS();: Y) ^+ O! E+ k: B  z6 m5 c3 `
        void Show();
    5 [, I% G: _  h' |! D};/ F6 m1 d( v9 Z0 O" Y- X) }
    # \" @( |& t! X) b0 U0 c
    2.函数的实现
    9 M$ j( Z) t* q" X研讨题,能够运行,但是代码不一定是最优的。
    6 Q' V5 F  {: |+ d' }% E3 U/ \* m* k5 i
    : ?5 ]* c: U* D9 ^3 D8 w1 n#include <stack>
    " d6 H9 w9 ~5 h! `; C#include <queue>& s7 c$ s4 r$ e3 p8 y/ h: x" F2 B

    ' C. ]& L, i  v, utemplate <class ElemType,class WeightType>" ~# P5 q/ F) N5 s
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    $ E* ~  f/ t5 j" w% ^5 S$ f# g) {$ }{
    + R! ^! y5 G& S4 t    if(vertexMaxNum < 0)
    8 j) L) |; b( w( Z9 l' l' j  Y0 i        throw Error("允许的顶点最大数目不能为负!");
    : P$ k0 \, ~6 n4 |    if (vertexMaxNum < vertexNum)6 f+ M* F2 a$ e) j" O! o6 O
            throw Error("顶点数目不能大于允许的顶点最大数目!");
    2 P' B; V8 x3 B( @2 P( r' `* I    vexNum = vertexNum;
    5 V7 ^! O! a% w( h  e' ?    vexMaxNum = vertexMaxNum;
    0 n' ~# f6 _( R8 S# N* L    arcNum = 0;
    0 j& |3 g2 r& h; K1 m$ O  p    infinity = infinit;
    ( x% d; t9 D1 |3 H- i) \) {5 P    tag = new int[vexMaxNum];
    ) Q! A& N: h$ {2 v$ e) l! R    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];: l7 t* q2 F2 L( l( j- D
        for (int v = 0; v < vexNum; v++)
    ' c- i/ ^' j, v' c    {. g/ b4 I( k. I5 w' S- |7 T# r
            tag[v] = 0;
    - p: b+ ^( {- t3 S! m& B        vexTable[v].data = es[v];2 |* ~3 v; W; @9 a* @' ~  t
            vexTable[v].firstarc = NULL;# ~, E' O" `1 E1 W  d) g
        }
    . l& P$ r* D2 J+ Q( d}
    1 J6 n0 d4 X- Stemplate <class ElemType,class WeightType># c& m" N7 o' h  K  I- U# Y& R& J
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)+ |* Z8 p  K8 w+ k& {
    {+ v1 t5 N9 H% G* W; u! {. {
        if (vertexMaxNum < 0)
    . `/ o9 K* @0 [2 ~% I        throw Error("允许的顶点最大数目不能为负!");
    ( A! a; f% H# x* J  d+ Y8 D/ i2 C: r    vexNum = 0;7 ~% W$ J6 m1 O& X0 C
        vexMaxNum = vertexMaxNum;
    ! O3 f) u# K9 P  r    arcNum = 0;
    . `8 I9 V; _8 N" {, w6 r    infinity = infinit;, k8 s% z6 s, h: s: F/ [7 c
        tag = new int[vexMaxNum];
    " O; e- u; g) G7 T7 R) f    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    8 |1 v4 o% z  z}$ k$ W9 B% [6 \. N1 S. b
    template<class ElemType, class WeightType>/ a  R& t9 b+ u2 e, B0 ~
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const0 S$ Z2 T$ P. f% @  q0 [1 l
    {
    3 O) F4 t5 i& u7 t$ w1 h    if (v < 0 || v >= vexNum)
    " ^  l" l% g% q        throw Error("v不合法!");: M3 Y( Q7 S7 n
        if (vexTable[v].firstarc == NULL)  {- w& ~( K5 @0 {+ S5 Q
            return -1;
    $ s4 l* l% o* n3 ~/ N  Y    else
    / C0 I  m- j0 z  Y        return vexTable[v].firstarc->adjVex1;
    + U$ s: J0 E4 ^; n}
    3 r4 U2 A6 x. D5 ?, W2 }7 N1 B- h  ~( [6 t
    template<class ElemType, class WeightType>
    7 V/ {8 j. m" K8 _6 Q' V/ Nint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    . C: N3 k3 {" g4 }3 ]8 J{
    # L+ R% h$ }7 y  p- S    MultiAdjListNetworkArc<WeightType>* p;
    9 g& y, `" S; \) V2 m+ j    if (v1 < 0 || v1 >= vexNum)
      O2 @  c3 C3 u8 O  }" m( s* K: p        throw Error("v1不合法!");
    + x6 S$ ?* e4 s; w6 R: j    if (v2 < 0 || v2 >= vexNum)
    $ v9 q/ J/ j" h  c5 U        throw Error("v2不合法!");
      J1 d* ?4 o+ L: m& y    if (v1 == v2)
    8 ?; ^2 f, m3 f/ v        throw Error("v1不能等于v2!");  }5 j0 s. o* R7 E
        p = vexTable[v1].firstarc;- B$ ^' X2 s7 x9 j9 h0 V
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)! c$ ]0 n  B, N  u- _6 u& L
            p = p->nextarc;8 b& s8 p5 `0 J, B) J; ]) k- n
        if (p == NULL || p->nextarc == NULL)  {- X$ x1 o' |# V% s, X
            return -1;  //不存在下一个邻接点  W: l$ P7 h( f/ B) s/ A
        else if(p->adjVex1==v2)
    3 k" b, F+ ?$ v* C. }6 n        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);  ~6 a8 Q6 n4 u3 J2 W7 q
        else9 G* A( c9 M7 o# R1 X! s
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);& l6 e9 f: U8 A) g8 {  l4 F/ z
    }
      D- X% @" S( r! z6 P* dtemplate<class ElemType, class WeightType>
    4 D' a: f7 o$ Z: ^2 {void MultiAdjListNetwork<ElemType, WeightType>::Clear()
    9 ]$ F7 ?8 z. {# \{8 K4 ^* K" x5 V4 E! s
        if (IsEmpty()) return;
    0 [5 G# d) }: h1 k7 W9 d0 N    int n = vexNum;
      L0 J* l9 I, O/ Y9 i    for (int u = 0; u < n ; u++)
    + p; c5 O$ u$ T        DeleteVex(vexTable[0].data);: {4 ?  ]$ n3 v' M( M) ^# i# t
        return;
    * B' w7 d/ F* ^# n# I}  C' [. \5 f0 |% C+ k
    template<class ElemType, class WeightType>
    6 ?% t' L! D' C" ]3 AMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    8 b0 u" w. G2 @' l{
    ' ^5 W* f2 y3 C" q    Clear();
    ; |- Q& T+ h' `3 S3 ^1 f}0 {' j5 r( X- E7 }; n3 ~! ~, s
    template<class ElemType, class WeightType>
    ) H% P5 b- s, ?- H' V0 uMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    . t+ P4 ~( j5 [$ X8 J0 e8 d) G* Z3 h{
    * N# H5 e9 F- C    vexMaxNum = copy.vexMaxNum;% \2 t0 G, W: k, G& i" G
        vexNum = copy.vexNum;
    ; K3 e! m: G& _    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    ) ~. v2 r8 [1 [3 c8 a$ J6 `    arcNum = 0;1 g! E2 Y3 _6 y+ L
        infinity = copy.infinity;
    . b$ K, |! m" o' U    tag = new int[vexMaxNum];$ j$ F6 T* V) ]" D3 G

    6 y7 Q+ B6 L5 b. h4 x, g; p    for (int v = 0; v < vexNum; v++)& }0 z* r+ |! L+ i; }$ o
        {) a6 V8 ?4 O/ r* Z
            tag[v] = 0;
    8 _+ A* M1 {& `& l        vexTable[v].data = copy.vexTable[v].data;
    - G; m+ z& O8 ~& K! Z: f% f4 a: l* u        vexTable[v].firstarc = NULL;
    2 I0 z; E! @( K* D/ T2 r, t" O    }( r" [2 ?5 k# Z8 E
        MultiAdjListNetworkArc<WeightType>* p;% `9 H3 E  p0 n' C% G1 I
    % n& q/ w. U7 }' H0 s5 v5 ]
        for (int u = 0; u < vexNum; u++)
    . @5 G4 s# Y/ J; z3 p    {9 @) W" e2 D/ E) N; n
            p = copy.vexTable.firstarc;) ~* M+ g8 @  ?2 e2 E# H
            while (p != NULL)# r. ?. F8 a0 f
            {9 P" z2 R$ w4 ?. R' n0 ]. p' V! y8 I
                InsertArc(p->adjVex1, p->adjVex2, p->weight);* S: d* Z# f( _
                p=NextArc(u,p);5 f0 e; e* @# M! k! v
            }
    ! l+ b6 h2 \  c; H. j    }
    8 ^2 i) b' Q6 Q  {5 K}9 R5 D" c; f8 r) v$ {
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&) M- M3 A: h( c6 q+ |
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)" d& N; l3 c! w: Q6 d
    {* U) f- A" @. R8 ?; Y. G: _5 _$ L
        if (this == &copy) return *this;
    ! p+ U3 W4 c) j    Clear();& V1 r4 L2 ?+ B* m7 ]& F" X( u
        vexMaxNum = copy.vexMaxNum;5 q! C" d6 y/ ^! c8 R1 ?. V
        vexNum = copy.vexNum;3 I3 t- U5 Z: y5 p8 f  j: G( D
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];8 g; J! z# N* f5 |' j$ y# v
        arcNum = 0;
    ( V) }/ M% Q/ v3 O* w    infinity = copy.infinity;
    6 g' w+ v% m# Y2 H( P3 Z3 j' h    tag = new int[vexMaxNum];9 ?) Y+ Z, V: O$ Q; ?6 X

    ) Q% C* Z- f8 I8 j# J    for (int v = 0; v < vexNum; v++)
    " U7 E" ^+ h2 x' `1 Z9 H    {: S: L4 o8 K% c7 J, i, t1 ]' l
            tag[v] = 0;" t4 Z8 I$ V7 o
            vexTable[v].data = copy.vexTable[v].data;
    0 J9 c& c  B- x+ ~2 J, M1 w+ C        vexTable[v].firstarc = NULL;
    , H4 D( n5 ~- U. q( U) S1 J; }" T    }
      s, q5 G& q; o! o  x+ H    MultiAdjListNetworkArc<WeightType>* p;
    , v5 s( V) q0 p- h! e  m' @9 Y* o- k7 ^4 T! b# u" p' U( o  ?
        for (int u = 0; u < vexNum; u++)
    ( ?$ `; T, ?" P    {1 n: |4 h8 x& h( m6 [4 x+ x" t
            p = copy.vexTable.firstarc;4 z% u, P) K4 i9 e
            while (p != NULL)
    + q! ^- |( N  O8 \) r7 v  o  |5 p' p- K        {; U0 i% n, w: B! c& i
                InsertArc(p->adjVex1, p->adjVex2, p->weight);: v$ s8 u' m: U- ^8 g0 T! P
                p=NextArc(u,p);
    . @. `6 Z  d& `; u% @; i        }
      o4 g% E" ]4 \% Z    }
    ( W- m% G! |% }$ B9 X    return *this;% e$ z0 H6 f6 D' v( T1 Y
    }
    9 G3 ?( V8 W  W8 h) W; dtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    2 t1 N/ \$ q7 t4 u. lMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const4 e) Q7 z" p; r) _7 N- \6 C
    {
    % J# ]# M) ^1 r$ c4 I    if(p==NULL) return NULL;
    2 _$ [2 ^0 c- C    if(p->adjVex1==v1)
    9 S4 R3 X& d4 I# H) w        return p->nextarc1;
    " i0 S0 Q" ~6 `: t    else. `  U& L, R% K8 ]0 N9 B
            return p->nextarc2;
    ! D! D2 `. }( S. l* ^, `}) u* Q8 T# R7 \( {" K6 a
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    0 p) B. q1 }7 L5 q4 BMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    & `  E$ \! o& |0 N{( }! K2 H. R2 p
        if(p==NULL)return NULL;7 \# w. s- S; x, \
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;' ]$ A) r0 _9 i+ U5 C
        if(q==p)
      m% e# L* j4 ^, S1 C        return NULL;
    8 U" ^' ?8 w# i# ?4 c    while(q)! L2 C  c5 s8 s+ m) p; I7 n/ J
        {  V; A/ z/ @' m1 @0 v; t
            if(q->nextarc1==p ||q->nextarc2==p)) C4 ]8 R: i6 f
                break;
    6 L- }4 w& r* i# i4 `( }5 h+ I2 s        q=NextArc(v1,q);
    - B; P$ n/ |3 j1 F* X: h2 G3 f% f    }
    , }* e+ R" _8 H* Z6 a# T% T    return q;" P7 G, M5 G; m" z7 ]$ k( F0 x3 ]4 \
    }
    : l7 c. W" x3 ?6 S3 Z, N5 p! b5 }5 ytemplate<class ElemType, class WeightType>
    * Q; n! m) B' ]" Z8 D2 u/ n4 X6 xvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    ( d+ x8 T3 m4 i7 k4 F( k# X{# _" |% W2 k/ n$ r4 B( g* n2 H5 _
        if (vexNum == vexMaxNum)
    / T8 D# u6 w! x( S8 @        throw Error("图的顶点数不能超过允许的最大数!");
    7 R# g. b0 c# m$ u( L, \% o8 f. m    vexTable[vexNum].data = d;
    , c2 D8 N+ ]$ {' a5 R" A: H    vexTable[vexNum].firstarc = NULL;8 V7 ]( y) f, ?4 b* y
        tag[vexNum] = 0;: e7 p6 D8 g7 B
        vexNum++;: @: X( a5 U- o
    }
    8 o) Z) z8 g& l# @% A7 K- Etemplate<class ElemType, class WeightType>
    1 C1 a" d5 h0 v' A# {, C' d$ Nvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)! ?6 x( W! E/ `8 d$ F% ]
    {. Q* n2 o& Z5 d; D* f
        MultiAdjListNetworkArc<WeightType>* p,*q;
    * V% S8 W& N9 ?+ g8 D    if (v1 < 0 || v1 >= vexNum)
    1 `& X  ?; c: H' V4 K  q' F        throw Error("v1不合法!");5 ]6 m" n7 C6 }& E/ U6 |' ^
        if (v2 < 0 || v2 >= vexNum)
    4 G# J+ j! K$ N( f& Q: o        throw Error("v2不合法!");; M6 n0 Z+ s0 M$ O8 v8 w5 D
        if (v1 == v2)
    " t+ j+ I* N) k' L* r% R* J$ n        throw Error("v1不能等于v2!");7 F6 p( Q/ l2 I: n' l! z6 Z
        if (w == infinity)
    * `0 |' ?: j% C        throw Error("w不能为无穷大!");  q9 N7 Z: \" |
    8 n# ^4 W. C4 i

    3 U. I' f5 x+ o& t- @( g    p = vexTable[v1].firstarc;. W$ H  @" Q) {0 c; T" V, _( d
        while(p)6 L3 z! i/ \$ ]" q
        {
    . {: {$ F% J' z4 ~" ^. _  f        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    " N1 ~* F9 a2 n2 O' V        {
    7 }! @4 Q3 g0 J& J3 x* x            if(p->weight!=w)
    8 Q4 R( d0 _* i8 v5 [5 x                p->weight=w;- y# {& _0 M0 c2 k) G) F- Z" `
                return;
    : s# u' i% e# y0 \# E9 y        }
    6 l  b9 c2 Z  z6 L9 X( E& z* p) O/ x' n" O& ?
            p=NextArc(v1,p);3 U! l% ?1 i% W# a  L
        }
    ' ^4 `- J  h# U, x+ b# Y    p = vexTable[v1].firstarc;
    + q2 z7 n- S! V    q = vexTable[v2].firstarc;3 g  M  k$ N7 h  q' \1 T/ \- ?8 W
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法% y# u5 i& m9 E7 k( p
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    + p& n& H. y$ n! p/ [8 s    arcNum++;. B+ r/ D; u& T# r, `. h/ J
    }9 x6 C/ V" x; J

    - [- U5 N% t5 Q) a* P) L4 Ftemplate<class ElemType, class WeightType>
    * C) [! g1 q& C8 ]$ |5 F' V; W% ]6 ovoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)% |- z& [  O8 p3 h( u
    {; M$ E2 F1 x' f- b

    & Q8 ^; ~* c1 ^0 Z    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    ( I9 w. \  b* d& u    if (v1 < 0 || v1 >= vexNum)
    ! C. }' m& ~+ E  V( \5 B1 d        throw Error("v1不合法!");' h3 P: z/ k. g, T* E4 N* p
        if (v2 < 0 || v2 >= vexNum)- m' O7 J0 ]3 q5 \
            throw Error("v2不合法!");
    / ^6 b: H; d8 a, w2 C1 P. N    if (v1 == v2)1 U9 r+ ?3 M! W9 G$ ]
            throw Error("v1不能等于v2!");
      e' T5 U- g# m9 U! J
    1 |: _8 `2 u3 j    p = vexTable[v1].firstarc;& x. b5 c: h" I0 t* p' R
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    2 F4 o7 G- L# Q9 Z9 G% C    {
    & C/ e- y/ G. N' ~% d  ~        q = p;
    8 N5 D! @4 l/ {        p = NextArc(v1,p);
    # O+ g, d; E/ J+ t7 F# E3 C9 v- w    }//找到要删除的边结点p及其前一结点q+ s9 j5 x7 Y7 \# a( O$ ?" T2 b

    3 B6 W9 q9 e5 h, h8 Z    if (p != NULL)//找到v1-v2的边7 [" C: @/ b+ y  j- ?
        {' q. m( t/ q( @+ M8 o
            r=LastArc(v2,p);  d  w* @2 X# _, J! @4 V8 _
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL: n5 q8 G  g$ z" d- f. g" V
                if(p->adjVex2==v2); x% R9 M) |1 _8 @0 O, y: X
                    vexTable[v1].firstarc = p->nextarc1;' R# e1 m6 s' z3 A9 l/ l) V
                else vexTable[v1].firstarc=p->nextarc2;: v) {  l. t" A) M' h  N# P4 s
            else//不是第一条边& ]( l+ l" H+ s" k; \8 ^- \2 j
            {8 A# g5 n& x  E3 U: G! T  q4 V3 ]
                if(q->adjVex1==v1)! b6 i/ ?6 N! D' f% I
                    q->nextarc1 = NextArc(v1,p);+ [& J3 {4 V, U
                else5 b& G$ K6 B, C9 j. I
                    q->nextarc2=NextArc(v1,p);, b7 u3 e$ p) q

    5 f. d. @0 c- |        }
    * ?" [+ k6 ]& ~, f% B7 j, j; n        if(r==NULL)8 v5 Q7 G0 Z6 c. S9 |* p, P3 K
                if(p->adjVex2==v2)4 Q" ]$ r) k7 ?4 ~- \, s% E+ P
                    vexTable[v2].firstarc = p->nextarc2;' b3 v& g" v* c! J
                else vexTable[v2].firstarc=p->nextarc1;
    ( B/ g1 {, [+ E- v6 J- [0 S        else
    4 d6 l, A) W, b        {4 }- B2 L9 |* ^2 U8 u$ I8 E+ \
                if(r->adjVex2==v2)3 s0 D* D9 m8 [* P
                    r->nextarc2 = NextArc(v2,p);
    3 R2 h9 S6 l. V- y3 V4 @            else
    3 k4 F5 {. ?  d- H( H  _) B                r->nextarc1=NextArc(v2,p);
    1 {7 n* h2 @* V5 ]7 p/ N        }8 Z, O% o: N' }# C6 }2 V2 A6 y. K
            delete p;
    2 G: S& z3 x" o: @& Z/ C0 X& o- l        arcNum--;
    4 @) M- Q6 I/ \( [& d    }/ n- a+ z, D, d) d
    2 |1 ?, v1 L5 B# B: x
    }2 i/ H! f1 V: t7 \: S) G7 x: C
    template<class ElemType, class WeightType> void0 g! Z1 y( V* d" A% _- \
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    ) s" X$ _9 c) L4 D( z{
    * e6 F. x: a! j' H( r! V- |    int v;  D) B! p) H( Y8 i
        MultiAdjListNetworkArc<WeightType>* p;! u& p5 R5 i' l) Z: {
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    / T7 ^' r6 v. _: [; U: o        if (vexTable[v].data == d)9 r" L& E+ L/ A. g+ ?% @
                break;# t+ q+ r4 h0 G$ I. z% H
        if(v==vexNum)
    1 q2 r( E6 W. C5 z# v" `        throw Error("图中不存在要删除的顶点!");4 M6 \0 b3 `1 R! c1 |) S3 L6 T8 |

    / a% N6 |4 `" e% e2 _9 Q    for (int u = 0; u < vexNum; u++)//删除与d相连的边, N' I- R# w! K3 ]. W( q
            if (u != v)
    ' C4 p: r! U& M  K; I! |8 s6 A        {  q/ h% w* N2 ]4 `3 h
                DeleteArc(u, v);
    3 n) t9 p7 D5 J7 ?3 ~; T( M        }3 y  ^2 i1 J7 x" Q7 {
        vexTable[v].firstarc=NULL;
    $ w7 a: c6 Q. Q4 z# f: j! `
      b- R& R& T- f4 ~: K    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    & Q+ W$ s, l% e% Q6 E# P) W    vexTable[v].data = vexTable[vexNum].data;7 e! W3 T6 W: X3 h2 h8 G8 |, M9 L
        vexTable[v].firstarc = vexTable[vexNum].firstarc;
    5 V0 m$ |  n: P, `0 t0 ^    vexTable[vexNum].firstarc = NULL;
    % f" b& C- s! ]7 w- r0 K  h    tag[v] = tag[vexNum];" G  M6 x. v0 T1 z- J# R5 v
        //原来与最后一个顶点相连的边改为与v相连
    " B: _2 }1 I0 J9 t8 q3 f    for (int u = 0; u < vexNum; u++). c. y# e; l4 p* s8 d# C# A
        {
    ) B  E0 J  W) S/ V# S( `        if (u != v)/ S  j0 n0 I  i5 k
            {' ~8 V5 a8 g0 {2 m7 [& w* f& Q
                p = vexTable.firstarc;
    / p" F+ m$ S/ G9 I1 I  |            while (p)$ V  r) O! w; G* B+ m
                {
    ' c9 _9 w# m0 r# E/ J" ]                if (p->adjVex1==vexNum)  t; \- y! }4 D+ K* d% `
                        p->adjVex1= v;
    7 y& n* c/ t) Y3 @4 a# d                else if(p->adjVex2==vexNum)
    2 u+ t8 G( r3 w. J                    p->adjVex2=v;
    8 J+ G& _* w! Z; m6 h( B6 l+ [                p = NextArc(u,p);4 G2 N, v6 Q' d0 ]' u
                }5 n' _% `3 Z! o; ~2 c
            }
    4 T9 T% R! f7 I. d/ O3 z. k0 s. y0 y6 i    }
    1 u; q; y) O. j) ^: z9 Q% j}
    : ^$ E* K$ j' J# d///深度优先遍历7 K+ q  E- u+ Y
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    6 f2 B% l) k" M( d" k# o{( E& v' h- E) w
        tag[v]=1;
    7 [- G4 M' e! T" j* v    cout<<setw(3)<<vexTable[v].data;
    6 S; n" I; B( a* J: X# Q) ~    MultiAdjListNetworkArc<WeightType> *p;3 [% C6 m$ \7 b6 G7 o2 k' ]1 O
        p=vexTable[v].firstarc;, C. l' N! m) r  ?# V/ H. q+ J
        while(p): F' A" m5 z) k4 `2 R* k  ^
        {
    8 E: p* ~) O( I; ]& u        if(tag[p->adjVex1]==0)- h# z) j7 B1 M, U: g" P! ~1 w
                DFS1(p->adjVex1);" X3 z# q  V( Z/ _& ?
            else if(tag[p->adjVex2]==0)
    ( a4 I' d6 @% {' Y7 j8 F+ K            DFS1(p->adjVex2);
    ; N, ]7 Z2 @2 y        p=NextArc(v,p);
    5 T+ m! X& d/ C- r; n( Y* c, B- u    }
    8 i0 ^# v1 A  R2 p1 h}( E4 f- Y& d+ U: t$ X/ `% l
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()9 h. X% M- C3 [
    {
    " e8 ~" i8 o/ ~* U1 d) I5 p$ G    for(int i=0; i<vexNum; i++); {+ Q2 ?7 R  H: E# c
            tag=0;
    ; L0 n* _2 l. V; h) u1 r    for(int v=0; v<vexNum; v++)) d! t# b/ }+ w# {2 c
        {& h( ~- K9 e9 B( z' f/ U
            if(tag[v]==0)
    $ J' \5 U! g2 @% L  y: l, K$ ]; y            DFS1(v);$ ?' J- @) y/ X8 i
        }9 @4 M7 m2 {, ^) y
    }
    ; {- s  j. ^" ytemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    # q; [* h. y. n+ L7 J7 A{- f7 W7 a1 Y! v  R, U* U
        stack<int> s;
      Y/ r; {" {$ Z+ H& T, m    int tmp;
    & d8 X$ T1 w' @    MultiAdjListNetworkArc<WeightType> *p,*q;5 w; u4 t- w; U
        for(int i=0; i<vexNum; i++)
    5 n) {6 i( d4 o5 x3 r) k7 Z$ o: B        tag=0;
    4 X# ?& {# N+ ^0 W' h! u8 ]    for(int i=0; i<vexNum; i++)
    / L7 K2 s( \3 X8 z6 @+ f    {( |8 F5 r$ N" u# X# v
            tmp=i;
    8 B3 a7 z! _. N+ F6 G; T* @        while(tag[tmp]==0||!s.empty())7 a$ y, Y. N( F7 P2 U0 D
            {5 W* |6 A3 |6 r/ R6 z; Y
                p=vexTable[tmp].firstarc;
    . R* t. [( ]7 ?            while(tag[tmp]==0). w2 u3 L; i8 M9 E
                {# k, y' }$ |6 T' V
                    s.push(tmp);
    * I7 U' s; e! \; l                cout<<setw(3)<<vexTable[tmp].data;4 I* Z# j# i& G$ V2 t% ~1 ~
                    tag[tmp]=1;0 ^( O, ^3 k4 M# B
                    p=vexTable[tmp].firstarc;9 \4 _8 y0 Z* }) G6 w( K
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for' g& @% \! P$ P" k) i- M6 b- Y
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    ' _% ?% J& O: [                //cout<<" 1st     tmp="<<tmp<<endl;
    6 n9 Y+ J8 N/ r; j' c& f5 A            }" r  `! z2 y9 n8 o- W1 t( I$ \
                if(!s.empty())
      \2 ]( b* B  y0 o: d8 u# g. N            {
    ) v! h" D" R- q                tmp=s.top();
    * z9 k/ @; v1 J9 X" L$ J4 K8 \                s.pop();
    ! J; q8 ]; d1 D) R                q=vexTable[tmp].firstarc;( d& M. |# v0 c% C, F! A( `: k
                    int t=tmp;' @' s" i) N6 h& h5 w3 W
                    while(q&&tag[tmp]!=0)
    2 w) r- O  Q- P# d$ u3 }* L) [                {% P% m7 V$ V8 D1 B
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    . C" f* O) s  q                    //cout<<" 2nd     tmp="<<tmp<<endl;
    9 p+ T3 u, a9 x                    q=NextArc(t,q);
    3 A2 u8 Q( \1 }) b* i                }* e$ t1 s2 \8 ]- B
                    if(tag[tmp]==0)3 d+ ]4 \" E; D
                        s.push(t);' S) z  ~6 n  l( T, F! `
                    ///1、对应上面连通分支只有1个点的情况
    " O( n5 g& S# y% v9 m1 H; n                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈8 O* W$ B* I& \) F% t
                    ///tmp要么等于找到的第一个未访问节点,$ l2 y( z5 O2 B: R$ R3 z
                    ///要么等于与t相连最后一个点(已被访问过)/ Y, G4 d0 b( B8 s2 B# Y5 o
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    + v3 F2 w+ K* u% ~8 X8 M            }& o' l' v5 c/ H9 d% p
            }
    : d2 o- c6 l9 X( u) G9 J/ [    }
    # _+ n+ N6 V. j% k! \}
    1 ^6 h+ u) O" m. H  C2 `. H/ d& S//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    $ p9 V1 ?# e; Qtemplate<class ElemType, class WeightType> int
    . U" j! }+ Q- g2 o* z; FMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    / \) w# {  z' M5 ]* [# e( t{
    % |2 r, E- U$ R; ?    if(head==pre), s5 D, |, P* X
            return -1;& S7 z1 o# X' w. F$ P

    % ^5 ]3 t0 u- A    MultiAdjListNetworkArc<WeightType> *p;; z: k3 N6 P, ?- g( Q8 k3 @, }
        p=vexTable[head].firstarc;# g! S7 W# y- X- F, \8 @7 f
        if(pre==-1&&p!=NULL)
    / D% z+ {0 w* R2 }1 J$ i        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    - C# D$ G8 A& P" c, _3 k    //pre!=-1&&p!=NULL" U# Y' {4 t. m6 O' X1 _& {
        while(p!=NULL)$ M/ m0 U* M" T
        {3 k, e& V) `6 C; s, u
            if(p->adjVex1==head && p->adjVex2!=pre)
    % J: {2 w- p% ~            p=p->nextarc1;8 C2 x( C: T# {) e# [! V
            else if(p->adjVex2==head && p->adjVex1!=pre)
      ?; @% H/ h8 e6 s. d) I            p=p->nextarc2;. `1 C* S' U0 R2 F
            else if(p->adjVex1==head && p->adjVex2==pre)
    ( \7 ^  l! W$ u$ l/ {, ?( s        {- m, b4 A7 z, ~" z
                p=p->nextarc1;
    2 x! o/ N0 u1 V- Y% B/ K            break;- h: n) v( H  j1 N5 U
            }  p. A$ v% s& {- M6 ?
            else if(p->adjVex2==head && p->adjVex1==pre)
    - Q9 U. t8 B8 c- O5 P        {
    $ t2 s/ F9 h4 c0 O( a- Q5 r            p=p->nextarc2;3 Q1 k" B1 W8 [% F  G1 i% B3 ?
                break;: x: Q3 w0 |+ I! k8 s2 ^
            }
    5 Z% t! ^. c3 c: R4 @4 `    }
    9 X* g6 t7 N+ k; O    if(p!=NULL)7 u  W  _& s! J
        {5 L2 r/ W3 K0 Y. r1 ], z
            return p->adjVex1==head?p->adjVex2:p->adjVex1;) Q# ?5 o" r6 J( V! z" o
        }
    + `1 B$ n7 l( c. b( K- q6 Y  u/ v% R    else  p+ R3 }" M. |8 i9 |* n
            return -1;) @1 `; ^* i! [& Y) r: Z( O1 ~
    }
    9 r7 z3 Y3 K' q$ n; J, j
    " y" s1 Q* J/ U- z" @: ?
    0 H( g+ N$ d" |* c6 U/ z' l- ptemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()5 z3 D  h" F4 _
    {0 A7 u3 p+ O7 G0 Y  T" Y
        stack<int> s;
    6 M( m) _- |- \. O4 \# w9 ?    int p,cur,pre;
    $ X5 V) g, c) d7 i- k8 O    //MultiAdjListNetworkArc<WeightType> *p,*q;6 S6 C& F" P, j  j$ M
        for(int i=0; i<vexNum; i++) tag=0;//初始化
    ' U3 u0 Y5 E: N' J/ K3 Q3 l6 M! k9 k) C4 B  q3 s! m6 d
        for(int i=0; i<vexNum; i++)
    3 z! D  {4 e. |5 Y5 O! y+ ]) A    {, F* J; g& ]; @, h" A2 x) I0 ]. g
            cur=i;pre=-1;
    7 A: ?5 b6 ]5 H0 \        while(tag[cur]==0||!s.empty()); g* [( Z) W$ F- h3 H5 x& N4 _9 c8 ?
            {8 o& V8 |* [7 k$ a# _; K9 H
                while(tag[cur]==0)0 i$ h$ i% e6 B5 o& ]+ e% f: K
                {7 H* H# k$ n) `3 j( U
                    cout<<vexTable[cur].data<<"  ";% A. b% d- Z/ \2 D4 ]6 r
                    s.push(cur);
    / t$ S7 U1 x  H" K# W( Y! |1 i0 s                tag[cur]=1;8 q, F/ B$ t: O( D$ w  z
                   //初次访问,标记入栈
    3 r8 O' n+ L$ @1 t5 G4 y( S
    7 M6 F$ Q1 ~4 _* B& C7 y& J               p=GetAdjVex(cur,pre);//p是cur的连通顶点; ]8 u3 U' Y( s- X& R0 b6 e" `0 ?
                   if(p==-1)
    & R- D" R4 p; S, ?               {
    - }. z; I+ x6 V! n' K                   pre=cur;s.pop();) p' j; `9 f( }- B5 D
                       break;" `% i4 p' l. i; e
                   }5 o$ Q7 V, v; R* T* ~0 ^5 j* C/ W
                   else8 u+ [! ~1 _( m2 c# C3 \
                   {
    , }. u7 e/ G& v                   pre=cur;, u( l- L4 {2 w/ X) _, h
                       cur=p;
    - [" F, s, h& z  A               }
    * r! q& w1 h4 u, T3 L& M- _- H# J7 k8 E8 F; x- ?
                }% ~4 U4 Q: `3 i4 ^2 I% }% F' \
                while(!s.empty())
    & c( @9 R- a: k0 Z            {
    ) e. H4 K2 L/ P/ W- H2 ~                cur=s.top();
    4 }) U0 K5 I/ ~& C/ u                p=GetAdjVex(cur,pre);# I8 S8 v9 {! c. \0 O
                    if(tag[p]==0)/ c3 n$ W3 ~' }4 w) ?; W) r
                    {3 ?) J' V- Y  @7 {! m2 R2 r
                        pre=cur;
    ( G# o% ^$ _1 G: T& J                    cur=p;3 E5 V9 S3 @6 N& |6 y9 j: C
                        break;
    % q! e& D! q" h' s                }
    7 r2 F( X; X  d; p9 ?3 g  R7 y                else' ?3 O- f$ P9 T6 Z! K3 `5 p
                    {
    4 Y, D8 N( q, K+ h                    pre=s.top();, i7 o% j' E* i6 h: g
                        s.pop();
    % F% G4 I* }; w6 b" O+ I' W5 s5 T                }: _( e1 Q5 _7 {% S
    - k& U' N# s0 k; f) u
                }$ n/ w  Z% l6 I0 e6 n$ d
    # O4 p7 W" V' n4 k1 W
            }
    5 f2 d" W, B3 P& D    }( ?, e* D+ @6 |2 ?; T0 x# |0 l
    }
    & q0 ^! _$ s+ etemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    # O5 W0 S3 Z% n7 L. ]$ x+ Y( I{
    6 P7 K. ?$ U) k- J% U" o    for(int i=0; i<vexNum; i++)" ~" L. n! l, Z; H+ O) s( E: _4 n/ C
            tag=0;
    & A! l  q8 Z: ~& z' b    queue<int> q;' I6 l5 q  n: O/ k5 _, K. I$ `9 ]
        int tmp,t;, ~0 f) o; s' i6 B% x
        MultiAdjListNetworkArc<WeightType> *p;
    2 D5 e4 @2 j+ P0 b& t( c7 k- ^    for(int i=0; i<vexNum; i++)
    & l" p' i6 Q5 ~, e$ `5 n    {- m/ y3 P1 m" g6 X) r3 d* S
            if(tag==0)
    7 k) x% [; \5 X% j5 t        {3 d; p4 `! z) [! b* U) s' q1 k& [
                tag=1;4 x% f( u3 d; A1 @2 Z6 L
                q.push(i);
    ) A! [* `2 r- J, E1 j            cout<<setw(3)<<vexTable.data;$ V# L4 C0 v+ M& q+ i
            }
    % Y; O$ `* b0 n) V% O- z        while(!q.empty())
    + l) x  Q+ K, G9 F, X        {
    3 S5 E2 O6 w; O            tmp=q.front();
    / ?) G' E* N/ Z, V1 {            q.pop();- a; w+ y4 \- F5 S
                p=vexTable[tmp].firstarc;
    6 T2 X# z1 ]. o; S- U% a/ y0 J            while(p!=NULL)0 X( {+ Y6 B% R
                {( m' I6 E, B# {: k6 Q: d9 ^
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    * i3 p+ B! p" q8 p, U# I  c. y: K, j4 a                if(tag[t]==0)
      d+ r& s2 g& X' `# b5 E! k) u                {  q: T8 I# m5 Q4 K7 J6 T
                        cout<<setw(3)<<vexTable[t].data;+ ^  t1 o$ T( ~8 _' v0 K! q
                        tag[t]=1;
    ; g, [9 B6 L4 A9 d! k; \                    q.push(t);
    7 f" z& T. b* q- t* u$ h  V                }& p$ T7 @2 ~1 n' P0 I6 e
                    p=NextArc(tmp,p);
    : R3 ]7 J2 R9 p2 p            }
    % }' H( p8 b! X        }8 A# \- f0 r$ f1 }
        }
    ; {: @) J/ V7 w1 e}' B. L" g" r) ?; M6 L5 o6 Y
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()) B- n8 j' K7 {( X% p- i+ O; L
    {' m% K& J+ Y0 X0 o
        MultiAdjListNetworkArc<WeightType> *p;
    : s/ u2 m! C( l5 a5 f    cout << "无向图有" << vexNum << "个点,分别为:";' I  d3 f* I; F9 c
        for (int i = 0; i < vexNum; i++)
    / _- T) c/ t1 Q" {9 Z! j5 v        cout << vexTable.data << " ";) x+ b; a- r/ T# J9 |- Z
        cout << endl;
    $ _( l% a1 X4 G0 g+ P: N& z    cout << "无向图有" << arcNum << "条边"<<endl;! w/ D7 F5 ^  M: z1 c& @5 c; j' a
        for (int i = 0; i < vexNum; i++)9 J. z' n% ?8 L; E: i7 p: z) K# W
        {
    ! v' F8 Z7 w, h3 S% ?        cout<<"和" << vexTable.data << "有关的边:";' K( ^$ ^8 ~/ g( e
            p = vexTable.firstarc;: B9 Y/ o) |+ s
            while (p != NULL)
    # o1 t0 v' E) s' [8 v$ M; }% R" b        {
    8 F1 f  W$ t) f5 r9 e/ F            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";; G7 x0 r1 H: N2 E5 r4 a
                p=NextArc(i,p);5 F2 q+ J8 D# `1 P" r
            }
    % B* w- ^( G6 S% l        cout << endl;
    * }# x. ^1 B) g+ I* E: Y    }
    / E2 v4 Y" L9 m. t}
    & Q5 U8 `! l& i( }/ t" u5 _
    5 t: Z# M- t6 z" r5 q; S9 V% j
    & o; l9 V3 v5 C邻接多重表与邻接表的对比0 K4 d+ f, }2 r1 `5 x

    % M- q2 p  F+ i$ ?, f邻接表链接
    / _, o, L* a5 H0 G- v0 b. n在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。2 _1 X* x9 I# |$ i
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    : Y' |( {8 q. [  N8 V为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
      t6 o4 F  y$ }0 S( {- A3 R————————————————6 C. p: b2 {& W5 F
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    * U7 e" _3 P2 Z$ a( R原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958% T) ]2 L0 e3 {7 q/ T9 c

    ) l6 E* F9 Z5 |& D* J0 e
    - K3 \: p6 w8 G* a" U  I( Q) ]8 c! K% T; b1 E( x) `  q: y
    ( L7 j/ q. T9 C0 |
    ————————————————
    3 [) s% @% A' x7 R  r4 z# `版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    1 \1 p6 q( ^  R& Q0 l原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    1 B0 S- F' D$ [1 d3 B
    9 g9 {  k5 _$ C0 c. @9 V5 X9 y. H! @. i& S  `7 B4 x) m& z- M6 _
    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-1-1 14:03 , Processed in 2.274270 second(s), 54 queries .

    回顶部