数学建模社区-数学中国

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

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

" M! g% B8 u8 N% Y% s+ z" C7 \图的存储结构——邻接多重表(多重邻接表)的实现+ H  w1 [0 c: l. K
7.2 图的存储结构3 |, a5 \6 s8 x; q) ]
  g) f; s" n% p
7.2.3 邻接多重表(多重邻接表)Adjacency Multilist" T' v; o5 h1 h
邻接多重表的类定义2 d1 n, U/ B+ U0 U, d
邻接多重表的顶点结点类模板7 j& b1 i9 u% j; F1 P* P$ p
邻接多重表的边结点类模板
  p+ C8 E- n  m, x% h0 r2 D邻接多重表的类模板( b3 }9 T; b, Z& N
邻接多重表与邻接表的对比1 S* ]/ G7 @2 V' o% r: {3 f9 g
7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
/ J; d' b$ F- i( t& P  R( v$ M0 \" b5 M5 a7 H$ J
在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。! b! Z4 _0 q0 w# j  I
在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
* K- G( S1 E2 D
4 |0 Z" o% z& t! V. }3 J邻接多重表的类定义' S. ^* L% z3 F/ W- @: w8 ]' c
1.png
; v- A9 y, A* |邻接多重表的顶点结点类模板

对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:, H( R, N$ Z9 M- V8 I3 Y7 d2 L# V
data域存储有关顶点的信息;
: j- H  p# \/ b6 i7 `; Y' hfirstarc域是链接指针,指向第一条依附于该顶点的边。
; c( h1 c/ t' W/ z; y2 {5 O所有的顶点结点组成一个顺序表。


! m, r+ }& S/ W2 Z( x" I6 W0 z$ u' ]$ @
template <class ElemType ,class WeightType>
! k5 }2 c2 R( K- Q% Bclass MultiAdjListNetworkVex2 k! w" j. I4 R
{
/ O6 R1 I; A: B/ p1 x. T& [. gpublic:5 ^3 V! v) F& {
        ElemType data;( f! Q5 p2 ^6 C$ L
        MultiAdjListNetworkArc<WeightType> *firstarc;
' w' D6 `- Z) B" O3 l. j
+ n$ P2 f2 F8 T3 `8 B        MultiAdjListNetworkVex()4 k& {) W% j: S2 ?  j
        {
7 a7 f9 g+ W+ L; I) d9 t' _                firstarc = NULL;9 X! K1 U9 j- g% w5 `" g
        }
2 F( y# Z9 W+ J( C/ D6 C! C        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
$ N) }8 j1 S+ m/ b1 M9 Q% B; |) |        {
0 f  w- l+ o+ w: k                data = val;- }7 S) D- Q1 j4 Y# {
                firstarc = adj;
+ i% n$ K; j( c  o        }
8 ~$ C, O' h: d; [9 _% X};9 Q( D, P3 J( Z; |  N
* |; N/ P3 r1 V9 w; E9 j
邻接多重表的边结点类模板% z" y+ G) U0 W+ s6 c

  M$ y& W6 p* f, o在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:6 b9 h! s) N( B& I2 o
tag是标记域,标记该边是否被处理或被搜索过;5 i6 [: a; i* D8 r# w- `; C
weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
, G" p! J+ M$ l" j$ Onextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
7 p% E* z( Z0 m- S# G0 qnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。. ^* w& W$ d' ~: }  U
4 B  H2 F3 Y  R
2.png
+ i, s! u, s" J) H. ?* w) Ztemplate <class WeightType>
- j2 L. D7 X1 S  G3 Uclass MultiAdjListNetworkArc
4 c" [7 n2 X2 U" N, H9 e# X{! I# H1 A' b. u  }& j
public:
' K* n2 j  q3 @, u* s/ Y2 `: k3 Q/ O    int mark;                                       //标记该边是否被搜索或处理过8 B( [  C7 w+ G$ C% H" S# \" Z
        WeightType weight;                              //边的权重
+ F8 N# p0 @+ r% M% I( ~* b        int adjVex1;                                    //边的一个顶点7 s$ T! i0 H( k8 ]6 E
        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1( ]' L. q0 Z2 G- O/ k# {
        int adjVex2;0 {9 ]' B# r1 u; f" T6 r
        MultiAdjListNetworkArc<WeightType>* nextarc2;
) u7 J; `1 L* K: @# M5 r5 M7 K; F: u& U' H) C
        MultiAdjListNetworkArc()
. ?) r7 ]6 b- u) G        {% w2 x$ @% b# ^
                adjVex1= -1;. c& `& Z3 Z3 f: \0 F" y
                adjVex2= -1;$ t: H. u1 C# W5 K' B9 ~
        }
* A1 b( O2 M$ d8 z5 m9 S- v$ W8 c        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
# P" o, X5 z+ V2 R. N( k        {
- ?8 }! _( j, x  S                adjVex1 = v1;       adjVex2 = v2;
! C4 j! j1 v8 w  w- t( D                weight = w;
! G2 p, e! \, H8 h* T                nextarc1 = next1;   nextarc2=next2;
, S1 X$ o1 x) N# ^                mark = 0;           //0表示未被搜索,1表示被搜索过
8 N( R; p4 ^4 |        }
8 ?/ O) R) B2 c0 J, B
0 @- Z3 |7 {# w0 B: n3 A( ?5 G邻接多重表的类模板

1.类定义

template <class ElemType,class WeightType>
7 ~" ~# S2 g: ~: x6 q! u* Qclass MultiAdjListNetwork! N8 ^9 r+ P8 i- ~
{) H- z$ ~6 K$ ?1 L1 K
protected:, ^% i9 i# q' o/ s$ g. m
    int vexNum, vexMaxNum, arcNum;4 z" Y2 c5 x, `
    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
4 p; N! ~9 P) Z- `( ^    int* tag;+ d6 f- B; I$ C& e4 n! a
    WeightType infinity;: w9 c6 }/ w- g( v9 e

2 y; r6 E$ J# j9 O' Dpublic:
$ t4 X( q( S: e    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);; w1 e4 D0 h" o9 b' W

" ^3 N3 R) b6 B/ Q2 |5 e9 C    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);6 ~, O3 b+ \6 d/ y6 N
+ s' S8 x# \4 B
    void Clear();8 v0 z- o: E; y* ]' t4 \. ]% P- t
    bool IsEmpty()
- I( _3 c; s/ R/ Z6 }6 z" y2 a" u( e    {, J+ E9 b. p) n* V8 P: t. Y
        return vexNum == 0;5 m( m6 T% I/ B' e( X. [; D
    }0 E. y& X3 }7 l! ]: j
    int GetArcNum()const. v' B! q; y5 R
    {
, K- [3 k7 k. [1 f3 q+ o- r5 @        return arcNum;! U8 k3 G3 ?# w
    }
1 t% G  x- L+ S& X2 {; W    int GetvexNum()const
0 C. ?7 v9 J7 m, }. U# Y    {+ ~- z! z' E5 U& U9 h3 F* X: N
        return vexNum;
( T( H& e6 E  c    }
" k+ \- X. \# f0 z* M7 Z; q* x' i$ @1 Z5 U% I, Y; ^& @) e

! l7 P. X) H5 J% l    int FirstAdjVex(int v)const;
0 s) Q. w& Q7 n% e! j; H1 {2 h    int NextAdjVex(int v1, int v2)const;& Q7 f* w6 |8 \( o
    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
! i8 f' [/ q. F6 o. L* C( o    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;- K7 l2 I+ l. A$ O$ |
* o4 \  ]& L* B2 h
    void InsertVex(const ElemType& d);
6 O- }' |1 i& C3 R% m5 f/ I    void InsertArc(int v1, int v2, WeightType w);: Z- h; t- Y0 K1 U  c, v
% G  t$ ]6 L8 j5 H9 A$ B; J- F
    void DeleteVex(const ElemType& d);
1 \' G9 i2 u0 I    void DeleteArc(int v1, int v2);
8 q6 I, N+ G( T" ]- Y' p; k! N) j. L5 M9 |/ m* Q5 S  I3 [) m
    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);) C' y. F; G: K3 b3 A
    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
* Q) J- O1 F: {9 m1 K3 ^7 g, R
+ i- w" [8 P/ `0 [! g8 v    ///深度优先遍历
& m/ i6 r. D4 g# Y9 K9 {/ W  {    void DFS1(const int v);- P7 M$ m( g, J1 \
    void DFS1Traverse();
5 `" B! z6 k: o' ^    void DFS2();" R5 W$ s4 X! O0 \+ ?
3 ~4 N# p: r  r2 x  f
    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1# J2 P4 e- Z- n4 i4 s. e" k
    void DFS3();
  x/ q2 e( C- [7 y* e* _, Z+ R( W" y, `. A2 y$ L+ g
    void BFS();
( W+ f8 D% }3 ], z2 c4 x    void Show();
0 l! g) O; e0 i};" P. r3 l. ~0 T7 m/ ?: B; Y
: _8 `. U1 `5 `% G
2.函数的实现5 l" E& r0 d5 I  a6 h) \
研讨题,能够运行,但是代码不一定是最优的。4 {$ k' i# Q, \/ n" k1 @0 N4 U

% D$ u' j7 O; p4 q* L% ~& e#include <stack>
8 d; v3 G- a$ Q5 G% Q0 z( o#include <queue>
; ]2 F- G$ X7 }+ A$ z# V4 u
! M- I* z. N2 G6 V1 c! D: @& Wtemplate <class ElemType,class WeightType>
/ D. [# Y/ P0 }+ F4 W# L- U% HMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)5 V% r" k. S2 @: f! R
{6 O) m+ m( F: Q) b( _
    if(vertexMaxNum < 0)' k0 W& u  Y$ Q* T
        throw Error("允许的顶点最大数目不能为负!");
9 w& |$ |4 K" t6 E6 n( {8 }    if (vertexMaxNum < vertexNum), X0 d% s" W, U& y: q6 e4 z1 ~2 |# R
        throw Error("顶点数目不能大于允许的顶点最大数目!");9 b0 g- S1 Z1 [0 ^
    vexNum = vertexNum;
9 R1 s, q/ L- ^% a    vexMaxNum = vertexMaxNum;
& [9 M7 q; v) l( W9 A    arcNum = 0;
: b( T6 ~1 H1 w& I' K' g  p+ k    infinity = infinit;
! c( h  `# s8 B+ D# n' ?  ]    tag = new int[vexMaxNum];8 l" e8 ?# F; n- p
    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
