数学建模社区-数学中国

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

作者: 杨利霞    时间: 2020-4-26 15:26
标题: 图的存储结构——邻接多重表(多重邻接表)的实现
- x1 l4 O  b( T2 ]
图的存储结构——邻接多重表(多重邻接表)的实现% K" Y% M% w" t& {
7.2 图的存储结构
7 Q- a! ^4 u7 A1 M. s1 p) Q" |- l. a( E
7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
' q8 z+ ^  ~  w# F% [, H邻接多重表的类定义
* S6 F$ Y( x# H5 m: p邻接多重表的顶点结点类模板5 e: [0 W% Z6 Z! K
邻接多重表的边结点类模板5 D; Q- r/ W1 k* i/ M
邻接多重表的类模板
7 l; m9 \4 h- j$ V7 \  J/ E邻接多重表与邻接表的对比
6 v1 A: J5 u( P" Q* D. E$ ~# ]7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
2 n; U- H# Z( R& \; }% I. [
* s5 {' m  V! r- g在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
- q8 A  j5 b. {在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
- ]% V" R  K, }# z3 n
! H( }- n5 M- s4 k( b5 M邻接多重表的类定义
3 X) y4 B1 F* r; |% Q( w5 S 1.png ; C/ B  V5 o8 b5 w3 U7 }
邻接多重表的顶点结点类模板

对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:" K0 r' K' _- ^
data域存储有关顶点的信息;
1 r$ E# G3 O- `2 n: f/ Zfirstarc域是链接指针,指向第一条依附于该顶点的边。+ a5 t6 v2 Q- h/ f$ l6 y3 b
所有的顶点结点组成一个顺序表。

* ]/ h! A. u5 B3 Y' x* C! c9 o

3 M! v( f9 ~6 mtemplate <class ElemType ,class WeightType>
1 R: k( b: z/ Yclass MultiAdjListNetworkVex: r  a7 _* j, F/ j
{, V( H; J$ m# H' h6 Y/ g/ t6 a, {
public:
$ Z- [; D+ R/ ^; W        ElemType data;/ q6 G* f( l0 j( N3 m% E& o
        MultiAdjListNetworkArc<WeightType> *firstarc;
9 q; g+ a$ l0 m; i# t6 U2 s; T- I
+ b- L2 R. G6 c        MultiAdjListNetworkVex(): _% @( h3 [2 ^+ ^. C, C( Q6 E$ t
        {
3 m1 c) `! h+ n+ C( }# j                firstarc = NULL;1 o, a6 P6 Y* M; i9 W( g+ _5 P
        }; o# e# J( s6 ]; Y& s3 t1 U5 T. Z
        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
* j# S) X! @& I  T" {4 H! L$ t& C+ L        {
5 ?) z9 S* I% L; V* x                data = val;) z4 ^" w" D$ p
                firstarc = adj;
& _. k* r$ M% T( }% B        }
5 ~0 N0 d* t3 Y" X};
+ g2 w! f$ c. M, w7 L" e" K
3 F$ P. X" _3 J: V: b/ b邻接多重表的边结点类模板
2 [0 i& F! Q" v2 e, }2 x& a* L% F/ V
在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:& v* w* Q1 B$ K# k" H; o( D; Z" ?
tag是标记域,标记该边是否被处理或被搜索过;. \3 k* v; G8 w$ c0 c( a9 I
weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
( z7 D5 D! V# R4 h0 Mnextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
1 f! L: q- O  ?$ E# t- M3 r% R+ }nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。, h# J. d6 a' i8 q# p' k/ B
% [" I+ S; y+ {- H, ^
2.png
$ m- g' H3 w+ {+ i* }8 stemplate <class WeightType>6 @; n1 n. ?" g' t( U3 p
class MultiAdjListNetworkArc  `7 n& p; d0 W. x. i; e
{
& K9 u" s9 o# B6 e: n0 \public:
" G4 `3 B4 w+ H! b2 f! h- ^. O7 `    int mark;                                       //标记该边是否被搜索或处理过
: J* V+ T0 B, T  Y* E        WeightType weight;                              //边的权重6 l; {; G* D2 |0 r
        int adjVex1;                                    //边的一个顶点
7 A; L$ g/ o! w* y# y        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
0 v1 F% C' X" B) G4 S$ a$ W        int adjVex2;8 S! k( ]" T+ P1 m: o/ t
        MultiAdjListNetworkArc<WeightType>* nextarc2;
4 T* c4 P* I) R: d4 E( I+ A6 Z
! B* L5 w+ A8 n/ N4 Y        MultiAdjListNetworkArc()) v6 a" V! @( t! ^4 ]
        {) t) r2 a9 V  R$ L' R; ]$ s
                adjVex1= -1;, L$ r2 R* z9 C6 [& m
                adjVex2= -1;
! ^" J. t8 e4 N3 ~3 y) F2 P        }# K  z3 v( L, G' _: l& Z: j0 K6 r
        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)3 Y  k# f  r4 ]+ ^4 @; q; d
        {& R( j6 a. H- c+ ?+ M
                adjVex1 = v1;       adjVex2 = v2;( O' x" {9 p% @2 N( _8 g% s
                weight = w;" G; E$ b& a0 b6 B" i  ^* |
                nextarc1 = next1;   nextarc2=next2;5 T- p+ A, q7 q; O
                mark = 0;           //0表示未被搜索,1表示被搜索过
7 Q* h, N1 |; [0 Q2 S        }$ q% r1 u1 u9 m. [& W
! g3 \. f0 T* g+ t
邻接多重表的类模板

1.类定义

template <class ElemType,class WeightType>
0 [; \6 n) o* G8 \1 A- Kclass MultiAdjListNetwork" D; i+ k6 ]% q% z
{8 }  R/ O2 E% }9 L+ s4 E& P
protected:  m% Z+ u9 Q. e& N8 T3 b
    int vexNum, vexMaxNum, arcNum;
2 U0 N' _' w) f; A4 N3 ~( X    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
* Y$ U! z2 \2 a$ X. v5 i* F    int* tag;" M5 D' }" f- K" B
    WeightType infinity;
9 l: }. v" V' c9 M/ O% A" S
  R4 c2 ?5 Z- l2 ^' _0 spublic:# V' e; \5 c- U& o
    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
. \6 `; C% V7 Z1 k: z+ d# O3 U& m0 }& a& k8 s+ R3 s
    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
( \! K! O! p& }1 }; o3 G) u0 i& A  [0 \& h5 L
    void Clear();
) X( |+ l4 b' j9 o/ H    bool IsEmpty()+ Y# P, r, E6 @- k. f
    {7 S7 F: J/ n8 z$ T( N
        return vexNum == 0;
# s0 b/ O- y3 \' y4 g    }
0 C' Q1 t* g  ^8 Z5 q    int GetArcNum()const* Z: E# K+ W( q
    {
7 I: h  ?( y4 k- i3 L        return arcNum;
6 o# d; H6 `1 p3 M& f    }
8 r2 R1 o2 h* Q, X    int GetvexNum()const
" d! p4 u5 t/ x- ~' w* B2 }4 b- G    {2 S3 H0 x8 P2 g% R0 z2 _
        return vexNum;4 n7 c" W9 e; d; ?  ~, M$ m
    }
; K9 O3 |1 V  u% a) p4 Y: Q6 G
7 n' s8 c" I1 n7 A+ ^- d. ]; V, b
& `( |7 J4 k, w# q' I9 Y    int FirstAdjVex(int v)const;
3 @' O% \0 R% Q/ ^' s( y    int NextAdjVex(int v1, int v2)const;  G! b  ]% Y) `
    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;5 d' b% C6 ?) s8 v
    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
' ?8 Y- O, c6 x8 b0 g; ?3 o+ W4 q, J; l2 P7 t: S& _6 Y
    void InsertVex(const ElemType& d);8 p- |5 r9 T/ m& S
    void InsertArc(int v1, int v2, WeightType w);
1 q+ U' Z0 }) B8 r! y) S# q5 T- r) {% i6 s
    void DeleteVex(const ElemType& d);1 i" u1 V( \5 O
    void DeleteArc(int v1, int v2);+ F) X; U2 b- g
. P/ ^4 }) j8 h0 d: r
    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);. `2 y# S) T3 x/ a
    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);" G- M7 e. v  g8 w2 p
: ]! {4 o8 x4 x1 _7 P( \, r7 P
    ///深度优先遍历9 d: c2 x8 }( F* P0 L; ^6 @: m
    void DFS1(const int v);
$ T# b& x% i8 `) o# d    void DFS1Traverse();
5 }: O  c0 K* X& i    void DFS2();
0 G: U8 H, _" X: {
  I5 L) s1 U% y/ y# H" e# W    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
7 B2 ~' k% f. j8 i2 j% D    void DFS3();0 E( v& C* e( w/ q
, f% P( }& }9 k# ]
    void BFS();& T( E( R" W! I( K5 x8 Z! J. l
    void Show();
5 O1 n7 {/ r% k$ ]& y1 M};
7 u' r; i2 L4 w, N
3 R/ Z2 y  M0 E' o2 ]2 h2.函数的实现' h0 ?& I$ Q/ {
研讨题,能够运行,但是代码不一定是最优的。& f. G. L* K* J& p

. T, ]( g- R0 `6 l7 y; p8 j#include <stack>& d  \. d% ]" N+ f! ?
#include <queue>
) N* w5 Q0 e) o
% f5 `- z, r& O& l9 o- Ctemplate <class ElemType,class WeightType>! \. l/ X+ ~9 @. M6 h6 F
MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)+ c0 g# g1 H1 }8 d: L* }
{. M- E1 }1 z  |1 V
    if(vertexMaxNum < 0)! c, }3 i) ~; `+ k& G6 Z
        throw Error("允许的顶点最大数目不能为负!");( W. i1 F) b& C# M
    if (vertexMaxNum < vertexNum)
6 d$ G9 M, u: W/ J( J! B+ Y4 @        throw Error("顶点数目不能大于允许的顶点最大数目!");
& P& \- F+ Z% s, E# H6 z9 _    vexNum = vertexNum;) |) f8 N) ~/ u* ^# Q0 W# O0 u# o
    vexMaxNum = vertexMaxNum;" p: d: {: ^; W1 b! R/ t7 f7 x
    arcNum = 0;
' u( ?% S  V3 W# h$ w    infinity = infinit;' A( K/ D$ J  W
    tag = new int[vexMaxNum];9 }$ H& W! ^; Z9 `
    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];- H5 h; Y. O3 F3 j' L- }
    for (int v = 0; v < vexNum; v++)/ e3 \" n/ l* Q) x6 q
    {
- j, W0 n  o8 d' O        tag[v] = 0;
  L! x4 }. Q( D        vexTable[v].data = es[v];2 C' [2 _5 i2 g% W+ |
        vexTable[v].firstarc = NULL;
- [$ L6 ^9 K) w  c    }
9 m# Z& f& P" Y  J}
0 G0 s5 Z1 m3 F4 Q  P) x+ n3 ^/ Itemplate <class ElemType,class WeightType>
+ C1 N, ~+ R2 S% QMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
( `& q; V3 q* q& {! l) ?{1 g- s  B. c8 S( U
    if (vertexMaxNum < 0), Z0 @/ N$ b+ r! \$ D- d1 n2 Q
        throw Error("允许的顶点最大数目不能为负!");3 @$ O5 e( ~% q: M' j7 R9 {
    vexNum = 0;6 H$ ^" d% D3 }
    vexMaxNum = vertexMaxNum;9 o$ i8 G% G; H7 n+ v" i
    arcNum = 0;9 ^& B: S0 B4 y: S5 y' u
    infinity = infinit;9 j" _5 _) Y5 n
    tag = new int[vexMaxNum];4 {( {9 a) x' E" U
    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
" X0 n4 j6 W0 d" O8 S}& u4 t3 a5 c% H# J9 j# B. p# H
template<class ElemType, class WeightType>6 I+ X" h% g' X" V% Q8 @0 n+ ^
int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
% G. b, h4 S! u. _# P{
- B6 _" g2 m. x2 E9 A3 C    if (v < 0 || v >= vexNum)! y1 h' B1 |/ e# ^# M
        throw Error("v不合法!");5 G6 {6 [" H, H  @9 ^$ m
    if (vexTable[v].firstarc == NULL)
0 ?' s- B( X0 V: o        return -1;3 Y4 g- R+ l; {
    else6 j* R  e) E& b- |* k
        return vexTable[v].firstarc->adjVex1;" j7 K: I: Q" {6 y% S8 `
}* q8 J. s2 I7 [6 k4 A) G: P
! E; e3 k: a" w5 w& ^
template<class ElemType, class WeightType># v) g* j4 Z+ D  G
int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const$ }9 M' z' d( J% z7 O
{. r6 o, y& ~7 F. I
    MultiAdjListNetworkArc<WeightType>* p;
- D8 O/ X! x3 r3 H5 `6 l    if (v1 < 0 || v1 >= vexNum)/ m! Z9 v- r" u& r
        throw Error("v1不合法!");8 _6 P/ ?8 N4 s' Z9 P; q
    if (v2 < 0 || v2 >= vexNum): x) s% V  ^7 S5 [, y
        throw Error("v2不合法!");
5 f5 D$ Z- T+ u    if (v1 == v2)+ S: `5 S7 D1 y
        throw Error("v1不能等于v2!");+ P0 y+ }: z) E  l# c* c( d
    p = vexTable[v1].firstarc;. G! R1 c' |; U1 n9 E& E: C& B  K
    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
