数学建模社区-数学中国

标题: 图的存储结构——邻接多重表(多重邻接表)的实现 [打印本页]

作者: 杨利霞    时间: 2020-4-26 15:26
标题: 图的存储结构——邻接多重表(多重邻接表)的实现
% @& l, h1 K- b% `& o
图的存储结构——邻接多重表(多重邻接表)的实现( ]7 v3 m3 e' e' F$ @$ m, U! f
7.2 图的存储结构
. X& c" A3 U# _
- L3 d# F) C9 U& ^# N7.2.3 邻接多重表(多重邻接表)Adjacency Multilist0 J& K9 M2 b7 ^& H* P6 n! H; d
邻接多重表的类定义6 [% F9 o0 ~% f, r- W3 R& P: U( r
邻接多重表的顶点结点类模板
! b; X) J: y' M' G邻接多重表的边结点类模板) D3 |3 j, `) M0 M' C2 p
邻接多重表的类模板
4 Y2 d2 P" R4 k. o3 Y- I邻接多重表与邻接表的对比9 g. J* j$ c( S. ^
7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
  Y  t  g$ w! I3 M% |, Q8 {, L3 l  v# I  x# n4 e3 z9 D4 y; e6 R+ `
在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
! a1 X) \5 Y1 H9 |9 n4 U: o' W在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
- _$ J( G# |6 X; h" i+ u' S% g/ C& X2 H0 R7 u/ u
邻接多重表的类定义
0 z) ?/ _: g6 p 1.png & T' T3 L- Z9 H  r* k' r
邻接多重表的顶点结点类模板

对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
9 ^9 U0 P% ?4 S! V8 s9 A2 ]data域存储有关顶点的信息;
3 [* ?4 i% h) g1 @. h- C# @! mfirstarc域是链接指针,指向第一条依附于该顶点的边。* Z1 I3 o( O6 j) l  v6 r% k/ c
所有的顶点结点组成一个顺序表。


: S$ R" ]6 M8 g5 G# S! a; F$ X% s# J+ z2 R) |# m, l2 p
template <class ElemType ,class WeightType>
; a/ S$ m  Y6 H2 D) |class MultiAdjListNetworkVex4 t1 D9 B+ p' u% {; S. |
{
1 u7 B% \; o- }- z* gpublic:
% r/ |; o% K& s5 ~, _/ w$ N  o        ElemType data;
. Z" \2 Z2 C0 V) Q2 L, a. G        MultiAdjListNetworkArc<WeightType> *firstarc;) @2 J4 z7 @, h+ a

! B. E! d) H( U1 t        MultiAdjListNetworkVex()
5 l, X  L( L* K        {& a) ^6 r: P% r+ z; Y
                firstarc = NULL;* K- G+ h5 m0 x2 D4 n, ^
        }0 s$ O3 z; j) }3 e0 s* A; P& Q* Q- B
        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
1 K2 M5 c& j7 v  a, n" A7 n1 k2 H1 B        {+ A# j2 w) }4 P. ^
                data = val;2 h6 R3 _5 I) C/ q- J
                firstarc = adj;
& S" B0 g& E2 u" ?5 p- Y        }
4 b0 ?3 i0 d# G) s) i7 Y};
/ W- i! P! B  s/ L0 @- v2 X' k% e2 x" p
邻接多重表的边结点类模板7 G7 @6 c  |5 R& F. n  C) }

' f" b( v) O% F8 f* a在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
9 q  f, y) I1 B- F$ V. V. {tag是标记域,标记该边是否被处理或被搜索过;
7 ]$ @3 T  w: z1 d; u' c. N+ Jweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
: a$ X; c; s! I, K% w8 c3 ]nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
5 |2 H* A5 ?* N- Y) mnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
* q" }6 q% Q" v: I: O7 u: k) W& E1 V; G
2.png
0 `6 ]5 I; E& ~9 Z' C" `template <class WeightType>8 q# f5 a% E7 W4 W) x9 Y& w
class MultiAdjListNetworkArc3 m& c! `: W& d9 U, R' f4 M6 W
{
- {: ^& y0 q- X7 t5 Vpublic:
  g% h& A; g# [6 K) C    int mark;                                       //标记该边是否被搜索或处理过
) f1 }( o2 i' u# W$ h' Q        WeightType weight;                              //边的权重( ^5 c- e3 U0 _! M' W
        int adjVex1;                                    //边的一个顶点3 X' d; i) V& d; W! A! P- Q5 v
        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-11 M5 |. B; w) p+ j: Z4 \" D8 |
        int adjVex2;
9 G, r: `( W5 ^1 g4 T# {        MultiAdjListNetworkArc<WeightType>* nextarc2;) Z% y* E* [3 ~( k" Z
" M3 @. ?; b+ L) t) v' L! z! Q
        MultiAdjListNetworkArc()
4 ^' d- r0 E% q8 ?4 k        {
/ y, ?' w) ]5 a; m8 E5 v                adjVex1= -1;
  D  ]6 I6 i/ W9 v0 Z* h, F                adjVex2= -1;5 x  T( U: t+ D0 J$ V5 o
        }6 O3 G+ L- E+ Y( o# u) c
        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)- y% b  x" \1 y' {# {' {( @
        {
, C& K3 n% V) \5 k4 S4 r                adjVex1 = v1;       adjVex2 = v2;
' |" q5 P# w# G0 D1 O7 ?4 Q! \                weight = w;. Z% C- P2 n; u0 }
                nextarc1 = next1;   nextarc2=next2;