9 Q# c( p. e( q# p7 _    for (int v = 0; v < vexNum; v++)
& x# i1 [: E- ^/ y; @4 E    {
" S0 G6 {  z9 [" K8 F- u        tag[v] = 0;
" }( C5 i5 P4 c* [* R        vexTable[v].data = es[v];  T' w  @5 O# n+ Y0 K
        vexTable[v].firstarc = NULL;/ S* ]+ \  N* |4 _$ d  {
    }
. I/ b1 P' [( U8 F. [}
% e- j8 o4 I, o. l0 Ctemplate <class ElemType,class WeightType>
7 v" @, f% M& @7 ~2 H" s. vMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)3 Q# b$ d* L- e4 n
{
; ~6 }* @  `. o1 J. |! h0 w7 D    if (vertexMaxNum < 0)* r+ Y& f- l0 U! _% h9 q2 \
        throw Error("允许的顶点最大数目不能为负!");
; Z! w8 |; E! {- B+ U2 q    vexNum = 0;1 R1 E, E, Y  S. G3 o7 Q
    vexMaxNum = vertexMaxNum;
0 B* r8 p5 K: ?* q0 O7 g+ ?7 f* E    arcNum = 0;
+ |' S7 F' r, ?0 e# ?' x0 F& y    infinity = infinit;
+ H1 q! y4 C$ P& t4 B    tag = new int[vexMaxNum];
* v+ V# g6 U/ W$ k+ V0 Q    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];: O: H& I9 W& D: u' M
}
; E* q8 k' r% j" X+ O9 ]5 Q9 K+ i; }template<class ElemType, class WeightType>$ k8 \8 T( I1 {9 l) g
int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const3 @6 [: i$ P" r0 b
{/ ~4 k+ ?9 W4 b6 p. q  y* K
    if (v < 0 || v >= vexNum)
; T) }( E/ t7 g        throw Error("v不合法!");
& ]9 l! ^% T( Y' p+ ~  d    if (vexTable[v].firstarc == NULL)' V1 u' @, X' w# s) P
        return -1;4 f$ t' ~! t( y" g  u2 V% V
    else
. z, I& Z9 a, C' l% A( j        return vexTable[v].firstarc->adjVex1;% C- _1 b) u7 f# D6 X" j3 c
}. o' ^" w0 a, h! E* |! L

8 d+ r+ x5 d# }& s+ Ktemplate<class ElemType, class WeightType>
& Y" S  f/ P) k! v& F1 O' ^int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const5 K. I- |9 A2 b$ c
{
% V5 y* I9 k4 ^    MultiAdjListNetworkArc<WeightType>* p;
* u' n' M! X+ x' O- O    if (v1 < 0 || v1 >= vexNum)# K: M# y5 |" K& x: f
        throw Error("v1不合法!");
: Y9 j: |6 @, M% s    if (v2 < 0 || v2 >= vexNum)3 u. C  ~. J3 o
        throw Error("v2不合法!");
3 p2 ]2 ~4 n( c) ^    if (v1 == v2)
& N2 n) X: w7 @8 ]+ S        throw Error("v1不能等于v2!");
; q$ E% b4 T$ d- l* k    p = vexTable[v1].firstarc;
  I) W' M  q% A& H9 ^: Q( J! ?    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2): [: Q+ E; J# a: O  r, W' _
        p = p->nextarc;
; U) p4 ~7 i: u% T* Y7 e. q2 g    if (p == NULL || p->nextarc == NULL)
0 Y' M0 V. F. ]' p, w( [3 e, W, Q/ Y        return -1;  //不存在下一个邻接点7 Y. @1 C/ g3 t
    else if(p->adjVex1==v2)# S  Q! C' X1 d
        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);% j( K3 z+ P1 C! E! T7 [
    else/ W1 F' Q. F* z2 t8 @8 }( c) s
        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
, L/ F+ h" Y+ t& v- G* d# s}
$ t6 M* K: h" d) S* o$ xtemplate<class ElemType, class WeightType>
9 j: o7 O7 E- l  R0 _void MultiAdjListNetwork<ElemType, WeightType>::Clear()
# J0 o* ~  i5 J2 S- |{
* c) a' c5 l0 Y; K    if (IsEmpty()) return;
2 ^  y/ [& y( O" Q, [6 a/ U) a( y$ ]    int n = vexNum;
: F; ~- P. w8 h9 g0 S6 f% G' O8 n    for (int u = 0; u < n ; u++)
' z. \+ z* m# Q9 Y5 Z        DeleteVex(vexTable[0].data);
+ I4 X. Y# l, W5 e2 @    return;. B0 x5 N7 Q* B8 Y  v
}
. v# U+ L# S7 w1 Vtemplate<class ElemType, class WeightType>- p  y8 k6 h" |' x( g! _
MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()* `! S8 ]4 w+ @. k; X  i
{0 |! t, m2 i! P5 ~2 l+ a6 ~
    Clear();8 W  {8 I) e$ y
}* H; y5 ?, Y9 _7 X& k8 \6 \' I
template<class ElemType, class WeightType>
0 J3 o7 _0 `0 Q! h& C+ GMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
. i1 v1 Z  h* c2 v: X2 }4 U{% y9 h0 n- K' F1 e& {1 f
    vexMaxNum = copy.vexMaxNum;
  k( Y. \3 D. T4 V2 I7 |5 u    vexNum = copy.vexNum;2 g7 o6 A( d: F
    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];5 R9 F4 W6 K1 `8 X! B
    arcNum = 0;0 L3 ?4 b8 q8 P- `9 B4 Q
    infinity = copy.infinity;+ y$ i7 {: E; R8 {. h9 ?2 [
    tag = new int[vexMaxNum];
7 _5 V1 ^% F4 m* K# R7 c
; p& w. q4 k' I; x  K    for (int v = 0; v < vexNum; v++)% e& p3 k( a3 ?4 X6 C
    {. c) i' b9 o8 C: w. D( ^
        tag[v] = 0;
: @1 {% i9 V0 b- I& c        vexTable[v].data = copy.vexTable[v].data;7 F0 r7 D& W" @# H6 ]& @/ S  t
        vexTable[v].firstarc = NULL;
" C3 n. j8 B1 m+ k* J# ~    }; x6 e( B  v# C2 e0 b
    MultiAdjListNetworkArc<WeightType>* p;9 O- X# U" |; N- Y( }+ M

5 ?( f* a6 e, p    for (int u = 0; u < vexNum; u++)  C  r+ B* S+ U0 z
    {
' ~* S0 s- r( x9 C        p = copy.vexTable.firstarc;8 U. y6 g1 Y* _; P$ g( p
        while (p != NULL)
4 p2 E, B+ I, z        {
2 ~: `9 r- V2 @5 z" [; L% h            InsertArc(p->adjVex1, p->adjVex2, p->weight);
# ?8 U2 o9 A+ w; g4 v! d( }            p=NextArc(u,p);
8 S( ^" e5 t$ k( M$ j5 k        }% P, r6 I1 T6 t+ ~7 o
    }