$ ~' w/ N- I* g, n8 h. ]" R        p = p->nextarc;
) \! R+ a4 m  a, m" H; Y2 w6 |5 I    if (p == NULL || p->nextarc == NULL)4 x% o; S% s7 f, W2 W. `
        return -1;  //不存在下一个邻接点* ^) K& B! d1 ?
    else if(p->adjVex1==v2)0 v4 f. y* S* q  ^2 b  n+ z5 M/ x
        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
$ Y1 W  \5 j+ M7 D. @, {& a    else
# a( G6 S2 S  b9 `        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);& a3 X3 u: V- E# c% d1 V2 l9 ~
}
. q6 F, v- K3 M7 t* ttemplate<class ElemType, class WeightType>% a- C2 G4 w! ~5 l6 Y
void MultiAdjListNetwork<ElemType, WeightType>::Clear()
( W, r5 w( ^7 [) ^# \{
2 M+ y$ C2 ?/ ]/ n; f, X7 w$ }) B    if (IsEmpty()) return;
- ^8 E/ Y( Z% R    int n = vexNum;; t! `% E. k# Q2 ?2 |1 G* ~
    for (int u = 0; u < n ; u++)2 ~+ V9 |0 \& m$ S- v4 H9 G
        DeleteVex(vexTable[0].data);" b" Z/ G4 i" |( ]6 \- Z
    return;6 ~0 K) `2 P, z( C4 u
}4 A, Q" q  v# M. O" x  q1 N6 K' n
template<class ElemType, class WeightType>
4 Z6 }$ g7 L) }' ?8 z3 x" m6 C. rMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
3 t$ m7 T3 m4 v+ Z0 Y/ v! e' B{* w& x$ j+ [( \: X: U2 P
    Clear();' _4 E  }/ q% ?( K6 o0 @* I
}* \+ v$ [/ `, W
template<class ElemType, class WeightType>
/ K) \' q' F; @6 _+ D3 RMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
! s7 k2 Y; g' J, F, }4 |{4 y( H! |( P: H# U" ~
    vexMaxNum = copy.vexMaxNum;
5 i4 a  ]3 h8 }, u% A- X, |    vexNum = copy.vexNum;1 F+ b, j/ }  l8 M( B, Y8 ^
    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
9 K# Y, @$ ?' y* l  t0 I    arcNum = 0;4 h7 `9 Y+ B& {% o. L  ~) L1 B
    infinity = copy.infinity;
1 {  c2 H& k5 d0 a4 O. o5 [    tag = new int[vexMaxNum];0 Q$ W+ S8 ^3 x
" d3 D0 L: O7 l2 v3 W% J, Y: x1 [
    for (int v = 0; v < vexNum; v++)
1 w7 O) {* D8 ]    {& Q4 U. I, ~) p- R2 b. ^
        tag[v] = 0;
" e- E" P8 _7 q" W1 M0 E" ]        vexTable[v].data = copy.vexTable[v].data;' l+ A& a' H- D/ b1 a  M5 x
        vexTable[v].firstarc = NULL;
2 P/ j8 e0 I+ ~+ n, i  ?6 T    }
9 |$ G; J! n7 `7 z, e! @    MultiAdjListNetworkArc<WeightType>* p;# C' D6 X4 Y8 @3 V7 u# b

& ^. o) j, x% K1 \    for (int u = 0; u < vexNum; u++)
7 k# C/ I0 {$ X9 v! v    {# G% S  e6 U" Y( H: q8 {
        p = copy.vexTable.firstarc;# z- N5 K7 K0 J# a
        while (p != NULL)
" O, }0 e# |% k7 s2 ]7 g: Z% r        {  {4 x0 L/ v( Z7 u7 g* C8 M. G
            InsertArc(p->adjVex1, p->adjVex2, p->weight);
) U3 G7 o% `5 Q8 i  U            p=NextArc(u,p);: H- ?- h' W% I: Z% E# a
        }0 [1 `7 g7 J8 Z* M7 _
    }
5 J+ M! ?2 E! t" V8 j2 x5 a4 B}) {6 L) X! {, Z; ?' [
template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
* m: i  ^& X. [8 D4 HMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
  O# w9 D8 m+ Q0 A4 K{6 ~3 H. |1 ~5 g# o- X
    if (this == &copy) return *this;' \) w! O" b* C% O6 [& z0 U: [
    Clear();
7 D5 V8 f7 D: B1 X    vexMaxNum = copy.vexMaxNum;+ g. l8 f+ T) m! A6 Y
    vexNum = copy.vexNum;2 ]; \3 g( M; x' _/ J: x9 V! u2 r
    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
5 O" i! A4 B/ E" _8 f    arcNum = 0;9 y, k2 j7 A0 S8 U* U
    infinity = copy.infinity;
2 {" X- [9 i+ _    tag = new int[vexMaxNum];
6 x$ J+ i) t4 N$ Y* T4 I& f3 b8 l- E) h  D
    for (int v = 0; v < vexNum; v++)
. e0 X! ^  w/ U% l) R) a9 F    {
# n5 h6 _- K3 @2 Q6 k+ q) i( D1 }: T        tag[v] = 0;: X# K' p& @; m( `( R
        vexTable[v].data = copy.vexTable[v].data;" g) q7 [" I+ M, T$ J" a& K. }
        vexTable[v].firstarc = NULL;
" d+ Q" k9 W  V) K; {    }
  O- F( N1 |3 [$ @3 \    MultiAdjListNetworkArc<WeightType>* p;* z% x6 {+ s+ {) e4 k
; G1 q# A% j: f9 ^/ C  K3 A( j
    for (int u = 0; u < vexNum; u++)
' Y, [7 c: t2 Q    {) b8 D9 U" C: i8 i2 u! a! G  f
        p = copy.vexTable.firstarc;% }  ?2 I4 Y! @& [4 p
        while (p != NULL)7 v; h4 S8 n/ Q) R8 P
        {4 X$ ], B, k! E: R- T) r1 Z9 d
            InsertArc(p->adjVex1, p->adjVex2, p->weight);% P& u6 c' x1 \* p
            p=NextArc(u,p);( ~8 S1 o  `& p/ w2 X
        }: P1 U" J) c; j' ]
    }
. g7 }, n$ U( m8 G% I    return *this;8 S- U2 C' D/ c1 T. D  W7 b/ }1 W) k
}+ |* o& e) O8 y& s/ w" `- h
template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*7 |3 E4 p" D6 v- b: t
MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const  H) d! W7 y2 P4 J
{
+ {+ H, w2 m6 @9 E* \  ?    if(p==NULL) return NULL;
7 G6 F( V( a4 D* Q0 c; L3 T3 M1 c    if(p->adjVex1==v1)
& K  c0 }/ h* Q  {* x        return p->nextarc1;
; ~! L, @: z2 s, f5 G    else
9 V" l7 \1 D; ?# D$ H        return p->nextarc2;
  V) M/ O$ p- q1 c' U, ^}- l! a1 N2 @* z1 L+ k: J
template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
$ }" a5 E' G4 \' y3 v6 E& Z9 fMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const- k4 y3 t& C1 T& U9 i. z4 {  D
{5 N% y! G8 ^, c# k8 s  F  ]7 J  o
    if(p==NULL)return NULL;
+ @  o( s; l. f2 V    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
; M# B9 w  G' T; _+ o: f! W0 E- g    if(q==p)
5 a( l" J+ a" Q, i9 E        return NULL;
4 g% q, R! ~& _6 ^& Q5 p    while(q)3 u/ [7 V2 f9 k4 _5 R
    {
& K' f/ z. S" |, M        if(q->nextarc1==p ||q->nextarc2==p)) q7 ^0 `3 V  S3 u
            break;$ _3 F# ~, Z2 a& Q
        q=NextArc(v1,q);
; Z& o0 g6 e! v    }
" L( p$ `: L) D1 C% c1 I4 t% I    return q;, {( D6 d0 b) Z2 E' f
}
& F0 R& f1 p. n0 Y" K: j9 mtemplate<class ElemType, class WeightType>0 Q& R0 ~# F6 W0 W% |
void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d), ^  |7 F" {( x3 m; i
{/ o/ m3 ~" [7 ^& f
    if (vexNum == vexMaxNum)
' o+ }$ K% g2 q# e4 G& w% N) n        throw Error("图的顶点数不能超过允许的最大数!");
  p* A2 c7 U: j6 t1 l/ ~    vexTable[vexNum].data = d;
- E$ X6 X" E" }- ^% ?4 P; \8 y    vexTable[vexNum].firstarc = NULL;. t- F: V" G) N- j2 i4 u& w: b
    tag[vexNum] = 0;" M8 H/ B2 P3 P8 S7 I
    vexNum++;
& |  p( C/ S& L) r4 l  J}
  c2 l2 Y9 T. \) W5 Utemplate<class ElemType, class WeightType>0 ]! m8 ~4 V* J! g8 u; y
void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)( X5 p) U% W1 b" \
{
7 c  M/ T& F' F5 \, v    MultiAdjListNetworkArc<WeightType>* p,*q;
, }) }7 L, w2 r# L& w+ I    if (v1 < 0 || v1 >= vexNum)
$ r3 f6 M5 S) h* _0 b0 n        throw Error("v1不合法!");
) B& n) K8 s# Z+ f" s" \6 [    if (v2 < 0 || v2 >= vexNum)5 s: p& ?, @+ h1 u7 g2 r
        throw Error("v2不合法!");  g0 y8 Z. l" ~. g, T1 R
    if (v1 == v2)' Y: r( C! i: p; z! c6 X0 i
        throw Error("v1不能等于v2!");