: R' e1 `3 h( i( ]6 R                mark = 0;           //0表示未被搜索,1表示被搜索过
. Y: F& T& \# R        }
9 Y, j# F* K4 ]- }! U
$ n2 J: r: \- [邻接多重表的类模板

1.类定义

template <class ElemType,class WeightType>/ Z$ j! f- z0 {9 c; ^9 c7 C
class MultiAdjListNetwork; v* z. O& z# G) v6 M) n  A5 F
{- Q1 ?+ A  z6 S
protected:
; G; A$ U4 p1 I& E& J) d, a: J    int vexNum, vexMaxNum, arcNum;% Z. \, S5 E3 b* e
    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;2 \+ @7 W% d& Q: M. y. q
    int* tag;
; G- ?1 k" s) l: @6 l+ c" D    WeightType infinity;
. `5 ^; n# S2 Y2 g: ?3 `6 z# j: s& `( [! C3 G, I' T
public:4 Y' b. G% l1 i
    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);7 `# `8 j/ u* A: b0 \

0 L% f1 r5 \( p. ?5 C    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
' B; I. M2 Q& X4 I8 V4 h: A+ b' a9 v) Z$ B" n) O$ b; J4 D
    void Clear();
) f1 R( N6 @  |( _* s/ m) t    bool IsEmpty()8 _: L5 p# e, w: J
    {+ b$ n' F! g, Z& M; Y8 C
        return vexNum == 0;
( z2 `$ c  ~8 B/ U- ^" o+ ]    }
' F5 R& ^0 h3 Q: g) g$ d    int GetArcNum()const
, E, G5 o" b  _1 {! @! V    {/ h/ b' E9 u9 K: Y
        return arcNum;
, i6 M+ e3 N4 b9 m5 P% m1 k- ]    }1 n1 n$ A, _+ |, ~* Q$ t" N
    int GetvexNum()const( q: N) L' W2 o4 g$ S
    {6 z& Z+ G2 u0 H6 |# A. U
        return vexNum;
3 W  ^4 k) }4 i8 n    }
" V2 f, O5 \0 x( Y2 n/ g9 r. p/ [. J' {
, L0 \! a+ `( A4 i
    int FirstAdjVex(int v)const;
0 [2 |% I8 L' g    int NextAdjVex(int v1, int v2)const;
8 x4 o8 Y$ c: i, L    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
* k% g- w3 S3 [$ X+ o0 E1 H$ U    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
9 ~/ U- L( p) ^2 F; e6 k* m+ ^+ @/ R) D: |8 x  v1 {! W5 Y
    void InsertVex(const ElemType& d);
, m4 g, A4 P  i0 c% X# N( D% q    void InsertArc(int v1, int v2, WeightType w);
1 o: w# f2 {. ?: I0 R2 C+ K* @2 x3 n
    void DeleteVex(const ElemType& d);
5 T+ @, ^) [! z$ [' x# }1 E    void DeleteArc(int v1, int v2);
; y3 ]8 [$ {' @4 T9 \/ Y$ V
# z/ }2 ]0 C3 Z6 Q: H2 ^9 }    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);) a8 u/ [* x5 e" T
    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
4 b9 w% `) Z  Z# x' d+ a# C7 v& ]! m8 @9 U  x, C7 ?( H% R  Q
    ///深度优先遍历
4 A+ W/ G- f8 h7 z, F! z( _9 r* J    void DFS1(const int v);
! _6 O6 M7 c! N    void DFS1Traverse();( E# C  k+ s' C  t3 o
    void DFS2();. {; R4 ]. E7 y4 ^

, O/ a% p( @& O( T0 X( Q6 v    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1* `, _/ n) ?# S5 c& ^
    void DFS3();% s- ?/ s: G' C1 m2 Y7 _5 |

3 A. p4 x# L" p$ A( J' |7 Q% u5 P    void BFS();
' f" c' d- [' t% x- t$ Z  k    void Show();' |3 T1 z: `6 P( D
};
% Q+ F# O4 Z6 C
. w) O( ~% W. S1 I" L) j2.函数的实现) T+ {2 C8 Q7 }0 a0 q  S  u/ i
研讨题,能够运行,但是代码不一定是最优的。: h4 Q- b; c% Z- r$ P2 }; C

: P6 V+ Y: v. y5 [& j#include <stack>! G; f) f9 S* Z" H7 C+ A5 C: ]6 T
#include <queue>% }9 {" G/ F8 x; _6 H4 d
: j+ q7 `5 V! u& b, X7 [2 H# w
template <class ElemType,class WeightType>
- |, S, v5 Y2 m% _5 }% YMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
5 k' Z. i* \! M9 t3 d8 P{
; k8 m) p/ A* ]    if(vertexMaxNum < 0)
7 C( h0 z  r$ q" h        throw Error("允许的顶点最大数目不能为负!");9 {/ |# \0 k3 \' u5 F0 A
    if (vertexMaxNum < vertexNum)
& K: c; U; _. B) ?: |; A9 ]& r        throw Error("顶点数目不能大于允许的顶点最大数目!");# R* O& u( C5 K7 Z( p
    vexNum = vertexNum;' f" v3 y. C4 `( g2 c7 |) ]
    vexMaxNum = vertexMaxNum;
! t' N/ @- q5 o* r6 N/ P: U, m7 d    arcNum = 0;& z6 W5 E9 g( J5 B& M5 g
    infinity = infinit;  o# u$ L0 S+ Y
    tag = new int[vexMaxNum];4 ^; U% C( X+ W* k
    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
5 m6 Y* p9 x0 |. f: S. O; P5 \    for (int v = 0; v < vexNum; v++), i6 T* R9 g- n# a, ~3 N* {
    {( d/ ]2 J4 Y2 e6 {8 H8 N$ d
        tag[v] = 0;4 g! }0 J* o* t# |" M; N. t9 T# {! r1 ?
        vexTable[v].data = es[v];/ o3 _8 h+ Y+ S( _' X. Q, s" k
        vexTable[v].firstarc = NULL;
3 N8 q9 H) e7 h    }
/ K% k" K) n! c2 {}
& e$ `; W/ C$ o: f% @2 M7 @, jtemplate <class ElemType,class WeightType>
( b# d0 S. I" T$ e9 C2 A# {- I% o# BMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
$ X  o* }) Q% F8 t0 L% {) d3 p/ ^{
, d3 F7 Z, R5 x    if (vertexMaxNum < 0), y, i0 b- ]' d% O) f
        throw Error("允许的顶点最大数目不能为负!");
* Z1 }# C4 F$ p    vexNum = 0;( U+ W6 C$ k9 v$ N; J; ~4 ]
    vexMaxNum = vertexMaxNum;
4 t; r3 o7 q# Q( \& m    arcNum = 0;
2 n' L" z) J0 q& r4 r" I) V    infinity = infinit;' s" I1 C$ t2 s# N. ]
    tag = new int[vexMaxNum];/ I* ^1 Z$ r  X3 y5 H: z+ t
    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
( w* X1 f2 R9 {6 X}8 @% p* ^2 {* F/ A5 |8 Y) e4 e
template<class ElemType, class WeightType>8 F" o8 j* A* o! s: B
int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
3 S5 s6 P9 h- A! z{
" H7 k2 E$ W5 a" }) U    if (v < 0 || v >= vexNum)8 Q% ~+ t( H" E6 p8 H6 R
        throw Error("v不合法!");
8 Z8 i( G0 w0 H  x    if (vexTable[v].firstarc == NULL)( V  Y" Y6 D2 J8 ?2 c. Q5 ^, c) g
        return -1;; i) z5 J) a# k( `/ M; g- `
    else
& ]! J, k3 `9 C0 l        return vexTable[v].firstarc->adjVex1;
/ q# v3 t: _4 a8 X$ r  W% s! c}; l9 B2 |6 g! ?( v& M' U

/ B+ a) |, {! p2 d  Itemplate<class ElemType, class WeightType>
* [: o* e4 g/ ]$ Rint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
8 r2 t3 E5 ~" m" C1 }& z' J) q4 e" [* c{
0 Q: ]' @4 @, d    MultiAdjListNetworkArc<WeightType>* p;
3 j! h+ L; A/ Q& Q- G% R- C    if (v1 < 0 || v1 >= vexNum)
/ U! x% Q7 Q; r5 W3 I        throw Error("v1不合法!");+ u& V5 l9 \8 `/ W& Z  h$ p
    if (v2 < 0 || v2 >= vexNum)3 U6 f" j. o  u7 {
        throw Error("v2不合法!");
" x. t9 f0 |) C% g& g, i8 I9 A" j  C    if (v1 == v2). i! b% t' F/ y& ?1 Q1 I7 W0 x
        throw Error("v1不能等于v2!");
) _% k/ O: D. g" r    p = vexTable[v1].firstarc;
% [# q, _/ R7 O, V+ q7 S3 \. d) I    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2). N' A, |/ a2 U
        p = p->nextarc;& [8 u! z' N/ C3 R
    if (p == NULL || p->nextarc == NULL)
6 F9 d) h2 m9 \* b        return -1;  //不存在下一个邻接点3 J0 g2 V# W9 P; W! s
    else if(p->adjVex1==v2)
, r# |9 L. m) W2 ?; Z        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);( g+ D+ B. o% t
    else
4 q4 J  `8 G& y4 N) c* `5 V0 }" T        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);! h' b" Y8 K' _
}
) W. ]  A7 T2 `; Wtemplate<class ElemType, class WeightType>
5 [" i3 ^8 ~3 M6 L* cvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()3 i" F- D# z% }
{; v" Q$ q2 g) }
    if (IsEmpty()) return;
6 h8 F1 W1 u5 g4 z" e3 W8 T2 Q" m    int n = vexNum;- S7 g! \6 j- Q4 U
    for (int u = 0; u < n ; u++): ~  D  l7 c/ d, ]1 W9 B# |
        DeleteVex(vexTable[0].data);
- L3 ?: g( E5 D! V    return;4 o! T! l/ _/ V- D$ k$ @, k
}
6 r% l0 _! a  }# b  gtemplate<class ElemType, class WeightType># u. N1 n- X; A" `
MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
) J1 ?" u- F8 n5 B9 g8 _( Q1 k{! w1 @$ }2 W3 D
    Clear();% _/ g2 S9 h, R; D& u2 J
}8 K; C  W: O/ ]6 O2 ?
template<class ElemType, class WeightType>
. n: [  h( ^* q" E. tMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
- z+ Z3 A6 o9 ^7 j5 j3 u6 s{
5 U/ ]/ f0 B1 d" G4 H0 J# F    vexMaxNum = copy.vexMaxNum;
$ p7 V: Q# W" M! l. A    vexNum = copy.vexNum;4 v) Z* t* Q# F" m+ w" t' {! F
    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
3 O5 S6 ]2 i& B. p    arcNum = 0;
$ o9 l: u& p2 f7 o$ z2 o    infinity = copy.infinity;
* k1 ?, i$ j1 y/ K' I" E. \    tag = new int[vexMaxNum];: e1 s' {$ f( J; y4 G

3 h% v' p5 V" x9 O7 l7 g- l& y5 n    for (int v = 0; v < vexNum; v++)
5 p6 h0 }" a$ l8 A. B* r    {
, v9 ~1 U" F. a* C7 e! X        tag[v] = 0;
, T# l3 ]) t) p$ J/ m$ d/ j        vexTable[v].data = copy.vexTable[v].data;
& u/ [- i; H' Y  y& o        vexTable[v].firstarc = NULL;# `6 q3 n  C4 J% V+ \
    }
& Q8 T2 d5 x! H+ j    MultiAdjListNetworkArc<WeightType>* p;
$ a5 c4 I% J" X% }; G, r  [8 ?( x$ I5 l' X, O  l% G% Z" W  d- g
    for (int u = 0; u < vexNum; u++)" b- d: u, k+ |, T
    {
: X0 J8 i8 @. I8 o% i7 a        p = copy.vexTable.firstarc;
! A- k7 C+ L) |) I. P4 K4 m+ B        while (p != NULL)
; ?; O  G8 |; w- p4 J3 _        {
4 i/ `2 W8 T: {6 S- r: |5 c# }4 @            InsertArc(p->adjVex1, p->adjVex2, p->weight);. s6 Y2 _. e; \5 F  N
            p=NextArc(u,p);
4 I$ v) ^4 r2 y1 u; ~        }, x- C) W3 H4 A3 k9 n; d
    }
& L$ Q3 j9 b0 u; Z9 G1 b% v6 P; ]' F}9 D2 A) j/ W( w& h) M$ r
template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&/ b6 ~5 q* n6 R, I
MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
) H$ B% [6 Y- L# y0 Q5 Q{9 c, w0 s. y' I  M. y' h" T3 R
    if (this == &copy) return *this;- R( ~% w3 \2 {. D! M4 q
    Clear();9 @( t9 X; E. z7 k) ^1 z8 d$ N+ X; G& @8 q
    vexMaxNum = copy.vexMaxNum;
' x; ?) o, Y6 I6 B2 B* p6 y, Z    vexNum = copy.vexNum;
0 l# y! v1 U/ o    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];" h" W8 H6 k. [+ J
    arcNum = 0;+ I3 P$ j: h1 E0 i1 F1 P
    infinity = copy.infinity;. F, d- ^1 y2 n0 W$ J# g1 s
    tag = new int[vexMaxNum];
" B4 f2 u. t$ @2 `$ [, J0 q8 a; Z# `" d, V6 U$ G: {- r5 g$ u
    for (int v = 0; v < vexNum; v++), s# ^6 M- `7 v. H- T
    {% U. N9 I3 M1 h2 C6 `; t* M! }$ k
        tag[v] = 0;( J8 X, U! [6 J" t1 R7 e- ?. x  N
        vexTable[v].data = copy.vexTable[v].data;: w0 F, C% ~) V/ W$ G
        vexTable[v].firstarc = NULL;
. g: M- n3 R3 F* S0 J    }% J: T/ a% U2 L5 _
    MultiAdjListNetworkArc<WeightType>* p;- n: |2 F3 V- O7 A1 o

' T  ^+ p& s$ `# m" a( s* C7 C    for (int u = 0; u < vexNum; u++)$ e; ^) u, J4 d8 g
    {: N2 C$ x3 O% g1 R  M
        p = copy.vexTable.firstarc;
" q8 D' n. A; a) P, @        while (p != NULL)
; ^  S4 D  x" l5 W3 m2 {% @# f        {7 U# a& a* R$ C
            InsertArc(p->adjVex1, p->adjVex2, p->weight);, y; q  f3 ~6 `. z7 ^) @  V1 C
            p=NextArc(u,p);5 `, P5 k, f( G% B# n
        }( r, Y+ ?% p5 J& [* Z$ t# l2 d
    }
6 D* e$ a! x# b9 m6 M( L    return *this;
# e6 V+ f$ L2 _6 x, ]; a8 L}4 a; M7 {/ @6 g9 K5 N
template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
2 G* W' {4 V7 k% ~( RMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const2 X5 {6 \% N. @' y* P" Y$ o
{) p! x. @! c) t. F
    if(p==NULL) return NULL;
$ I2 D5 d3 P8 e. t6 }1 \, m    if(p->adjVex1==v1)
. V) D7 k$ S8 _( z4 c        return p->nextarc1;
! K; r3 a, d  s/ H8 Q+ c# s. x$ X) z    else
3 p# K& R* Y; P        return p->nextarc2;8 @; N: R/ E' g6 a
}1 Q( E/ |2 a- e6 _
template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
0 z5 g3 v! N" j- I6 G2 nMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
7 i, f# C+ d8 w% u' e" [) \) D{
; ?2 w4 J+ J& R    if(p==NULL)return NULL;6 X2 V% F( {" _* t  W
    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
  p  ?3 R& c4 z    if(q==p)
) c3 x/ L, M2 e" J1 H        return NULL;
* D3 W& o6 C3 D$ k) g    while(q)
1 i' F: q1 ?1 o    {/ g/ _& m8 G1 N6 [$ J7 W
        if(q->nextarc1==p ||q->nextarc2==p); M# ?2 Z4 K+ @7 E$ |
            break;& a2 r/ a% d. j# B3 E2 ?2 a; c# ?4 L
        q=NextArc(v1,q);
- D9 ^. r) Z% l- n, j  W    }
) _+ Z$ v$ K+ ^4 f    return q;; O, v$ {8 @1 n0 r1 L$ J' d
}1 V" e& f( f6 T* `7 v
template<class ElemType, class WeightType>* q6 G  g2 E& J1 q3 z
void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
; Y5 E( R! j. J. j4 E) O& @8 q. B{
2 r" D0 M8 Y1 u    if (vexNum == vexMaxNum)
) m/ V7 z% {! y. c! J/ X! v* L        throw Error("图的顶点数不能超过允许的最大数!");& b' V& `5 N% @3 j
    vexTable[vexNum].data = d;* U' _5 b0 C/ f, L. n7 {$ x& p
    vexTable[vexNum].firstarc = NULL;" z0 d) |# D6 s  m0 y
    tag[vexNum] = 0;, ~0 |9 p$ R- _9 Y5 ^& `/ ^
    vexNum++;
& o8 W" V9 |8 U$ N# y; T# T}- b1 |$ Y+ B7 _
template<class ElemType, class WeightType># Z# L% v9 L* `1 l+ y
void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)7 Q6 ^% G' P  X4 g. o, d) X& F  J$ C/ J
{' D  L( \# N  O; m4 }5 h7 ?
    MultiAdjListNetworkArc<WeightType>* p,*q;- x% @. @5 L- X& z$ o1 ^8 E! O
    if (v1 < 0 || v1 >= vexNum)" M* B& J2 ?2 T( C$ A
        throw Error("v1不合法!");
  g5 Q7 O2 s+ U* L3 r    if (v2 < 0 || v2 >= vexNum)
8 l( S! a" F' o2 a        throw Error("v2不合法!");
3 o  Y4 r7 L; r$ D" H    if (v1 == v2)
6 C! O5 ~# }$ f        throw Error("v1不能等于v2!");/ a: e' O6 `# ~  l- a  x
    if (w == infinity)9 U. \; l4 c4 W1 k
        throw Error("w不能为无穷大!");, N" a; o( I* x% N) y+ p3 f8 E

$ S. V- R# i" m) w; r4 V' x3 L" d5 i2 x/ [/ X3 d6 E9 B
    p = vexTable[v1].firstarc;
1 y* D: b: G. y5 n9 F8 |7 s    while(p)2 _* T% Y( j: u5 e  L" z( u: P  m
    {& ~: r: ~$ A3 G  D" e
        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中/ a" G% X) B0 W
        {5 J3 o$ t7 m0 F( [( ^  c% i5 J; [* {, i
            if(p->weight!=w)$ s2 c" A& V& t- u8 }+ q# i9 _, l$ D
                p->weight=w;
$ ^! c& \& [! T            return;
4 ^$ P) v3 B9 N" g3 z/ f) J        }5 m& P5 V" Z. q: ]8 j( R5 d

0 I  {( j! v: t2 y/ p1 V* U3 y        p=NextArc(v1,p);1 }# D/ \& J; s, t0 ?( Q
    }1 P# [! B3 t: G5 x  P
    p = vexTable[v1].firstarc;
/ h# p9 M. \7 M: m8 D% F    q = vexTable[v2].firstarc;
# t9 ~& j/ o# M, m: q( J8 t    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法0 k# N* n; j( Y6 o( [# ~
    vexTable[v2].firstarc =vexTable[v1].firstarc;
, X- J8 k, z0 L+ m' c    arcNum++;; E& ?" V/ t0 W; {, k$ M
}* t. X* m( w/ V0 q5 ?
2 O: C. t& p% a- o/ u0 b
template<class ElemType, class WeightType>
: T0 D5 n% K* r% Dvoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)* @( w5 O$ n* b
{
. e$ j: Q2 F, P6 [3 E1 i& @
4 a- y5 @  v* A9 H1 h. X# G% p    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
# {& L8 t1 B. W+ G4 F  u5 V$ Y    if (v1 < 0 || v1 >= vexNum)
- m) A- W2 r% d        throw Error("v1不合法!");
. u8 _$ o# |- h4 x" J6 e+ p    if (v2 < 0 || v2 >= vexNum)& ^7 d! a4 G& u
        throw Error("v2不合法!");) `, N6 z9 o' o
    if (v1 == v2)# P. m; p$ X# I- g( f. k
        throw Error("v1不能等于v2!");  K: ~/ g) l; n* G+ Z2 f
& U5 M$ F3 b. W  m# y+ d7 d
    p = vexTable[v1].firstarc;# p; p" `1 c/ ?! g, F8 P% ?7 B. X
    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)" q& q3 i; r! [
    {
  a' O' w3 g0 P3 E        q = p;
- a  V  a' `* q        p = NextArc(v1,p);3 W3 z) X* V% i" c+ s% W
    }//找到要删除的边结点p及其前一结点q) [" w4 E! K. `2 a, P& z8 Y, X

3 l0 N- D0 _. x- s& M2 ]4 l* O& q    if (p != NULL)//找到v1-v2的边
$ _' u& q$ o6 t" o    {
0 [: `* y* |4 Y: M- A$ v. z3 w        r=LastArc(v2,p);
5 v/ r8 T' x/ H2 t$ q% M9 \        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
0 i8 P& S( n, r9 O            if(p->adjVex2==v2)7 q8 V) ]& ?* d" Y( N* f' Z, J
                vexTable[v1].firstarc = p->nextarc1;' i* L5 h4 M  g3 _# n! Z
            else vexTable[v1].firstarc=p->nextarc2;
3 L/ n3 H# g/ v+ D        else//不是第一条边
" X+ h0 W4 H$ L$ a* d        {
# v/ Q, \* ?1 V            if(q->adjVex1==v1): s7 U( b- O- x" x- G8 P
                q->nextarc1 = NextArc(v1,p);
" \8 G0 }" o8 a7 N: m: h            else  k# q8 a" o4 q( {
                q->nextarc2=NextArc(v1,p);
' J3 M5 u% R+ l0 U6 B: Z
# |# ^) z4 O' F* E' ^        }% z0 R: `' V5 h8 O- W, P# \
        if(r==NULL)+ ]3 b: F6 p5 k) `% P* q
            if(p->adjVex2==v2)/ Z' M: b3 L1 t6 `8 D
                vexTable[v2].firstarc = p->nextarc2;
9 a7 ?0 o' o5 N1 e5 G+ N            else vexTable[v2].firstarc=p->nextarc1;( {$ w9 ~. J9 O, r
        else
6 J0 ~8 k1 a# `$ r+ t6 {        {
* p: x$ M$ ^% T; u# h            if(r->adjVex2==v2)- A1 [: |% S# ~1 j6 y
                r->nextarc2 = NextArc(v2,p);/ [* T  {1 _* ]0 x: N/ T1 M  r
            else0 Y; q/ k3 o5 o7 J
                r->nextarc1=NextArc(v2,p);1 P- [& s8 ~" |( D
        }( _1 F- d! Z  A. s. ]; b" o8 P
        delete p;$ G: }8 M% X, d
        arcNum--;8 v# ~- v5 {$ M( H- J
    }. D" v) Y0 ]# [* c) x4 X

2 R& N3 X- m& p4 r$ y8 r}3 X/ l" {$ [& G' |& u; {- E
template<class ElemType, class WeightType> void# m" e5 @! [7 j; e
MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
: [. o5 }- q, h4 O& l" Q+ {{1 N" y  \" v8 S0 [! l
    int v;) q( ~  o1 C4 [0 E& D1 u! _
    MultiAdjListNetworkArc<WeightType>* p;
# d1 ?( X, i6 f6 y0 Q2 z5 n. B    for (v = 0; v < vexNum; v++)//找到d对应顶点
& s1 A9 [/ q5 {' x$ s        if (vexTable[v].data == d)
6 I6 m5 F! T- F6 C6 v1 e: e2 i3 p            break;8 s2 e$ q3 k, G% k( B
    if(v==vexNum)
+ k& o6 V/ u* r9 Q% D) p        throw Error("图中不存在要删除的顶点!");( B  @3 E  S+ S

# e2 F9 h( c( l3 f2 {    for (int u = 0; u < vexNum; u++)//删除与d相连的边4 ?& }/ d" p4 a# E
        if (u != v)
7 v) I  U; I" Q4 o# Z        {
0 I- Z% B0 P2 X+ M7 {- X! i            DeleteArc(u, v);+ u4 S4 q$ g, o! z
        }
. p! g& g. s5 [    vexTable[v].firstarc=NULL;+ _- U5 A* s6 B* A% X% ~- b0 S# s
+ }- U& H: t# h- a1 B# _8 h& x
    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置! \: b  {8 I; B5 l2 g8 _
    vexTable[v].data = vexTable[vexNum].data;  f3 O7 y8 ]- h5 c+ G* F' @
    vexTable[v].firstarc = vexTable[vexNum].firstarc;8 l7 ]) N1 @9 {
    vexTable[vexNum].firstarc = NULL;
- U! S% c% f$ T    tag[v] = tag[vexNum];3 t) F+ P* r# O5 s' Q) }) e& [
    //原来与最后一个顶点相连的边改为与v相连5 p5 h7 K" c: s! E, Q
    for (int u = 0; u < vexNum; u++)
  H2 K2 I' u1 S8 @- l    {0 ^+ }3 ~! f1 H
        if (u != v)
$ ?$ L! \& P8 Y3 ]6 b. y$ C9 u        {
, M$ m1 U/ P% K6 z, {& E  ], m            p = vexTable.firstarc;& x; Z: U& C2 @! q
            while (p)
4 ^1 S: h' o# e/ [4 H4 [4 C            {
8 B% E% ~4 R2 E) L# w4 d5 S                if (p->adjVex1==vexNum)
- _: y" C# C: u5 k- M& r3 K                    p->adjVex1= v;& g0 |" t$ C4 r& L, X" [
                else if(p->adjVex2==vexNum)
9 D% C, R( C( d                    p->adjVex2=v;; m$ F9 u( W0 e- ?9 Y2 W& _" B/ K! }
                p = NextArc(u,p);8 a" |1 H+ C! U( s' s) m! L: ~/ R
            }+ S& {4 n" ]9 j& z  W, m
        }
4 j& j0 r. W- Q/ ^' y    }. e$ I- A+ r1 w  z9 d$ D9 j
}3 y  m$ k$ e7 N4 o+ m
///深度优先遍历
' t2 a% U$ v5 V, d8 stemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
4 N" D. D/ J5 D; I$ @3 V  r! _{
- M9 g2 |, h) A: e4 S# m    tag[v]=1;. q7 f9 ]7 b3 J( F
    cout<<setw(3)<<vexTable[v].data;8 w# M0 X  W- f' y( [! h% w. ?3 t
    MultiAdjListNetworkArc<WeightType> *p;
- T# H, [1 X% C" G    p=vexTable[v].firstarc;
% d4 M, C$ v# L! z+ Q, P    while(p)9 k( @! I* Y* O6 R" B' \+ X
    {2 ^' [4 l' i$ P
        if(tag[p->adjVex1]==0)* P$ y2 I9 Q3 v  t3 H
            DFS1(p->adjVex1);
' _+ f: n0 W7 W9 A& u        else if(tag[p->adjVex2]==0)
0 r0 ~1 X1 R% _1 q7 P            DFS1(p->adjVex2);
# n- m+ l6 h: }' N        p=NextArc(v,p);
' ?' w/ Q- x- K! Y" Q+ S& u    }0 f# j" {  N, w! @9 x4 j
}
( [. o0 C/ H9 xtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
* ], Y) {% R$ E5 Q: V6 Q{1 x" a& r) d" U1 W  T! m
    for(int i=0; i<vexNum; i++)
0 T+ s) r0 i. ]$ h, ?$ ?+ z        tag=0;
) y- {% F$ T8 S" ^% P; g+ `4 L3 K' P    for(int v=0; v<vexNum; v++)$ R; j. t# y" h' ^3 P1 H
    {
* F4 I) @8 x- a3 O        if(tag[v]==0)! V6 X3 n$ R1 D' q* ^# F# d
            DFS1(v);: U, V  J! a7 y: K9 q6 M
    }
' A$ U; s8 a1 M1 b, w8 c}( K5 ]/ L# X" y2 j- b% X
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
' y3 d; u" F4 j6 a2 h7 O# c{
0 W) M, q( q$ ^+ J! i5 v    stack<int> s;: L5 p4 V& e3 N" [; K
    int tmp;
2 o# Q8 n) M/ H+ K. R5 Q/ ^    MultiAdjListNetworkArc<WeightType> *p,*q;
$ x2 l0 X/ ]* a6 R4 a6 l/ P: ?- E    for(int i=0; i<vexNum; i++)
& [7 P2 u! E* d6 ~        tag=0;* O9 w7 p4 B. q0 L
    for(int i=0; i<vexNum; i++)
* ]9 ]& X* n/ w3 G" e1 u# ?+ K    {0 c/ A) Y+ w+ U1 y$ m9 T- B6 ]
        tmp=i;% l# I4 I/ R( V- D4 b) E
        while(tag[tmp]==0||!s.empty())/ {0 t3 k6 |" Z4 I
        {
. |; D! G1 c: ?/ n0 t            p=vexTable[tmp].firstarc;
1 J! N0 F: f$ T1 a  ^  A            while(tag[tmp]==0)
9 ]  V9 Z4 c! z; j' w! y) g            {6 n9 E' n7 ^# G9 R2 X
                s.push(tmp);
& ~1 Y; O4 h1 q. [5 W  \                cout<<setw(3)<<vexTable[tmp].data;
8 T2 i7 H) `/ S, _9 O                tag[tmp]=1;9 z7 I! e7 a$ G6 U6 J
                p=vexTable[tmp].firstarc;
" ~9 E6 @$ a, i" V) B8 _                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
6 G5 J' r  D* N; i2 e4 ~. R. Z( R+ X0 d                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);/ F: s8 w9 L5 i+ b2 L
                //cout<<" 1st     tmp="<<tmp<<endl;
' Y6 `& M! [( t6 p7 X+ T) Z            }
) i$ x1 ~+ B9 Q1 C- c            if(!s.empty()); Q6 I  D" G( W% S1 D* o- h
            {
! K3 ]2 P- I& g# d: z# G* P                tmp=s.top();1 b6 {1 [: q+ h# W5 @& Z
                s.pop();
  m. y2 y; F; d# t& _, w                q=vexTable[tmp].firstarc;
' p2 m# s" Q2 c& m7 p9 C' c                int t=tmp;  X/ e) ]+ z1 R( @9 Q
                while(q&&tag[tmp]!=0)
; M3 m" W7 j7 g                {0 {: [9 \8 I( w4 ~* {( I
                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);1 U' T: {( ^4 A1 e; `$ i0 {- B
                    //cout<<" 2nd     tmp="<<tmp<<endl;2 f1 T% l3 O. c4 R# T0 n& _
                    q=NextArc(t,q);" X% ?+ O5 N# y6 ^# I4 B
                }
/ ]/ M9 O+ Z% `2 \) _. i0 K/ o                if(tag[tmp]==0)
5 d9 P0 W5 N8 ?& t: V                    s.push(t);/ a+ g9 h; F/ o( Q9 g
                ///1、对应上面连通分支只有1个点的情况
8 l# A' ?3 l( s# T6 W                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈  [' \5 L/ }; }* }2 H& p
                ///tmp要么等于找到的第一个未访问节点,( D, R  }" ^  w& L3 ?" s
                ///要么等于与t相连最后一个点(已被访问过)
! ]+ P- Z4 I5 F  Z, [, w                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
# [3 \6 j: k, {1 ?' ?* S            }5 r9 D+ u+ U/ ]1 e, |1 e& f: y8 T
        }
+ q# t: @* o! k1 C* J    }
, z+ W, u5 r3 V1 ^2 h/ F}& a3 P# }9 N* N& z" I
//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
- u, F; @& _4 n: D( ^template<class ElemType, class WeightType> int
" f! c1 z- e6 n* V( T, A$ UMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)+ ^. m6 G6 n& X: ]6 Y
{
8 E% ^6 s* v, N9 F    if(head==pre)
3 p8 I% G8 x3 B. K0 |' F        return -1;  t1 S( @1 p$ \/ x
6 o- ^0 \9 d9 W
    MultiAdjListNetworkArc<WeightType> *p;
+ s; u/ s+ w& d4 A1 \3 u+ r4 p    p=vexTable[head].firstarc;
3 I- h* e7 y& O9 P    if(pre==-1&&p!=NULL)
. e5 l) M7 X( |; m- e2 `2 q4 U! r        return p->adjVex1==head?p->adjVex2:p->adjVex1;9 L" R( j* a$ m7 B, B: T0 n$ r- Z8 i
    //pre!=-1&&p!=NULL8 Z% O2 f6 C1 w, }; K! c' O, Q; Q" S% N
    while(p!=NULL), Z. p+ s# R6 Y* I
    {& `  c6 M0 D8 s: P
        if(p->adjVex1==head && p->adjVex2!=pre)- f3 K0 L2 g, A9 a# M& h
            p=p->nextarc1;; ^& h3 X+ V  Q7 s0 I
        else if(p->adjVex2==head && p->adjVex1!=pre)
5 c. ~9 y1 W( M; m- d' H            p=p->nextarc2;" i  H2 d: @' @3 t; \# _
        else if(p->adjVex1==head && p->adjVex2==pre)( U7 ?  `/ ~/ V/ g0 Z
        {* ^& L3 b- U2 Y" D/ u( R" c- F/ ?
            p=p->nextarc1;
  v  H4 V) `( q& e  J+ s7 k/ Q; f            break;
$ N2 c2 U9 ^/ H" k6 _        }  B" B- P# _4 g! D( e3 Q/ I" Y9 A
        else if(p->adjVex2==head && p->adjVex1==pre)
: ]. s2 ?) ~+ L" j9 Q5 {        {
2 B' K/ o6 P, E2 |8 P3 c            p=p->nextarc2;" @; p) H) H% L- T& `5 ?6 m2 o6 L5 X
            break;
- \% H1 v1 o4 T( F        }# `( j& b! A8 w  c0 f3 X
    }
: {3 {* ?5 V7 b/ G9 I" f: L    if(p!=NULL)
1 a# Z; D6 D) x& M    {
' V' v: j% J" G7 i        return p->adjVex1==head?p->adjVex2:p->adjVex1;
3 g) f  E& N( T! |& c: V4 R    }* ?3 L$ J5 P, w$ n5 ?1 [3 N
    else3 M) s! v4 {/ P! D
        return -1;, S7 X7 V5 w5 P' B8 E
}
$ _  W+ o5 w5 u+ n0 d
; |% z# y% @9 R7 H
* t9 s4 U9 c+ l- v( ctemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()5 }1 Z3 {: P8 v
{
8 _3 R9 Y, r6 |2 k; q% L    stack<int> s;
4 E. V# Q1 V8 a3 R% k' h0 v; u    int p,cur,pre;
1 S# A" n4 _* _8 X, N    //MultiAdjListNetworkArc<WeightType> *p,*q;/ v2 u: u$ ]2 m5 d( S
    for(int i=0; i<vexNum; i++) tag=0;//初始化
3 l7 c9 C# A. l* @$ |, I0 B, r1 R4 q+ ]& ?- e
    for(int i=0; i<vexNum; i++)
% [8 _, S, j2 e, I3 N( f* j$ f    {# \$ I) X4 h$ P3 @
        cur=i;pre=-1;6 L: @+ Y: L; R4 J! g& A- U. P
        while(tag[cur]==0||!s.empty())
+ t9 C: ~2 u1 X& ]& N6 |2 O        {9 X; s# G0 }# \  b; g7 o* x% @: c
            while(tag[cur]==0)/ D& e/ T4 c/ M9 u2 l
            {, L, P; @" [# X
                cout<<vexTable[cur].data<<"  ";# V% g8 I0 s9 Z" V3 ~# q7 d
                s.push(cur);
: @. a6 E- Z6 p                tag[cur]=1;
1 R; U- u6 g8 p$ U6 [/ b  Z               //初次访问,标记入栈
; d& U$ U) I- w  Z+ q
4 q  H4 w& g4 Q# ?2 E               p=GetAdjVex(cur,pre);//p是cur的连通顶点
  @1 K* e6 n0 W* n               if(p==-1)
$ a* r& h2 l5 h+ r9 ?1 x# O               {
* ^% m9 Y7 c9 v7 q0 u# Z7 C0 d                   pre=cur;s.pop();
: K4 f% c2 I; X) O0 o5 h# f# E1 G                   break;7 w, w, o. e3 `0 ^% `0 f2 h% e/ N& M
               }
* I2 O+ X0 z7 ?8 }4 \/ `& z- H               else
: \' @3 ]& m9 ]3 f7 O, @# Q               {- I! |7 E: S' j( h+ u4 z
                   pre=cur;
' _" D/ b% Z9 R6 H1 }0 G% I4 ^                   cur=p;/ b! n% g1 ~4 H
               }  v% X6 C' K& `) M4 B/ t
  M" c$ \! R; }' G
            }
, N' k. }' R8 W9 c1 c* R, X& U( q: ?            while(!s.empty())
+ X( x  M/ u2 E7 h( ^; L            {& n. }" P0 H& u/ T$ {0 {( G- ?9 E
                cur=s.top();
! B& S+ k9 w  }8 w. `) S3 V$ Z5 q                p=GetAdjVex(cur,pre);
3 \: F1 @4 V6 |9 F7 T/ z9 \  `                if(tag[p]==0)
. u5 @. J0 g+ D# i; [" F& H                {
* Y3 T; x8 ?( G                    pre=cur;
8 d9 E- @" m1 T                    cur=p;
* s. B: ^4 b; }: C9 q                    break;
/ Q+ R: N8 ~' U! ~. Y                }4 C7 q# E( j7 `( I' K. j6 @& n5 V
                else
0 k' d# G, l9 ?/ @! \2 x4 z4 \( H                {& I  m7 h  Q* h$ N* T, x
                    pre=s.top();
5 a$ J: h6 A. p, x! s                    s.pop();
) z/ _( S" E" @( B. x+ v                }
0 z) g! o1 b! ]
& O" b4 }! I' e# {            }( P( F2 _9 H# P: ?0 i

0 {0 t8 M1 N, k& T) p. _        }% }7 ~% t1 l" U% U1 r9 |& V! Y/ `% W
    }7 s: X0 w, C, i. G' A: ~' Z
}
' f* {; u; M1 ^+ k% b7 I" d2 ?# f8 btemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
% a/ `! f7 W% d{
4 F+ f3 z1 y% h4 k; K    for(int i=0; i<vexNum; i++)
' e" G+ h) A' m& g9 |! f  ?0 I        tag=0;  d* g8 X5 j& `) o" y
    queue<int> q;