3 Q% K3 d) n3 J! B}/ c0 S$ A2 h" I% ^7 U  w5 v1 o
template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
! c7 ~% D( h; u4 g1 BMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
5 l/ s7 @9 U, v& l. W: U1 ~- C6 F) j{
8 Z: b/ h4 }9 J    if (this == &copy) return *this;
, N, p; z" @0 r) h    Clear();: z* j3 W+ B6 a- }% n3 T" J% K2 D+ m5 L
    vexMaxNum = copy.vexMaxNum;) w1 l% g+ Z7 O) |1 X: C, b
    vexNum = copy.vexNum;
4 O( E1 [  Z- w6 e7 q5 [& Q) g# u    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];/ C9 W" o( n9 a) v. M! b4 ^1 t2 J* [& U
    arcNum = 0;
) ]) w, B6 S+ A, Z    infinity = copy.infinity;, N4 Q6 H& y& b+ C
    tag = new int[vexMaxNum];
/ P0 [; y" J8 P7 |. g% w( D, D9 e) @, D. `' o6 X
    for (int v = 0; v < vexNum; v++)4 m% A6 T5 t" i( W! s
    {
. C" V6 B- I+ F  {5 C5 L        tag[v] = 0;8 W. w& I4 F( C" ~
        vexTable[v].data = copy.vexTable[v].data;
8 C( r1 A. {: b, T3 o2 l- O  B        vexTable[v].firstarc = NULL;
* a- U/ t, i8 K3 X    }
6 \: y* n  x8 w# z    MultiAdjListNetworkArc<WeightType>* p;1 n3 e- W3 h5 l) W
( h0 `+ \. o" B1 }8 d
    for (int u = 0; u < vexNum; u++)' C8 s8 K" ^- R; r9 E' B$ e8 k+ \
    {+ A, w6 c- z# J4 {9 x- ^
        p = copy.vexTable.firstarc;
' K7 Y4 T% ?$ i0 a2 ^        while (p != NULL)* u* W2 ]3 f/ T# ]: N
        {
5 u! @' K% Q! N$ a            InsertArc(p->adjVex1, p->adjVex2, p->weight);$ `/ O+ z- S; G2 j% L
            p=NextArc(u,p);( u( F( {5 \# |' i/ R+ W
        }
- w, [% c: l; `( |% b    }- H/ @/ L6 q5 X
    return *this;
" }/ R: b! l% n7 H3 W0 \$ x}+ y' S* ^# G+ J2 [0 x% ~$ I, U
template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
( W% t% o3 ?; H8 IMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
' T: r+ f7 V" d# k. {+ Q{7 X$ x2 S$ O  ^6 k, O! h
    if(p==NULL) return NULL;
0 B" U2 J7 R6 x) i. ~2 p$ e    if(p->adjVex1==v1)
# `* J" t7 d5 w+ x0 h/ L9 J        return p->nextarc1;
. ?* ?& A5 P( t- a4 L* [# ]    else" Q6 D4 J3 H) M, K7 f
        return p->nextarc2;+ y, _: L0 P+ X% H% C
}
0 [& D  i6 L" T% J5 @template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
' L, T" o( D8 Q3 n" L2 E* S) HMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const7 B8 ]1 F5 D- t1 k" v
{! H" M; |( H" I3 Y0 \! w7 C4 P" I
    if(p==NULL)return NULL;
2 H+ O" K# ^2 k0 r2 u0 ?: U# ?    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;% R8 [' F" `+ A5 I  S( u* a: Z2 V
    if(q==p)
! ?$ a6 i: b7 A/ C5 u% J3 O! L) M0 g) j        return NULL;
! c# a/ R' w& F$ ^% L/ j: w* W: k    while(q)
8 s( n5 q1 p% W" F7 `% l- a7 [* j    {
1 f' U- E. ?/ f& M9 U) V) D5 }        if(q->nextarc1==p ||q->nextarc2==p)/ J$ P) a! f) r4 L: p
            break;
2 a! Y% N- q4 r; o6 p% p. s+ U        q=NextArc(v1,q);& A% C' a( v8 X
    }
" ]$ H# Q1 t) O3 E: F, v    return q;" K7 D4 f& @2 S) |; O
}
" ?2 a4 `. N' d- A) {9 G: wtemplate<class ElemType, class WeightType>
: K+ N) z% g% ^, p9 Avoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)) s& X5 W! T! g/ t; L! u- C2 \6 c. C5 b) G
{9 F1 J( T1 t& H/ n- w
    if (vexNum == vexMaxNum): r6 p& ]1 y3 o. H# [1 R5 U) z
        throw Error("图的顶点数不能超过允许的最大数!");
# P% n7 X$ a" ]! |; E: p2 u: J    vexTable[vexNum].data = d;
9 \2 L/ A  S6 E- O! _2 T: P- _0 Y    vexTable[vexNum].firstarc = NULL;2 i/ z. w. R6 [$ \+ G# Y2 X
    tag[vexNum] = 0;
7 u+ p0 M9 u% M* S2 ~) T    vexNum++;# K) M1 q) b+ V0 j
}7 ]- \- ]4 k7 m% N7 G$ P
template<class ElemType, class WeightType>  L& V( M. V- e. K7 ]0 Y8 X) u
void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)9 ^- u- v  p- Y& o
{
3 y$ Y0 ~) ?( P' H    MultiAdjListNetworkArc<WeightType>* p,*q;
( J' Y6 I0 C# m! d) ^7 q7 P# C    if (v1 < 0 || v1 >= vexNum)
: `/ g7 R8 p' _; ]! y; `! w( G, N( Q        throw Error("v1不合法!");5 r; d! Z0 X5 Q$ s2 t* q% \8 y
    if (v2 < 0 || v2 >= vexNum)" ?+ `0 q3 e. k% h. B9 P
        throw Error("v2不合法!");% S  C; k- _) Y/ J- b
    if (v1 == v2)
3 m( l! I8 ]( [6 v. {        throw Error("v1不能等于v2!");  E" }* H. {+ _* @. e
    if (w == infinity)7 o- ?, Y, a3 |$ Q+ r$ c
        throw Error("w不能为无穷大!");
2 b* g9 Y# {9 ~; C6 T5 F$ v
1 ?1 L& L% h* o
' H2 w/ I. s% d+ e2 `5 i    p = vexTable[v1].firstarc;
( Y" R/ f# l! W; F) R. W    while(p)
  J3 e' U: y" b/ G2 s& e    {
2 h6 M9 ^9 q' ~: Y6 \        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
6 m; i+ J# C4 V7 x9 f+ m        {% y/ s6 Z( N5 D, n# o
            if(p->weight!=w)8 Y/ b, I' Q4 h. T* ?3 W- u/ r
                p->weight=w;
* E( m+ l& W: M3 l: ]            return;3 E( u1 l& D* H1 V& j' D( |
        }) G8 v7 z6 s. b! y. q$ Z

: U+ L9 t5 }) z9 w; K( o        p=NextArc(v1,p);/ }8 Z+ w/ M: N( h1 E
    }. w, t& D# v( J
    p = vexTable[v1].firstarc;
+ L3 ^# e6 Q' r" O2 F1 Q    q = vexTable[v2].firstarc;
, L5 @% ~( G4 x8 ]1 L+ G    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法/ {& [, M1 N/ t' |
    vexTable[v2].firstarc =vexTable[v1].firstarc;
. [" Y1 M! [$ T' }) d- v) k: U    arcNum++;, L- [$ n: v& j- J
}
6 o. Q# M3 z) Y
: m" H, z, ?/ [4 }: r: s2 btemplate<class ElemType, class WeightType>: D) Y. V; ?( `; E& V
void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
& [7 e6 e: F- Y! H) `# t) l- c( D{
5 _+ Y% A: j- G+ A6 O( J/ [4 s- w6 ]2 m' G  g" j
    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
, E: G1 I& Q5 z7 L( O# v! \    if (v1 < 0 || v1 >= vexNum)* M; o! ?8 ]/ u( k& |. k6 V* G
        throw Error("v1不合法!");9 J# {% S% h% W- K" P3 n# _, z
    if (v2 < 0 || v2 >= vexNum)2 c/ C5 ^8 j% |4 o) U7 w3 g
        throw Error("v2不合法!");" g7 @" r7 S5 U3 o' c
    if (v1 == v2)
  b) m& @/ y( K. i7 Q        throw Error("v1不能等于v2!");
$ g5 w4 Y4 ~9 Q/ S4 U( P! |7 B$ t; {6 f: D2 l
    p = vexTable[v1].firstarc;: k" @; N2 w5 O) y3 G/ L5 O8 I
    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)$ E  C9 n0 E7 ^3 t$ `6 l. x* |4 Z
    {
: l+ B8 M7 ?, E8 M        q = p;
( x8 H' r9 s5 l4 O  h# y2 z; @        p = NextArc(v1,p);
3 H/ c5 l- K& L; _    }//找到要删除的边结点p及其前一结点q3 Y4 J- e5 i3 c. C6 n
( d! g+ T+ t0 E, ]& S5 [% y9 T
    if (p != NULL)//找到v1-v2的边
0 Z- s6 A. k) K4 C3 b    {
% b; X( Y! v) A: |4 ~6 ]+ z        r=LastArc(v2,p);
  R+ p5 S* H9 m1 f6 O' L- s        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
8 m4 p9 {" C, K$ h8 m            if(p->adjVex2==v2)9 p% I/ y7 c' V+ N$ s0 Y8 P: Q
                vexTable[v1].firstarc = p->nextarc1;3 ], r1 e2 J/ N6 o- D+ E& s7 ]
            else vexTable[v1].firstarc=p->nextarc2;" I- q! r8 B* W; z4 z3 M) ]- v6 F& y
        else//不是第一条边
- S/ _! d" M" f( \& [! W3 b9 G        {5 D  Y' m/ T* n+ Q1 n
            if(q->adjVex1==v1)7 P8 P" y) U) S2 H
                q->nextarc1 = NextArc(v1,p);
3 u1 V" {6 `5 A+ q; @            else& E: ~; c* z' w8 S) ~; b0 R) p
                q->nextarc2=NextArc(v1,p);$ E" N# g. n; y% Q! B6 b$ a  D+ c

' T5 [! l- a2 e+ v2 B7 j6 I        }
8 M0 M  S1 ?+ N+ d' I        if(r==NULL)
0 T4 k: N) V; W! ]8 O! ]7 s2 N            if(p->adjVex2==v2)$ a1 R: r) |7 V
                vexTable[v2].firstarc = p->nextarc2;" j5 R3 K% x) r
            else vexTable[v2].firstarc=p->nextarc1;
! v* k+ h* F3 F        else5 z# a) t9 J) G. r$ T; x
        {/ e/ v( r2 J7 I4 b- w7 W% P& _
            if(r->adjVex2==v2)
; x# a( ]/ q( {6 A                r->nextarc2 = NextArc(v2,p);
# ?1 X' S5 d5 g9 D  x            else
8 S$ e& u% r, `! H9 A1 r( Y$ I                r->nextarc1=NextArc(v2,p);$ m0 f3 U" {3 S  ]9 \
        }6 f5 j4 {& d  r8 J
        delete p;
0 o  m/ L; M4 o0 p6 x        arcNum--;
; B9 Z. l3 H8 q  q# S- {4 ^1 V    }7 t' K2 |" d& S
) h: o9 {/ |- {6 @4 N) ]
}
, G9 a; `) J7 K0 Vtemplate<class ElemType, class WeightType> void. y  Z0 ^! u' ~" I, O" g. J* ]" I
MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
' J. v. v% V7 i& C  e/ y{8 E1 y9 M, q+ N6 i8 |+ z
    int v;+ v- h$ F5 M) |# Q
    MultiAdjListNetworkArc<WeightType>* p;; ~- e6 }* D; N& C: l4 n
    for (v = 0; v < vexNum; v++)//找到d对应顶点1 c9 P$ A0 A4 t
        if (vexTable[v].data == d)' W9 J* y* A( N+ v
            break;
  y( c; Z+ _1 v' J$ ]    if(v==vexNum), e) g, `4 f0 |6 O! I' T# K) K
        throw Error("图中不存在要删除的顶点!");7 i) j, d3 I0 [0 [7 B4 h

  w: d' e2 l# w    for (int u = 0; u < vexNum; u++)//删除与d相连的边
0 A( @+ h9 ]6 i; m        if (u != v)
) `8 q3 D  `4 {+ k0 x7 B, D        {
! F8 v( z. A. K$ Y            DeleteArc(u, v);/ x/ X7 k/ L: p$ ?; |  h/ k
        }
9 S! `9 Q1 P8 O1 ?* v    vexTable[v].firstarc=NULL;
5 R! j: p6 M% y. b* J: m0 F8 z2 A+ n& T- v4 ^+ \5 Z# W
    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
1 P; Q! d7 h" t9 D    vexTable[v].data = vexTable[vexNum].data;
4 h9 N4 A6 ]9 U6 y" h& @1 I, a$ F    vexTable[v].firstarc = vexTable[vexNum].firstarc;" H3 x5 {! E6 h7 e5 r$ M, v! G) q
    vexTable[vexNum].firstarc = NULL;
% N3 r" r0 Z% i* X& U5 b6 ?* d2 U    tag[v] = tag[vexNum];
; s0 v) c# U3 q7 _4 _    //原来与最后一个顶点相连的边改为与v相连6 f/ e  Z% N4 Y3 c. S9 F1 E
    for (int u = 0; u < vexNum; u++)
: q, b! O0 H. I/ i2 A9 L2 Z    {
+ Z# z' M" K+ o6 j" r$ t3 W8 n. O        if (u != v)! {- S! H( h5 Z" V7 A$ q! h2 S
        {$ B  I% D! z# C
            p = vexTable.firstarc;+ k8 R1 v' x4 _: P7 q+ O9 ^. C% S- _
            while (p)
" l) O5 T- p6 G            {
4 K5 O) `$ O& n! D" h& D                if (p->adjVex1==vexNum)
* u8 y, M0 h) x& K4 n9 k                    p->adjVex1= v;- `' l4 W: s; t+ q4 w
                else if(p->adjVex2==vexNum); r1 h0 A/ C  v' R
                    p->adjVex2=v;# Z  P2 @$ Z: M6 j$ ?& M
                p = NextArc(u,p);
6 O  w6 l1 F: z7 J7 l5 ]            }  I, r8 t% c$ H4 }  M% `
        }
4 ^9 m7 j& h/ A    }
; [% k9 H/ w5 P. y! P7 ~}3 {; i$ z' X5 Y, }9 t
///深度优先遍历
6 J; \/ g- q7 A) Rtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v). f( V6 c: J0 W/ I" p% d! Q
{
9 f3 _' Z2 g/ ]# q, \4 o    tag[v]=1;
) X8 n/ F, {7 o4 M    cout<<setw(3)<<vexTable[v].data;
2 g( k$ i  N) p    MultiAdjListNetworkArc<WeightType> *p;2 x, U( _, x& a- {# k! X
    p=vexTable[v].firstarc;5 v' n. K( N+ [  ?3 g
    while(p). o) u% H" i% y: ]% }
    {+ `; z( Q/ w& r, q( h
        if(tag[p->adjVex1]==0)* [2 K3 ]+ Z/ J. }( S
            DFS1(p->adjVex1);
( r0 q" N7 F, V  f        else if(tag[p->adjVex2]==0)4 l$ s' k  G+ h: Z, Q
            DFS1(p->adjVex2);
* _/ V2 c+ E8 p        p=NextArc(v,p);4 V! i2 k' v1 M
    }: _1 r' x# s, F
}
+ s3 @2 M, B5 q/ F3 a0 n( ztemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
- N; D% ~6 r# |+ F5 n{
' v( M5 }% R( N! A* \  u* [& [    for(int i=0; i<vexNum; i++)8 {8 w( X0 n$ ]+ J$ S% x6 n6 S
        tag=0;
3 `8 W5 ]+ C9 y# e( U  z    for(int v=0; v<vexNum; v++)3 E; \& ?! L. k+ [+ I) F
    {
5 h& W/ F& c# e$ O* V        if(tag[v]==0)) i, z7 i4 n9 z  M
            DFS1(v);
8 x; x5 _4 U+ C% F6 O# F% _% j    }
: M# E1 R! b! A, d% p  C- T}  `% r6 g3 m/ d. Z5 L
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
9 h8 w  @  _. C: E( \9 |& F{
, D& c) V& p; c! l% i* M" b3 I    stack<int> s;$ e9 v* x+ ]. _$ b6 ~* _# A2 ~1 E
    int tmp;
7 d0 e' X# N+ j0 L6 Z    MultiAdjListNetworkArc<WeightType> *p,*q;/ m9 b0 T1 u6 B: r/ ^
    for(int i=0; i<vexNum; i++)
$ ]. }& ^. t& }, O) z        tag=0;1 L+ o2 v  R  b5 z6 f, B  Y
    for(int i=0; i<vexNum; i++)
  @1 ~( q& s% x) s) R  C    {
8 o( W( h) A. F# J3 L+ K( T        tmp=i;* F& |6 X+ }# I+ y4 [/ q8 I
        while(tag[tmp]==0||!s.empty())4 [. x4 L4 Y% b' A/ a& {: G
        {0 I  i' S: j4 t- [9 U- g
            p=vexTable[tmp].firstarc;
/ h5 Y% c3 f% e            while(tag[tmp]==0)4 Z8 X  q' I* o1 ?& j6 C5 N
            {
' Z, F) R( A8 k: e8 c                s.push(tmp);
6 h1 Q  W; H2 M) e  q6 J                cout<<setw(3)<<vexTable[tmp].data;
0 s% @  u( B, E                tag[tmp]=1;
% p2 K* |" h; Y: d                p=vexTable[tmp].firstarc;: n5 k4 `$ \2 i
                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
# X, A" G+ N( k9 _6 F) V                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
; T5 o- w# u+ c: s7 {# \! v" U                //cout<<" 1st     tmp="<<tmp<<endl;8 Z7 @; c3 |9 G+ j
            }. Y: p/ J0 j8 P% X4 Y
            if(!s.empty())
" p" A3 ^* `3 W4 z            {
8 Z/ u/ A6 T9 q3 D3 y                tmp=s.top();
$ z9 v6 w$ i( {8 U, X                s.pop();9 c0 `. y9 V7 p" Y/ O
                q=vexTable[tmp].firstarc;
! A& V/ B6 T" ~                int t=tmp;
+ O, H1 `' z! G' F  t                while(q&&tag[tmp]!=0)
6 j! s1 l0 O+ M                {
& i! a& @5 h8 i, R  s5 B                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
* g: l. [1 x5 r3 ^6 K8 m                    //cout<<" 2nd     tmp="<<tmp<<endl;
- a6 ~1 r9 G1 `8 s  J' B                    q=NextArc(t,q);& ]+ r0 j0 v$ a" x+ E
                }! c, p3 r, _* W# X6 m* _$ d- y- n0 N
                if(tag[tmp]==0)* L& E( H8 b+ L/ `5 r: Z
                    s.push(t);
* _) |# a6 y/ g7 o# |4 _- R                ///1、对应上面连通分支只有1个点的情况
; u; d' h. g( w. X                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
/ F3 d0 o' B9 N$ A: J                ///tmp要么等于找到的第一个未访问节点,% u+ V" D8 E$ s! l% m; M& Q
                ///要么等于与t相连最后一个点(已被访问过)+ y* L1 S+ Z) E
                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点) f8 \( M. p8 v) t
            }
, x4 W: K3 ?& V! j& R( v4 h) u        }4 S& X% X# H1 @1 ~" @
    }& g, p9 W0 T2 X, R
}
; _: x6 r# K7 H3 ]//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
9 D* ^" O, i0 }* G- F2 I2 Ntemplate<class ElemType, class WeightType> int0 |, f1 g" n7 V: j
MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)0 \/ ~: ~7 p3 S4 J( e
{( S0 l5 |* W- ]* B1 f
    if(head==pre)
' l5 }% s( i0 |' R: O- x        return -1;) u; D1 n# I8 O# W* X/ u
* f. z  b) M' d: J5 t% a" u4 X  ?
    MultiAdjListNetworkArc<WeightType> *p;- R7 ]  N- x0 W9 U. f7 z7 g8 M
    p=vexTable[head].firstarc;
. f: Z* D* P+ a0 K0 [    if(pre==-1&&p!=NULL), B6 e: y% c. }6 d1 K
        return p->adjVex1==head?p->adjVex2:p->adjVex1;
9 w9 e3 [8 g1 `" X% E) I  ^    //pre!=-1&&p!=NULL
6 ~2 n% |% u4 c4 A2 B    while(p!=NULL)' a( v" B4 E7 B' K
    {
2 `) Y, V7 E5 R2 n# T/ \        if(p->adjVex1==head && p->adjVex2!=pre). J- a  E3 C! p3 E  B; `
            p=p->nextarc1;; y( c* O. L  d4 R
        else if(p->adjVex2==head && p->adjVex1!=pre)+ w2 ^9 x4 d. s, G' h) L5 _/ I) x
            p=p->nextarc2;
7 r9 p7 u- f2 W& |! }        else if(p->adjVex1==head && p->adjVex2==pre)
& S0 j9 W! U$ w, d% G. p$ a+ j7 n        {
( J- g; J' C# H$ }& J' L5 R- q            p=p->nextarc1;6 b, R% r# u$ R' Q# l5 q5 j- a/ N
            break;
6 F4 C6 F: e! h2 f" R9 y        }! S6 j2 D0 T0 A+ R
        else if(p->adjVex2==head && p->adjVex1==pre), X) B8 ^/ a/ V' X0 n/ [3 J
        {
9 Z3 \) H/ H7 O- s6 b            p=p->nextarc2;/ S# _8 v3 w: p; H, l$ n
            break;& W& p+ e  o2 Z8 a
        }" M9 {- G* h7 q  I9 w' h" x, L" ^  o% O
    }
, y  A# H! e  ~( T7 L    if(p!=NULL)
, n* l3 ?& D0 I! E/ K- e    {
2 e8 s  `$ u! P. D& H, E        return p->adjVex1==head?p->adjVex2:p->adjVex1;
. y& N3 o  e% A# b, ^( b/ b    }
" Z7 @" S7 Z+ o    else
8 W& c4 K! [$ _) d+ }        return -1;: P+ }; e9 j$ M8 O  j* N# ]
}; m3 l3 u3 Y3 Z2 E; m
. S9 M# W" z. Y+ [
  S# ?$ l/ X0 X
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
# F! F+ x$ k  \/ [{  g7 h2 u6 ^9 x3 S8 p) m
    stack<int> s;: X- _0 h% I  u" S4 z
    int p,cur,pre;
% J% g  R0 ]7 I+ d    //MultiAdjListNetworkArc<WeightType> *p,*q;
9 r( O7 k% x5 l9 U1 T. v( h  Q/ ]4 M    for(int i=0; i<vexNum; i++) tag=0;//初始化
" V7 H; e) n( ~/ e+ z5 ?& f2 ~3 _+ j( ^* y( P' \6 C
    for(int i=0; i<vexNum; i++)( F5 n! z2 C! i( o, X
    {
3 c  z- J3 C: a( _8 X, P        cur=i;pre=-1;
2 G5 N( J/ |0 k: H1 y6 x; b0 Q) I        while(tag[cur]==0||!s.empty())
- R2 b/ ?6 A2 O        {
! @! c7 K1 d1 N            while(tag[cur]==0)
: k; V9 v  \3 G5 j; Y3 i% N8 M            {
( z& i9 S) I/ w! X$ F                cout<<vexTable[cur].data<<"  ";, t9 Z' q0 X3 u, c
                s.push(cur);
" ~3 ?: i+ `+ d/ b                tag[cur]=1;
3 U  ~, e4 R% i: Y: Z% u& z) Q( N               //初次访问,标记入栈: w6 R  A$ p9 o+ W- ?5 A+ X

, d. h; n5 P6 r0 e- O               p=GetAdjVex(cur,pre);//p是cur的连通顶点
8 [) ]' ]" h5 I$ f$ i/ L0 G0 n               if(p==-1)
. R! A2 z! Y' E) R' n, h               {
2 P, R$ ]6 t9 X                   pre=cur;s.pop();8 y1 u* T! @. z
                   break;" _+ i; R5 W9 B6 V, w9 R+ T
               }8 V6 I- i8 R7 E- O! |
               else
1 P& G$ A1 U" P( R; P6 M3 V               {
3 S& f; v, H$ w9 \; F                   pre=cur;
! l' c, g( z5 t* e                   cur=p;9 h; O. y4 v8 M
               }7 ]) j9 r8 a/ Y/ z2 @

& ?4 i9 F: m( O) l3 G; v            }
' b8 B7 a3 W3 i* G' p2 P, D# s+ H3 Z            while(!s.empty())
( }* Z" X0 X7 E, w2 |4 o            {
9 K0 c, j) j4 P3 P% s: W# f9 D                cur=s.top();+ K7 y' V7 x: D
                p=GetAdjVex(cur,pre);
' z: M# D* g! [6 w- H                if(tag[p]==0), ~* [6 ?" b) j0 h
                {) Q% I3 Q0 U2 \
                    pre=cur;6 l: @8 j* F% O2 t
                    cur=p;' p7 Q, a- w" v& g) D2 U
                    break;
, }& n8 K8 J5 J: h                }. |# X: ]( x1 S: |7 T8 k2 [5 X
                else
7 a4 c2 Z7 t! F; D* a9 x                {; t6 t; M8 [6 g. E; g$ K
                    pre=s.top();
+ n! R7 \/ r) z* ~7 j                    s.pop();
: m% R6 _9 H' P0 v9 h3 e0 l$ ^                }
8 u0 L* @" R# v: _! m* I: o, I( ?& K- v7 f
            }0 d9 ?' y* U- F2 P0 _. \: T

9 l# x) Q0 b! Q7 A2 y- M0 r        }% p0 T6 e7 t4 ]' m( t" k  C
    }: r5 O0 ~; q) A& a- j
}1 j1 I2 W9 w) {+ q
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
" H1 C9 `5 o& k: {8 @5 a% ?{0 }1 ]6 }0 B' l
    for(int i=0; i<vexNum; i++)" w) {$ f  U; q4 }% a
        tag=0;2 ]8 _( }' \9 r
    queue<int> q;