, Y; D4 |+ a& S( c+ h- s' G  [    if (w == infinity)
# \0 x: Y% z4 k4 R" ?; ]- O        throw Error("w不能为无穷大!");: g* H# S: p- [+ g8 C/ H  A
+ H, T. c, y6 u
: I- U6 W! V; L
    p = vexTable[v1].firstarc;: a3 B+ Z3 A2 _( v  l
    while(p)8 q5 D# s1 v9 ^& ^& A* h' P* F
    {9 `; u7 M7 i, K
        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
5 p$ K3 m: \1 J        {
1 a8 I; {/ `% {, h0 O% F/ J! d$ p            if(p->weight!=w)( N/ Y/ m5 t6 j! Q6 x. M  t! h
                p->weight=w;4 c2 y7 y% X* ?. e8 n' r
            return;
! S2 p+ N2 ?3 f        }
1 K. F# G+ v$ k/ ~2 X) R5 b& @. @
/ G& C9 R( H; _0 N: ?        p=NextArc(v1,p);  ~0 j1 e5 U( O8 ^" ?
    }8 O% f8 i* @! x4 P
    p = vexTable[v1].firstarc;; w8 K$ d% q5 B* u6 w# n* Z
    q = vexTable[v2].firstarc;5 E* j+ V. n5 _+ E( j
    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法7 S+ i1 f; t, p! r6 f
    vexTable[v2].firstarc =vexTable[v1].firstarc;
1 O. _9 w2 ?' k! d8 e1 k$ P+ w5 i    arcNum++;
& {5 Q6 m0 i& M' O. |  Q' l1 b2 [}  m; S! h% S9 P0 D

2 {* a/ \  |& Q' q7 btemplate<class ElemType, class WeightType>
: m2 M  Y2 ]$ m' B% p/ dvoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
5 [9 Y. _- p5 n( a0 h$ O" c; t{
4 f/ |4 ]$ R& A! ^
3 i. R0 S& i. O- ~: S! j    MultiAdjListNetworkArc<WeightType>* p, * q,*r;  ?# C2 \" A) N$ T
    if (v1 < 0 || v1 >= vexNum)' ]3 @  h1 p5 Q/ M# q, u
        throw Error("v1不合法!");; `  G9 n6 U) }6 ]# Z- T' S
    if (v2 < 0 || v2 >= vexNum)
( X9 y! G, ^1 f6 O0 h" S        throw Error("v2不合法!");. p2 m$ b9 p0 ~4 w  ]
    if (v1 == v2)
2 h  H( z9 R- r, j: y        throw Error("v1不能等于v2!");. p5 t% l8 Z  M7 _

) x! @& w  C' ~# m    p = vexTable[v1].firstarc;5 q0 |) L- H: I. N4 `
    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
1 s% j: L. w" ?9 P    {
+ f8 z8 k0 G7 K) R9 p7 f        q = p;
! R) w$ |- {' |7 F        p = NextArc(v1,p);
: `9 G* n+ @1 m) X  `& d+ F' \8 [    }//找到要删除的边结点p及其前一结点q
! b" L& a7 ]# T2 A  ^- t/ a, k( M( c5 p/ d) ^
    if (p != NULL)//找到v1-v2的边
: {# I2 S" V  l' |/ m. V& A9 N    {
# Y- C$ v  ~+ ~$ W( v0 Y4 I% j! v        r=LastArc(v2,p);
( p4 X1 W. O4 K+ ^) m+ f        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
7 _5 M1 m" T# \* K- K            if(p->adjVex2==v2)
4 Q/ X( U, }# z( I& K                vexTable[v1].firstarc = p->nextarc1;5 s6 o: p# p" G
            else vexTable[v1].firstarc=p->nextarc2;
  k7 ^5 H0 ^: v1 ~3 H, S! C( n        else//不是第一条边1 c- y- T7 J* v: _, y# }
        {3 h2 `' N. B; q: {
            if(q->adjVex1==v1)" b% ^  y7 H; [' K! W: ^
                q->nextarc1 = NextArc(v1,p);. P. v2 z  g4 u! y9 e0 P# g
            else; `" |6 ~1 ]0 j, ?4 r5 ?
                q->nextarc2=NextArc(v1,p);  u& D& i" U" e
8 o8 Y3 ~, v0 U/ p% s9 T% b% Q
        }( g; b" F; |7 B# {' G
        if(r==NULL)
! ^8 W% b: m8 H8 f, ^            if(p->adjVex2==v2)  S! j9 H" J! S5 }4 c3 U
                vexTable[v2].firstarc = p->nextarc2;- Z. A- f! O0 }+ F5 m- X; a. J3 C, [
            else vexTable[v2].firstarc=p->nextarc1;& T6 b- P1 `; `- E" n
        else( Z* m$ ?5 C& _- d' I7 h" ~
        {
- T9 q8 H" V/ ^* U2 H            if(r->adjVex2==v2)
0 h8 p9 C2 e# g) r; i5 C& e+ z. t                r->nextarc2 = NextArc(v2,p);
, c+ b" ?0 h. n( F8 v; `- _, T            else
0 K! b1 q+ b+ [* H2 D                r->nextarc1=NextArc(v2,p);
: \+ Q& y2 i% N7 l4 M        }
+ G3 @% V3 y* v7 r% W        delete p;
9 F2 H+ |7 c, O        arcNum--;
* A- }# V% k3 l# u' z4 f    }
' u0 |. p8 E+ R
( S/ f, Y$ u# R5 ~+ e. e0 a" U6 K}
. {% b# u& R, |9 y% xtemplate<class ElemType, class WeightType> void# j8 n# z2 {! n/ ?8 e
MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d); D. s7 }# r+ `9 c1 U7 W3 [4 ?
{
' z0 m, ^$ K3 t+ J# n% k1 m7 C    int v;/ x/ N$ i) h3 {$ F) F6 H* y
    MultiAdjListNetworkArc<WeightType>* p;8 P. _8 p% C- ~, ^4 B
    for (v = 0; v < vexNum; v++)//找到d对应顶点
9 D. E* ^& k' ?( V5 m, k        if (vexTable[v].data == d)0 A5 \  a: |% [8 D
            break;
4 O8 h) S/ Y7 G( p    if(v==vexNum)' f7 [) O' g& i' `) M1 C
        throw Error("图中不存在要删除的顶点!");
9 f% k3 @6 X% M
; I0 F1 u: ^- P1 [    for (int u = 0; u < vexNum; u++)//删除与d相连的边& S$ X+ T: a  K+ g' I) e7 Y
        if (u != v)
/ D0 B9 u2 t" Z# G% N        {
1 o8 R- h( {7 y+ b( o) Y            DeleteArc(u, v);
5 i2 ^3 U; Q5 C; J! J* h, c: x2 G9 W) Y        }* u* f) [. Y0 w" v  [: _
    vexTable[v].firstarc=NULL;
; X9 g% m4 Y$ Q0 E  P
; {. N# j8 W; l" H; T    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
9 P  K6 u  f! ~    vexTable[v].data = vexTable[vexNum].data;
* P! e/ @, y: [1 c1 V0 t    vexTable[v].firstarc = vexTable[vexNum].firstarc;, W, l4 p$ @0 f" o
    vexTable[vexNum].firstarc = NULL;
' [1 a5 ?4 k6 z8 ^- ]! x    tag[v] = tag[vexNum];. }! i+ ?- E# l/ k: u
    //原来与最后一个顶点相连的边改为与v相连2 ~1 R# a" e* h. Y  T
    for (int u = 0; u < vexNum; u++)8 S/ ^& P5 u" T! M
    {6 Z8 D( W" z6 \
        if (u != v)8 [5 y, B& ?  C
        {% o& [4 y$ C/ p3 M$ p' n; u
            p = vexTable.firstarc;
5 C% D3 G; d1 I: X) J' ?            while (p)
; v* c( L9 F! D) O! w2 j& K            {; k, I- W0 }& q2 A  A6 I
                if (p->adjVex1==vexNum)
) H1 W2 J0 W3 f1 I7 k) a                    p->adjVex1= v;
6 _* `" G) H( y. O* y/ `; @; E$ M                else if(p->adjVex2==vexNum)) G+ C# _* M0 M8 Z  _: K  s
                    p->adjVex2=v;. P2 S- ^% _! E0 W
                p = NextArc(u,p);
+ Q: O$ E) Q. h* x- a9 b$ K/ k! P            }
4 q2 V, b) b6 ^        }5 t; p- W- {" R8 M9 s# ]
    }. [" S" p1 @" ]9 y* y. F
}1 P" @' l' H$ u  w
///深度优先遍历
& T" Y! G6 D' \  f, v6 v- Wtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
2 T' y# z9 B$ c9 ~, k- x{
: n9 B! j( ]) T! O& P- {    tag[v]=1;
$ y  B0 t9 n+ m% X( e    cout<<setw(3)<<vexTable[v].data;" @) g) d# O! ^
    MultiAdjListNetworkArc<WeightType> *p;4 H* }* k$ i' G% ^1 d
    p=vexTable[v].firstarc;- X% M4 |( L" L7 ~+ m1 ~
    while(p)
1 ?0 A1 I3 e8 R    {3 R/ v5 X; Q* r( @$ w: g) ^5 I
        if(tag[p->adjVex1]==0)
# ~+ I/ b7 l% n& V7 ?1 r7 x4 g9 j( A3 t4 r            DFS1(p->adjVex1);
) e; |9 k- V! G3 S1 O1 Y        else if(tag[p->adjVex2]==0)
" z) H  M1 G+ e0 M8 f" p, q            DFS1(p->adjVex2);
, j: I6 X) m# r# j3 h9 ?        p=NextArc(v,p);8 y4 i% t& ]0 Q/ Y+ }
    }
& Z- G* ~' M4 C( J}1 ~* J9 j% q6 ]# P
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
3 s2 `3 f. R$ Q# |- H{
8 l6 q& {8 r: V+ M1 R' \% \    for(int i=0; i<vexNum; i++)
8 u1 W! U' p) J  F' G# F- V  ]        tag=0;6 w' B: H: |, N) G& b; z, c/ a6 Z8 Y
    for(int v=0; v<vexNum; v++)
8 l# O% [/ J" ^9 p: d7 d: G7 O6 K    {3 U# ^9 ?4 {3 t4 Y) p9 K5 b% y
        if(tag[v]==0)
/ j2 c/ a3 c. `: ]            DFS1(v);
2 u9 M% I' R$ E    }
$ |6 j- k3 F5 D1 ]4 E}
9 \& }! @2 K( |7 _, etemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
' X7 D! c3 w- ~. g1 r0 U* H5 ?" J{. N0 W* O" j$ b8 W5 w: r$ z
    stack<int> s;4 o: M' X5 V! ]8 t1 t; S) E
    int tmp;; y1 L1 E, }- B
    MultiAdjListNetworkArc<WeightType> *p,*q;# c$ z" _) \: M: [+ E! t
    for(int i=0; i<vexNum; i++)
8 ]1 e) o% {  Z8 j        tag=0;) X% [& m8 Q, i0 ~9 N; J
    for(int i=0; i<vexNum; i++)
2 E$ T: q. R, \" w# i$ i    {
. ?# X5 @* a1 J1 t4 Y        tmp=i;2 _# o; Y$ @$ a
        while(tag[tmp]==0||!s.empty()): m. Z  }) R/ }1 [3 X7 l5 A( s
        {
9 k& T: f' s1 b6 j            p=vexTable[tmp].firstarc;
5 a" |7 V7 W: @% R) v& q            while(tag[tmp]==0)6 D% B0 F* Y" D/ S/ ^7 ^: l
            {
7 M9 X4 J0 ^7 w# g# S& {; v7 h( h) i                s.push(tmp);' \: C0 Q& ?' D
                cout<<setw(3)<<vexTable[tmp].data;
+ _* ]9 G3 e2 e' r. E( r                tag[tmp]=1;8 C9 d# A2 f/ _
                p=vexTable[tmp].firstarc;
. b/ ~0 B, e) N, {6 _) d3 H4 B( x2 j                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
5 a. X5 C7 o  Y) j7 i                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
1 U7 C7 n: s, F8 ~; q( Q4 H                //cout<<" 1st     tmp="<<tmp<<endl;) d; B6 S, t6 r8 X/ L. s3 Z
            }
- X1 S4 i2 }7 M4 R+ J            if(!s.empty())8 X$ H# `; ?$ m9 X8 Q# N
            {
1 Y- J) U+ p( L' J$ d3 {                tmp=s.top();
; ~" H# X: i/ }$ `# ~                s.pop();8 ^  e- D. J5 k* x" i0 k5 _
                q=vexTable[tmp].firstarc;2 D% S- k+ L3 y: Y0 O* _4 d
                int t=tmp;" g2 g* m( t) j! e  u
                while(q&&tag[tmp]!=0)
/ @4 j8 `2 `  {4 f6 ~* d' y4 k3 p                {( T5 w* f, ^; I  L6 |. g( K
                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);3 s1 Z/ X% i& A4 S$ w
                    //cout<<" 2nd     tmp="<<tmp<<endl;
. ^- j/ k* _8 ?8 w5 _) X  k/ P                    q=NextArc(t,q);% C! V: z4 u9 o4 o6 s
                }
% r3 a$ }. j/ X% n; n! Q                if(tag[tmp]==0)3 L0 g- s8 }+ ?2 `8 ~
                    s.push(t);
* M# N* N! e5 O                ///1、对应上面连通分支只有1个点的情况; i; N( Y! j$ Z' G
                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
! h+ `1 h, v0 y7 ]) i* W+ h                ///tmp要么等于找到的第一个未访问节点,
; e; ^* a( C' H7 U. j+ g& @# _: x. Q                ///要么等于与t相连最后一个点(已被访问过)
. ^  C: P. |: E) h* B* H- x9 B                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
- q# I3 C) x% F9 [5 E            }
* t& z& Q( N% n* ]8 x        }
$ a0 F6 l, @! E) Y! n% d3 {" z    }
$ v/ |& R6 T/ A) l  D}
6 Q; g" c1 T  e//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
2 |+ s; [( q% o( M) ktemplate<class ElemType, class WeightType> int+ A1 A, k- J4 l' `& t
MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
* G; i( Q) \9 b  ^& o. \0 n; u{% k1 {8 ?1 R- P/ m. v
    if(head==pre)
8 H& V, L' m; {& F% w        return -1;
$ X# T/ p4 h# M" q; `
/ i5 |0 {) c6 t* [' u    MultiAdjListNetworkArc<WeightType> *p;
& E4 T" _" }# j    p=vexTable[head].firstarc;
* Y5 \  P" ~$ r- D: x7 }    if(pre==-1&&p!=NULL)
; ?7 L3 U3 f  b. Q- v7 w' S( p& ?  N        return p->adjVex1==head?p->adjVex2:p->adjVex1;
, B' Q/ ?6 F/ p  @    //pre!=-1&&p!=NULL4 c' b9 a1 m5 q) [
    while(p!=NULL)
# Q7 U$ j: D1 Y! b* Q8 }    {
( N2 j) K; h) Z# o        if(p->adjVex1==head && p->adjVex2!=pre). P; M' a( N. o1 ?, m
            p=p->nextarc1;" q5 o# B- C$ y* `/ c. J: M
        else if(p->adjVex2==head && p->adjVex1!=pre)& i/ \0 c1 y2 J" X4 `
            p=p->nextarc2;
; D5 G) R+ W& H1 K* Q0 R        else if(p->adjVex1==head && p->adjVex2==pre)6 f, j, ]  H3 B
        {
$ L' Z1 P1 l6 P/ g5 R/ y' Y$ s            p=p->nextarc1;
; u  Q9 T0 f' E6 b            break;9 j( M% p3 R$ b0 k) t
        }) U* ?; v: [5 c; S, W6 }
        else if(p->adjVex2==head && p->adjVex1==pre). `$ A+ p0 p+ c- j8 \; N: ?% r5 W/ S
        {6 t! m: n8 ^) Z' Z
            p=p->nextarc2;
, }8 S# T* l5 w; b: U4 z& t: q' F            break;$ h9 h5 N) B6 N5 h
        }
5 w1 ]) s/ \! Z  n4 v    }, E( g! F1 T4 o: b7 ]4 g# @
    if(p!=NULL)* S: i: {* P( l' H2 B6 }. Y5 S
    {
* u4 p7 Y1 _4 B" T        return p->adjVex1==head?p->adjVex2:p->adjVex1;
, k9 U- l* x; U& G    }
" X7 p& d9 [2 e# Z' m- H7 V    else0 M+ O5 Z2 P+ \
        return -1;
3 R0 [& |6 _7 m3 a, H7 \}
/ r6 _, D6 J$ \: R. |
1 C# r/ Y, Q/ v  o$ L; ~/ Y* K$ B! ?: c7 R$ Q2 t! |2 c
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
, l& l% [4 x+ ~4 f{
. I: E, E3 e  i* Z    stack<int> s;+ R: P* _+ Z6 e; T
    int p,cur,pre;
  o  i6 V  J3 Q( C    //MultiAdjListNetworkArc<WeightType> *p,*q;+ C( d0 |/ s5 |) m! y  w
    for(int i=0; i<vexNum; i++) tag=0;//初始化
& g& V1 K3 X1 G! ]' e* q' U6 v9 O( v, w( m5 J+ h3 C- t
    for(int i=0; i<vexNum; i++)3 C1 A) `$ R3 z- U' K; i
    {5 a* S! T9 K5 u: g2 B8 Y
        cur=i;pre=-1;0 y1 d, a, R9 E0 g
        while(tag[cur]==0||!s.empty())
2 P/ v- ?' K! u2 M& \8 N        {5 x% U, ^3 T& p4 L7 I' X
            while(tag[cur]==0)) A9 N2 N2 T1 F% B7 y' f
            {
9 h3 {6 B. |4 l  s) W$ q; {                cout<<vexTable[cur].data<<"  ";
# \( S1 S6 u+ N, }                s.push(cur);) B8 ^4 o' [$ z5 V# b
                tag[cur]=1;& k4 L6 C# E& ^, q: u1 \$ y$ s
               //初次访问,标记入栈! D0 q( b2 M* g  |8 N
( P% d! M* l5 l  w4 L- I/ ^! e
               p=GetAdjVex(cur,pre);//p是cur的连通顶点8 O3 d9 I) b+ ~
               if(p==-1)
; h/ S8 }% f; n9 P               {( c" S  }7 g0 a$ `' \
                   pre=cur;s.pop();
7 j5 P+ t) D% h8 D  Y                   break;
, E' b+ l( m2 X" Q( `- ?               }
" N" E" t: }( w% _$ `               else) W* C7 S, ?: C! [1 W* R
               {
  \* i& J. s) P: u0 ?5 y+ y                   pre=cur;, B% ]; b; o; ]1 Y6 o! N1 T: ]
                   cur=p;
