数学建模社区-数学中国

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

作者: 杨利霞    时间: 2020-4-26 15:26
标题: 图的存储结构——邻接多重表(多重邻接表)的实现
$ R! `: N  O# G0 q9 E6 j- C
图的存储结构——邻接多重表(多重邻接表)的实现9 j3 s% G1 [" n" a( g- R
7.2 图的存储结构
4 `, l" u3 Q( t- F* P+ K( E/ @2 V/ b1 S5 G
7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
% O1 s$ @, r5 _9 E邻接多重表的类定义
  Z$ O0 P  ^; g- h2 r  n邻接多重表的顶点结点类模板
8 h- q/ V- ]3 L7 I% a邻接多重表的边结点类模板
& R. Y. Y! U- l$ W: W: C邻接多重表的类模板+ z; ]7 m4 L8 z& R! s
邻接多重表与邻接表的对比
) ~# ~& y, c) _/ Y7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
# i# S: S- q8 [7 c# Y1 \
: \( x' `& O6 s2 c在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。4 `5 i& C3 g5 c2 l& w. y: W
在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。& o' f2 }- B/ B4 ~. k* w5 R: e

  r3 L9 `) z' D5 z' s  G4 T邻接多重表的类定义
1 o. ?7 ~% v& T; Y& \& j 1.png
$ D. k* _4 w8 y# x4 p4 Z+ A* n邻接多重表的顶点结点类模板

对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:8 \) O% j# l# l
data域存储有关顶点的信息;
6 n0 N- |0 b" C5 y7 |! @$ N8 I3 L, lfirstarc域是链接指针,指向第一条依附于该顶点的边。
1 z2 B  j( y# h, s! r所有的顶点结点组成一个顺序表。


. `7 @" m, J5 p1 J  x4 k) V$ X2 t) p" i8 Q% ?  [$ f; W
template <class ElemType ,class WeightType>
; ]. j  X- {+ s9 Uclass MultiAdjListNetworkVex
! Q4 a) D6 c# d: g) r/ D{
, s" T  q) N6 @7 y/ }" wpublic:
8 N. a0 I9 f4 z$ ^( D8 a# I$ P        ElemType data;
# i) B, ~, Q% }: U: t; q        MultiAdjListNetworkArc<WeightType> *firstarc;% h. N, c, ^2 `8 _& h

6 M; K. r6 s" A+ @0 q6 O        MultiAdjListNetworkVex()
+ n4 B  W- i9 A" A9 E        {+ j& {- p7 b3 O( v: ]" l
                firstarc = NULL;
# h- a- g9 a8 p' l( s: E; G        }8 \5 ^6 i& S( r4 {- v! w+ ^; Z
        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)2 q. S6 q9 d/ ^# n- K
        {
/ a8 n7 i6 S/ S                data = val;
; {1 Y. m1 A+ b  j0 @1 o2 E( a" \                firstarc = adj;6 M+ L+ Y# l+ B% P4 ?# Y
        }8 V% g1 I) p' y( `" \8 e" F* `
};
9 z7 d: e5 J' [) [. Y5 D7 Z
, b3 P: Y. L) w) W5 E邻接多重表的边结点类模板% J) T0 b% G( M* L+ J; ]& M8 }