3 o/ W  E; {" o$ s    int tmp,t;, z7 Z& a' f6 \* Q- j6 r, Q1 w+ F
    MultiAdjListNetworkArc<WeightType> *p;
& K/ o# u+ ?; I( x    for(int i=0; i<vexNum; i++)
. Y# D8 L* [& O$ j  F! n% {    {
( p1 x/ Y2 l  U7 N" C+ @  l  k- M        if(tag==0)
; O3 |4 w8 G/ E- g4 N/ e        {
; k& Y- W8 B  ?# x            tag=1;
& B, p- E2 p1 B0 i0 H            q.push(i);" R, J9 w( u- P/ V/ G; [3 f
            cout<<setw(3)<<vexTable.data;
3 i" m1 a4 |' F' A$ ~2 u# V        }
7 G* y2 x, g, F' Q6 E9 g; u        while(!q.empty())
+ A2 D$ z5 l; h" A: G6 W        {0 [  Y7 Z  I8 \6 ^0 M3 }" @
            tmp=q.front();. }' W' T* _! t& t' ?
            q.pop();: R5 X2 ^+ r& K2 ?/ W
            p=vexTable[tmp].firstarc;
; {+ \) G! N6 R9 M            while(p!=NULL)  h0 r* Q( ]3 B4 R  O- s. B0 L
            {
1 G2 L$ z' O& D$ B% o                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
+ S+ ?+ s1 Z, T$ r6 n7 \                if(tag[t]==0)6 U6 q$ q( A% u# H+ s
                {
' Y% Q" E& ?) C/ x/ b5 z                    cout<<setw(3)<<vexTable[t].data;- ^2 H9 }0 d' ~- e& v( p+ F
                    tag[t]=1;
% o! x# F" b& b2 g' x  F5 r                    q.push(t);
  Y" z' O, [) k0 K) _' M                }2 i" N& J% _; U1 ?$ I7 X/ r7 i
                p=NextArc(tmp,p);+ ?4 I; w! c& l! Z9 @# ]
            }
$ S! K5 X/ {; a" v1 K        }
( u* c0 f' ]4 ]/ w6 }' |0 [    }& }9 T, o6 {9 y2 f$ X8 w2 {
}
. }/ S' K) k0 [. ^2 Y/ utemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()! H, X* A6 l" O& d
{
/ m; X2 Z2 \& f% j" {" Q; F    MultiAdjListNetworkArc<WeightType> *p;) k6 l* t- p  j
    cout << "无向图有" << vexNum << "个点,分别为:";
8 D1 f( I3 s4 m5 ?- c8 v4 y    for (int i = 0; i < vexNum; i++)
. E- r$ j( {. {( A5 n+ m        cout << vexTable.data << " ";
9 a% y/ O5 u+ W# E: ~    cout << endl;
, [& n3 n# y" h  X2 K- J, O) O% X    cout << "无向图有" << arcNum << "条边"<<endl;9 g, F2 y* c0 B* E5 t9 q
    for (int i = 0; i < vexNum; i++)7 c: q0 ?1 N# z
    {
# f( n, E& L& C        cout<<"和" << vexTable.data << "有关的边:";
7 x  m- @. f- r/ |        p = vexTable.firstarc;
& J& K1 @6 L/ u        while (p != NULL)
" Q: @5 A% f3 r. {0 p% J3 ~7 P; M3 c        {1 O' M* a  g2 i( C. N, K& K' T
            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
: Z# s4 W, |/ `- B            p=NextArc(i,p);
9 f, `  Z# M1 X/ W+ Q2 _  s/ W7 j        }
+ Q& u/ Z# l0 x) N2 D        cout << endl;
5 c1 q; c* r5 b$ B6 ?: V    }0 R" W5 r! G* J
}
/ y3 i9 u/ l7 f( _
% b, r& x6 I# [1 \- S4 o( A. N
5 H' _7 f3 u" Z+ D9 ^' M邻接多重表与邻接表的对比  }5 U' S& J7 J0 V6 T

, F7 m3 u8 U+ {4 U, W邻接表链接
; f- Z" `: d+ u在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
$ x6 a3 {+ C8 ?: N# }. B: C在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
  y" t6 c5 [$ f6 }1 m' o3 c4 P为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。, X) b6 o3 A1 Y$ W
————————————————+ s4 R) q5 w' B' |2 o: E
版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
' W8 }  D; x) L6 o/ c- d8 L原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
1 K9 S4 Q8 {/ G, P; U8 I
# O( ]" A0 x4 K+ Q) x  K8 |
# H: u( s7 S3 [1 ]7 T3 y% d& _2 d, }( `: D

; q- B' z+ {+ K% l" L————————————————4 S, \& g$ Z# u5 h+ N+ n' E2 L$ p
版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
5 \  B8 z: M, [( P原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958/ f! R) J  @0 X
. m* e$ |+ y- p6 |1 |+ F* w4 e& o

- ]: G, {& \/ y' D3 V+ o& ~$ d




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