; l4 b/ Q' g+ L: `2 l. i               }& c5 B8 ^  b; G2 C

9 j! n* _: V+ u8 a' o+ T7 h0 F            }
9 J7 D- \4 h0 ?! I0 e            while(!s.empty())
8 U1 C5 }2 J& I: E- @6 [" m% C7 v  F            {0 r' q& r8 ^; D1 M$ z% r; ^
                cur=s.top();$ o9 v% b" S- u. L, v0 Q/ Q
                p=GetAdjVex(cur,pre);; ?5 W7 S2 e# i; @# |8 \& ^5 \
                if(tag[p]==0)) |7 H) `) j" A9 F0 O1 n
                {  s' _1 U# w, g6 o
                    pre=cur;
/ a! `, U- U' ^; w3 Y) |( x2 q                    cur=p;
$ b+ k! |$ @# ]$ A% f                    break;
* ~# d# {0 l: e                }3 _+ I  B/ B7 ?' p" m' r" p
                else7 X8 {6 `5 q. |$ B/ k9 }
                {
' R+ a, v7 H9 ~# P                    pre=s.top();
- S5 |$ O# K$ P1 {                    s.pop();  Q, x! ~0 P/ D4 S
                }
5 _0 K8 M+ a) \: \5 B4 G% J! n2 d# c) }8 R
            }5 U# ]" [# {6 ~& G

8 E. D1 U( ?- ~1 M0 p- d        }
& v$ b4 @% A/ ]4 C) V& x    }
* \& G% [1 z0 l% U}
6 @4 h! @: m. E( G  K4 Mtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
# j, p* C; k8 A( S2 f{5 A1 ?; U5 s' K1 k: t
    for(int i=0; i<vexNum; i++)
1 ?1 {3 c! ~% V2 G9 a/ o: u        tag=0;" ]4 l# h( {4 ~! J. i  A$ x4 J
    queue<int> q;
/ d3 Y( v/ Y$ E' E2 Q    int tmp,t;
9 B  q: s  p! p, d" a+ U2 N/ N    MultiAdjListNetworkArc<WeightType> *p;
. a9 G! n! X3 Y    for(int i=0; i<vexNum; i++): X. x' d2 l$ E1 a. Z# E# m% {
    {
+ A& ?5 I  k; X2 x        if(tag==0)
' m  Y% b5 H5 J5 B/ T        {4 M) S! e) |3 j$ ^4 G7 I
            tag=1;7 ^3 b) @* H1 l8 O5 k
            q.push(i);3 @* S' s. K& X1 z
            cout<<setw(3)<<vexTable.data;
' g/ _0 H3 |) m/ i1 [+ t        }  `% a# e' q$ o1 {+ s6 k7 H3 t. h
        while(!q.empty())
* Y9 t: c# M7 R+ c        {
% O& Y! h3 T8 K: X. o6 R- h            tmp=q.front();
! q5 Y/ z. `7 m3 w8 m            q.pop();! X* ~# l4 X# F: t* x/ f9 e  b
            p=vexTable[tmp].firstarc;) f3 v% h' F& D$ `# F# g
            while(p!=NULL)
: K& S; E. o7 ~1 U/ ]3 W/ G4 x8 R            {
6 B/ N" Z" f9 E8 H$ k9 V                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);9 I& l$ @7 U  v* {
                if(tag[t]==0)2 l: W7 G4 S# {- r/ [
                {
1 F2 a: ^) N7 O* l                    cout<<setw(3)<<vexTable[t].data;$ \- [( R& o# S. T7 @6 F2 a7 J
                    tag[t]=1;
9 S4 |3 }3 r& _7 J/ [/ G                    q.push(t);
& P5 |# q4 W1 G" p                }
; G& X0 ]$ W: G5 ]' y                p=NextArc(tmp,p);
& n! I/ e  Q/ \7 L$ K/ w$ h$ [            }
0 z4 X# V# p/ R' u        }/ T2 X) i/ H: z, f2 y
    }
