数学建模社区-数学中国

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

作者: 杨利霞    时间: 2020-4-26 15:26
标题: 图的存储结构——邻接多重表(多重邻接表)的实现

9 c* m: B. r' ]! N2 f& D- b4 ~/ l! L图的存储结构——邻接多重表(多重邻接表)的实现
8 v8 C* K5 X* P0 H+ a7.2 图的存储结构2 {8 o- |: W2 E
4 y6 k- D; z3 d' V  U. T
7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
$ s% Z* b' {' d+ `+ \邻接多重表的类定义% O: {/ P$ [6 [( G
邻接多重表的顶点结点类模板5 n) W3 P# H4 t8 d
邻接多重表的边结点类模板
) k7 |( d& c2 _' I邻接多重表的类模板: ]- d* g& N  _# C+ t+ }
邻接多重表与邻接表的对比
1 J7 O- C6 `6 i* u* |3 Q" s7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
8 k! Y/ T+ w* `* G( L# w
/ p, d% M+ q/ S9 N, x6 P7 [6 U在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
8 q" X; `* m! p( b! t2 b在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
0 v+ e4 L7 d7 D; P( M5 m, t0 B- g4 ~; o% r, N) ?8 Q
邻接多重表的类定义
7 n: Y& D# k: u3 `" o 1.png
9 f% {3 J" j) u7 D邻接多重表的顶点结点类模板

对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:( A( w3 k2 P' `/ o6 @. A
data域存储有关顶点的信息;
+ ]- v% y+ n1 m/ U6 {) c& g; Lfirstarc域是链接指针,指向第一条依附于该顶点的边。1 S' W3 u$ B' G! y/ U) Z0 _* E; T3 ?
所有的顶点结点组成一个顺序表。

; _& X. K7 f& J$ ]+ d

4 K  P7 s: d3 r, j+ Y1 n/ Ztemplate <class ElemType ,class WeightType>1 ?, T, c" F* _2 Q  C
class MultiAdjListNetworkVex- \5 U; x# }- e  ^# {1 ]9 O$ @
{
5 W% O) `$ a$ {public:: F- W1 g& _# R1 r  F- \* q
        ElemType data;/ ]  i( l0 t% i/ N
        MultiAdjListNetworkArc<WeightType> *firstarc;* T9 Q0 a& H/ m5 t' Y0 j+ q

/ z4 L" x" J3 P) e+ K, b7 [5 ~+ z        MultiAdjListNetworkVex()
1 |6 A* h4 L! N5 S        {
" {) b/ r) q# {. }! Y1 W# E3 U                firstarc = NULL;
5 G! r: ^/ r, E; r- R$ Z        }8 L( |! o) Y) I! Y8 W
        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)# G3 v6 r) ?0 k8 {
        {# j& X! z# E8 `! m* H
                data = val;/ M4 V: u0 Q/ P4 Z. X: X: d
                firstarc = adj;
4 C2 x! t8 }+ J" M3 z! j        }8 K! _* Q( r, H2 A( a% b- w7 h2 P: \
};1 S( d5 r, S0 @, e
7 y- q  p& g9 T+ z8 r
邻接多重表的边结点类模板
" I# \( K1 D( @' [: r& Z2 F2 M- Q
在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:; ]) v3 \  e# Z. K* B
tag是标记域,标记该边是否被处理或被搜索过;) o- p1 X7 r) d! Q6 O
weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;& I4 }, w5 `* @
nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;2 O6 @7 o2 @7 A7 R0 |
nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
7 z. y( f9 d  z9 k- b9 k) l4 u2 X( u
2.png 9 G% _* ~3 [* {7 y' X4 d( x
template <class WeightType>2 H7 ~3 q' s4 C9 P8 T8 `' e
class MultiAdjListNetworkArc
$ K" r+ W# \/ [{2 W8 d' a; s: L  j
public:+ U2 Q0 A/ a  l& w1 X
    int mark;                                       //标记该边是否被搜索或处理过
" }5 J# Y5 Z+ n3 }8 U: V( [        WeightType weight;                              //边的权重1 |0 }# c& p0 q- @: ^7 q$ p& v
        int adjVex1;                                    //边的一个顶点