+ ^5 O* L9 a* u0 W+ ~- \在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:+ {8 o3 [% B  U3 V9 U& u! c
tag是标记域,标记该边是否被处理或被搜索过;' ~" o6 \6 }" j7 X) o& f- A
weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
. b+ H! F+ f+ [' [9 [1 znextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
" p7 A0 M; ?: U4 v# Lnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
) m$ M7 O- d8 }! _
) v% h( {& P2 z. l 2.png
$ T, \+ U6 P4 _) ]  t+ y+ u/ Dtemplate <class WeightType>, l" e' j' L: F
class MultiAdjListNetworkArc
) }. V# `/ w( \, e$ v4 j{
/ S& Q& C( [" M6 Mpublic:
+ P" ?: H; q+ E    int mark;                                       //标记该边是否被搜索或处理过, v' J% B  B+ Z; u' U
        WeightType weight;                              //边的权重
8 M# S2 r+ O8 X1 q8 N) k        int adjVex1;                                    //边的一个顶点
+ @( x5 a/ E, m- I* k1 d        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1' G, \6 h0 w( z7 E/ ^3 x+ G
        int adjVex2;/ U2 F, V- ^4 q" g
        MultiAdjListNetworkArc<WeightType>* nextarc2;
* V( \9 m  J0 k4 j8 z- j& o8 s; {4 u
        MultiAdjListNetworkArc()
9 Z" `/ \9 Z5 P$ s& v, \7 V( _1 U        {2 {4 F3 u* T/ Q5 \6 v7 d
                adjVex1= -1;: i; O7 `9 p4 M( R
                adjVex2= -1;
% B' O$ T+ r- X7 a/ I. b; A        }6 G0 p' C4 Y" Y/ ^) P8 s8 c
        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
3 D: d$ a! y( U, o- p& x        {
4 j3 F: E/ @( v! L* O                adjVex1 = v1;       adjVex2 = v2;
* X1 m; ?- ?* u/ `2 K. l5 y" x. [                weight = w;
- I. J  J3 d. X9 d7 b/ |                nextarc1 = next1;   nextarc2=next2;
" \) v' {: ?/ N, I8 O: u8 ^% f                mark = 0;           //0表示未被搜索,1表示被搜索过
" |8 b  P& @9 Q1 f* X        }. z$ \/ X7 v. \9 O% n

* |$ y1 h* ~& P* r# P# |邻接多重表的类模板

1.类定义

template <class ElemType,class WeightType>4 ?- D' d4 P" x* [7 t! T
class MultiAdjListNetwork1 j  ]' f/ q) x3 B! e, F
{
+ Z* z! U4 h# l& ~protected:
9 q* e" m" Q0 o. O+ `$ {- ~    int vexNum, vexMaxNum, arcNum;
, x0 G& Q6 A* i: }% G6 Y" X    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
$ r# _5 m  _! l2 T4 X    int* tag;
, Z0 @5 ~2 x7 M, R1 ~$ M3 Q! o& S    WeightType infinity;. L. P) L; k0 m' s7 J0 ?1 ^
, }1 V0 D* L/ G8 m" w
public:
( G3 r$ A' K) N( @& n/ O& E1 M9 t    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
: K* W! K+ z) j& Q( \; c( t( Q
5 O* B+ u- a# d9 s1 K    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);6 d, O* e- k# G/ g" x3 r' c
* n. M  L, t) s0 k9 p
    void Clear();$ H# C' d6 w5 Q% z2 Q+ k# Q- W9 H
    bool IsEmpty()
2 C* p; A! l* }' F8 |; t% c    {3 ^' J2 u& \* s0 v: H4 i
        return vexNum == 0;
$ g2 p2 P0 J' d6 _( }7 H    }+ [' ?& A! v- A( W$ N
    int GetArcNum()const: t. ~/ H3 G: f$ E
    {- o8 ^/ a; r% n1 W$ b5 m/ z+ b
        return arcNum;/ _  B! F" u" Z- x$ O* @
    }; ]4 R( b: O. Q/ k8 |
    int GetvexNum()const
' P- {+ F4 h7 B3 C  ], O% j    {
3 w* F2 b  Y9 ]$ n. |0 W. L        return vexNum;: F( d. b1 F, U" U8 f$ S
    }6 _, j( O0 a  Y3 u8 s' X
8 R6 P2 i7 \' W- x

/ y* K1 d( n! x) J2 m/ g: N& Q& V    int FirstAdjVex(int v)const;& T  S( N/ ^. W( w
    int NextAdjVex(int v1, int v2)const;
6 ?$ \4 c! a1 h8 ^: i  E    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;2 _9 E; G0 L7 z8 a
    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;( T  \+ w" A7 O3 V6 _( y3 O1 G5 P
0 ^+ f3 E& M$ a: \* W6 u+ {
    void InsertVex(const ElemType& d);
; `7 j3 V2 F6 K+ q& ~% G( r; ~    void InsertArc(int v1, int v2, WeightType w);
) o3 u  Y( J# x( w
. l6 V$ d  c- u4 n- e    void DeleteVex(const ElemType& d);
. ^' e) L- }8 b" V' |; V7 i    void DeleteArc(int v1, int v2);- Y9 r/ b) {' D
. D9 T$ @4 l5 z' X+ T& O
    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);# |' u/ m2 l* t! R# |, E
    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
: Z+ {, m# B9 P7 b- Z0 c. ]8 A7 W( L2 b* {% M( ?( S5 o
    ///深度优先遍历
4 f  x1 u, M+ D% f* H8 ^# N9 Y8 z    void DFS1(const int v);& R1 f0 N4 j3 G4 |
    void DFS1Traverse();1 O, `' ^4 }0 i5 _* B, W
    void DFS2();1 z' K. o; l  U% ^

) A% ], B; ]/ j( P8 f6 p, M    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1- b* w9 e' Z, {
    void DFS3();2 d! X2 _  l5 X1 @
, [; p+ _4 ?% \$ f5 r5 A( r
    void BFS();
5 p# V; Z3 B2 O    void Show();) R1 P5 Z* _6 W& j
};/ d$ V, P; f, h0 F& Y* l

! [# d& O8 o% `2 E2.函数的实现9 n1 C& ]! v$ |3 \$ o" |& I8 v# H. v
研讨题,能够运行,但是代码不一定是最优的。% A4 A& E3 s; W) _$ ^
! b) B$ ^  ^  V" v4 z1 X" p  T
#include <stack>
9 G4 U$ m* h6 o/ M#include <queue>
4 c/ v+ D  a8 b, z% R& |+ r1 [7 J! a3 f' Y2 v( E' \$ c9 S
template <class ElemType,class WeightType>
4 ]; k; g7 @7 \: E( f( mMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
* T" {/ E' G) o! g/ w1 ^  B) A9 E  w, d6 F{# F2 A; x; Q; u
    if(vertexMaxNum < 0)
3 J0 }) {% i( @        throw Error("允许的顶点最大数目不能为负!");$ u" F( Y9 k& I' r/ F4 }
    if (vertexMaxNum < vertexNum)
* d: \6 B- v+ v; N5 n. s        throw Error("顶点数目不能大于允许的顶点最大数目!");6 E$ H- t" @! ~$ q
    vexNum = vertexNum;
, U' x6 ~' w6 {. z5 O3 G    vexMaxNum = vertexMaxNum;" u% w% ~/ h: e& |3 y
    arcNum = 0;
& f$ w' ^& @' A0 N- }" W    infinity = infinit;# a: b9 j" Y; J6 p4 P9 D
    tag = new int[vexMaxNum];
7 f5 Z2 F" w# C# s% c    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];4 G6 m/ a: a/ N' y0 K
    for (int v = 0; v < vexNum; v++)) K9 C) [, G8 h% J/ G
    {( G" H; c1 S+ p
        tag[v] = 0;. B, k0 _. r* L; d- h/ d' |* G
        vexTable[v].data = es[v];5 ]* o; D! o. u2 }" T' v/ l% R
        vexTable[v].firstarc = NULL;
! K/ g( v1 `& p" L' z. K' L    }
2 C/ f, H3 _* F9 p  ~! |}$ E/ u4 P4 P( |
template <class ElemType,class WeightType>
, O- D( c% I3 c1 H1 ?5 ~: R: BMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
$ f: J9 r+ I" R( O! z! C+ r{
0 a" }; ^; M; d; v    if (vertexMaxNum < 0)
% h2 t( r4 |$ F) O1 l  `& s- ]        throw Error("允许的顶点最大数目不能为负!");7 U4 Y9 o5 V) X/ \2 }/ e$ q
    vexNum = 0;
) T! O  k, g6 h' W2 ]5 T    vexMaxNum = vertexMaxNum;
7 ^1 f: x" x2 o    arcNum = 0;4 F, q2 y  @' @$ o: {
    infinity = infinit;! z2 E' o4 n+ A% Q
    tag = new int[vexMaxNum];3 C9 k7 Z; e) T/ d$ d
    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