0 S6 g1 ?( j: h$ J+ [$ ?    int tmp,t;
* I$ M: j+ Q8 Z$ o9 F    MultiAdjListNetworkArc<WeightType> *p;
1 s. z' I+ p* O" \7 R2 z' M3 n" B    for(int i=0; i<vexNum; i++)& T- v% a% z8 @! A8 z' N8 f. Q5 }0 ~
    {  J3 \0 I0 V0 `+ n7 ]7 J4 Z- ]
        if(tag==0)( {5 @6 D: [8 b0 f  {
        {# A$ V, y$ J+ h) y* q! _
            tag=1;
$ l+ p. L) I4 G6 B            q.push(i);
! j8 w( [" T8 K0 ?$ f" _            cout<<setw(3)<<vexTable.data;- `- }4 C' d3 O, L( ?) @
        }  k! L; W: e2 W2 g0 p
        while(!q.empty())
' I& }  G& l/ W" [. W0 D8 G; ]        {- i$ H2 x$ Y% W9 X
            tmp=q.front();7 O1 r- ?6 X8 k( h
            q.pop();
. |- L: q+ P* v1 W            p=vexTable[tmp].firstarc;
; l( f; @& J& q            while(p!=NULL)' j; `6 T, G" r
            {, a+ \# o5 Q, K# Q
                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
; J$ E& S  }5 |; [3 t                if(tag[t]==0)+ o( _) o  r& x- Q7 `3 m
                {+ V' ~1 t7 W' L2 R
                    cout<<setw(3)<<vexTable[t].data;7 m# a8 E$ ~  Z& Y4 i; U
                    tag[t]=1;
0 F! M# y: b8 e- @                    q.push(t);
2 `8 g9 ?, `* z, u: G                }5 q; k( z$ }# ]' m. W. N1 r* a8 q
                p=NextArc(tmp,p);
; ~, C% h/ `& a9 e! b; c, s            }% N  b3 K: R  Q& r: i  M
        }" T) o5 ^, i  Q# t
    }
' p% Y" ^" F+ v/ p# k8 n}; Z- r8 z0 H, m
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()0 U0 c& \# F4 i1 i; M
{
3 g% \$ I  e. S    MultiAdjListNetworkArc<WeightType> *p;
3 U: v; H4 s0 H! x0 d8 H4 M$ G( m    cout << "无向图有" << vexNum << "个点,分别为:";" h- `" V3 G+ |4 F  _9 f0 W  k
    for (int i = 0; i < vexNum; i++)
  m, D! v0 t4 D+ Z8 \1 R1 N        cout << vexTable.data << " ";% m% p6 a. q' j8 j9 d
    cout << endl;3 Z7 w& ~: n' d: V0 h% ?9 x9 [
    cout << "无向图有" << arcNum << "条边"<<endl;
7 H* J( h$ D3 u3 i6 g0 `2 v2 C% g    for (int i = 0; i < vexNum; i++)  E# Z7 N  n2 _
    {) E7 T" i1 ?+ A  M0 l
        cout<<"和" << vexTable.data << "有关的边:";# D- [$ Z4 `# w. o
        p = vexTable.firstarc;% Z! a7 Y& U4 U( n
        while (p != NULL)5 w6 {7 i2 ]2 z' _7 H
        {) O6 h; j, g0 i/ W' B/ ^( |
            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";( ?# N+ w9 c/ l4 N' k8 A( C
            p=NextArc(i,p);
0 w. F* ?3 B  q# f        }! Y! q  T$ j- f& G8 K
        cout << endl;
2 i7 d; N7 I. K    }
) f0 m# T" @& D0 i# w. V" ]  q}
' f2 U, I' I' w$ Q: l& Y5 O9 B2 S3 p2 p2 C: a! @
2 R$ s. r/ C( b* d
邻接多重表与邻接表的对比
$ f3 u2 J8 [$ C5 C( E" Y+ T3 s7 |3 A# O; Q5 z8 s; m( \
邻接表链接
$ V: m9 b$ q1 S. Y* s在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。8 X1 V: ~& ~1 w# c; H
在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
/ F" K, c2 y# ]: @1 d  u2 P4 [为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。4 ?" }& f+ U! E" A8 M/ f: X
————————————————
. n' t6 B7 A. x7 n版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。9 t& H6 `, ~" x
原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
# D$ Y3 j  w; }: h& T/ O4 R: I, |! M5 S& R) p
$ y( @  \! n* Q9 @  W
6 w! C; W9 i8 d* A4 O. w. K
6 l4 i+ c* H* y0 [0 @- M7 K
————————————————
: p. H1 [8 C# K6 J3 n5 J版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。7 t+ q) a! k2 a# b5 R
原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
- D: M; t' Y# B6 F
2 m, w: |2 J! g1 G1 R
) {* q2 g  z' h  P  t: W




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5