2 G2 V% Y0 R: ^. M8 Q0 t        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
: V) H  b. _$ U0 |: H        int adjVex2;% @: [% d/ ^5 `# l
        MultiAdjListNetworkArc<WeightType>* nextarc2;
8 e3 M3 N; x9 F9 J6 i: Q9 P0 b; h$ H
        MultiAdjListNetworkArc()$ N0 P( A* d. C/ p3 ^5 U
        {
, R+ T. Y3 O" u  H                adjVex1= -1;
" M3 b3 h5 U+ H& q) I, v                adjVex2= -1;# p" b% r+ [: L, E, [: i
        }
, d5 ]) o! c# I1 }        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
$ O3 W. U7 i# h        {8 A$ A! u% q& |! u
                adjVex1 = v1;       adjVex2 = v2;6 ~# i, r2 k7 v0 V8 \7 @8 U
                weight = w;
( m) Z0 P1 ]4 V  r& Y                nextarc1 = next1;   nextarc2=next2;
1 ]8 _" }. V' l3 j% r! t                mark = 0;           //0表示未被搜索,1表示被搜索过
7 n6 e: v8 d: e- f5 R& ~        }4 t6 Q2 I$ f0 I# ~; }

9 |2 n+ b6 ]) w( x$ z邻接多重表的类模板

1.类定义

template <class ElemType,class WeightType>2 B- Q4 S& g- Y& m" W
class MultiAdjListNetwork
* s! ]9 [& ~& v{
' ]$ x/ b( S% ~: M6 p5 l) kprotected:# i, P. ?" R8 I
    int vexNum, vexMaxNum, arcNum;, w5 a& n4 M: Y3 r7 F5 |% a# {, }* o
    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;; h% e$ \' i+ [, F2 r# i" {* t
    int* tag;) G3 d: ^- L2 v3 e! B. x$ R5 W
    WeightType infinity;
# E& c) ^# ~! O% a% o3 c- F9 X3 b4 w8 a+ d" ^9 z( R
public:
' i: H$ d0 \7 I' Y    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);# H  u4 t8 B# Z* B8 M# v" b
( o  l, t, @3 R  ~$ g# ]6 i5 _
    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
. g: _* i3 G' [) @5 A( }, }: Z7 ~+ i, m& F
    void Clear();9 j! W% [- X1 w* K
    bool IsEmpty()
8 [  q' \+ T1 o6 N' A6 |    {) j4 M% K2 f* d" W
        return vexNum == 0;# N, J( o1 m( A" R
    }
6 H! J/ G# f: C    int GetArcNum()const1 k  N4 D# E7 v$ C  u
    {/ b( d) D7 q; e6 L. B1 y6 M; T
        return arcNum;
6 k4 b+ Z) z7 [: O    }* y6 o; ]: ^' q+ M' F/ O
    int GetvexNum()const: t$ Z2 ]! p8 I) H: N; C4 m. N
    {
, F# n# @: a6 H* z8 b& P        return vexNum;  D, N- k6 o7 c( v3 x
    }1 y; b/ V- w; f8 A9 r- F
) R$ ^; U8 _. n" ^  ^

  D; |; `7 c- X( J+ i0 A& F    int FirstAdjVex(int v)const;
& d( z1 D& i+ n0 R8 O    int NextAdjVex(int v1, int v2)const;
7 h% r" w. Q$ d8 N5 G: d    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;$ `4 A3 @- Q+ M9 v# ?7 `
    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
% Q# C4 E% r% N2 a6 P
& G+ B; n3 Y( e    void InsertVex(const ElemType& d);0 w  b6 a" h3 a/ `$ T5 f. W5 a: H1 j
    void InsertArc(int v1, int v2, WeightType w);$ \* h& T# m# i$ o4 A

" Z/ V8 K; ?. z6 _' [0 n' H& ^9 g    void DeleteVex(const ElemType& d);7 f7 k( ?: V) \* r
    void DeleteArc(int v1, int v2);
, l" }# {2 i+ Q3 X; _# F$ E# D$ c& A. v+ E1 i, ^  D
    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);$ h. O% D9 u1 @7 j( _
    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
( U' j  \, S4 x" B8 |* t# w' L2 v3 m8 ]2 z- \0 w  u8 k. K7 h6 S( [
    ///深度优先遍历7 Y6 ^! W  j2 L: y- P- b4 U
    void DFS1(const int v);* `  K* V6 i3 o; R0 H. C
    void DFS1Traverse();
0 b8 A! q4 J1 B    void DFS2();
. H$ w7 c3 y/ y5 F7 R: }4 L7 O% [) k9 T  o; L
    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
0 d* T2 q) {  I: K/ |9 X' z' S6 Z    void DFS3();8 w: s& C4 ?! G! c2 @+ e2 P- _

6 b% {& P- m2 S- _7 c# T& Y    void BFS();
3 u% k# `( E0 J+ c/ F# D    void Show();7 Y, F$ u5 [( c& U
};9 t9 A9 w0 q( y/ }0 ~

/ Z5 K5 M' c3 Z7 ?& h# Q6 h' R" Y2.函数的实现
9 H9 P+ k  k0 L8 K! F9 E# n研讨题,能够运行,但是代码不一定是最优的。
/ |1 i* O3 m! W" S) r: ~, W# c9 g; I! O7 Q
#include <stack>
8 P! c% R+ [9 q! C/ C, M# I#include <queue>9 u; Y% ~7 p8 f8 Y% U2 c' V( h* a
4 j5 G1 u% R) \5 I
template <class ElemType,class WeightType>; ~- }' x; p; |+ W6 D5 L- ?
MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
' i3 Z9 X0 a% T9 ^  l{
  }1 p; I7 |: Z- U1 F8 y    if(vertexMaxNum < 0). R2 M  i3 X, K* S
        throw Error("允许的顶点最大数目不能为负!");6 O- y4 J$ q  v  @* J
    if (vertexMaxNum < vertexNum)
* g* p  e: r4 n( _+ h" b        throw Error("顶点数目不能大于允许的顶点最大数目!");
4 W9 D$ L! |6 L# j- p5 P3 C% j    vexNum = vertexNum;
- B" a, ?3 H) u3 B; i    vexMaxNum = vertexMaxNum;
. P( p/ Z0 n# v$ R6 @2 b    arcNum = 0;, S, Q8 B: V! D4 V# r
    infinity = infinit;; K, I: [% b# l( h
    tag = new int[vexMaxNum];7 f  t6 v: A7 g8 X7 f
    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
: P9 V# ]' }4 G7 \7 d4 l0 \    for (int v = 0; v < vexNum; v++)# p' Y) J6 q  v; y" c
    {. C/ q+ @( v+ }7 V. }
        tag[v] = 0;3 \0 G0 S7 E5 |" J
        vexTable[v].data = es[v];
2 N" U% p) j" c, |- M8 q4 B        vexTable[v].firstarc = NULL;8 T# z3 w, [$ V
    }
7 i9 @+ b2 U- z  t2 f- I- c# b}' t/ d" x# x8 f& o
template <class ElemType,class WeightType>
  v/ j5 ]4 O/ L3 h8 Z6 i# PMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
/ ~5 {5 M6 Q* Y+ A! g* r7 Y{+ i/ }2 v& m5 |2 i
    if (vertexMaxNum < 0)
$ p8 g7 g- i! N5 I        throw Error("允许的顶点最大数目不能为负!");
& q* Z# Z! ?3 F    vexNum = 0;
2 |" n0 l2 X' N    vexMaxNum = vertexMaxNum;5 m( W. A* T. @  M8 f
    arcNum = 0;
2 n0 D$ D, S6 i# j+ ^    infinity = infinit;
* d- N$ x) E' W4 H) b& L    tag = new int[vexMaxNum];
) B6 Z' c2 z8 z3 \' J4 }& x    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];% K) D+ D0 x! \3 V0 H6 E4 r& K
}
! O7 ^6 n  [) q* r: I. k$ ntemplate<class ElemType, class WeightType>' ]0 |) q$ T* Y$ p
int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const2 C7 q. r  b' ?% I+ d+ |
{
& E" P. b) q! c  S* F* A9 r4 J2 b    if (v < 0 || v >= vexNum)
  U* ]' |# ^7 V; y! O& @/ r# m0 X        throw Error("v不合法!");6 I. M4 U' D. W5 Q; s
    if (vexTable[v].firstarc == NULL)
; Z$ `* ?& t1 j" R        return -1;
- _( t5 D) r" V4 P- U" z* X+ q4 T    else7 P8 I5 ], F% ?6 k% D/ R8 i
        return vexTable[v].firstarc->adjVex1;1 q8 |0 j! I9 G; Y; {
}
9 b5 b4 l$ D3 n
, z4 s! @0 f$ L& utemplate<class ElemType, class WeightType>! G- r6 h; G' _7 I
int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
$ M" T; F- m. O7 \2 F$ E5 }9 I7 ]2 S{2 ]; U( ~, T) t1 }
    MultiAdjListNetworkArc<WeightType>* p;' ?5 h0 I0 z4 M% h) O  p1 H
    if (v1 < 0 || v1 >= vexNum)9 V- X$ ~$ k) j, H
        throw Error("v1不合法!");2 N2 U4 z% p' J" o, B$ K
    if (v2 < 0 || v2 >= vexNum). d( ?% ?( g) N( T( F" R
        throw Error("v2不合法!");- C1 n8 ]: ^& h$ Q; R  E' ^
    if (v1 == v2)0 m; m0 k! n) w0 `2 X; l
        throw Error("v1不能等于v2!");; N6 A' r  a5 J) ^
    p = vexTable[v1].firstarc;
$ Z, r- a9 T% `    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)6 {9 |8 @- E1 ?( E4 _
        p = p->nextarc;
8 d, h% ?; p. ^5 b& ~" p0 G    if (p == NULL || p->nextarc == NULL)0 Q$ i& N9 N8 m; ]
        return -1;  //不存在下一个邻接点/ k" ~! L& ?& F- H0 t9 e
    else if(p->adjVex1==v2)) ~8 i' D  D* A6 d
        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
$ i9 U! g: p8 U( v8 r  E( d    else1 C3 O; G, z1 ]; I
        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
0 ]8 Y0 x7 Q7 j" S% @}. G% s/ D% V, I) Y
template<class ElemType, class WeightType>4 D, f5 @. x1 s( w( f# N3 H
void MultiAdjListNetwork<ElemType, WeightType>::Clear()
" R+ g7 z0 i% l{
3 d+ U7 D; a" Q6 Q, S: z. W* l, h    if (IsEmpty()) return;
- e; i: {' X7 ^    int n = vexNum;
) W/ e: F# [+ d! Y4 @    for (int u = 0; u < n ; u++)* _- n% h3 T# V
        DeleteVex(vexTable[0].data);; w( V( F5 E/ d8 p5 _) _
    return;0 Q# |* t( \) y: K; H
}/ S+ f2 f& O( B; c( C' f! U' ]
template<class ElemType, class WeightType>
* ~, O) r1 a  {  W1 K* E0 j8 ^MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
; i$ i2 y6 }& x7 K3 F$ W/ l{" h8 r5 L- b% a" h) N* E
    Clear();
  h. U3 q2 o$ j$ D3 Z}  J5 o. S2 z) F& x% w) s% }4 e
template<class ElemType, class WeightType>
( z6 x! A( x8 @1 @6 K- YMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)* ?2 c- N8 ]; w+ h& b) e3 v
{# s2 O8 }; N( \) r
    vexMaxNum = copy.vexMaxNum;
9 R& G% x0 z( b; [/ f' j% y3 Q    vexNum = copy.vexNum;
, z. E  @' F& z9 U3 s% j    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
6 n; O) o/ M* \% m% k    arcNum = 0;
& K+ @# J1 _8 L# m' W    infinity = copy.infinity;
; {2 t* I3 O1 _9 d3 T* h    tag = new int[vexMaxNum];
) Z- z6 t/ H" U: ]6 A* B
% U( z' u5 L8 F    for (int v = 0; v < vexNum; v++)
7 X- B" ?/ l0 e. @% }- M6 Z    {
/ J. B; m6 p4 p        tag[v] = 0;1 P/ Z+ {% }% \2 @
        vexTable[v].data = copy.vexTable[v].data;
+ ~  K& l3 G" n. h4 K4 C        vexTable[v].firstarc = NULL;8 l  o7 M2 f+ M: B  X$ n% b; \
    }
: j; t- M0 q. h2 E( S    MultiAdjListNetworkArc<WeightType>* p;! ?5 Q- _8 i! l1 K% v! g) `

+ O, ^8 w2 U0 z3 F$ ]' `! w8 I    for (int u = 0; u < vexNum; u++)0 |1 M' q1 L8 T% O
    {/ T  ~& Q2 C5 \# @8 `2 r
        p = copy.vexTable.firstarc;, y& X' C  q" J: O, f# [
        while (p != NULL); z" s( C0 D3 ^- j
        {
- d  u; H- f) Q4 b- V            InsertArc(p->adjVex1, p->adjVex2, p->weight);
9 x: m, [4 K9 G0 s0 |' p  F            p=NextArc(u,p);! c) s" E# V/ ?) u; {2 e4 ~  n' `
        }
7 c/ \; U) e$ v+ t% T    }
$ i$ {- f3 K# Y- {+ Z}8 F( {4 _4 v8 ]  g7 K$ f5 }% m
template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
$ J) a# `' _; h1 z2 RMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
- i. M0 w( l  q{* D9 {: [1 f6 \" N: @
    if (this == &copy) return *this;
2 \+ N$ S! J& p    Clear();# H- L4 B' f+ S6 _  v. q2 v; {
    vexMaxNum = copy.vexMaxNum;
( {% r$ l6 ~8 V! X. t6 c( R    vexNum = copy.vexNum;- m2 N0 X$ S) |. V9 b7 S
    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];* v) Q+ N' w2 |+ N$ u
    arcNum = 0;5 f& f+ C; E0 D. j2 }
    infinity = copy.infinity;
$ k" }: E% O& F0 W    tag = new int[vexMaxNum];
1 c$ f% y% N3 H/ Y1 j6 {/ ^( H- U- d1 g$ g
    for (int v = 0; v < vexNum; v++)
/ o8 |" e) \; S. e0 ]& ^    {4 H$ e* S% l1 n4 P' S- |5 |+ m  ]' J
        tag[v] = 0;0 }. k3 i$ N3 h2 V9 t6 }
        vexTable[v].data = copy.vexTable[v].data;
# [3 K* J- U, M$ g1 T' x/ \2 D$ c9 ]        vexTable[v].firstarc = NULL;
5 M2 S% b. s. `) [    }+ z/ x) T# g; c- V
    MultiAdjListNetworkArc<WeightType>* p;' p/ O! O) h* N3 o0 D
1 [% V  S" f  ?0 }* K
    for (int u = 0; u < vexNum; u++)
2 R; @5 ^3 j1 l    {
! G- w% F$ Z. S3 e% }* P        p = copy.vexTable.firstarc;
) ^4 a6 }) y! a/ q, e# _        while (p != NULL)
4 ?) Z& A  Z" c4 C, H9 T        {
8 S0 T4 f+ h  ]% p5 l6 }            InsertArc(p->adjVex1, p->adjVex2, p->weight);0 L3 Q* y3 S; j1 _% E" L* C! S9 @) d
            p=NextArc(u,p);
# O8 S# o- m0 `& a4 ?7 [! \        }
* s, d  U" {. R3 u% J+ U8 y1 `) x+ L. C' A    }. n! r4 D2 e' f# a: Y; ~% n/ y
    return *this;
9 c! P( G. b% U( c1 v- B}
% c/ ^4 ^( c2 b- d& S0 R# `template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
3 O; r" U+ Y  N- H( o8 jMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const/ y3 ^& o  {$ p" h
{4 T+ D/ |3 q0 F  D3 G: q
    if(p==NULL) return NULL;
4 ^5 z$ M7 K8 T7 z$ W$ j, G    if(p->adjVex1==v1)' W+ T% V( R6 _. i$ v
        return p->nextarc1;, W4 F. F& v9 ^9 _. p" A
    else
3 [7 }$ b+ W% L  ~+ m) }, a        return p->nextarc2;* a. V, |/ E. H! k7 i+ T* X# A8 @& L2 }
}4 E2 u( H( d& R- Z4 B) _; }
template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*$ u- w( ~; a0 P& N5 D1 q, L- |
MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const$ g1 E+ w; H# q% o
{
2 N9 Z) `+ h' W& \: s! t  F' P! [    if(p==NULL)return NULL;
* c7 J: H1 `  o3 H; U, u( ^+ L2 T    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;* X$ Y/ N2 c" Z! H, K! \0 g5 E7 D
    if(q==p)
: [) E. n& l+ T  y- I        return NULL;
. n  ^+ l3 ^1 R! M2 v( X# ^) Q    while(q)
$ |# X) V- N4 g' d9 M( a3 O4 c    {
: b( y7 m; o' I( d* @# C% K9 P        if(q->nextarc1==p ||q->nextarc2==p)
  M" {% b' _3 T- R) a0 z; o            break;
9 ^) }, \% H6 `; e: r4 F        q=NextArc(v1,q);: `% U. k0 |6 h" Z$ K, q
    }
0 z3 K+ |: l- y    return q;6 e, n' q1 ~, |0 U3 S+ |2 i# g! D6 w
}
& C  R3 J- o( x" e+ htemplate<class ElemType, class WeightType>) w" g2 K4 k* D7 ?3 c
void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)6 v: c2 k1 ]( K7 R# x' H' d. N
{  B4 P4 h+ K% \( I
    if (vexNum == vexMaxNum)
# [. M5 V$ `3 h* z        throw Error("图的顶点数不能超过允许的最大数!");. [: @8 F# @2 C, G/ q" z0 B5 V
    vexTable[vexNum].data = d;& S2 w# u) G7 e" z5 S% n
    vexTable[vexNum].firstarc = NULL;
/ [  D2 `* Y( W$ `    tag[vexNum] = 0;
2 ?* _" W' F! F  a0 G    vexNum++;; M% U( w0 C8 K
}
& ^& ]' k' \' z6 v; Q9 b' rtemplate<class ElemType, class WeightType>
( C) ^  i. z- i( T& nvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
! u6 C4 ?, n% [! G* o+ ?{
, n4 D& `3 h9 }: A8 s' B2 v    MultiAdjListNetworkArc<WeightType>* p,*q;/ w) w/ x3 K& Q+ N
    if (v1 < 0 || v1 >= vexNum)9 f1 y1 c3 N* Q1 G& h
        throw Error("v1不合法!");3 C$ P2 b& k) h6 K
    if (v2 < 0 || v2 >= vexNum)& e' d' u3 \% `  ]' ]( t% M! v' X
        throw Error("v2不合法!");
& _# R- e1 D  U. L- j  _    if (v1 == v2)
& w6 @9 v% o, W' j7 Y, w        throw Error("v1不能等于v2!");
2 U# b  r; j, v) u/ q    if (w == infinity)- c  ]- K7 y/ {  C. m' A) @% Y
        throw Error("w不能为无穷大!");: g% I. Z9 `- G; J/ C

( y& z# J/ g8 v2 i: E9 y6 q' I
7 H$ P, m+ `5 Q( l! c$ g/ g    p = vexTable[v1].firstarc;
! c4 _, b) I* H% q: j7 M( l' Y    while(p)8 W) Z+ }+ p4 r- }9 W; n
    {
' |8 l0 R; {, T1 r        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中- o* u2 b! b3 Q' @0 `0 t
        {2 R" D$ {. Z1 G0 S
            if(p->weight!=w)3 t4 R; `8 w8 i7 h7 a9 S3 M
                p->weight=w;& K3 g6 ^, l8 V7 r/ }4 L
            return;/ q2 v& ]: D' x* }! @/ q6 U$ |" p
        }$ i4 ~, }& _: T# ?. G) T1 }8 L

# ]9 l0 M7 o4 {* g" k        p=NextArc(v1,p);( ?$ k' E+ C  S- K* M! }
    }
; Z5 |( ~; |* Z/ g% W    p = vexTable[v1].firstarc;
" v# e$ k7 b/ Q1 t9 i1 d/ M3 ~    q = vexTable[v2].firstarc;( t  f/ y% H# T% ~8 S# l5 L
    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
2 T$ i, q# C+ F5 C9 `/ z% t1 \: E- ?& z    vexTable[v2].firstarc =vexTable[v1].firstarc;
; _. q+ |4 q# K" y/ i# ?    arcNum++;
4 A) D' [; u- b. n/ \# f}. ]; w: a8 _/ @& A$ h
" j1 ]. `1 K0 {
template<class ElemType, class WeightType>& T3 ~# F0 _% q0 H1 L
void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)$ ^- N- H6 ~0 ~) g8 @
{
. b% P( ^: }" T" J- k* q& H  t
3 D! {4 j6 e  M8 i0 K, u    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
7 G+ Z0 t* J% z# B  }    if (v1 < 0 || v1 >= vexNum)
9 Z" R$ z( R. d& a; p! {0 h        throw Error("v1不合法!");
) U  ?7 D- u3 c+ v! W6 r+ Z3 C    if (v2 < 0 || v2 >= vexNum)
2 R! D( v4 a. w        throw Error("v2不合法!");6 g  u* U8 Z2 d' h9 W
    if (v1 == v2)
5 |) p7 m+ i# P* x        throw Error("v1不能等于v2!");
: J% A8 ~  ]3 V# X2 b8 H9 v3 Q* x9 z$ R5 |2 F6 k; {+ t
    p = vexTable[v1].firstarc;
4 Z/ ^+ L  c3 _4 y: i: G1 H    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)5 @* w# B! C1 n, C: m. ^2 _. \
    {, U0 f2 `% _( T' h3 ^
        q = p;! N. n% ~( F& d& R, w2 ?
        p = NextArc(v1,p);, u0 N8 [) [4 A# |7 o9 e5 J3 S2 ^
    }//找到要删除的边结点p及其前一结点q
& W- S( P1 d6 m" _- E
5 ~  W5 n# }+ H/ g4 O3 Q    if (p != NULL)//找到v1-v2的边2 O8 E0 f0 [# M& z; |5 @7 G! B
    {* F: ?4 W$ g& C* S- c
        r=LastArc(v2,p);
+ a" q- i$ ]; ?) z) ]        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL5 k6 e! k5 k+ q, U- L4 ~
            if(p->adjVex2==v2)
$ n/ l' E3 N' k                vexTable[v1].firstarc = p->nextarc1;# v/ ], e3 u3 C! s
            else vexTable[v1].firstarc=p->nextarc2;  {) p) b% H# Z0 {9 i- W
        else//不是第一条边
  d( v6 g+ x  M. H1 o5 F        {
+ M6 L  n+ w6 p            if(q->adjVex1==v1)
0 {* X( g! W8 T9 W' j2 L8 P                q->nextarc1 = NextArc(v1,p);
; o% _3 X$ P# l6 {2 }            else( E* s3 [  n% j8 S
                q->nextarc2=NextArc(v1,p);
: K( _% U/ ^& W+ s! r
+ p6 c9 R" r6 h9 |0 d        }
/ U7 H9 m# Q/ e; B/ z7 c$ Y8 a4 W        if(r==NULL)9 t1 E+ U1 t- x5 T
            if(p->adjVex2==v2)3 r2 c, ~5 b3 t+ l5 U% E
                vexTable[v2].firstarc = p->nextarc2;6 }% n% n9 u( I
            else vexTable[v2].firstarc=p->nextarc1;
. }, \* u& j( v        else
2 \. R* i  l% z' u        {8 M3 V" j( v9 g0 l4 Y0 ]
            if(r->adjVex2==v2)' ^' X4 p6 ?" @) L# h
                r->nextarc2 = NextArc(v2,p);* L' x2 O$ T$ c" G" x
            else
0 y1 d. E; o9 f/ Q* _1 r8 _                r->nextarc1=NextArc(v2,p);
7 B; i6 T5 z2 v        }) x; P' i' R! q  }. I& x
        delete p;
# a# q& i* c8 j- z: M        arcNum--;
7 W0 r% B5 Z1 E. P% z    }/ q5 _# O! @1 a# {; h

! T  ~) S  W' `4 \" k}
  ?* Z+ C; @$ t+ V6 rtemplate<class ElemType, class WeightType> void
" T( y* `+ p$ }$ m" XMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
& y5 p) {/ Q! D6 v5 A" k6 h{% g, h, v  M4 f9 o
    int v;+ p3 A1 I4 ]3 B2 O: A* I
    MultiAdjListNetworkArc<WeightType>* p;
7 Q* t3 j" p6 C    for (v = 0; v < vexNum; v++)//找到d对应顶点
$ F0 y2 o1 r. M0 g! h4 {' x/ ^        if (vexTable[v].data == d)
0 x+ q* B0 v. V5 |8 X1 j- S$ ^            break;+ W4 I% ~% e! }& }0 I
    if(v==vexNum)
/ k; N* q1 \; P0 v) k        throw Error("图中不存在要删除的顶点!");
2 C3 f( V9 Y8 Z* B0 r4 @* u+ y0 W
2 g$ q) b/ W$ \7 p9 ?4 }9 w    for (int u = 0; u < vexNum; u++)//删除与d相连的边
- g# r2 R( V8 B+ F5 e        if (u != v)3 y. J5 A. e/ x. c$ f! B
        {" S, g5 a$ p' P! [4 D  \
            DeleteArc(u, v);: [3 k2 K9 b3 E2 L+ {% {' U, K
        }- k% Y; x$ q9 g" d  s2 Y' X# L
    vexTable[v].firstarc=NULL;5 L; m! e3 C, H
9 D& \% b; M+ w6 A
    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
/ W8 Y2 b/ _4 ^- R7 X* r% n    vexTable[v].data = vexTable[vexNum].data;
: S; F5 z% w& G3 [3 k    vexTable[v].firstarc = vexTable[vexNum].firstarc;
  z8 |& Z: o' v" v# c9 t, Z8 `/ B    vexTable[vexNum].firstarc = NULL;
  E* O( ^3 I( T9 O8 L+ c    tag[v] = tag[vexNum];" Y% S0 e- k. |0 Q& m) b+ f
    //原来与最后一个顶点相连的边改为与v相连$ i: ]) x& c6 K" `6 B
    for (int u = 0; u < vexNum; u++)) e" U% m* w& i" k" Y( p9 g* Y$ C+ R
    {
! z* X0 c( N! W/ u; i+ p, s6 i* L        if (u != v)3 w9 D$ y+ ^1 T
        {
& s3 G( K: v7 D" p! Y6 H& ^6 U            p = vexTable.firstarc;& w/ ~$ u3 `  L* w/ j
            while (p), R) V0 J: w4 E; [6 F4 H3 Q  g% H
            {
3 a4 \4 C; C/ x7 P& e% m- L                if (p->adjVex1==vexNum)
6 K* D9 k, k4 H- n                    p->adjVex1= v;0 n7 c% c' ]/ K& ~
                else if(p->adjVex2==vexNum)
$ ~) i- k- G# ~  l' b, c                    p->adjVex2=v;
" b. M, t( M7 T( V/ w7 g, [9 U                p = NextArc(u,p);
8 j% L3 t& i+ Y  F" n5 W+ |            }
8 [6 k! y  K. J7 V/ g3 F2 \        }# [2 a6 Y+ t" `' G8 Z
    }( [/ n: a" c) |. g, r# f2 f7 q
}% r8 T" i+ P+ L. C3 @9 b
///深度优先遍历# q1 T: c5 s  L. H) D
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v), n3 k, d9 Q( I3 o
{
, n* k. f" s6 r; `    tag[v]=1;
( B  k* B& ~8 }- s4 v    cout<<setw(3)<<vexTable[v].data;( c1 {! g: s% L! V1 I
    MultiAdjListNetworkArc<WeightType> *p;
( Y5 w  \7 J; y, O    p=vexTable[v].firstarc;0 i! F& Z9 T' N7 q+ w0 ]
    while(p)
# S6 m# \2 B# T! U0 |% p- D; t0 D    {6 K! P- g1 N4 D0 f$ ~) N
        if(tag[p->adjVex1]==0)
! q# \3 d4 s5 R8 l7 m% ^            DFS1(p->adjVex1);
" g  }3 _7 {4 l, a' \" @0 a. I        else if(tag[p->adjVex2]==0)0 i/ s' u2 \1 U4 |. }$ v  @
            DFS1(p->adjVex2);0 K3 k2 T2 Z0 b+ n
        p=NextArc(v,p);
3 o2 z2 [/ G" n  T; J4 N4 T( z; A    }
$ `. V( N8 V7 t5 D5 U1 D}
) R# v0 u; F2 J9 o# y1 U" etemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()% n& Z9 n5 ^2 g2 h( U
{
  T9 K  p( W+ o4 h    for(int i=0; i<vexNum; i++)
+ G: A7 X: L. X# \5 L7 R        tag=0;0 M6 P$ f1 @/ N- I2 S" N8 N  ^
    for(int v=0; v<vexNum; v++)
' D3 b+ T$ {7 v+ g' L6 V. D2 e$ n    {
3 A, _* b& Z- Q1 e" U4 }        if(tag[v]==0)" ~  Y* s; H8 \5 x% `1 x
            DFS1(v);
, r$ u" i7 h* F    }
: c  T( X! ^9 \- E5 P}
9 _/ G3 M% l* c8 L8 p' Rtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()  Z9 }( ^) S) p7 a
{8 R; G9 ~% a9 J$ q, s+ f
    stack<int> s;7 d; C7 J7 b' _
    int tmp;5 Z) U- Z5 U$ z
    MultiAdjListNetworkArc<WeightType> *p,*q;% T$ K$ Q5 m9 x5 ^6 t
    for(int i=0; i<vexNum; i++)
1 O$ x8 u( ]- u( t        tag=0;0 h6 U/ ]) i" f5 }# |+ C+ R
    for(int i=0; i<vexNum; i++)
2 i" ]8 l6 q+ D- Q) E    {& j2 S" Q$ m8 l* f+ x
        tmp=i;- y. S- P9 d7 |2 Z% R
        while(tag[tmp]==0||!s.empty())+ ?. V6 r" K4 u# P
        {6 `; O4 p! p& ]+ t& ~: r& B0 X
            p=vexTable[tmp].firstarc;- b) \, G- V6 q2 h' G/ i. B2 ^
            while(tag[tmp]==0). O- l% b5 K$ H4 I
            {; A: t9 N* i" R; r% H  h
                s.push(tmp);  |7 x9 k: N) ^' ]# ^2 h1 {9 B& R
                cout<<setw(3)<<vexTable[tmp].data;0 ~' @+ |" T6 z' J
                tag[tmp]=1;
6 ~* }) d; i: E                p=vexTable[tmp].firstarc;+ l4 D, p3 U2 p) b8 X- o
                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for( W$ y! m% s* O
                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);' c4 a, H1 I3 ?9 e& I  E
                //cout<<" 1st     tmp="<<tmp<<endl;/ L9 L) C" B- @8 {6 P5 M6 V0 Z
            }
. v' l' B( \7 E5 D! }; w            if(!s.empty()), \5 O+ t4 F% g. n8 l1 E
            {' G5 H9 n/ C6 z  ?& R
                tmp=s.top();
9 Z) P/ ~5 X  a2 U9 _6 u                s.pop();3 L- p4 T, L8 z
                q=vexTable[tmp].firstarc;7 I& L2 Z& u2 a, J& L/ e3 h8 a1 ?
                int t=tmp;/ f( ]6 L, Q6 ]
                while(q&&tag[tmp]!=0)9 v; g+ h& a4 m7 f; i; d% E+ B" ^! e
                {% j0 c" x. I% P9 }( O* M3 o
                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
. O, v& J; H' v+ w* @0 W: r) @                    //cout<<" 2nd     tmp="<<tmp<<endl;
9 A) S9 Y; I; K1 h- z( G                    q=NextArc(t,q);" o1 f0 `3 ]8 h0 ?. f. u
                }
  N$ _# N- K* T$ C8 B: |                if(tag[tmp]==0)
5 h6 M9 z, @- o$ K6 ?# J                    s.push(t);
! T9 u% ^: t% f+ o) X: Z; H                ///1、对应上面连通分支只有1个点的情况
2 `; t7 `  r" m5 x; _) t                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈" z% n- U- }! E9 F, _- r6 E) c; \
                ///tmp要么等于找到的第一个未访问节点,+ u3 \* U1 _1 W, ]- v) u
                ///要么等于与t相连最后一个点(已被访问过)
+ L1 f0 K: t& T7 I+ J4 w, e                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点2 V: K3 f9 G, w6 q" I1 ?
            }: O9 ^+ e% p. ]+ o: v3 s
        }% G$ y6 U( w# E0 O2 N/ X& u% z& ?9 W' v
    }- k" h3 I! u8 h  @: z; b8 D& E
}2 F5 `, u) N$ T4 K
//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1( T9 x# z6 W( _" O9 G0 T. f
template<class ElemType, class WeightType> int( e2 {: X: \4 @; d, y! S
MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)/ M) d% p% V; c: M
{
* k  {! X+ }3 E* y) i# W$ z- B; c, e/ R    if(head==pre)
9 G. y9 [3 o1 @3 [' f2 @. a        return -1;
) r" W( B8 ?' ^6 ^$ h- k8 F: |# b7 d
    MultiAdjListNetworkArc<WeightType> *p;4 `* j. z; u& t# }# [0 n. H9 U
    p=vexTable[head].firstarc;
+ `& f* G/ l$ M: k    if(pre==-1&&p!=NULL)( x; P4 H( v+ N
        return p->adjVex1==head?p->adjVex2:p->adjVex1;8 w2 ?% c* ^1 o+ }, p0 Q& W  y
    //pre!=-1&&p!=NULL( B7 P( g8 _  t6 H; u
    while(p!=NULL)
# o* C, X$ o* B6 O" F$ f    {
- Z- J; K* E! V) Z" a2 X        if(p->adjVex1==head && p->adjVex2!=pre)8 D# T7 j% `$ h
            p=p->nextarc1;
+ O0 ]: \4 r. H$ I7 `& `        else if(p->adjVex2==head && p->adjVex1!=pre)
: z+ f" a$ l. s* G; `            p=p->nextarc2;8 `7 ^% X2 ~, r* P6 A
        else if(p->adjVex1==head && p->adjVex2==pre)+ F9 R# Z( j! _  d
        {- M1 @  ]7 X  t
            p=p->nextarc1;7 ?9 ^$ `5 A7 @) t% P% b
            break;) n4 v, T* F% \3 d. k
        }
6 a9 X# {( ]& ~, g' j7 s        else if(p->adjVex2==head && p->adjVex1==pre)
" S- o& ]0 R/ i3 L/ I& h5 y        {
( M/ [! c: r: P0 R3 S) g$ h' L& [            p=p->nextarc2;( E# a" u$ T* Z9 R
            break;% {1 i) V: I1 @" f
        }) _, e2 Q& i: e
    }
# t; ?! E- {! ]% t0 V  _    if(p!=NULL)
* R5 Y) V. r0 g# Y# H; O4 u    {5 j2 n8 p; a: Y3 \, N/ t2 T' d  k1 F
        return p->adjVex1==head?p->adjVex2:p->adjVex1;) O! ^; \- }9 Y/ Z
    }
/ O5 `9 E$ m0 c    else) B5 s% ]/ V  h# T% p" l
        return -1;