7 B) S' s' S& u: [1 @/ z6 h5 J}, Z* ~- O& V5 W1 H$ H2 [& Q& o
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
* B7 e. r! s, Q; m; ?$ C  \{' v& ]0 o- f. \8 A3 I
    MultiAdjListNetworkArc<WeightType> *p;
. z4 c0 f# C1 R7 @6 S    cout << "无向图有" << vexNum << "个点,分别为:";
1 {' z+ K. B% ]. E  R, j- P, ]! r    for (int i = 0; i < vexNum; i++): O2 g9 {) k. I0 \9 l
        cout << vexTable.data << " ";% Y+ e# ~5 g; p9 F9 r
    cout << endl;3 e0 y: d2 j9 e2 R6 I5 ?( }) C
    cout << "无向图有" << arcNum << "条边"<<endl;; o) s. l$ [7 Q$ _. S
    for (int i = 0; i < vexNum; i++)$ l( X% Y; }5 k( {+ M7 @) J
    {
' O8 J% J$ A: f        cout<<"和" << vexTable.data << "有关的边:";
; }2 D. G, r+ M) h        p = vexTable.firstarc;
1 Z: Q, U/ P1 C  U        while (p != NULL)$ T2 b+ g3 y- E' L
        {. p0 C1 d0 R7 z) }; T8 G
            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
$ @7 L+ V7 k2 F/ b# ]( I  ]) M            p=NextArc(i,p);
3 I. m, K8 _# ^& H/ I0 P        }: v  |$ j4 c& K) }
        cout << endl;( `5 N( m* Y8 z: N) d4 T) F; C( @
    }* f1 O% k2 P7 p; f/ G' U: l
}. c, e0 W/ c# L! L; a+ o5 b

' R" E1 Z" j4 F, Y+ _4 _8 R$ S% C+ O. m- k! Q+ j
邻接多重表与邻接表的对比1 }: Z* X! D, @6 V. ~$ A2 v
! [6 ^: I( T3 A
邻接表链接
6 J" S% y# L4 E& P/ x, n( g在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。; F* v* h& G) ]8 R
在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
; S; |1 U9 `  V/ \. k$ I* b为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
' D- h1 ?9 E7 B- A0 u* q8 L- A2 P! E————————————————  L) A. T, O2 ?2 x1 }
版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。1 q3 P( M9 O  e
原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958( y& W2 s- m) F% A8 p' z5 C

! \1 m9 u5 d6 p& T# o8 f, x
; l& c0 ?- z; X9 g7 R: T8 h- _6 S: L3 _5 N. ^$ n

0 a. a) F" d8 W7 e2 R( Z. O————————————————
' W0 N! h/ p/ m& B* Q) k7 c版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。0 `' j0 X5 @" z5 G) N( Z8 A, \
原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958) U' U$ H2 r6 e  h: x

# ?% y' f" @7 [9 c
$ a# o3 f8 L. Q' n5 S- M




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