- T- u& y1 h$ c8 ?' ]% K}
/ |7 o& `# Q0 L. {template<class ElemType, class WeightType>
. A( ^: R9 R5 k1 Nint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
) y4 @3 @2 j7 j! X7 q0 e{
+ f- H5 x/ {! }8 Q9 u& ~6 |+ S  B    if (v < 0 || v >= vexNum)
  F6 J% Z) F+ ~        throw Error("v不合法!");
6 V( z( H$ \6 e$ x4 h: Q) p" b    if (vexTable[v].firstarc == NULL)
5 q& t% p- r% ~1 @        return -1;
  g: q* S7 l; F0 y/ z1 ~    else
$ H0 i# u5 U% }        return vexTable[v].firstarc->adjVex1;
5 ^( o* L6 F/ I  F}
3 X! i9 W0 Q/ S9 j. i+ l) L2 z- Z8 s
9 I6 f2 t" e+ {3 y6 {) U, M; J8 |template<class ElemType, class WeightType>
6 B7 X% z+ J) o7 tint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
0 v+ t9 l2 O2 D5 d{6 H, Q7 N* P" v; h& p8 i
    MultiAdjListNetworkArc<WeightType>* p;. g. q* s. v  R+ W  n) t# k; E
    if (v1 < 0 || v1 >= vexNum)
4 i3 H. m" g9 e5 y% w1 a0 B4 e        throw Error("v1不合法!");. V2 U2 B- X2 i* b' r) |
    if (v2 < 0 || v2 >= vexNum)
4 b, J# j$ V+ |2 C        throw Error("v2不合法!");
; T  [: b' n( `, N! d8 }    if (v1 == v2)
8 Z3 L5 A% P2 e        throw Error("v1不能等于v2!");
" X: i5 I3 l& {* t1 O9 j* O$ f" Y    p = vexTable[v1].firstarc;0 Z4 f. w: o+ [5 _7 v
    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)% H. J/ A' s+ z* d- b
        p = p->nextarc;6 x) R: p$ U( P: c
    if (p == NULL || p->nextarc == NULL)
% Z5 G3 L8 G3 p, v( `" s        return -1;  //不存在下一个邻接点; S% W7 n0 Q7 t9 }2 A: n
    else if(p->adjVex1==v2)
, L/ w7 Y& }( b8 O  A8 _        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
4 N6 H5 K9 \3 D$ \) {! P. L5 E    else7 c  D' P! L+ B5 u! N
        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);0 G+ P4 |, c" G( G: P) }
}' P1 R2 S; @: v0 f# `
template<class ElemType, class WeightType>+ p0 [: ?* L, u0 [" M! ^
void MultiAdjListNetwork<ElemType, WeightType>::Clear()
" q" Y. C1 c2 U# \; B{- h$ y" H4 S; b
    if (IsEmpty()) return;
8 C  L! {- H& G1 y# h    int n = vexNum;
& f  e4 k7 b6 W. j, D    for (int u = 0; u < n ; u++)
, h( h* k& `/ P. g. t% }  L+ d( |$ f        DeleteVex(vexTable[0].data);" n! S& i  B! r/ }  z
    return;
- n/ }4 p& S- H9 M# M; A}& ^% C+ s% ~# s. U. q
template<class ElemType, class WeightType>' }; o) Q' R8 Y( w
MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
  n5 @( H2 n+ z% L6 ~3 K{7 _+ X! F( K+ ?4 Z
    Clear();
0 r5 _" S2 T9 F2 s& p1 B}
5 ]( f/ g% e) f) B/ ]' Q5 Otemplate<class ElemType, class WeightType>
/ k1 ^  r4 }$ QMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
( v/ D) o2 S4 }$ [( w{
% l1 M1 o& ]+ v! N, y$ N* q; O4 g; f    vexMaxNum = copy.vexMaxNum;' g3 Q# h7 D7 R6 u: r
    vexNum = copy.vexNum;! U  t$ S; I' A. c4 s
    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
* Q! I8 x+ J8 L; m    arcNum = 0;- [# m4 F5 H1 \/ A8 {6 f7 y
    infinity = copy.infinity;
% l/ X& b+ s6 F4 O: x    tag = new int[vexMaxNum];
9 b  P) P# T* d! b0 h) W' E* ?5 G
8 M: g0 {4 y1 @    for (int v = 0; v < vexNum; v++)' G- k, v( g$ p( G* r! q' _( U
    {3 v. ^) w/ t5 x5 ?# f
        tag[v] = 0;: x& f' g; |$ ]
        vexTable[v].data = copy.vexTable[v].data;% I5 L7 C2 Y! U% m, {! d! l2 N
        vexTable[v].firstarc = NULL;
- m% l3 u  _$ l# j3 d    }
3 Z# v) L- F+ o' I    MultiAdjListNetworkArc<WeightType>* p;, d) U3 b* j# v- Q' {) Z

$ Q- V% |% g8 t5 h. K8 }# j+ M. I    for (int u = 0; u < vexNum; u++); D0 X: h& g) P2 n( D' u- N) v" i; L6 K
    {
# U6 u: L0 u6 O" e$ s: F7 @2 e        p = copy.vexTable.firstarc;
; z! }' {- G/ k! j- V        while (p != NULL)
% ]' \! H6 s+ l, F% t1 L        {
+ P8 h3 y, _0 q- `5 i* }            InsertArc(p->adjVex1, p->adjVex2, p->weight);& f* g& R( W4 P. |
            p=NextArc(u,p);+ e" p! _! C7 Z  H) }  a
        }
1 {+ k& x$ R2 ]" y1 _* ~    }
0 j& I3 L3 `2 v( ~0 n( U}) l! W5 x1 I) p# O, p, D8 T5 ^8 C
template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
! f% o1 j" Y1 uMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)  o/ k  Q# A+ m+ w
{) d2 ]/ {1 k7 B! `
    if (this == &copy) return *this;
9 B2 l  D! B" q+ e7 O    Clear();
7 B9 S% i# l: J0 i, F- T% L$ x    vexMaxNum = copy.vexMaxNum;+ Q) M& s" V0 {
    vexNum = copy.vexNum;
0 D2 r$ F' L6 k+ }! V* w4 W    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
0 E+ g6 Z0 p* k2 w    arcNum = 0;
& G6 b, X4 j$ ?* J. g$ {; ?9 A, d    infinity = copy.infinity;
, J! V2 D: r' N1 l# U9 G    tag = new int[vexMaxNum];/ m* D. F/ W) m; l' }# L6 M3 S
: B. p4 @; @$ [
    for (int v = 0; v < vexNum; v++)
! t' o' ?6 H/ {/ `, I0 v, e    {: p. l# e+ n( j
        tag[v] = 0;
3 y, l3 I) w4 `9 l1 `9 C8 Y        vexTable[v].data = copy.vexTable[v].data;
/ a& z& [) Z7 }7 _+ Y2 s7 y        vexTable[v].firstarc = NULL;7 d4 b& h3 U% E0 \9 s3 }
    }
" K( O& C7 e8 N" d5 N+ q+ {    MultiAdjListNetworkArc<WeightType>* p;/ z1 ]) B2 A7 G% z

" x( ^8 W! |7 W/ Z* K# ~. p    for (int u = 0; u < vexNum; u++)
- f0 x/ ^1 j* U/ c    {
- @- r$ z) D. X' s% H. T6 f1 H        p = copy.vexTable.firstarc;
2 ?; D/ N- ]/ M6 a% o6 C        while (p != NULL)
, A6 h& i# ], |1 V. R/ c        {7 a* U/ A3 F2 j
            InsertArc(p->adjVex1, p->adjVex2, p->weight);
8 S+ U: h6 T# v) m* a! U            p=NextArc(u,p);3 V# J. j4 m, y# h9 @; k; ^
        }' ?1 o+ m( @% p6 J+ c  q" U# a+ A) h! A
    }
+ g& E/ S, P3 N& l- c    return *this;
2 }8 l- R' y' j: w3 D( ]}( Y0 C4 W) O* d- j% ]5 y
template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*; l* x% H/ O5 K' [1 A  i& a- e
MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const' Q% E$ S9 C3 ~# P
{* O: g5 W) S' b9 r0 m
    if(p==NULL) return NULL;
" f0 b. S  v# W* i    if(p->adjVex1==v1)
2 y! d7 W# x  P( |* r& p+ q' d        return p->nextarc1;" i' ^& r" P6 O2 y6 d: n2 c5 H
    else- b* k2 {7 J6 ~; f2 t
        return p->nextarc2;
7 `( M8 U9 A, C( q; x7 Z}( P( J3 g7 \' m* _! T. e
template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*1 F8 F1 Q3 C  i3 i! `
MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const! y0 y! u+ o2 u9 t; f  L8 f9 a" x' T
{
$ [! i$ r$ i; r/ q: c9 F    if(p==NULL)return NULL;
2 Y: x6 S, \$ y2 A    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
$ y( b+ t8 ^. H$ Y& o    if(q==p)$ c; E! {3 @' @
        return NULL;
) \; F# _- H! f$ v5 e: h    while(q)
7 z" X  _0 m  D    {
' S$ f9 B$ Y6 z' Y$ q, }        if(q->nextarc1==p ||q->nextarc2==p)( q5 e9 c$ d' k9 r% J
            break;
0 ?- ~; L' c7 F7 f1 q, f: w& P" |        q=NextArc(v1,q);
; `* l5 }" D1 n, B5 P    }: ]- Z/ |! l' @2 W3 H0 @
    return q;( ^3 x  g) _8 L. v. |. ^! F
}- }! |* g, B: N' m" d
template<class ElemType, class WeightType>
& ]9 }$ Y; u& Q  j5 V3 }void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)5 n+ x+ {( U; `' U  x6 b
{- J5 C/ {8 Z3 a/ A. P; n2 N
    if (vexNum == vexMaxNum)" y5 u/ |" X1 Y; s( f; t
        throw Error("图的顶点数不能超过允许的最大数!");
0 t0 t) b1 l; z! ?* ^' q; t    vexTable[vexNum].data = d;7 `1 s; g: q& _+ T9 b) \+ g0 g
    vexTable[vexNum].firstarc = NULL;% F3 F4 h% N+ k6 v& c
    tag[vexNum] = 0;0 z+ K. k+ U+ D( l# S# I4 ^
    vexNum++;5 [. n" W  ]0 V6 m, Y1 b
}
# j- f; R5 z( B6 J% g' m$ g4 etemplate<class ElemType, class WeightType>* F( C( `, r) K0 c
void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
6 T6 _4 ], R5 b, x5 q( j; y1 p- ~/ C{
+ Q( Z% P7 `; U8 v: R    MultiAdjListNetworkArc<WeightType>* p,*q;' V  ?% T( ^! Z' d) [& d
    if (v1 < 0 || v1 >= vexNum)
5 Q% ]2 {; w3 W1 d        throw Error("v1不合法!");# H# e, e2 X0 l: |# I$ V
    if (v2 < 0 || v2 >= vexNum)
. o: L6 g9 r$ N) E* o$ j0 J        throw Error("v2不合法!");/ @  B, U# w1 q) U6 D
    if (v1 == v2)
' g* H& E& M- f0 \" T' `7 R        throw Error("v1不能等于v2!");
1 p) ]+ }1 `# N  @/ F    if (w == infinity)# u$ `- b2 }: `& S
        throw Error("w不能为无穷大!");
/ z% [% |3 z* R  D
- W$ x" @0 ]7 R( }# v- U. ]) p3 K, y8 e8 G" ]2 f7 U( U) c8 R
    p = vexTable[v1].firstarc;
/ @; a* B( A# U6 f    while(p)" ]' u7 \7 e- A6 [8 ^6 z) m6 N
    {8 t3 A5 B6 \, R: b" o9 T
        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
# F+ U% r" F) t3 y1 X7 g) U        {; q% I) J' s8 l: P: E6 d
            if(p->weight!=w)
6 k2 l2 U% u9 Z: y                p->weight=w;
: i+ R6 `9 h5 p: f            return;2 K' U4 y' N- I
        }% F4 `/ v+ u% ?3 h4 f" m9 `
6 f$ O0 L3 @* o) [1 H
        p=NextArc(v1,p);
" E; a- W8 A- R: I: S    }
0 y- e# ^7 `  W" t. A5 g) h: s    p = vexTable[v1].firstarc;  X( `( B2 F- p. R' {4 w
    q = vexTable[v2].firstarc;$ i& i. U3 f! C* g; O. p
    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
, @7 T8 G( K& A! j4 _    vexTable[v2].firstarc =vexTable[v1].firstarc;
0 k2 q* {: M( `  x1 R, T7 I( B    arcNum++;
$ `! _+ c& M: X) K0 a/ n}1 e5 N" U  o* ?* y7 u4 Z3 |0 G; T

0 q8 ]2 y( z2 btemplate<class ElemType, class WeightType>
/ v7 @' q! a( r  h; z" ]5 qvoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)& a$ p& W: {6 P, I: g: S1 Z
{
( ?: {; u1 q" F  C) U% G/ D( R
  d! f7 [9 j! H8 c1 k    MultiAdjListNetworkArc<WeightType>* p, * q,*r;) s' X# ^' S: n1 k0 w* S3 x
    if (v1 < 0 || v1 >= vexNum)% f# G* p: H. \3 S  O3 E4 l
        throw Error("v1不合法!");
5 |* Z$ N+ I( _; w    if (v2 < 0 || v2 >= vexNum)
5 J  G1 N4 r0 m. {# Y& w. @        throw Error("v2不合法!");
) y3 T1 }' [9 }  O0 j" M    if (v1 == v2)
* Z7 ~; r! H9 T- N0 z0 d        throw Error("v1不能等于v2!");
! A  I( j' g  y8 p; t! @# q7 n$ ~
4 g, p% ~% s) k, w    p = vexTable[v1].firstarc;# ~( d$ x0 Q0 G2 G: _7 ?
    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)& w6 C; |2 W1 ^" t* o# O  i& E0 _
    {9 w. |  S% Y/ z5 S6 U* R
        q = p;+ l+ a& Y* h4 r
        p = NextArc(v1,p);
1 q+ t0 g0 Z6 U. ?3 ~    }//找到要删除的边结点p及其前一结点q# o; u* F3 A& W- r" t
- N( r  F7 Y' _0 W+ K0 Z3 h
    if (p != NULL)//找到v1-v2的边) x! Y7 e. l- q( X$ Q& W
    {
$ l# B3 C  I0 c7 S) _6 k        r=LastArc(v2,p);
0 V; x5 c2 x5 ], Z        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL8 {9 t/ [0 l& [
            if(p->adjVex2==v2)
. e# a3 T7 E. s0 M6 w                vexTable[v1].firstarc = p->nextarc1;
6 l5 o+ r. E  v" X/ m* j            else vexTable[v1].firstarc=p->nextarc2;/ e3 Z$ o- ^/ H& M
        else//不是第一条边
  B( T' J; b; ?( l        {% ]  N2 x( e; c. I9 e
            if(q->adjVex1==v1)
6 A9 X! g2 r0 D$ J                q->nextarc1 = NextArc(v1,p);
9 S. u! P9 X$ S3 @; ~            else( |& P: S' X6 k4 y) e( f
                q->nextarc2=NextArc(v1,p);
# ?. u; z/ I% N6 p+ }1 H  U* n0 [$ r$ o; Q
        }" w) h6 T/ O( W2 {  [  h: w6 a/ p/ _3 k
        if(r==NULL)
. _. V# P) R8 `# [! b5 f            if(p->adjVex2==v2)5 v$ X" p3 \# Z' @
                vexTable[v2].firstarc = p->nextarc2;) {& j' q8 k$ t; _% [( N! l0 `. \
            else vexTable[v2].firstarc=p->nextarc1;2 V  u# z! c4 z& W6 F6 V6 i# A% r
        else
) D" o7 S. z" Z; a7 x1 m- k( K- G$ B: x- m        {2 w4 x1 M' ~% e
            if(r->adjVex2==v2)4 @/ e' p+ |. l4 h5 |8 @+ |  b
                r->nextarc2 = NextArc(v2,p);! Q/ H. U0 l* v! w4 }$ I8 X" r
            else
& z; m; N$ o$ c$ Y' v3 i                r->nextarc1=NextArc(v2,p);! r% e) E( _- d% S/ ^3 F
        }! `% L& T: F3 {+ s- s8 r0 S
        delete p;
: D8 x+ u0 B4 c$ c" y- g        arcNum--;
1 V$ m! \+ G, k6 N" p1 P    }
* l% u4 Y7 @% L  {* Q: C
0 d9 c" N4 D; i, D# k# ]- ?( }# C7 o}
% r7 e. g/ g9 Htemplate<class ElemType, class WeightType> void; `. t" {; W* s" r3 b. J
MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d). h+ h* H% _8 k' O3 k
{
8 X- ], T: n" S/ g1 k; m5 N    int v;
, n+ G5 E3 U. f6 R$ @    MultiAdjListNetworkArc<WeightType>* p;
7 ]! F& I+ Z" U5 |- T8 @    for (v = 0; v < vexNum; v++)//找到d对应顶点) H8 p/ X6 q6 k6 H& L. F
        if (vexTable[v].data == d)" A% a- d/ {% T# ]% ]
            break;
7 T0 `7 @: c6 ]/ G2 b+ w& w' f    if(v==vexNum)2 V3 g, H: d: ~+ H: P3 a6 _
        throw Error("图中不存在要删除的顶点!");
2 y* k3 m) R- @- X; m8 X
' `* S! c+ m% M( s& A, H2 u+ ^    for (int u = 0; u < vexNum; u++)//删除与d相连的边
: Z. F: U3 [0 o. X. M        if (u != v)
3 `: f2 f. q1 }! C; [- j        {. o' C  q6 j( L0 ]- \% F
            DeleteArc(u, v);
5 B! U; @4 s6 O! _- _        }. {. z* v* U3 f  [# ?0 M  |
    vexTable[v].firstarc=NULL;7 w2 b- z* y2 t7 x" T5 F) c
: A8 m7 ^, Z2 o* S. V
    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置2 [3 q' A5 V+ V- R9 t; v/ l6 j2 o8 @
    vexTable[v].data = vexTable[vexNum].data;  u1 g# `0 g5 P! k
    vexTable[v].firstarc = vexTable[vexNum].firstarc;
# I% g3 _4 m2 S4 f. n& h    vexTable[vexNum].firstarc = NULL;
! W+ P% M- I* A( |    tag[v] = tag[vexNum];, S. F: W  \! E8 [
    //原来与最后一个顶点相连的边改为与v相连2 r' L/ U$ s/ u. D, P/ z
    for (int u = 0; u < vexNum; u++)( q; p# e+ ^, s; y  Z; |
    {
% k( n6 d5 y* {, S        if (u != v)+ {1 w+ Y, Z- H/ f5 D7 g+ i" K
        {+ G* B# p. v5 s/ W+ B4 K2 Q& K
            p = vexTable.firstarc;7 U1 }* X% P$ p; G
            while (p)
/ B2 p& _& M! j6 f9 g            {1 S9 J4 y& r1 ~: R8 \% q! @  R
                if (p->adjVex1==vexNum)
: W3 ?% \/ L% h+ Z/ z% a  B  N1 P                    p->adjVex1= v;
8 G- |  E, i" n1 j- c) W- D9 G                else if(p->adjVex2==vexNum)- p$ e, U6 u+ S9 e
                    p->adjVex2=v;3 A. T1 @3 E$ w/ p& [
                p = NextArc(u,p);6 V5 i% R" y$ g% [! T8 g. j) P  H
            }
4 y3 a+ \& f) w8 @        }
0 R2 K" `2 B7 \1 N5 |8 E    }( q0 t: c. k) O$ T
}4 x* S% x6 ~0 ~: Z% N! D  _
///深度优先遍历6 V& R8 Z5 {/ B2 l$ q0 z  ]
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
  S# v2 f6 n6 T0 i; Y9 j: ?2 e' g{
0 k' l. d5 c' [$ X    tag[v]=1;6 m+ Y- [5 H5 h2 Q9 D4 F( O
    cout<<setw(3)<<vexTable[v].data;
( O. i* Y( ?3 ]4 o2 }  {    MultiAdjListNetworkArc<WeightType> *p;- l' h: h) z4 J( X7 i6 a
    p=vexTable[v].firstarc;6 x0 h" F" m1 Y7 ]) _0 e0 L! r
    while(p)* Y: H/ @1 ^) |# A
    {+ R2 X* }: z8 X3 [( t
        if(tag[p->adjVex1]==0), G* k, z5 Y) a  x8 k0 B( _
            DFS1(p->adjVex1);
8 E& n* l9 K4 l& x        else if(tag[p->adjVex2]==0), T9 b4 t" U$ K& @) A
            DFS1(p->adjVex2);
) d6 C$ ]0 @2 Y( |7 c5 c        p=NextArc(v,p);0 \8 C* H) W2 p' D) p7 [& U
    }
" K0 L; D; J# ~% |' _}% p( N2 U) u$ B# }5 B; v
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()7 d% @: @5 ~, a# n6 N0 z
{1 ?! \# `* P" X2 ]
    for(int i=0; i<vexNum; i++)& i; B- k$ |5 s; o. Z
        tag=0;
% N" M, [4 Y9 P  k  a    for(int v=0; v<vexNum; v++)
! O5 ~. a1 z3 j    {" g$ V. n5 V5 Z2 f- C5 J) e1 }
        if(tag[v]==0)7 ^+ A# L, A9 B
            DFS1(v);
0 B/ N& t5 J+ I    }
6 ^3 @: l0 ?% c; A8 f: o/ W5 O, p}( X! p# ^) ~+ y+ P3 ?
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
/ L& ~% e& r$ M# B( t{% a# @" J* D+ P
    stack<int> s;* ?2 B! t6 ?4 L6 A, i& a
    int tmp;
' J# r1 a% r0 O5 `4 V    MultiAdjListNetworkArc<WeightType> *p,*q;
7 U; ?  s, v/ C( f    for(int i=0; i<vexNum; i++)
) Y% B: L2 A- \; Z8 E$ n        tag=0;* C; X2 ~4 S, @2 w8 w! T' M' l; O( s
    for(int i=0; i<vexNum; i++)
: G, E* t& l1 `" n  i    {
! u: ?# x' ^% _, G/ [        tmp=i;
" |- t) h. b/ P# S$ j        while(tag[tmp]==0||!s.empty())
" m& O7 u5 O9 u" n: T- F( b4 P        {/ [$ U2 o  i' d- }6 a- m
            p=vexTable[tmp].firstarc;
$ i9 C9 {3 z1 ?4 S& N7 j; Q  N            while(tag[tmp]==0)
' e- ?- Q* e5 q+ Y            {) A7 v& b% p( }# C0 |6 c
                s.push(tmp);- l6 l4 z; u0 ]! c% ~& [1 d
                cout<<setw(3)<<vexTable[tmp].data;
! h) x7 m9 }0 K( M& d                tag[tmp]=1;( h$ q6 h$ {7 p
                p=vexTable[tmp].firstarc;. q% w) {7 V1 Q$ a
                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for( m4 f: u1 t5 u- e& r5 x
                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
& ~& K8 y( w. V6 H4 n+ W                //cout<<" 1st     tmp="<<tmp<<endl;
- e! o; F/ O1 t            }
! ]3 \) ^& O6 J1 _  M9 x8 N& k            if(!s.empty())
5 p5 [( ~* k5 n# O4 s            {5 ~+ r2 M4 k9 X, q
                tmp=s.top();* o8 z/ j" {& ~& b
                s.pop();
, v; S/ m5 R5 N# N                q=vexTable[tmp].firstarc;
( M; h% u/ b( u; G/ v                int t=tmp;
! L1 Z" {+ Q* c1 s1 l9 s$ d                while(q&&tag[tmp]!=0)& k+ g4 P1 Q5 ^; B
                {% L$ C% t6 N2 Z2 S9 t' g1 |
                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
* P. J+ L4 o: B5 Y* f9 D. ^6 C                    //cout<<" 2nd     tmp="<<tmp<<endl;
0 P' k0 ~8 v; h4 w: m  L% [! o                    q=NextArc(t,q);/ x  }. @3 j% w
                }
- z0 T7 H# W+ a; d" u9 O                if(tag[tmp]==0)
2 y, x. v' f* m/ C/ j                    s.push(t);. Q5 K# J2 a' y9 i) W9 W
                ///1、对应上面连通分支只有1个点的情况
7 X0 k" J, q9 e& i' }                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
0 `9 X4 K7 {! r+ ^) f$ ~* _& a                ///tmp要么等于找到的第一个未访问节点,
* O& M- i; F0 P  K                ///要么等于与t相连最后一个点(已被访问过)+ I- P. [" N% T# N
                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
& I, @0 ]2 k5 Y4 n0 f9 `            }
2 X/ n+ \+ ]8 i; H0 g. C        }
/ M" q1 `, J- d5 S0 W" ]8 y, J    }  s0 J9 V  v# F6 i& K+ L; G
}/ n$ _6 P# s- ?- y
//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1$ r: B0 }4 V* w6 r5 w
template<class ElemType, class WeightType> int6 F% H1 y% U8 p) \. ?
MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
) a! K( a2 h  b. i{# |/ U9 [5 ^  ~1 P# O% V
    if(head==pre)
: X9 v4 {( \* r  T+ [6 F. f7 Q        return -1;
$ I2 T0 X! k! E2 G" g
( q, g5 e2 x( }3 t3 h    MultiAdjListNetworkArc<WeightType> *p;
3 t. K$ M3 |0 R1 I7 c: N8 g' G    p=vexTable[head].firstarc;
- s* X$ Y: f6 {. A: i+ E    if(pre==-1&&p!=NULL): r& R; N, o# U$ _3 B4 d
        return p->adjVex1==head?p->adjVex2:p->adjVex1;
" \4 z# m7 A# ?6 x, E    //pre!=-1&&p!=NULL! g3 c+ |, N# s% p! u
    while(p!=NULL)
& v, R% s, W: O. y: c' U! z    {% x: y6 C3 C' A
        if(p->adjVex1==head && p->adjVex2!=pre)) K, g9 Y+ m* D) c1 ?' Z# t
            p=p->nextarc1;  _9 ~; b& R, v  _
        else if(p->adjVex2==head && p->adjVex1!=pre)
! q' p1 u+ X! B  Z- e( r; I2 Y8 @9 l            p=p->nextarc2;3 z1 G7 x# k7 q8 \: O
        else if(p->adjVex1==head && p->adjVex2==pre)
) A1 N% J. P5 m4 J        {
" o' Z6 W; {# q  u            p=p->nextarc1;
2 y$ m2 r1 f; B: T, P( t6 O            break;9 ^, e! v) U5 s
        }' W! ]: s* K9 z. G
        else if(p->adjVex2==head && p->adjVex1==pre)
3 u% y- k( F6 d- x% ]( F0 h2 A" t        {
2 R( V3 Q. ]9 N6 l2 S; p# \            p=p->nextarc2;
- p( I5 i& Z( E- x            break;1 n3 v- C" K) w8 f
        }
/ l+ J# \: I" o( p! Y- s7 L    }$ i% \# \  U( g6 ~% z2 W5 i
    if(p!=NULL)) W# |- V1 Z, j
    {
$ d) _/ `% B$ g8 B" H; _' D5 G        return p->adjVex1==head?p->adjVex2:p->adjVex1;$ P1 ?: K5 X. h0 ]( v" h
    }
! O. j. ~: G& Z  ?    else' D8 Q. C( i3 b: B" [* O
        return -1;
2 i. i1 p5 ]- k}
' l  d8 A9 z* b  U$ j2 a4 S' B
; V- B; z2 P. U( |3 ]
' y& H) F5 E6 h' p3 ~template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
' C5 o( R) f. s+ M( y{2 `* y( U8 v. @# F1 `. w  _
    stack<int> s;
7 `$ W" P" j3 C    int p,cur,pre;
- l( i. K! s- v  o    //MultiAdjListNetworkArc<WeightType> *p,*q;) e$ U" G& y7 C% u# W, x
    for(int i=0; i<vexNum; i++) tag=0;//初始化
* M& n  O# f3 C* \2 v) Q/ P" ?3 s( P5 P% q) B1 k7 o
    for(int i=0; i<vexNum; i++)* t7 ], p5 i1 r) I$ F
    {* s  [1 O( p. @& n( v3 b! D. L
        cur=i;pre=-1;
; H8 e. Y. U" D0 s        while(tag[cur]==0||!s.empty())) j: n7 [+ |5 j+ g! X
        {
7 T+ I3 q! ]) J, X* K( j            while(tag[cur]==0)
8 Y2 s- c+ `7 \1 n) ~/ ]            {$ A1 A) C) }1 w, b  ]3 [- z' c
                cout<<vexTable[cur].data<<"  ";' d- S3 X. y+ U! }3 R/ ^7 B' d
                s.push(cur);6 m% N8 u* g  S( G# }
                tag[cur]=1;
6 k  {* O3 @* k* Y$ \8 c" G               //初次访问,标记入栈+ e% d( ^# d# o

4 G! X2 p5 W3 z- e7 x               p=GetAdjVex(cur,pre);//p是cur的连通顶点: H; P3 |6 X% C* N
               if(p==-1)9 e% z: R' B9 L, L3 p
               {! X7 o/ v8 Q" V& W, z
                   pre=cur;s.pop();5 F! \: y5 \  q: R* v& j5 T5 {
                   break;# w7 y) R! x2 B: k$ C# ~- w" ?
               }
4 k" n4 A0 \0 Z4 P9 H               else& l$ T5 A" ^9 \, c* u1 S& r7 P& r
               {! D. c% ?, Z. N) C8 `2 O: f
                   pre=cur;
# I8 r" v+ r, v, [5 ~; i                   cur=p;6 J. k. L6 C) q2 M; g% u! t' D( i
               }
- S! P3 b0 ]6 l, w* W7 U, l* y- g2 x( @+ A  v. g) c
            }- N5 h8 L- Y4 c4 f/ Q
            while(!s.empty())4 z/ M9 c/ h6 S  I
            {- m$ s3 e& W- v- @" z5 e8 ]
                cur=s.top();
) Z! H4 l/ T7 g& O' q                p=GetAdjVex(cur,pre);' x% }. O, q% n( a' g3 F
                if(tag[p]==0)
2 e7 K7 ]" B1 q                {8 @+ P" U& I5 v' \3 q' a
                    pre=cur;7 C% g; y; v7 {
                    cur=p;
8 k  k7 O- Y7 {5 g* Z! [                    break;
2 o; n4 _6 L$ N. V: |5 M  @                }% P+ C3 I- y$ v. T$ s6 z( u
                else
, ]9 E5 i! ]& b2 K, h3 y                {
/ W0 |& S+ ?& A7 a' K7 ]+ P2 m                    pre=s.top();
( i/ Q1 v* T4 b  f3 H& U7 o& G+ r! m                    s.pop();
- s! a) x9 T( C% @- C1 M                }' P" Z& x+ X* g# w
+ U% z; Z$ I3 }
            }
! @1 Y8 d( j+ w  H: d, a2 O( d' D7 X0 S7 g) b
        }
0 d& }1 n1 C9 e+ B# e: I    }6 Y* ]5 w. X" J# W" Z' ~
}! F1 _5 Z7 h# d& p
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
: B0 H3 o0 ^, A% O{2 a3 m) [& c; }+ O) ?/ n
    for(int i=0; i<vexNum; i++)7 `+ C; W) ?: s6 U
        tag=0;7 \+ I! A+ n" s; ?9 z8 F
    queue<int> q;2 W) g3 s- p. [" d
    int tmp,t;/ t- t8 Z2 E# c$ p' o- e3 R
    MultiAdjListNetworkArc<WeightType> *p;, K8 J1 R' r- m& X6 ]% a
    for(int i=0; i<vexNum; i++)) ?- \' K3 E) [
    {& |' Q0 @( P, }* r- E
        if(tag==0)
3 m2 z9 p3 j  D        {
* V! X/ g2 @1 G4 g            tag=1;: J1 f' l9 X) @) T. m$ y' H+ K
            q.push(i);
9 I7 t5 g( ~0 t$ p7 k            cout<<setw(3)<<vexTable.data;
( D0 U& k, t& c  B9 e        }+ o$ J5 M9 c7 Y9 t4 a- k
        while(!q.empty())
- ^6 }  c" t) u9 z+ ?1 T0 I        {
. z9 w6 E& Z* O# e9 R) V            tmp=q.front();
6 l! b/ I* f; m3 Y            q.pop();% D+ z, o7 N7 U) M
            p=vexTable[tmp].firstarc;! I5 j1 {4 D( |( W- H% X
            while(p!=NULL)8 I4 ?" }7 G- P+ l8 w& i% C' i( c
            {
/ E* B( f5 [  N( U) z                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);% S$ i* ?1 K( T# v: E  I$ y3 `
                if(tag[t]==0)4 r9 @# ^$ A; g: B4 h
                {/ ^) B  Z, Q( D& T( K* h) F
                    cout<<setw(3)<<vexTable[t].data;0 A8 i2 L- A+ [. j! W/ l) J+ S( Z+ y
                    tag[t]=1;
! Q% m/ i7 l0 L: o                    q.push(t);' t( C; ^: [+ B/ ?; T3 Z0 S: T5 W
                }
5 {* a: r/ d2 Z' @. O, ^' C& Z, `                p=NextArc(tmp,p);
6 P9 t5 Z) W/ ~. w: C2 S            }$ Z) ~0 K5 l3 C+ \& T
        }8 h, h9 ]1 B' z$ Z
    }6 M7 p# }" w  _# f) t- J  H' v
}
* B) @$ k; Q0 k2 P. X" P8 e( t" o* rtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
& Z0 u& n+ {. T7 }6 Z{  s4 s2 m9 L9 l. G' ]3 I
    MultiAdjListNetworkArc<WeightType> *p;4 J- C1 X- f& j4 ~7 y
    cout << "无向图有" << vexNum << "个点,分别为:";% x0 }& N1 T# ^% h3 p( I
    for (int i = 0; i < vexNum; i++)
% w/ l) K7 E. A/ d        cout << vexTable.data << " ";& g. d3 M$ z1 m! a& w  ^$ B; F1 g
    cout << endl;
0 m. y, w+ K' K    cout << "无向图有" << arcNum << "条边"<<endl;% F# G, Y  e! w8 ]1 p; C
    for (int i = 0; i < vexNum; i++)
: J  O3 R0 z; I. z- x! o: ]    {7 z* P- M2 N( k
        cout<<"和" << vexTable.data << "有关的边:";( E2 Z- B% J8 g: @( m
        p = vexTable.firstarc;
& w9 h' s7 O7 e2 |  q7 p        while (p != NULL)
7 Z0 R: e3 j& o        {
, G* j! k4 P% c* E$ [- R" _            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
. I% ?  E; d. i( m4 _: v) b            p=NextArc(i,p);% F& W0 f# V7 {
        }* U% ~& ^% r4 k+ m+ D# _7 i1 m
        cout << endl;
; T! V/ F. I3 p& @( c. W( W2 i    }) p2 s% P* o  E/ [8 ?2 `! J5 `
}$ O7 `" G% h) d2 H: `: Z
; `+ z; j4 F7 j# p8 g" v5 _

" h) u2 \. L/ P* `" b邻接多重表与邻接表的对比
* ^' }* y; r) g' M2 L
# F/ E' Q2 [* D& k邻接表链接( u! q3 p! r1 Z& C% L4 S
在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。7 k0 Y$ l1 N% e- @) I6 M
在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
5 P) H7 M% V  f9 e! Q( D' m为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
* c2 d# L( I4 E9 v  b7 J) R6 z————————————————
6 k# a, |; y% ?" Z  h1 |版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
5 t* u3 t. U& U9 J- ~原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958# r2 D4 ^, \' h

% u- {2 u: P: {- h' c' _1 Y% B# I# J" r, D

! @5 c. d) r' @1 U7 V' U" x  U/ C; Q: |: N8 L1 L. c( |
————————————————
" p6 A$ d2 j! J( i版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
2 O) _$ }# H4 _" u: g, b原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958+ @, {& B; z& P7 e4 P( A

! m$ G" }5 @5 O7 H. o- v; h: ]) ]# g/ R" M  C





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