+ q3 `. s* {0 [! P3 ]}
! r6 l9 s0 v) x- H/ a% L9 H6 t
+ X3 V9 I6 x8 n/ D: N0 A$ @9 n, f: U+ _
0 a, R+ v6 K/ }. v1 ~template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()" \( e6 D- B$ P% ]
{
& ]7 ~+ S6 |  ]8 k. I; y9 F    stack<int> s;
2 v  A1 y4 |9 \/ M5 R1 q    int p,cur,pre;
% ^4 J3 s: \0 p! O# n    //MultiAdjListNetworkArc<WeightType> *p,*q;) m# j- d$ }" q/ L
    for(int i=0; i<vexNum; i++) tag=0;//初始化4 w7 y, x- Z& S: U+ P7 H9 A- B( {% C

; q$ T# R4 g2 t. W! M: O4 I    for(int i=0; i<vexNum; i++)
7 ]/ E) v4 B4 J+ {6 j& |    {
# @; k( t- e  D8 I! ^, e        cur=i;pre=-1;) a5 N+ C+ K8 S) D1 u
        while(tag[cur]==0||!s.empty())7 y, u/ X& ?) I# }& |( C0 o
        {
3 L! A: f  c! `$ Q3 W" J            while(tag[cur]==0)' L; y* C  n0 U! `
            {
, M* a8 ?$ p6 r6 i4 V                cout<<vexTable[cur].data<<"  ";
1 ]& K# _. {6 d, C0 [; c+ X                s.push(cur);
4 x0 E  c- G4 X6 p                tag[cur]=1;
4 q- e7 V1 |+ c! P1 ^% f7 |               //初次访问,标记入栈3 L; v( u/ }- e

