数学建模社区-数学中国

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

作者: 杨利霞    时间: 2020-4-26 15:26
标题: 图的存储结构——邻接多重表(多重邻接表)的实现
$ a, |1 e! Q% E9 Y6 D( E
图的存储结构——邻接多重表(多重邻接表)的实现; j- ~" P! ~: ?. K6 h
7.2 图的存储结构5 n- g& \8 I: z0 z2 V

! Q- P" t% @: G& F) ~' Y7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
+ R# l0 C' c. ?- o邻接多重表的类定义
0 k: m5 @# p4 Q9 I/ A* }8 i; Y邻接多重表的顶点结点类模板7 ~* l! D4 [. d0 v) z( v
邻接多重表的边结点类模板, g0 U. ~* r$ |) z, \
邻接多重表的类模板4 d& h  u0 O  g( d+ O
邻接多重表与邻接表的对比5 Z9 l7 ?6 S' o1 l# r( n1 s  l0 W; P
7.2.3 邻接多重表(多重邻接表)Adjacency Multilist1 O' k- q9 K% c! u$ o6 f
* L, x: ], \0 n5 M5 b
在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。) b: s! h9 \( ^' L
在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。! i8 @0 T' G! Y* s  Z
. A% b/ r- g2 N# A( Q, j2 v
邻接多重表的类定义' z/ a2 \( f% K7 X0 q3 a, V) v
1.png
1 l6 A$ e$ M; x0 O" ?邻接多重表的顶点结点类模板

对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
2 |: d/ r8 ~/ v& X* qdata域存储有关顶点的信息;
/ a$ b! e" {9 L( p" D. ^firstarc域是链接指针,指向第一条依附于该顶点的边。& r$ i( b  a  z* I( o: [8 _% r
所有的顶点结点组成一个顺序表。


& ?' K1 @& T1 R% K4 m' v, m$ |. Z7 t) ]6 A4 C# M
template <class ElemType ,class WeightType>
& l  f) n4 N! R3 L! m: iclass MultiAdjListNetworkVex( a/ ]9 _5 t& [% c
{
& @6 K3 c- Y- F  d0 l' fpublic:4 P3 q, Y, H  n) g/ x2 _
        ElemType data;
6 y1 X9 E: `! h. }        MultiAdjListNetworkArc<WeightType> *firstarc;
9 L8 s5 w0 t# _3 ~7 `% G' H2 ]+ |- ~8 v- Z( |5 _
        MultiAdjListNetworkVex()
) d/ w  `1 y, Q* s0 i        {! k9 N9 L$ Q& o) z
                firstarc = NULL;0 v& z3 Q. Y' t* U% e  N% E: x3 g
        }8 m! ^+ Q3 H. t* `1 V- y* t  {/ ?
        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
; l  @' x8 h# ~, K% `# M2 Z        {; k6 b+ [% V2 n+ D% r7 a
                data = val;* K" w8 I2 N( q* t) t
                firstarc = adj;
6 x2 F0 Y" ?0 l2 b# Y        }) x6 o; V3 ]2 u4 ?; V
};
1 ]/ f( E; @. F& \. ~$ i2 P/ F# C! i" x0 q
邻接多重表的边结点类模板
2 p) W1 ]7 c$ V, N+ [7 X' j  H( T3 w2 e9 G. S- Z9 [0 P! F% D5 I8 g( [. r
在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:$ }7 i; [/ v+ ?
tag是标记域,标记该边是否被处理或被搜索过;7 s/ E4 g( |% f6 ~! \! N' \
weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
# C( l2 p1 o" K9 E5 A! Tnextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
* q6 a8 B  C: }nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。4 s3 b( {' g* \+ Y4 D% l

8 Z1 m6 q' ]' L; [. @+ i 2.png ( D1 `7 r$ ^& @& h4 o
template <class WeightType>
8 W' @$ p8 H4 fclass MultiAdjListNetworkArc: _2 }, X  J  @" P6 U1 k
{
2 h0 [1 m( L" A/ n- d' q' t+ H& epublic:
( n& b/ _* e( w- }" o1 ?    int mark;                                       //标记该边是否被搜索或处理过  r/ [0 u* u. Q' U6 M: c0 \
        WeightType weight;                              //边的权重
( c& _4 t7 m) O2 A( {        int adjVex1;                                    //边的一个顶点0 q7 Z; ^  ]' K* ~& H$ L9 b
        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
( s+ }. w* T! n" I! _2 }        int adjVex2;
4 H5 s9 G# L, T& `! ?4 ^        MultiAdjListNetworkArc<WeightType>* nextarc2;
  z' m  \. _0 F
$ v  p" G) w8 m        MultiAdjListNetworkArc(): s/ m( c- E. K" Q* Y& @# m* i
        {9 g* Z. ^+ E, `, o
                adjVex1= -1;9 [$ x  Z4 O  [& o/ J; N
                adjVex2= -1;& U" ?4 l- D+ T6 j5 h. q
        }
) A8 h6 L& q" Q* U( C. O        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
% t; I, E3 E" m        {
3 x" k7 k. f! f; f  C& Q1 `                adjVex1 = v1;       adjVex2 = v2;0 y. D' o# L  H# G% S: ]! S2 x7 ]
                weight = w;
) {' B: d8 B# f5 f! @$ S" s3 x                nextarc1 = next1;   nextarc2=next2;
% h; i5 V- e3 h$ Y/ {# P                mark = 0;           //0表示未被搜索,1表示被搜索过
+ G- J5 J  B9 `0 S& F        }
$ l0 X- E; p; ]# v- I% j9 u$ a5 j
邻接多重表的类模板

1.类定义

template <class ElemType,class WeightType>
, w0 R9 q2 [* A( {4 f5 ?' H" z8 Sclass MultiAdjListNetwork
  o( D9 v, k1 K{' _9 X, K5 R( N3 F. n( M2 I) Z
protected:6 B+ o" z8 ^0 ~( x, A$ Q
    int vexNum, vexMaxNum, arcNum;$ ^( ^+ f  Y3 k" o/ l
    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;6 h% @4 ^! ]+ R7 C: \+ G' f4 ?
    int* tag;
" I" u9 t0 _  F& c1 c    WeightType infinity;4 L3 `) `) J$ f/ I; [6 A0 b# A2 ]3 r

+ j9 @. e  |9 y8 K( }public:
" C# R' U! m0 N    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);) p) V. c0 r, h- w
! F4 l9 ?' |/ h0 m% Y5 W
    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
0 ?4 J+ y: X8 U% O% }# d0 ?. z7 f0 b9 G% V9 v; i2 M* l
    void Clear();8 f6 i4 w4 y/ O; ?* u+ O
    bool IsEmpty()3 m! C" Z5 V0 w# @0 J; N* B
    {2 L/ _% ]) x, V9 h
        return vexNum == 0;
2 l: A. Z$ f9 p, S  o7 b- M1 R2 H    }
& t% `5 y. u5 n+ R    int GetArcNum()const
. t" a2 g8 @6 m0 R    {
6 ]' I- V  i7 y1 B        return arcNum;# a! T: l4 {8 U/ X% p8 \- ?
    }3 w& @: H  B2 q: I* n% ^
    int GetvexNum()const, o5 d4 E& @1 O+ |0 ]
    {
) s4 t& c. Z: A  H' R% D: e* \        return vexNum;0 j& ]3 g: E2 Y2 B0 _* R7 ~7 `. {
    }2 ^5 g$ v5 b1 W8 `0 W) g4 P# ?

1 i( k5 m  _- b# A- z' k4 z" e( e7 J- r# s) I" u  j) y
    int FirstAdjVex(int v)const;
  n* T* u" C6 T$ J4 y    int NextAdjVex(int v1, int v2)const;
6 o5 `+ z) S2 g& F& q    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
" R9 X3 u9 o, d. E    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
$ f, C! s0 h3 A/ V0 B" o; x" x
6 H8 l* y3 e0 X* W    void InsertVex(const ElemType& d);
; O- f- f9 C; W. r    void InsertArc(int v1, int v2, WeightType w);
- {' N, g/ J/ U2 f, [: i
, Z. j" B( ]" s3 {    void DeleteVex(const ElemType& d);3 D9 f$ K8 K! _
    void DeleteArc(int v1, int v2);
% E7 Z+ y  i. Y) e7 ]: S+ R% C. y' r
    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
/ U, l- i) J% }4 Y$ `9 U8 b    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
3 g! D- }* E6 j( c* ?
# F1 ^, o4 i; q( F4 l$ B% U    ///深度优先遍历
1 Y/ f: I' R! Y; N4 q# T    void DFS1(const int v);
7 p5 X7 p/ F% n% n& g  a, H3 U$ g    void DFS1Traverse();
6 w. S  c7 k; g! B; e3 Z2 r2 p    void DFS2();% p9 o! |* Z7 O2 a" z: C6 X
3 Q$ ^3 \! W9 c- F: O4 Q) y
    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-17 y, s' @9 K2 A+ {+ X
    void DFS3();: m$ x7 E/ H: Z7 ?/ ?# a
( y0 j# E/ f# X7 u+ ~7 B
    void BFS();8 v, K, ]# f% }- K- y
    void Show();
' X+ j; H" j* P- Y& ^};" H" {3 Y+ c' O/ z+ O/ u: L
, _- d# r2 M! [$ u
2.函数的实现+ c# C& p8 g! w' b) J7 ?
研讨题,能够运行,但是代码不一定是最优的。
; i* j  m+ H! f- o/ P- I/ j) B5 C: [( }- r5 G7 `; U- h6 g6 G
#include <stack>
0 e' O% _- c" }; f) t, S0 x#include <queue>
. X+ B  G) W4 ?& j4 b
6 c5 G) x# ]# E/ Atemplate <class ElemType,class WeightType>9 b* F( c3 ~) ^, A) e6 y/ |3 L
MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
& x8 s- p) ~, U  M$ D  g{
- `3 k- @$ Q6 `9 P& B; L3 E    if(vertexMaxNum < 0)
* l1 E& e' ^% l; {* q        throw Error("允许的顶点最大数目不能为负!");
  r9 Q' P' }% Q( F    if (vertexMaxNum < vertexNum)
2 y/ x( \5 `# `: y7 N" O% r5 A        throw Error("顶点数目不能大于允许的顶点最大数目!");
8 Q' O" I4 [6 C( B- {2 b* K    vexNum = vertexNum;9 N! }: ~' \9 {
    vexMaxNum = vertexMaxNum;9 l: Y2 X/ d& X3 |
    arcNum = 0;
# h4 x, X. ^* ]& f* u    infinity = infinit;
. f$ v! e% g/ y& S" q, J    tag = new int[vexMaxNum];0 L9 I4 D& H' k$ v' u% ]! j
    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
4 w# b2 B. a6 w. A1 }/ u! Q    for (int v = 0; v < vexNum; v++)
4 t  r  _4 x3 G    {( ^- F; v' o) S0 W" e/ |( Y
        tag[v] = 0;$ c, j: c( q6 r
        vexTable[v].data = es[v];
- {( j. S3 H  H" j- t: w( S  y        vexTable[v].firstarc = NULL;* Y3 R* G; j) x- ?0 F9 u
    }: Z2 t1 ~. p, ~2 a
}$ b, f& f5 D" d. {2 ]
template <class ElemType,class WeightType>" N. g/ }0 t# Q2 w8 b! ^
MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)) n  V7 D; t. A2 K9 H+ Q3 c' f
{9 Q# e4 ]5 A' e& d- \$ Y4 }
    if (vertexMaxNum < 0)& J9 i' I; \, l9 _% r2 R4 v
        throw Error("允许的顶点最大数目不能为负!");# b$ H! _+ w' ?7 F( c) c% M2 C
    vexNum = 0;
( i" u! m7 @+ j$ C; U$ q    vexMaxNum = vertexMaxNum;& t2 g4 E8 S0 @- O5 e) D1 Y) W
    arcNum = 0;
* E! M  y* M0 Q( z% Q& G# T    infinity = infinit;
7 x( |0 p" j) W- F3 q; E( M    tag = new int[vexMaxNum];0 x2 F# T4 |  V+ N
    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
, O/ g$ A0 \3 f}
3 V% {: |4 y% Y! K" r, o  F" f3 u, gtemplate<class ElemType, class WeightType>
: @3 O5 s2 d' rint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
* b7 S% M/ I* Y- {" g( U{
, H) o# D: K0 p7 o: [4 S# g/ [! X    if (v < 0 || v >= vexNum)* U2 d) B, H  M2 I
        throw Error("v不合法!");) D. r5 n1 \% U- ]
    if (vexTable[v].firstarc == NULL)
3 j) M; j  R/ F6 S9 o8 I9 c5 T$ q        return -1;
! k+ e6 M5 x7 K3 u4 \% ?3 ~1 s    else0 S- J$ o$ q, F( P( T0 g
        return vexTable[v].firstarc->adjVex1;
% ?. ]& w5 I4 @) |8 d}* ]& {. n1 K% _% B: f

* F/ |$ B  d* }; R1 ^4 @3 o: dtemplate<class ElemType, class WeightType>9 G- k" g- z) i' {" m
int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const& v( E- g  g1 F& d  a
{
/ W* M2 M# z9 x2 g    MultiAdjListNetworkArc<WeightType>* p;
9 U# H" j' O5 ?    if (v1 < 0 || v1 >= vexNum)! l& R" t3 S/ z# y
        throw Error("v1不合法!");1 x0 O1 L0 |5 _5 }
    if (v2 < 0 || v2 >= vexNum)1 L5 t6 W8 [0 i( z6 F0 m- c* @1 v
        throw Error("v2不合法!");
- J  P4 t! E- S    if (v1 == v2)
6 f% k: l; U' C& A4 r% z( B- S        throw Error("v1不能等于v2!");1 R. u" Y+ I9 \0 b0 g
    p = vexTable[v1].firstarc;
* M% m  b0 M4 d9 b- L) B# H    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)* C6 G3 n; L7 i0 g6 |# l) Z0 j
        p = p->nextarc;5 ?. V- {3 G3 d; p
    if (p == NULL || p->nextarc == NULL)
$ X! Q4 `5 l2 z9 S! B+ X+ Y+ V        return -1;  //不存在下一个邻接点
* f2 E  V3 P7 \: Z; s. i' Z  U" z9 Z0 m    else if(p->adjVex1==v2)
& p4 m' M* n7 Q* F% G% V        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);. p" d5 i( x) D6 Z' e3 T
    else
2 A# D. Y! J2 o7 }' B  u% k! @        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);8 e$ `$ B: T6 D8 @. Q# q
}: H3 D8 }6 I) Y: D, a3 _
template<class ElemType, class WeightType>
# A5 R+ ?6 v, j1 S' @void MultiAdjListNetwork<ElemType, WeightType>::Clear()
( M, B  s( V( k, E$ m; N{
! s! `8 G/ V1 E: X    if (IsEmpty()) return;
1 x3 T! r9 ~5 I" }% `    int n = vexNum;
2 C0 x  s* `. O7 S. i# f8 J    for (int u = 0; u < n ; u++)) y* A3 P' l8 h% R' Y% q: x  ^% F
        DeleteVex(vexTable[0].data);6 p0 `5 g" J% t
    return;6 D$ g* d- z! D5 u2 L9 E
}
. _3 n% o% y5 }template<class ElemType, class WeightType>
" |. C9 _3 }3 [; pMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()) {: q# S0 T2 N
{
! X% C! H, [; C& a  m8 K$ w    Clear();
% K" E3 g6 o- Z5 Z; @3 v}" a" n7 h5 z1 t) O$ D
template<class ElemType, class WeightType>
# s+ J0 R# b7 x) b/ w, vMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
% Z/ h; S+ w* o, q/ h5 L' y{3 h4 k  d1 y- v/ J3 s- G, }
    vexMaxNum = copy.vexMaxNum;
( Q0 |# A% [9 y/ p, ?    vexNum = copy.vexNum;
. `% h( y( C. z$ Y) k) M& F    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];1 V0 r4 M6 g+ S- j7 {1 R$ C
    arcNum = 0;
5 ~- c1 n; T7 X, E" z& i    infinity = copy.infinity;
1 W+ c7 J. A8 f* O9 m" o& @    tag = new int[vexMaxNum];
; k0 K* F0 K* ~% w4 q) _9 ^) t9 o
    for (int v = 0; v < vexNum; v++)
+ k+ ]( R; Y- M1 h: s    {5 s$ {4 x% W8 f7 G6 G3 h" O
        tag[v] = 0;) R8 t: V7 a9 s" T: s
        vexTable[v].data = copy.vexTable[v].data;
8 H) d% C- A4 D$ ~        vexTable[v].firstarc = NULL;
0 E" S+ v- \; |# V. a& R    }% t" e; A. M/ X" A
    MultiAdjListNetworkArc<WeightType>* p;3 s' I5 q' q6 [* T# s. w" k
: H) z/ @' V* z8 I- }
    for (int u = 0; u < vexNum; u++)' S4 N5 \5 {& y9 z/ x
    {
& T; F' {* ^1 Q: T, k% G        p = copy.vexTable.firstarc;
% d8 s/ X4 s" Z: y3 y        while (p != NULL)) V1 l7 n) g7 A) F' h7 K4 u
        {0 r; c- _  |* E( T  D  o
            InsertArc(p->adjVex1, p->adjVex2, p->weight);, f' S" A5 H3 w# F! o( n) k( D
            p=NextArc(u,p);1 u* e7 r& k0 V1 S$ j# w
        }6 |4 B! t/ f* s5 }9 |. ?6 V
    }
, @0 y# P! ~8 H) x4 y5 z}0 v# d1 Q5 `, p! S0 x
template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&" ]/ `! H- j, q0 G( C
MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
' X3 b% O, [, w8 D# k1 M8 F{
! T) H. P- E+ g' S8 d+ p    if (this == &copy) return *this;
' e/ P3 g' u% K( [- i: N0 {4 ^    Clear();5 c  T, L* Q+ R/ J2 U. `
    vexMaxNum = copy.vexMaxNum;
, f3 H9 q* J  s! H9 W    vexNum = copy.vexNum;
3 `4 r) Z8 U' q7 b    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
! v$ E& @9 @1 y. i) h1 E2 g' Y    arcNum = 0;
0 e2 ?6 e4 y1 L$ \    infinity = copy.infinity;% o" X' ?/ F; ~; A" B
    tag = new int[vexMaxNum];/ u( X$ E. R7 \8 ]
- F6 h, b( q% R$ G( s/ L% c) Z
    for (int v = 0; v < vexNum; v++)8 h' X# i9 X8 f0 [6 n1 t3 N) D1 N
    {
6 J5 T& w% p& P  k        tag[v] = 0;
6 u3 Y; A. r% Q( S3 w& Z& g        vexTable[v].data = copy.vexTable[v].data;
" r4 L+ i' B. T4 G  L+ W) R: A2 ~        vexTable[v].firstarc = NULL;
1 i* l& b4 ~; }& M) ~% b    }% P  z  ?$ `/ H+ E5 y$ T
    MultiAdjListNetworkArc<WeightType>* p;
- S2 a( ]  S& s3 i" F
, a+ v( j* r# v, s' [: [" W3 S    for (int u = 0; u < vexNum; u++)
6 Y; Q/ {2 y6 r* e3 B# d    {  y% }( o" v3 }3 u
        p = copy.vexTable.firstarc;- I5 @% D& M+ G- Z  e) Y
        while (p != NULL)* u, x" i6 e. w" Z' d" i: \
        {
  o$ x) r) }4 q. B            InsertArc(p->adjVex1, p->adjVex2, p->weight);$ ~! o; t" D8 a( y+ b2 u) t9 a
            p=NextArc(u,p);* l% O! d$ D7 [! R6 E* T
        }' M0 k0 n/ ]# E6 i
    }2 J( L% i6 F4 o5 }4 m
    return *this;
1 o, j8 l. b( Z. [}- f' ?  ]0 ]" G* K) o
template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*$ |7 `- _2 @  \' _4 C
MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
' }5 f$ K) G; e! k  [8 V" e. @{8 R, ]4 i' p9 e! |+ D' J
    if(p==NULL) return NULL;0 Z; W2 W# _- t% s3 d! _( i
    if(p->adjVex1==v1)2 W& T: d0 ^$ |) v
        return p->nextarc1;
! `9 W" T8 o: w  D7 ^0 z. C    else
0 J- M6 M5 l$ H) U  _) U" X        return p->nextarc2;* F& D; m3 L) p' D! {7 g* c
}
$ s* K; C  O) |- U' m. \' vtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>** o. z) O# U6 y9 ], I
MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const9 |4 j' `% n2 h* U$ n4 r
{
( O; h0 D6 L# |4 j5 w$ y    if(p==NULL)return NULL;
+ V( X; u  b$ n) V/ V' D" w0 f2 m    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
. {' K- U3 n% u9 X    if(q==p)
4 [, Z% t& n) i1 P3 e! t; Q  h* R        return NULL;
: q' X& N$ _2 t( ?. `    while(q)
+ ]4 [1 o+ k! e: I  c8 F/ A0 y$ y6 n. J    {; f; Y3 W0 H0 ~8 Z5 B4 [2 v  O  ^
        if(q->nextarc1==p ||q->nextarc2==p)6 c( P- C* K; H# }9 c
            break;7 \. J4 I1 ^) X5 B# `9 M* l! O
        q=NextArc(v1,q);
2 A* C* H! m' h. Y' h. {/ E0 J    }4 {" b" M( M9 Z9 P
    return q;
' U2 w) E+ e$ G2 e- j/ m4 \}
( Z# B! c- |, _6 C# M- d1 wtemplate<class ElemType, class WeightType>
( F- S: F& E; \3 O9 ]) q2 _void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d): R7 x5 t+ r9 U1 W9 T) o
{' h' @4 m9 ]  I
    if (vexNum == vexMaxNum)
4 y. p8 S7 M6 x9 C        throw Error("图的顶点数不能超过允许的最大数!");
6 d& D& j" m7 @9 ?7 ~+ b% L8 h    vexTable[vexNum].data = d;% T# f% v, V: o5 K* Y  R, o
    vexTable[vexNum].firstarc = NULL;
8 Z3 v; S% S* k8 `    tag[vexNum] = 0;
$ h9 ^  J% H1 J    vexNum++;8 b' o! f- I8 L# j
}
  _1 v, P0 o/ H) V4 g9 mtemplate<class ElemType, class WeightType>6 e; u* ]4 c* B6 ?7 J. O
void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)0 k0 D8 u' Z$ o$ ], n) d; e
{) X) |* H4 V# f& p0 K
    MultiAdjListNetworkArc<WeightType>* p,*q;6 M7 }# |; l; Y4 h
    if (v1 < 0 || v1 >= vexNum)
- \% h+ V$ c+ v+ J+ K0 a        throw Error("v1不合法!");+ |; @; H$ ~/ c  v* \7 ?
    if (v2 < 0 || v2 >= vexNum)3 J4 u. j, v. z5 B
        throw Error("v2不合法!");
5 ]) S. C3 [2 f* S  w' T    if (v1 == v2)
& M4 }1 F1 U# }3 k        throw Error("v1不能等于v2!");
4 x5 ^" j5 Q$ Z8 o& a$ Z0 j- U    if (w == infinity)* f5 ~7 m$ S! k& B7 s( ]9 q* K- E8 k
        throw Error("w不能为无穷大!");
$ [# j+ L$ o  Y0 i7 m# p+ r" }
9 l5 c' A% _+ T# \7 `+ P) I* q5 F# a9 s6 w  M, {9 x
    p = vexTable[v1].firstarc;5 u2 i# H) b$ ~  u, F7 E; s
    while(p)
, {* P0 D0 H' L1 H) M    {
4 c1 \: B/ Z+ F8 ]$ N- Z        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中$ S  t8 d7 N( Q* q
        {
6 a; F# h: f  [, |  V9 O' s2 v            if(p->weight!=w)
9 O7 |3 L% z9 h( i  O# k3 z6 o                p->weight=w;
5 d) m# j% f6 {: Q            return;
! ]/ U# |. a5 Y; C. I        }# E5 J9 j8 T  v8 f

: H* m, @# Y7 S5 [# ^& E        p=NextArc(v1,p);
8 Z* G. V$ a  f    }, [% }( J# o  \5 e! k( i) p1 M$ p
    p = vexTable[v1].firstarc;4 f. n1 G; T- }: c, z/ b; b
    q = vexTable[v2].firstarc;
& C+ T  g  \8 |1 K% y7 f    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
& [8 f4 S* o- x    vexTable[v2].firstarc =vexTable[v1].firstarc;. }& ]9 Z" ?: o" q1 u+ h* m
    arcNum++;6 f  q; g9 X1 C( E2 _/ z
}0 k" ~4 J$ m$ S# X4 R

6 ^. c- ~' {6 v/ @template<class ElemType, class WeightType>5 H8 [9 [# U- \1 r- v
void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2); b3 H/ Y) P8 o5 B; M8 K
{
, }7 i- P* M2 I6 I/ g1 i( l) t; w1 }3 ]: W% B% W) H, f
    MultiAdjListNetworkArc<WeightType>* p, * q,*r;5 n& q+ g7 L* @4 b( r3 w. m
    if (v1 < 0 || v1 >= vexNum)
! ]8 f( A- F7 k( ~- |6 e        throw Error("v1不合法!");
1 \3 A/ n$ V: B. E    if (v2 < 0 || v2 >= vexNum)4 ~  w& F8 S0 m, J; m. I
        throw Error("v2不合法!");
( g  \5 }$ B: P6 Z0 I3 H" r. n    if (v1 == v2)8 ~6 H, p: B; e; M4 e# S/ s
        throw Error("v1不能等于v2!");
( Q, h, s( a& H1 p5 a/ M/ E2 J2 U, z4 W6 l! P; u! t$ E8 p
    p = vexTable[v1].firstarc;$ b' a" t8 f' v; H* c7 k7 f
    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
4 |- U$ y8 P$ P* X# X    {
- K. v5 {0 X/ |; T) ~/ _        q = p;
1 D) C4 Q$ N0 F/ H        p = NextArc(v1,p);; @1 `! V3 p5 x- o0 z3 V
    }//找到要删除的边结点p及其前一结点q
4 t, C& P2 `  M2 z' u* P- w1 ?
" @: t, U4 P2 E: s! A    if (p != NULL)//找到v1-v2的边
/ J+ ^; l: h% q3 M. Q/ x  e    {
0 Z$ t( e' i; }7 u1 T        r=LastArc(v2,p);6 R' s; b- F& {( O4 o* f# d* |
        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL7 k3 H9 P+ ^% E& F, \0 j5 c/ ]8 M
            if(p->adjVex2==v2)1 e: m7 D$ r% i9 ^+ K
                vexTable[v1].firstarc = p->nextarc1;
1 ^9 ~9 _' R9 D            else vexTable[v1].firstarc=p->nextarc2;% {% f! x: b$ f9 L7 Q! p, W
        else//不是第一条边) F/ x3 Q( ^: y5 ^( v9 {
        {
. K: }3 S+ v0 ?9 Z            if(q->adjVex1==v1)/ J% y# x8 O6 I8 Y) R( O
                q->nextarc1 = NextArc(v1,p);
7 P$ \4 i/ H+ y! w            else5 ^3 @; }4 J) Q
                q->nextarc2=NextArc(v1,p);* b2 P2 i# b; Y2 ?( Y
( t2 l  ^  z$ d2 i' ]
        }
8 a7 k# q! K7 F: y: z        if(r==NULL)4 f5 R- v; _1 U) E+ S5 M3 {
            if(p->adjVex2==v2)8 K/ l5 `: q$ ]# f
                vexTable[v2].firstarc = p->nextarc2;
; o+ t+ }: F6 Q9 w            else vexTable[v2].firstarc=p->nextarc1;
& m% R; l/ b% e0 `        else
1 Q7 M  b; Y- ?2 k3 ]        {: m2 r2 M! @+ `: {: s5 _- z
            if(r->adjVex2==v2)
# `. h  }8 ?! {" x+ X7 I# Y$ x                r->nextarc2 = NextArc(v2,p);
; v1 R  d" Q, u5 W* c" t. j- v            else
; i/ v0 P, Z$ u" ]. U# O                r->nextarc1=NextArc(v2,p);) y: h# c+ f) A4 j2 C# }
        }: r' b3 D9 F% v, f% t" y
        delete p;; I% H, o, q& j! w. L# \
        arcNum--;
7 O) O2 m8 O+ s0 ^; C5 ^% ~" o    }
6 @* B; ]0 r# m& g/ ^2 z' y8 T) q& G0 L: h- B: ]+ ~, Q
}
- ^$ G% R! _" p; Ttemplate<class ElemType, class WeightType> void' Y" e5 i+ I9 W) g" t0 @1 ~
MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
$ Q2 e" f) F' v) ^{, G# |5 b! i5 s* p- o4 @; a. I# H
    int v;" L2 S# B! h; q: Z  s
    MultiAdjListNetworkArc<WeightType>* p;
" c- i- n7 q/ g& ]    for (v = 0; v < vexNum; v++)//找到d对应顶点. k' k* e  O# M5 W* i6 H
        if (vexTable[v].data == d)4 [4 U( G! x7 }# U* S+ a
            break;% {, Z' \( z/ g' G) W3 B5 E( \! f
    if(v==vexNum)3 D1 ~  L; v1 K# z3 n
        throw Error("图中不存在要删除的顶点!");( q5 R% l7 R; Y% A& n( L( U

# h- ]2 y' U% s, `: z    for (int u = 0; u < vexNum; u++)//删除与d相连的边3 T( p' q$ v; M# g% ]4 u/ l
        if (u != v)8 ]1 |7 F/ E/ g1 I; L4 L! _
        {
/ I/ Q  A4 K* ?7 v% t* D            DeleteArc(u, v);
2 D" u& g$ V8 U        }
8 d5 \; W$ @7 J, @    vexTable[v].firstarc=NULL;
% N* n" U6 ]" v) M4 y# r
. ~$ I9 I2 x) n* N  J/ z% ^    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
7 u# K2 e0 k8 y0 C    vexTable[v].data = vexTable[vexNum].data;. [3 g. G7 |* N, V
    vexTable[v].firstarc = vexTable[vexNum].firstarc;8 g' P' b3 X: S* j8 C) t6 s
    vexTable[vexNum].firstarc = NULL;
) Q, z6 |( B$ @8 ?    tag[v] = tag[vexNum];6 W% t3 R+ j5 ^9 d: O  [, Y
    //原来与最后一个顶点相连的边改为与v相连0 q/ F7 A) ^7 Y" R9 C1 b
    for (int u = 0; u < vexNum; u++)6 b8 I* f( z! }9 r
    {
( d$ |  D$ a1 e! U+ `+ q8 G        if (u != v)
! T" {. z7 {/ M        {+ `/ x" u- e$ \
            p = vexTable.firstarc;
& i/ O* h4 |! n2 n. B$ O+ O; m; \            while (p)) v3 U  E) d8 X& r: s
            {% H0 Q4 |# a) T
                if (p->adjVex1==vexNum)
+ D0 D4 ~/ A" f                    p->adjVex1= v;" y; H1 \+ U; `& n* _. @5 U! I
                else if(p->adjVex2==vexNum)' p" H& L7 F; x# `
                    p->adjVex2=v;/ l* P8 x) U' @+ f; {1 L* g6 D# ~
                p = NextArc(u,p);
3 S6 j$ ?. k. _* [            }' c+ N) N) }3 P; f: u
        }9 H6 f2 p' W# |
    }
) r% o' B7 F0 i6 L1 N5 \' z}
8 K# l# h5 i- [1 }///深度优先遍历
! d1 P% {% A; c+ [& w4 J. dtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)  t! ]9 j2 y4 s8 D: \5 j
{
, `4 z' F8 {/ N3 P    tag[v]=1;
- s6 `+ i; j# R2 w& g0 g0 u    cout<<setw(3)<<vexTable[v].data;2 d5 i0 y: D& a- ?0 W( Q8 {
    MultiAdjListNetworkArc<WeightType> *p;( z! A! E$ q+ j+ x) N* O- E
    p=vexTable[v].firstarc;
* k" U  w4 O/ U0 ]+ ]( D    while(p)
$ C6 I6 A" k* t! U" J% P/ b    {
% W9 @' [0 _3 G! a        if(tag[p->adjVex1]==0)! X; W; f" h6 r4 f7 [1 M, N
            DFS1(p->adjVex1);# H0 z4 J2 z7 w
        else if(tag[p->adjVex2]==0)
1 X: A  A5 i+ H" y  o            DFS1(p->adjVex2);" i; Q+ T4 w2 \3 e1 C/ j! C+ s0 v
        p=NextArc(v,p);) y6 E( E5 \0 Z, U6 [( J, }4 X7 e
    }
& J/ K# v$ S  {- }% r+ C}
$ x+ F5 `3 }" I0 K  Itemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()4 m8 K, {  }* \, z  Y& _
{: `* p8 h- p3 X1 x6 Z8 u% b3 i
    for(int i=0; i<vexNum; i++)+ A, ]9 W/ C' d: v( Z2 H8 x0 [6 G
        tag=0;% B1 b! ?2 B" s- ~/ W
    for(int v=0; v<vexNum; v++)
5 y3 R7 w  N. B. H% k8 v6 {) ~    {2 T/ S6 `3 N% U
        if(tag[v]==0)
! y' x# D  x% [2 b            DFS1(v);
; w: A1 n1 l* X9 d! o    }
' `1 k/ a9 M# _5 c}
5 ^4 j2 r* h$ g! R6 {! ytemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2(); ~) P6 N# j" T, U: j  x0 e! S
{  l2 c7 f# @, R. @2 \8 v, m
    stack<int> s;
) H5 @  e' ^' C  l    int tmp;
, w" f# Z4 X& j3 W; c, [# V    MultiAdjListNetworkArc<WeightType> *p,*q;1 C! e0 r$ l# U. }, n5 e
    for(int i=0; i<vexNum; i++)
/ }7 i- J1 u$ d8 B        tag=0;, m* Q  s! {/ w; F! i8 R
    for(int i=0; i<vexNum; i++)% D' a7 x' l- b  F7 E3 _5 w0 b* J
    {
! A9 R! x5 y+ b8 K        tmp=i;
9 k- H' P  B$ a        while(tag[tmp]==0||!s.empty())( P. i7 x* W% n( }' {9 X% q) \
        {
8 g/ ?8 c9 e" t! s3 N& _* k            p=vexTable[tmp].firstarc;1 w' {' q4 g& m7 `) J) L7 d
            while(tag[tmp]==0)8 P1 _1 J# ^! Y
            {
7 O" S5 o3 c+ D$ Q9 c6 l) g& b                s.push(tmp);
( v/ s* u5 q' G2 p$ l$ `/ I) \                cout<<setw(3)<<vexTable[tmp].data;# y0 w7 c% l5 m2 \+ @# z0 z
                tag[tmp]=1;2 W, Z( _! v- u9 @
                p=vexTable[tmp].firstarc;
' {" S, k6 c: e                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
8 y, O$ o; c1 T2 e) q+ n                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
$ t& w/ H: H  b5 s5 z9 k                //cout<<" 1st     tmp="<<tmp<<endl;
5 l2 P7 p0 ]: z7 c" s            }
6 S( Y. X; T5 t% `: m$ g* m            if(!s.empty())
( N* m, S! t6 H5 O/ v# w7 }2 \            {
6 K; H5 R$ a8 E) _& z# o, t+ T1 f, m3 \                tmp=s.top();) f) ~3 ^  l' h( z
                s.pop();2 I' {4 z- Q, [" J5 b1 H
                q=vexTable[tmp].firstarc;
, {% r* v( D; [$ T6 v                int t=tmp;; J4 p* _, G5 ^3 _; M+ |
                while(q&&tag[tmp]!=0), |7 C. _3 ?1 L+ ?
                {
1 u' S& L4 Z+ u* F                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);0 m& [+ t# `/ j- {( |
                    //cout<<" 2nd     tmp="<<tmp<<endl;
* ^' V4 d  L- R/ N                    q=NextArc(t,q);5 i' }8 l* U: }/ @  O" m% t: f
                }
5 K! k2 K) Q$ h- t# P* g                if(tag[tmp]==0)
) @( ^# n% U5 ^2 q                    s.push(t);2 S1 u$ u2 S$ x  ^$ A$ j
                ///1、对应上面连通分支只有1个点的情况
) v, }& K* ^6 R& H1 s/ q3 ]  j                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
6 r) i# o) q  F; D. Z                ///tmp要么等于找到的第一个未访问节点,- _2 D7 n5 z6 K; s3 W
                ///要么等于与t相连最后一个点(已被访问过)1 p, {/ p$ A* g
                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
1 g% I# y+ m* `* d" A# a( {8 g            }
9 G# J& ]4 ]$ O0 B1 G0 r* e        }! z4 {. l+ k! N; w0 J
    }$ e! b8 i1 @0 X+ e6 I7 R. R; x
}9 }7 b& v0 s" L3 s4 {' D
//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-17 I. F# S; \, J, @' f/ t/ a( W5 H: t$ ?
template<class ElemType, class WeightType> int1 `8 W# {" @, n2 S7 K
MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
: k# `' v; o: ]{
, N) o6 T8 x: x8 N2 j6 ^' j    if(head==pre)
' U. w1 `; g; B* P) c. K        return -1;
' }  F: x; l0 l& f& V/ ]; ?4 g/ R- D( C/ ^
    MultiAdjListNetworkArc<WeightType> *p;  l0 u/ ~4 H$ O( f
    p=vexTable[head].firstarc;
, s* Q' \$ F! F. u6 Q    if(pre==-1&&p!=NULL)
+ [  z/ D# e3 j# B8 L  h        return p->adjVex1==head?p->adjVex2:p->adjVex1;3 G/ x: {7 ?7 F! j9 e. Y
    //pre!=-1&&p!=NULL
# T) P. J' O0 }, k* W5 b    while(p!=NULL)
) B3 D8 G+ k7 R! M    {2 C1 `) j; ~: M. V, O+ O
        if(p->adjVex1==head && p->adjVex2!=pre)4 b0 O& ~3 `, m1 y: p+ Z
            p=p->nextarc1;
$ f' k: J4 g3 I8 V. W0 G        else if(p->adjVex2==head && p->adjVex1!=pre)4 Z- Q1 v- J6 _
            p=p->nextarc2;! N4 N5 [  M3 X$ R# r1 I
        else if(p->adjVex1==head && p->adjVex2==pre)
5 d: X! s7 U! d5 c% [, s        {
+ h4 s% t: w9 x4 C2 r5 h            p=p->nextarc1;
- s1 K" {& J" t( e            break;
: Z9 v* T4 e- w; E" i- a+ _        }
0 L4 w, E: M! Y6 C' U        else if(p->adjVex2==head && p->adjVex1==pre)  h5 R! W* E  y
        {
$ m6 e! \6 `# E  Z$ C# y+ w            p=p->nextarc2;, S: F4 {7 W7 a! a
            break;
, j7 n/ X, w* B7 i! U* R/ F        }/ H" o* y+ t$ v4 r9 }$ G$ H
    }, o7 B4 e* h2 W
    if(p!=NULL)
- S' J& U1 g8 E9 C    {
, x2 h9 N% u6 o1 n+ C        return p->adjVex1==head?p->adjVex2:p->adjVex1;
! i2 Y( U! o+ Z5 [7 _" p, O    }
: G/ ]2 a# h( L% f    else9 g' f) \/ b  K* {- N
        return -1;
0 M5 L( A, N5 `, F9 g}+ w) L5 l8 v7 O' c$ F- ~

% W4 S6 s7 s3 z
# L, b$ s/ F# ~4 _template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
, Y3 H  G7 t7 u5 @; I/ v; Z( j3 Q6 b{  K" O' ^- S7 y% U  v
    stack<int> s;: n+ t' g) b7 P4 @4 o* ~8 @9 W. E
    int p,cur,pre;
# s; y7 {+ C& Q0 h; J$ s    //MultiAdjListNetworkArc<WeightType> *p,*q;
4 W; O! v3 h  Y8 o    for(int i=0; i<vexNum; i++) tag=0;//初始化
( o9 U$ L9 d# N1 H9 u; [
3 ^% C0 Q: o2 c8 e    for(int i=0; i<vexNum; i++)
% p; x( S( Q- b    {
7 Z* v) c  V& A! Y        cur=i;pre=-1;" G, s8 ?, F6 H2 C5 E1 N4 G* }
        while(tag[cur]==0||!s.empty())  S! H2 i4 n" w% [% }! c
        {8 ?, N$ }# Q# M9 d  A& h5 ~
            while(tag[cur]==0)
; A; @! m; V/ R1 l6 r            {
4 |. M2 |, F& q  F                cout<<vexTable[cur].data<<"  ";
& k8 G6 m( T2 a; b5 j4 _                s.push(cur);0 {3 t9 w9 g, a; o
                tag[cur]=1;& U! v8 v! O6 M! J
               //初次访问,标记入栈6 k2 k( Q% q( u- |
2 u7 x+ q0 R$ ?, t
               p=GetAdjVex(cur,pre);//p是cur的连通顶点( R7 T: q" d# e
               if(p==-1)
% L; n  }' I- I. x/ {               {
# `2 m% t$ p2 C6 Z, t, \                   pre=cur;s.pop();
9 R+ e( X4 J0 Z6 [                   break;- g* O+ x! [4 _7 K
               }
$ {' p# [# X3 I               else2 r' s& {# \- \" u7 A" G7 V
               {/ \! z: N* G' n2 B/ [
                   pre=cur;/ V7 u+ g, Z+ [* t
                   cur=p;9 e! ]) L: M' S
               }
, b. s4 a$ ]$ p/ G& Q9 ]2 ^2 }1 z  ^/ r" o9 y5 p8 R
            }
) `1 t; i1 I# d. O1 h8 d6 L0 J            while(!s.empty())) i, H* K7 ~, b6 v+ p6 `
            {
9 p- n) a+ P. M7 w0 V/ ^                cur=s.top();
; G8 P& @! S8 I; g5 C  _                p=GetAdjVex(cur,pre);3 |9 M: `3 K: q' I; i+ i
                if(tag[p]==0)! [+ b( b$ Q* Q0 s" s$ ^1 B8 z: D
                {
- e$ h. u: N  u  N; U                    pre=cur;- W- Q- t: i; w" P4 y/ @% `6 n0 Q
                    cur=p;8 a8 k! S. ?. C: u4 E  X9 W9 m
                    break;
* {- w$ K) J  _# y& t4 |" ^                }
8 J& q$ Y! y+ N! o  X+ `                else! J$ M" z3 i% U
                {
9 Z% t+ n/ @' W0 t3 v6 H% _                    pre=s.top();
1 i& \. \- M) v. W  L                    s.pop();& F% k( Q* ~! T% l! h
                }
' W/ o& z2 B+ @, g$ n+ b! P$ J8 Y0 X  [* T
            }0 ~) v8 `/ u0 T* _$ w, I# U$ `
  \7 ^6 \, i9 }, z3 s
        }" U. f& @1 m7 V6 r  S. F- B9 Z
    }
$ B4 X$ m+ y* k8 A) `$ M}+ u% B* C( j) }0 K; B. O5 y  u# u) c  |
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
. r. U8 }% v; |2 _0 M{
) M: A" \. o$ w2 F- v% k# N/ K    for(int i=0; i<vexNum; i++)
1 `- W. O, e# Z/ J$ K+ l        tag=0;
& H4 I4 \& U( z9 H5 e    queue<int> q;
, i% O9 |& [" s4 ~    int tmp,t;
8 t! f/ c- X/ Y& R1 r    MultiAdjListNetworkArc<WeightType> *p;3 u( x# }! ~: J2 `4 J9 z
    for(int i=0; i<vexNum; i++)
2 O+ M- ^5 n. I3 `& Z2 ?    {0 b/ Y/ A4 r7 ]/ W  _5 g9 l* K
        if(tag==0)1 E* b5 Z5 {3 G1 [0 ]9 M
        {
( q" r; h5 {9 U* c6 q" d            tag=1;
, ?, ?2 A+ h; p! J            q.push(i);
# N) o0 j# z( B+ ~8 J            cout<<setw(3)<<vexTable.data;
7 X2 B6 V7 m/ v7 ~9 N0 o        }0 A# W; ]4 f/ u# d
        while(!q.empty())
& U- H( ?$ a2 j- `+ X; z6 }9 w) c        {- k4 Q5 n; K' ]9 d2 S  L( Y
            tmp=q.front();1 r& @: J& x: c* E2 L
            q.pop();/ j% u+ e" e" S2 d& Y5 M. O
            p=vexTable[tmp].firstarc;
4 g( [$ g2 f+ h3 k3 K+ `9 k            while(p!=NULL)
9 ^' j* Q# s: p+ O' T; ?            {& j; b/ x( m/ C: r  F
                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
5 Z1 R/ K% S+ e. u                if(tag[t]==0)
& N9 }) i! M/ B  s                {
' m" k, }/ H. k* `  T% Q4 o( d                    cout<<setw(3)<<vexTable[t].data;. v+ d5 a* I" p& Z  j+ p- g
                    tag[t]=1;
  B2 N4 K! i$ g- T" X                    q.push(t);. k  y: Z1 w0 K6 ]7 W
                }
7 e7 b5 i% L3 l+ C; v( m0 J. m                p=NextArc(tmp,p);+ c% M2 |7 [5 c8 o- B' t* |
            }
3 N; r0 K$ q: n( O7 T        }  \/ t0 m4 L# G( z8 C. c( g& d# \
    }  G% d, P1 E) j4 R8 \
}
2 j2 L! W( e* R" R' Ztemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()1 h0 O& H( R  B9 O& T
{% D4 k. `. H' C- u( e9 t2 p
    MultiAdjListNetworkArc<WeightType> *p;3 B6 t. ?) L$ Q, I
    cout << "无向图有" << vexNum << "个点,分别为:";
/ D0 G; T. b6 d4 L    for (int i = 0; i < vexNum; i++)
- l* t- X& j! \6 T9 R        cout << vexTable.data << " ";: S7 J+ O4 z; j' X
    cout << endl;% l2 V+ T' c  H3 L6 k  s* z
    cout << "无向图有" << arcNum << "条边"<<endl;
5 L, v# u4 W, R. i/ y' C    for (int i = 0; i < vexNum; i++)
* w8 Y, K- G% @) H    {
4 ^1 f) S3 H; F5 [0 U5 u; y        cout<<"和" << vexTable.data << "有关的边:";
7 `6 j5 K6 Z2 ^3 |+ [. o3 j' z        p = vexTable.firstarc;
+ b) }- R* K% |& z! m        while (p != NULL)# j7 ]* s* i' z/ `
        {5 T- l7 m- F8 \" @  N' f- a
            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
* r2 u& i( ?+ ]; E8 B/ L: `            p=NextArc(i,p);
% d: A, z/ h" i! r# Z* m        }9 {  S: F/ @" ?+ O; r- {7 K
        cout << endl;
6 ~* V3 N( x( N  o    }& |0 M2 Y3 [* ^  K- m3 q
}& S+ E3 D8 b1 b1 K7 |" x5 a
, h8 t. I( l: E/ v3 Q

0 n0 |8 e! h( t( ~) Z邻接多重表与邻接表的对比
( b4 t9 G9 b6 G% w9 _$ O) b. l0 h
7 p1 q+ q! Q& Z: V邻接表链接
, f) J" Y4 d0 k# b& O% x  w1 q) T在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
% i% |7 c$ L. \* M. I7 |& n在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
: g; f& ?5 Q% K8 G8 G; b9 i为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。) V/ e7 g" v9 G
————————————————
7 b+ Z# z2 V( r6 n' r版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
  k$ s9 w5 [. M& S原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958* O( Z* ^& R0 ~6 h# a$ I. M8 S
# b0 I! ]. k+ g7 I& d8 M8 ^

' v& ^: r( J2 s5 \) X( E4 l* ^  u& a
0 G& \3 e* c" v' r6 s2 ^
————————————————5 M3 z1 h! k5 b6 _) b, p+ X
版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
2 e0 g/ p' A2 y* i( {& q原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
8 ^1 J; D! ~: K* @+ ~' v8 g2 U2 [4 ~! ?3 K; L3 L, w5 B$ H
0 Z3 X  S, S6 P- i





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