# Y$ b8 ?3 c) y( {9 ?               p=GetAdjVex(cur,pre);//p是cur的连通顶点
% ~# j9 f4 c8 s) F7 r# [: U% M               if(p==-1)8 g# L7 q% c% Z8 f9 g) Q
               {
6 c5 [2 V3 j) X' Y+ E! \1 a+ l                   pre=cur;s.pop();  y2 x8 z8 }9 N5 W
                   break;
" Y- V8 N+ E1 i8 t$ L" `) ^6 _# O7 x               }5 N! |. S% ~; P7 w: a0 M
               else/ z* H% c9 h0 G; {, R
               {
% ]7 f& E. g0 @6 U6 q                   pre=cur;
7 I: c- `1 d2 ^* O0 d                   cur=p;9 ]0 q6 W; A4 d/ M% P" ~" x6 P
               }0 ]- [# r/ Y4 K4 x! h$ V$ w% s5 }

% \0 j9 [7 l9 M& v1 s' m            }
3 `# s9 B: p4 `4 E  l4 y            while(!s.empty())
+ a4 ]& `2 y; D7 Z4 O0 U            {# W. ~3 M: @: p7 `7 m; u
                cur=s.top();. s' Y7 L+ [: u  P% J" d
                p=GetAdjVex(cur,pre);0 t) e( ~  `0 l
                if(tag[p]==0)
& t, _) |/ C8 s" `                {
$ n4 u- `, }: i: o' J5 Z9 O$ L% i                    pre=cur;6 e4 T+ ?+ E' p. h/ ?
                    cur=p;! E1 X, |6 P" l5 Z: b. ?6 \3 ?% @
                    break;
& I* C: ?/ @; A8 H                }' _% n3 I+ p& T8 m% R
                else
, m; n. j. D# Z) z' d4 g                {; b  K5 g0 |! e! |
                    pre=s.top();
) _7 o. q" ]: _! ]                    s.pop();  R  Z, j: x' d  X& \/ |
                }9 W$ w3 ^5 W2 R* ~
2 Z5 ]2 z+ E& V( s5 h1 L
            }) Y; h! P4 Q+ U$ Z

% x* j7 a6 e, J4 E0 S2 [" c( X1 U        }. \4 F" E9 _2 Y  {" u* f" n
    }# _0 @8 R) F8 h5 E2 X8 t. W5 V
}' W( V+ x) \' k, T
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()) ~9 E. C. \4 m6 M. X$ G5 O+ D3 t
{
- [8 i: j. e7 j3 l( N3 b- m    for(int i=0; i<vexNum; i++)
; I% o+ ]2 h, d        tag=0;8 V# H9 O9 @# E/ P/ O1 S- S
    queue<int> q;8 n% }  F% o* R3 T* q
    int tmp,t;/ d) H( [9 ^7 l  X
    MultiAdjListNetworkArc<WeightType> *p;
: I3 S! @* a- _+ E) q) p    for(int i=0; i<vexNum; i++)
( Y- W) B1 k0 g2 e    {
: S5 k  M2 O' _% Z, h        if(tag==0)
6 G' F3 O) z8 ^* T; w$ @1 ]        {6 N% H3 `6 S. o' d. Y; ^, `' W
            tag=1;+ q! S0 ~1 a* z) W3 f0 a% d1 a" ]3 \
            q.push(i);" C, Q. d4 v8 s5 h- b. X
            cout<<setw(3)<<vexTable.data;
9 n2 D7 [7 M- q  J        }( i  y  L/ X2 h. ?: s+ k
        while(!q.empty())6 T: e9 ?8 Y! z
        {% K6 U) P' i1 H$ e' V
            tmp=q.front();
5 l1 Q2 k9 I& E0 T8 I7 E            q.pop();
- x( d4 ]: w( i0 i! q( C1 ~- U% S, ?$ e            p=vexTable[tmp].firstarc;
" D, T4 x( `/ r0 ^, K            while(p!=NULL): Z$ J% |* X: l1 R% g# a
            {
8 g" h1 c2 n% _7 _2 }. o2 s                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
  o. i' P$ m9 l7 G% b# i7 q                if(tag[t]==0)
0 M: y1 R( K% _# q                {
4 X7 @' g2 B- k1 z' x$ ^                    cout<<setw(3)<<vexTable[t].data;
( r, f9 n& A0 w- _' G; B( W                    tag[t]=1;
. U! A1 l2 Y, v9 }! {! C: p                    q.push(t);
/ r# s# ]5 \# O4 ?                }
% H. k, R, U$ H8 n; ^; h: q                p=NextArc(tmp,p);
8 D1 K7 T: S5 ~3 S            }0 \0 E6 y. L+ Y
        }
7 Y1 [% |; ]- D; o0 d    }
8 s( s7 w) [* g0 w& S}: R3 @, u/ N( I9 R4 p
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()1 T' d# W9 p  Q' C6 K- D! O
{: l# _- K9 G9 p0 {, Y) F
    MultiAdjListNetworkArc<WeightType> *p;, k2 u& {* \" s! `5 g
    cout << "无向图有" << vexNum << "个点,分别为:";
9 K7 @8 ?4 \( z& {* h$ T2 z    for (int i = 0; i < vexNum; i++)
9 a8 F* D5 P/ H" `8 k: O: [3 H# U        cout << vexTable.data << " ";
* m& `4 S; v9 u% U5 g' N    cout << endl;
, {2 r6 d' \: e% F( I    cout << "无向图有" << arcNum << "条边"<<endl;! _& u! `, m6 ?/ r
    for (int i = 0; i < vexNum; i++)% e: c% M8 T% d5 }1 A% `
    {  e/ ~  c! N+ H+ ^$ H! S1 w
        cout<<"和" << vexTable.data << "有关的边:";. K. y: q" U; Q
        p = vexTable.firstarc;4 A: N$ [5 H& N: F1 J
        while (p != NULL)$ o# n5 B9 d2 ~, D5 h3 e
        {. b% C5 B2 B/ V2 ?, p" g
            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
3 u+ y2 h7 h! Y: j7 ]$ ]0 g1 q            p=NextArc(i,p);+ I. Q4 c8 C9 P7 b2 z% I1 t
        }
9 u0 E6 V: _3 y0 r        cout << endl;
: l! l4 R% L( i    }0 X8 Y$ j3 H' }. U+ U! E  s1 M
}
8 Y5 ^1 H& g* @& T( p/ K: d; Z
( `" v7 j# f& H, {2 w9 F- P1 m
& R/ b2 p" N- U0 ?# i5 |邻接多重表与邻接表的对比
1 A" k+ T. N- i% W+ c
1 j1 \5 v# B1 \* |" ]0 Y* Z+ ^4 k; Y邻接表链接
( Q" M7 O: E3 H# F2 R# d在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
' A! o6 x5 p' F6 x在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。5 G  c" L+ |7 q0 H! x3 {
为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
) Z: b; ]) F+ I  T9 U/ I- L————————————————
& T" |. @+ M) z" X& g! B  c9 r版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。& @6 m; T3 i$ a  _4 x& O
原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
* ^: @4 U  n5 o6 u9 D1 [' f; }1 S7 Z% ?+ V; N9 ?* x; I% A
3 v) [% a! @- Q" F7 l
- k. ~% A4 Y) a% L: a
( U3 E, m+ U# l' T* m3 d/ c
————————————————1 A7 v$ ?1 E* N
版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
4 w6 K7 d  d* w  W+ j6 k原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
* _9 i! h- G" w- N6 E1 t# W" A+ u2 Z+ t; a9 ?" x1 H, v

% `- D2 x1 Y  ?9 @" j) k& G




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