数学建模社区-数学中国

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

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

( B# X  j6 t4 ~, e1 k1 Y图的存储结构——邻接多重表(多重邻接表)的实现9 n" W0 U4 {8 T' a6 ?7 G* h
7.2 图的存储结构
  t% ^7 Q: v8 r% ?# \9 k; C% D+ p! B+ ]$ [6 o
7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
8 v, K: @) N$ ?. `( c4 i邻接多重表的类定义* p) ~0 T0 ?( s! O" P. m$ o3 X1 A
邻接多重表的顶点结点类模板% [+ @& a6 Q, Y- \0 @0 v" v- d
邻接多重表的边结点类模板
2 l0 S/ o6 r* s邻接多重表的类模板
! R/ W! z2 U% y7 f  m! {邻接多重表与邻接表的对比: G* z0 Y3 I, o( l" s  T
7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
: g1 |9 N6 {7 ]. @4 k: I# A( @1 p7 F. @6 L/ d, Y- e3 Y( a
在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
. Z. y5 Z! b" P$ Q在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。; P1 s( \! U" g4 C, e
% k. B" A% k$ K( {
邻接多重表的类定义
# x2 y8 D3 G9 {; U# f/ u 1.png " x/ y: o# c7 H6 A
邻接多重表的顶点结点类模板

对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:! q' N* z  @- W3 d  m
data域存储有关顶点的信息;: l/ o) c; U" K  }  w- v) e
firstarc域是链接指针,指向第一条依附于该顶点的边。
) v& i5 d) p: V7 u1 X% @$ g所有的顶点结点组成一个顺序表。


/ ?2 i, _4 G7 O1 l6 O6 v. \3 T  ~' P+ @3 T0 _, A: G" ?- i
template <class ElemType ,class WeightType>
- K5 L+ U3 I5 j2 N" {% Fclass MultiAdjListNetworkVex# e5 z4 z: V" @6 j* o, q
{
! Z+ F' x+ f7 X7 g( q; \$ ]public:4 o% V1 W4 W# _' T) R: [
        ElemType data;
8 K+ X" @7 u+ z' _        MultiAdjListNetworkArc<WeightType> *firstarc;" u" J4 t0 E; u" |( }& H
" U9 Z& D& [4 K, T0 l, X& }% K3 f
        MultiAdjListNetworkVex(), V0 n$ N7 y( P. f% T! e
        {( O5 |) ]: v+ g/ _5 q
                firstarc = NULL;
, P) l! \# M  s! p        }' t3 v" e8 C6 k! p# O! I+ E
        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
% O2 u" W$ W) m2 j& |* `$ |, B# g8 Q        {
6 b5 P* C4 F. R" ~                data = val;
; K8 f  u' k# Z/ Q                firstarc = adj;' B( q0 U* e, O8 l% Q
        }6 Z- c7 D7 G0 u/ ?. e. ~& {$ Z
};& @3 j1 c$ s7 F1 G
+ C6 E4 M2 U+ {0 F' t
邻接多重表的边结点类模板3 E9 ^* E( ^( c; @: O5 e# P% V
- r. b2 B$ {, A% S
在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
9 V: l1 g: J; ~# d- v  a" M! htag是标记域,标记该边是否被处理或被搜索过;
" l3 \; P3 e& o$ m% t2 uweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;) u. E) Q% C4 `6 a6 ~* b
nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;5 N* ]5 s5 P1 \1 m' x
nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。- ]6 v6 g& c$ `

6 }& }5 s! O7 J: q 2.png
5 R% o+ k4 u: y! Z$ n" }& ~. X9 Otemplate <class WeightType>6 l7 h9 W4 G4 W, v9 v5 [4 Y
class MultiAdjListNetworkArc( P  C: w6 k/ r2 C7 j
{
6 i' j1 M: n7 a& R$ Z$ fpublic:
; ]0 S% k& i+ M6 d8 W' h: [; e& n    int mark;                                       //标记该边是否被搜索或处理过1 A, E; d' \0 j! P% P
        WeightType weight;                              //边的权重2 e0 N( g- H6 B* S  l0 X& p
        int adjVex1;                                    //边的一个顶点5 n- x. W- m, f0 c, T! O# |
        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-11 g/ V, R, k, v; j+ b/ M; R: e2 x2 M
        int adjVex2;9 E- a: U8 x4 V" O; H
        MultiAdjListNetworkArc<WeightType>* nextarc2;& V+ }5 t' Z! s2 q" N
$ N; w( F# I' ?" ^! _2 Q' k+ [
        MultiAdjListNetworkArc()
% Y) t3 J8 Q* ]* O( g! O3 Y5 R        {
6 R/ B3 x6 x3 @: G. L" q  `# Y                adjVex1= -1;$ {" i0 C# B. K) ^5 K3 b
                adjVex2= -1;) V+ [2 z* w1 z  V+ p1 C
        }5 Y. ~: u0 e+ T) @- x$ v
        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)5 j' W: n! i, j7 m% Q- Z
        {9 Y6 k* ~6 c- E5 @$ E- E
                adjVex1 = v1;       adjVex2 = v2;' k0 z2 `7 f1 h
                weight = w;
9 U& v+ S3 Y  H% D  q                nextarc1 = next1;   nextarc2=next2;
: r0 z3 T# M+ ~3 `                mark = 0;           //0表示未被搜索,1表示被搜索过- d) K/ V- r3 t7 O; ?
        }
2 m% y, G% a- ?
/ D, p9 x6 O, c8 R( M邻接多重表的类模板

1.类定义

template <class ElemType,class WeightType>% i  R2 [3 _: l% r, N# P( p) d
class MultiAdjListNetwork8 J  L2 S3 y- h$ Q0 g" p- K( P' X
{
! B" q- ^) N+ l( R! C$ S5 `protected:) z7 X6 Z8 L( A" a7 i9 b  A0 y+ g1 p" m
    int vexNum, vexMaxNum, arcNum;
6 ]0 a" r4 O" a" c  V% q* C% Y    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;0 ~* n% z0 t) ^! B! h9 t
    int* tag;
) G+ k, a+ d( l' e    WeightType infinity;
" k2 D2 z2 q" A
0 _" W1 Y: ]" Q" H+ b* jpublic:3 A2 N8 s+ z! F0 A* y/ s
    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);  ]/ }; M3 t( U$ C5 }
0 d5 M; V! ^0 n2 [$ M8 @
    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);1 V% {  V& g" N5 l- R

- [. a& j9 p  X) V: S! o3 e    void Clear();
8 ]- m, E" [+ p" _    bool IsEmpty()2 S+ S7 I! {% `$ d+ y2 O
    {
7 W' G# k, L. j        return vexNum == 0;
1 b3 |, t, K% @* Y2 e    }; m2 R3 F1 k9 e1 Z
    int GetArcNum()const
" k) S6 c  A6 M# o, X9 @    {- G0 f7 u8 o  q& @3 Q: ~# k4 S
        return arcNum;
  f  R+ |, Y/ T9 ~0 g3 k    }
  s! Y7 W6 {: ^' P/ W0 ?    int GetvexNum()const
" g3 y! u- c: o) p( Z! {    {! S& J% G3 b0 y
        return vexNum;: x: O/ k0 ]; B8 A6 m
    }
( }- p) F3 e  r4 L! U& \. o+ Y. h; I8 ]2 T
0 e1 y9 y. V( h5 c1 |$ W
    int FirstAdjVex(int v)const;
; U0 f5 s2 s( t) ?9 d    int NextAdjVex(int v1, int v2)const;
% ?0 ]! ~& I! q+ y5 n9 F    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;5 z7 J; o8 \1 C* e! _/ T/ }
    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;6 Q& g# x. V& X" Z7 ?

9 `. E6 K# }5 b, U    void InsertVex(const ElemType& d);
2 n+ w  C2 e1 e+ j3 x3 F1 O    void InsertArc(int v1, int v2, WeightType w);; C. h. w1 K: g, W

! p6 g$ v) o* y0 r4 g7 `3 U7 N    void DeleteVex(const ElemType& d);
2 ~0 U; H$ m+ T, R5 F/ U0 k    void DeleteArc(int v1, int v2);* Y! [9 p4 {( v% X; F
4 f% s+ U% g- g! V- \) A
    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
6 G0 r# ~7 A$ e: S    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);1 n$ z; }8 x0 z+ T
" a; R) o6 K  }
    ///深度优先遍历$ f0 `6 o3 `7 z+ I( q: V, q
    void DFS1(const int v);
- N/ x) Y% `6 ]1 n    void DFS1Traverse();# V$ s0 a4 r4 h3 |5 _  l
    void DFS2();3 ^0 J8 F' u9 Y0 y) C! Q4 _6 O2 r0 r( }
& T, T; V6 P  k) G3 j
    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-16 `# K# l9 R- P* f$ J2 d
    void DFS3();
% g( U# f+ k- I! {8 |  K% u2 \) B" x* c- q/ B
    void BFS();8 ]' `9 I: J( m5 f0 D- T
    void Show();
8 |# j( ^) V* ~" T+ g};* W  a6 h5 V: B! V4 c

$ m2 a. Z. ~" [2.函数的实现
  `/ Q4 W. X' q" k/ @) I研讨题,能够运行,但是代码不一定是最优的。  }4 N! W/ z. |% {

% x" g5 F1 Y* X3 N  Y#include <stack>3 t! b: [( b% \. g2 l3 _4 @9 T4 c5 X
#include <queue>& U9 d! c/ c8 t4 I

/ I" T3 N8 ]) C9 Itemplate <class ElemType,class WeightType>
+ ~" C6 X" @4 U9 Z! D6 C' _+ UMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
( o# y* L* K# K) h) [+ j* z1 a{
/ j# M- p; ?/ x1 D    if(vertexMaxNum < 0)
6 S8 |+ t( M1 U: T4 |  }7 H        throw Error("允许的顶点最大数目不能为负!");+ B7 A! ]& A0 {/ F9 X* k
    if (vertexMaxNum < vertexNum), e: M$ @# E3 r9 t, m7 E: j1 R
        throw Error("顶点数目不能大于允许的顶点最大数目!");
9 G: r  q( ?7 b  _: [# i. T  {: h1 N    vexNum = vertexNum;- J% H' Y% ?1 ?  g& A) P
    vexMaxNum = vertexMaxNum;7 ?1 s2 f" G9 I, w; L; Q( y
    arcNum = 0;
% Q- B5 _0 z5 U- O$ l: @' g6 G    infinity = infinit;: t. N- g. V9 i% s! }8 z
    tag = new int[vexMaxNum];
( z2 ?0 o' k3 _    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
: D+ C: H7 X% F" M, [    for (int v = 0; v < vexNum; v++)
: V) B, O7 U, u7 n1 r% F. a    {; p3 Y6 v# P2 A% H$ w
        tag[v] = 0;
+ |( c( N5 s3 r/ ^# i& L3 E' t        vexTable[v].data = es[v];
! ^9 [( U6 |; I# b' m( G        vexTable[v].firstarc = NULL;
1 P- n5 I& _" e. X    }  R% D& ~6 F( r
}+ H6 [+ ]8 N. I, D: T
template <class ElemType,class WeightType>2 r; y% C% U! N3 k
MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
' U3 D$ m4 x; {{7 [! w- F. z0 Z' ~' @8 N
    if (vertexMaxNum < 0)
9 m& \2 Y4 N4 O$ }        throw Error("允许的顶点最大数目不能为负!");
" ?: f' ^6 i7 L5 z3 h    vexNum = 0;) p* ]# M9 a0 W% c* }; F
    vexMaxNum = vertexMaxNum;7 T9 ^4 x; a7 a# s+ R$ R4 z
    arcNum = 0;& o" N# J+ s/ c. G
    infinity = infinit;! M$ ^5 N& o- m
    tag = new int[vexMaxNum];
0 W0 a2 w; d" t& [    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];  `! r$ N3 ]" ]/ ?0 F; A& y
}& |1 _/ O% W0 P1 d& V
template<class ElemType, class WeightType>  ~  F3 o. i5 `$ \" V$ G+ K5 c4 y' f+ n
int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
+ R7 U! Y/ Q- {9 b1 f4 \" R! R+ R{% u$ j5 ^; w9 c3 h
    if (v < 0 || v >= vexNum)
& Z( m0 C6 z1 q5 F0 F7 r        throw Error("v不合法!");+ `/ U% c5 {9 D5 h% D& Y, o
    if (vexTable[v].firstarc == NULL)
8 p' K8 S* n6 Q0 H% ?        return -1;
! s* A) z/ m1 `    else
8 F/ ]9 M) {/ ?4 W7 O) n) V        return vexTable[v].firstarc->adjVex1;
  d8 a1 ?& l" L7 v6 J3 W& i}
% J7 F  ^8 v. F! i/ @) Q' C: Y* i/ @
template<class ElemType, class WeightType>5 P0 A4 C) N* W* x( g$ m6 v8 d  `
int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const! o8 ^+ o. a2 O3 }4 Z6 m$ x
{& v3 C* v$ P6 n
    MultiAdjListNetworkArc<WeightType>* p;
& i( g! f/ r: n, m    if (v1 < 0 || v1 >= vexNum)
0 j+ H* b* i' g9 I$ F, S. v        throw Error("v1不合法!");
+ k- B5 A+ Y/ ]$ o3 M/ \4 ^    if (v2 < 0 || v2 >= vexNum)6 n9 k1 Q. x  R6 X# i
        throw Error("v2不合法!");! R* I. H; B  n  z( C3 `- G; ~0 B
    if (v1 == v2)
+ m$ c3 |, o! ~5 J        throw Error("v1不能等于v2!");
7 t6 U6 |% e- }7 o& k2 w/ w) u    p = vexTable[v1].firstarc;
. w& ]9 S7 N3 G8 e6 f; R; r    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)' H, B, p! R0 ^4 N
        p = p->nextarc;/ b! q3 U1 _9 v8 [+ J
    if (p == NULL || p->nextarc == NULL)% S( g% c& g5 G% h7 R
        return -1;  //不存在下一个邻接点
) g  V/ t1 S" M( {* A# j$ m    else if(p->adjVex1==v2)* a* Y- M* m1 g! m4 Z/ \
        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);+ J1 {- I' u. q# ~9 w4 E" e7 P
    else7 t* m. D* |: e" }( E
        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);" A" |) E2 u+ J) M9 ~
}/ E- j/ ?! A- L4 v
template<class ElemType, class WeightType>. z0 i) o" p  l& b/ E6 h$ {
void MultiAdjListNetwork<ElemType, WeightType>::Clear()5 ?" d2 I: x$ f/ x, D0 b* {
{
  t* ~- U: v; U: a6 u    if (IsEmpty()) return;0 R5 @9 h! E  N! L# u0 r/ _; m# v! Y
    int n = vexNum;
8 X, M" ^1 G' r: b$ z- V    for (int u = 0; u < n ; u++)
0 c" T4 |( f6 \        DeleteVex(vexTable[0].data);
. J0 \$ F% f$ S- F    return;
+ c# T& k% ]# h5 z  H) Y$ c) W}
  w7 w' E% y( Q+ z! i! ytemplate<class ElemType, class WeightType>
) F& ^; R! i! L9 }( h: yMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
; X1 V7 C. x* V0 `; X{) B2 y/ E; n# Z3 X1 C
    Clear();
' j: p! N  ?! }- g% _}
  w7 m& o3 ~% c+ T$ |9 H0 otemplate<class ElemType, class WeightType>
$ A! _' F% S, v+ i3 |# fMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
& s) A2 J7 h3 m2 r{
" l8 o4 f& L" S  |    vexMaxNum = copy.vexMaxNum;; z4 {5 d9 U; M0 f- i
    vexNum = copy.vexNum;2 ?( ^7 N& K* W, r# X
    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
: B4 W8 J1 g. T  x# |1 u, {9 Z    arcNum = 0;1 z' d/ s0 ]) G2 m/ a  |4 v
    infinity = copy.infinity;
. O" ?* l7 E/ `) ^1 z6 c1 `; n    tag = new int[vexMaxNum];
6 ]1 G, v. D$ t) W$ O; h4 d4 b5 }
! U) M5 G3 ~8 p, k  \% l. }. k' c3 `    for (int v = 0; v < vexNum; v++)% b& O6 v7 g( d+ D! ~
    {
; _. J3 y4 a5 W        tag[v] = 0;
/ }1 a4 n: I) Q5 b; d( @% x        vexTable[v].data = copy.vexTable[v].data;3 j4 f8 V% t; c/ Z' W4 e
        vexTable[v].firstarc = NULL;
9 F8 G. a& M1 q7 L1 ~    }- E- f& Y2 D7 o' n- a9 q
    MultiAdjListNetworkArc<WeightType>* p;/ o: p- f& C8 m/ K5 ]
; }0 d6 N8 b, e% \1 i) K& v/ u
    for (int u = 0; u < vexNum; u++)# M7 I6 j' R% A0 p) ^9 e  E) a! R
    {% B) t+ ?5 u! w3 z/ j' O% _* E- W
        p = copy.vexTable.firstarc;
# m- M  }% X5 }; e; }& E        while (p != NULL)* m+ G  o0 o0 d% H& m  O
        {: X( v' V3 g- E( v) S
            InsertArc(p->adjVex1, p->adjVex2, p->weight);
' N9 q9 }8 j+ _3 B" g7 v0 `            p=NextArc(u,p);7 g: L) a1 l* y8 V4 v- }6 T4 N
        }: N; q( t/ ?0 [
    }
: r# B6 _) Y3 |# c, h1 s$ n! Z0 e) |3 @}
: d2 x6 ~& \2 x- Btemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
$ n& ?8 R+ {' u! v* o/ ^: gMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
* C' w; j  X' Z* f$ g# T9 E5 q7 B{
/ m+ _& D8 \4 v0 g, Y* W0 d    if (this == &copy) return *this;
; A( O8 Q" ~3 H! e4 Z) G    Clear();0 p! y& s" v' x% v) E. j: m
    vexMaxNum = copy.vexMaxNum;
' y: ~& c# g7 m6 V    vexNum = copy.vexNum;" B! f" f+ e: M) G7 w; \9 ^
    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
4 F! d! d8 |8 u) L# a    arcNum = 0;
& d5 y& [; l& g    infinity = copy.infinity;3 k5 j' ~5 B& \" L4 }, y
    tag = new int[vexMaxNum];5 q, ]% J( Y/ v+ n  B- _
, s9 |" F/ F7 e* C0 s7 I& h+ a
    for (int v = 0; v < vexNum; v++)
5 }! b) h8 B3 v7 d' ^    {
& r. U* o4 H9 [4 m4 \8 P. G        tag[v] = 0;
& M1 Y- I6 ~: h        vexTable[v].data = copy.vexTable[v].data;, l% x) |4 N' y1 [
        vexTable[v].firstarc = NULL;5 o7 d; F! `, K- m( y0 Q, z
    }
/ K$ t8 s( s) ^6 H% }' y    MultiAdjListNetworkArc<WeightType>* p;
. {  @- {, v# t. S% k
9 |/ K; b% n/ {- U# {. Z7 M    for (int u = 0; u < vexNum; u++)
6 T6 J6 V9 D& E* E    {% P5 u; H- u+ M: W
        p = copy.vexTable.firstarc;
2 o. M% G2 D* }        while (p != NULL)# N" ~5 G- a- {* ]- m( F5 w$ V
        {
5 B- G9 n0 @) ]- X: e            InsertArc(p->adjVex1, p->adjVex2, p->weight);) _' S) Q1 c" }) w
            p=NextArc(u,p);9 c' O' ~, f/ S" @7 V) D
        }3 d/ }. _5 e6 {3 I0 r. U' |" Z
    }
- E0 B1 e; h1 W- }5 H0 k* N    return *this;
' m; D/ Q9 k* C& r  o7 I- ^; Z}2 C2 S: l; E- w
template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
- G* E0 l5 g, V( n' v; WMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const9 q" v4 y$ d, o  `7 Q. `
{" C" X# F. [( v: i# n; a: |
    if(p==NULL) return NULL;% g' L5 |0 J( c1 f3 @
    if(p->adjVex1==v1): M  y: a8 I) X- I" }$ y, g4 H
        return p->nextarc1;
" D; W1 a2 {8 X# e+ H, a+ M% X) M, Q    else
0 d, y% V+ d6 O) Z, G* `2 F! V        return p->nextarc2;
/ M7 i/ [7 O  O+ `) l4 A}2 ^$ |+ y% V7 _  l3 }
template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*) a/ ~4 a7 G, V( P* }  c
MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
5 P- }, T4 a; {7 t- g' ?5 r{
6 S" u* d& n; O' t. y% h    if(p==NULL)return NULL;
: \1 o0 k5 x3 k/ E2 L2 m    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;* v( x. X! @& G, B1 m5 q0 j
    if(q==p)
& k; z0 T$ [& V6 L- u- x' _        return NULL;
" k: k8 q  I4 X$ H    while(q)/ n8 E1 N7 u3 z/ H3 F; p& d/ M+ J
    {: U" L4 ~% [( V3 s; T
        if(q->nextarc1==p ||q->nextarc2==p)
# L% n) o% [& W% ?6 t' f+ r            break;- ]5 k  i: o; j9 b' `* \; u9 b
        q=NextArc(v1,q);
1 l1 }' t( [; r; Q8 p    }! R1 C6 P# A9 t6 B1 K2 R, x' X
    return q;
( {& Z* I! n$ l' T8 O/ u1 U}
. m/ P. B+ |( x. ftemplate<class ElemType, class WeightType>
6 s1 L! H# ?( j7 t* C. U( xvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
6 k6 H' A. y, D" P; j{9 I% q4 V5 R! d4 _! G, t
    if (vexNum == vexMaxNum)
* e+ f9 c+ L6 O" N( w        throw Error("图的顶点数不能超过允许的最大数!");& h/ L9 _8 c0 e" ]
    vexTable[vexNum].data = d;, E8 D' p6 ?' ?! z( ^( B
    vexTable[vexNum].firstarc = NULL;
- x" I  j# K3 t: V    tag[vexNum] = 0;9 Z; j4 p2 B% p7 E0 V& a$ u
    vexNum++;; Q2 z1 O$ R- W! q. `
}# w$ l" S3 n# E1 h* n/ ~. [/ ^
template<class ElemType, class WeightType>+ b7 n- v1 {" S
void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
- f8 Q4 K, n  [- K{
. i6 }4 [8 c! A3 R0 e    MultiAdjListNetworkArc<WeightType>* p,*q;4 |- Q5 [+ P0 c+ }/ ^  x- ~
    if (v1 < 0 || v1 >= vexNum)
3 m9 d" J) n& U4 n/ e4 _        throw Error("v1不合法!");
4 ~& j( B2 R, \) \, F* Y. j$ W" c' \    if (v2 < 0 || v2 >= vexNum)
! E; \+ o; e# |1 l        throw Error("v2不合法!");
: g! H% i* O5 _    if (v1 == v2)
. r- ~) r2 l( e, D* G3 k        throw Error("v1不能等于v2!");
/ B5 V0 j. Q! i1 F- I/ X( N6 m    if (w == infinity)
% `9 T1 x7 c4 O9 t8 k4 J! ?        throw Error("w不能为无穷大!");
( [4 J3 K8 l. r( H' f
. `+ ~& W( O9 p! O6 K2 m+ p5 ]( q, C
    p = vexTable[v1].firstarc;1 l$ S2 \& |& M
    while(p)  g' K9 d$ ]% g
    {
7 X) b- K3 ]( M        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中) K2 d" q8 u, G' }7 N4 p2 W% Y* X
        {
8 v7 C' O4 c. q            if(p->weight!=w)
7 h$ @: H5 x5 r8 I9 J- s$ g4 x) Y                p->weight=w;! p% g) h) N/ m1 F
            return;* o. j+ J) h3 _  B/ B3 t: r
        }5 l! E1 P' [# v9 z+ {& i
2 |" T# ]0 Q. D  a2 o
        p=NextArc(v1,p);5 K: k1 v9 ]4 h
    }
3 R9 _6 n# Z9 t2 U2 N4 p4 S' j. [    p = vexTable[v1].firstarc;
2 X6 x5 z3 I( G$ X( ^' F    q = vexTable[v2].firstarc;* \, f& t, ^, Z# i7 C& Q9 A
    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
: _+ ]3 A7 R  R0 S7 k- a    vexTable[v2].firstarc =vexTable[v1].firstarc;! i+ u% V6 _6 K% l
    arcNum++;4 W3 c. r9 l. y5 v+ G
}
# y) D/ a: Q1 N
6 E* }4 t3 [* I. Q; ~7 p5 ltemplate<class ElemType, class WeightType>1 G) q4 e1 A) t) _* i
void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)7 ^0 T5 |' u1 [
{3 e" _1 ^3 R9 t) T6 q) j% T7 b4 j

" S- U! T. ~; Z- `5 s    MultiAdjListNetworkArc<WeightType>* p, * q,*r;, J- L% P" D. C& |' s0 }- y
    if (v1 < 0 || v1 >= vexNum)
2 Z) O8 Y* x7 ~) |  }0 P  h3 W        throw Error("v1不合法!");3 R9 f5 c, I: ~4 U
    if (v2 < 0 || v2 >= vexNum)
# P8 k6 Q! K8 c) D% @# M: l* {        throw Error("v2不合法!");
# o% y8 G( A* N" r+ ]0 K    if (v1 == v2)) p# J5 O! X5 o$ S% n
        throw Error("v1不能等于v2!");' Q$ n+ R. w5 q$ N% D, y* x3 L' H/ j

5 ?9 ^  g; _$ z( h% Q( w    p = vexTable[v1].firstarc;. r; d$ v  f1 i! ?- w
    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)1 @& D* T1 u  O* J6 _/ Y0 _' z
    {4 C/ O5 S& q$ a4 N
        q = p;
/ G" |9 j" b  i  m) Q3 N0 I        p = NextArc(v1,p);
! q; ]5 N2 v7 w% c4 N4 e    }//找到要删除的边结点p及其前一结点q' H; m# i0 C: T3 ]0 V: q
4 u  d2 _! X) I- V2 I% `, C' h8 U
    if (p != NULL)//找到v1-v2的边
" X, S2 p% L7 O2 M/ t, g! c    {. l" @, L' v7 y' P
        r=LastArc(v2,p);
; i1 r0 K- _$ S: W        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL) |1 v* ?2 h- i* S/ y3 y
            if(p->adjVex2==v2)
! u+ @. [8 ?' E0 d                vexTable[v1].firstarc = p->nextarc1;, ~7 e% l$ [( X4 p
            else vexTable[v1].firstarc=p->nextarc2;8 i- W0 N3 U' \
        else//不是第一条边+ m, M' K7 u+ x# \
        {
- S! [) i2 G/ x# n3 D1 i. P' [            if(q->adjVex1==v1)
  s- o# y+ @. z8 J' O7 V( c                q->nextarc1 = NextArc(v1,p);
1 _- h& c  N  G/ \            else
. y' b2 z: K  @9 q- ]3 G. j                q->nextarc2=NextArc(v1,p);
* m: L6 o4 |7 S" f1 I' o) n) m* D& ?8 b8 n% S
        }2 \% V9 l* X, L8 p- S8 F1 T3 h: I
        if(r==NULL)7 e+ z( r+ N8 }  x2 o) @" r
            if(p->adjVex2==v2)+ R: w1 q/ x" q- X
                vexTable[v2].firstarc = p->nextarc2;
8 m) W9 C9 s% ~* s# ^. {: \            else vexTable[v2].firstarc=p->nextarc1;
* n+ o  O# k( K5 |        else
# o  z- C2 D, G) E' t2 R+ _& b        {
2 k5 F- v0 a& P& D            if(r->adjVex2==v2)
: O( K& N3 p& [: P8 d" }9 K                r->nextarc2 = NextArc(v2,p);- `2 w. b2 ^( K& D+ H" l
            else
6 _& v6 T5 U! s. q                r->nextarc1=NextArc(v2,p);
* L- u+ K7 ^1 B; g4 j        }
- Y# ]" W3 A3 E7 ^) R6 }! A        delete p;
, |. O0 B. c* B8 v+ c! @        arcNum--;
1 F6 U- Q" Y9 z$ m" \6 V    }
$ O9 X% Q! m* _) F; F8 m, H  s" C+ s' W6 V6 I" u7 X
}
% `6 [+ P9 R! E, C  V0 dtemplate<class ElemType, class WeightType> void1 M- c, J1 t9 ]7 e) E  K% D! w
MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)2 L, g( u- j* D2 W4 w( \4 p5 ^3 n
{3 b3 L. B' t( o$ L
    int v;
. P$ t5 \( ?& S+ G- r    MultiAdjListNetworkArc<WeightType>* p;
4 Y! V9 Z- F/ `    for (v = 0; v < vexNum; v++)//找到d对应顶点
8 i8 N( _4 d0 r3 B        if (vexTable[v].data == d)
9 H1 `0 K( a- ^9 G" U* I1 Q  p            break;
: _1 e$ v7 a+ a4 @2 \1 t    if(v==vexNum)
& M  r) P1 Z  J$ o9 C* s        throw Error("图中不存在要删除的顶点!");- A- K! h8 [6 S7 G
/ a) b! l, r; I+ B) c: I* Q& D
    for (int u = 0; u < vexNum; u++)//删除与d相连的边; Z5 e' L/ @! i( A
        if (u != v)& ?) [) I" L: t* E! {$ j
        {& F" |/ {1 m2 R. [8 E  a% [
            DeleteArc(u, v);! \5 ~; o$ r0 Q4 f2 L, D
        }
4 R" x7 m9 c; g8 }: U' }4 G8 M7 J    vexTable[v].firstarc=NULL;
% q" }( S, A; S$ w
# ?9 S( O, ~: f5 k$ H7 R    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置) |3 n4 D8 t- g+ P5 j3 Z
    vexTable[v].data = vexTable[vexNum].data;
1 w/ `$ e0 C# D. C! b7 N/ t    vexTable[v].firstarc = vexTable[vexNum].firstarc;
7 e, Q. H* [) u- m* G2 J) U    vexTable[vexNum].firstarc = NULL;. a; r$ r, O3 E+ h; S% Y
    tag[v] = tag[vexNum];
+ \; |4 M& `# S+ K. f    //原来与最后一个顶点相连的边改为与v相连
- O# I$ Y/ f9 W1 L, {; [' r    for (int u = 0; u < vexNum; u++)
! e% H) J8 `6 R1 K    {
: t3 g0 N* Q- P0 S$ Q* X        if (u != v)3 E* O5 Q( l$ s, v1 f7 ~* G
        {
3 j# C5 I+ E- }( p. H            p = vexTable.firstarc;6 Z; u6 [" |' i9 _7 u
            while (p)5 @- Y# h! A# e' A1 V
            {
% B  i- e5 g7 J) x2 t- P4 E8 l0 Z                if (p->adjVex1==vexNum)
# o/ e0 E0 Z# r/ L! u1 X                    p->adjVex1= v;
' ^0 M  h2 r" t/ K! K% R9 P                else if(p->adjVex2==vexNum)
$ g* b. N) O/ l                    p->adjVex2=v;
" G1 J+ S4 r9 o# J, i3 e                p = NextArc(u,p);
2 [$ r* ~& M( t3 \" M8 E: Z            }0 u- a# h& [1 Y7 u/ L
        }: E; _. \* k5 t8 h
    }* P- k3 O4 W: l; i" k
}
5 V6 D- g# v9 S# U  N///深度优先遍历" m0 q/ r$ S* M& Z# K3 t8 a
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
. D* H, [* Q+ m: N- k{9 m$ @8 v/ S2 c8 @+ ]6 T
    tag[v]=1;. q9 Y& S! e7 P) j) B, N
    cout<<setw(3)<<vexTable[v].data;7 R/ H1 @+ f0 G0 M
    MultiAdjListNetworkArc<WeightType> *p;6 ]8 T5 c: V' H( m+ _/ s" S
    p=vexTable[v].firstarc;
2 Q' v5 b, G  {9 K0 }$ |    while(p)
2 v/ a# C) ^" h3 l# {. f) p    {
/ ?# H% h6 S3 X        if(tag[p->adjVex1]==0)
% @; S1 W- l* {. X: ]4 v            DFS1(p->adjVex1);0 i' ?/ O; u6 R* M0 }- ]
        else if(tag[p->adjVex2]==0)
7 J- J7 V* _9 W5 N7 K            DFS1(p->adjVex2);, X; n  W5 C# N1 D7 g; f  f. T5 C
        p=NextArc(v,p);
+ W' Q' y$ W$ s; e    }" T7 W. N8 B0 ~- D( o7 i
}
1 Y* f. a* P! utemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
2 @1 k* U  W/ g3 h/ H6 M4 Y( c$ N{
$ [3 `- W1 |* G6 v# e) W    for(int i=0; i<vexNum; i++)
5 `, Z8 t3 T: P  T+ y/ D% ?        tag=0;
% V& h6 `: _6 X4 _, U    for(int v=0; v<vexNum; v++)
9 r8 O% `( @: x7 I4 n, F) i* H    {
" J1 N, G+ I" ^4 R) {: {9 `        if(tag[v]==0)" A7 E$ p8 Q5 P7 A# b( G# ^! U$ X
            DFS1(v);5 t0 ^  G( S$ ^5 g, ~7 N: t
    }/ k2 s4 v' d: a" v* ^7 d2 p
}5 L( Z9 @8 J: N
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()4 G4 c& _/ O( G- ]7 k
{: @0 j+ a% Q/ S( _
    stack<int> s;
5 P! x% ?8 o/ F0 [    int tmp;
! y& @2 q9 ^( s    MultiAdjListNetworkArc<WeightType> *p,*q;6 f0 q8 W0 X+ }% x: U) Q! q0 ~0 A% ?
    for(int i=0; i<vexNum; i++)
# n9 b( ]! N) c/ Z# W5 ]        tag=0;% _$ J- D: m. j# Q
    for(int i=0; i<vexNum; i++)
* j* s4 l& P0 E& Y7 J# k    {
$ G+ R! U9 @; ?" r8 O        tmp=i;
+ F( K" ?# m5 W3 d) v        while(tag[tmp]==0||!s.empty())! Q2 [8 q7 b  {; C3 c8 H- ~
        {  }( q4 n1 K2 l. C4 j) p0 T
            p=vexTable[tmp].firstarc;
7 }3 ], x+ ?% h7 W0 o$ r            while(tag[tmp]==0)
; o1 E8 @% |2 s% L' `5 ^9 w( B8 P            {" f9 l' M. [( {, C
                s.push(tmp);' M2 O4 ^2 u9 [& W3 ]
                cout<<setw(3)<<vexTable[tmp].data;
) K- |# i$ |$ w$ ?9 s                tag[tmp]=1;, W: R8 n2 L2 K0 K  o
                p=vexTable[tmp].firstarc;
# p$ j: }8 K$ G! M& p                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for: @! U& `& {- ]( C9 N
                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);3 V4 x! g, X8 G1 O. g
                //cout<<" 1st     tmp="<<tmp<<endl;+ t& K+ H9 n" A# W1 _
            }4 O: t: O# m& {& i
            if(!s.empty())5 r& M0 k: x* Y$ b2 C, s2 s/ q
            {
- R) Y6 J* J3 M                tmp=s.top();4 q5 I$ Q6 m4 c+ m
                s.pop();6 T0 P1 f" O" }% [0 J, o' |( @0 @
                q=vexTable[tmp].firstarc;* y) \! T% Y' D/ W8 h
                int t=tmp;) A6 o4 B+ D( Q, V  v* x
                while(q&&tag[tmp]!=0)# q, [- [9 {* _' Y. H
                {* c2 B+ T8 f1 t5 L) s, N' T
                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
; E4 l7 d+ @- }, T& S6 u% \+ k                    //cout<<" 2nd     tmp="<<tmp<<endl;4 `0 ?& f) f1 q& [1 G% M
                    q=NextArc(t,q);4 d5 B8 y$ e$ m
                }5 D. W+ ~3 [- E- Y9 J& L* B7 h! K; b
                if(tag[tmp]==0)
4 W" q! V0 r3 h                    s.push(t);
* i1 t* T! B5 H! C                ///1、对应上面连通分支只有1个点的情况) K; {+ P/ ~" E# a9 D" ^
                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈1 s- g$ T* i- @- H
                ///tmp要么等于找到的第一个未访问节点,
9 G. Z/ v/ L7 Z                ///要么等于与t相连最后一个点(已被访问过)
( l5 j. {& J% h                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点' g/ p0 `4 Z- \/ f
            }
+ x  K$ f* ?! V9 T+ H5 i        }
0 ~5 B6 T6 {' a* O    }
; m% B) p: x  S) Q0 O% ?}
& T/ E" r* J6 x# W4 v; M//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
- R  o3 c3 l9 R: V9 O8 A, stemplate<class ElemType, class WeightType> int
- e3 \1 }" v, \, S0 pMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)' m" n; d& T* g' `8 y! G# h3 C# N& ]
{& J6 O- Z# T/ I+ o; i; U* g3 L
    if(head==pre)
' O& ~: k5 K) L0 q        return -1;
' y$ }2 {( y+ w+ ^" X# K' g' c3 {0 I3 @' n% P2 w
    MultiAdjListNetworkArc<WeightType> *p;+ b1 R1 W- o9 j7 l, K1 p$ B4 L- S
    p=vexTable[head].firstarc;1 M: v0 v% g) b- s
    if(pre==-1&&p!=NULL)
; E1 y' i- q1 s        return p->adjVex1==head?p->adjVex2:p->adjVex1;
. e. [# f/ |! D6 w    //pre!=-1&&p!=NULL& r% m" `8 I- C1 J0 x1 Q' Y
    while(p!=NULL)
/ P& z" d) U$ s' b, ~! Z. u    {# W, |' z! `1 z0 z2 z; J4 H  a
        if(p->adjVex1==head && p->adjVex2!=pre)  k9 \# j$ o3 S' q
            p=p->nextarc1;6 X5 r5 |8 l- L5 z, y) Q
        else if(p->adjVex2==head && p->adjVex1!=pre)# T& @, q- b8 o( N8 g8 a
            p=p->nextarc2;- _! m' p2 a2 t0 T7 B
        else if(p->adjVex1==head && p->adjVex2==pre)
9 C, [; f* [( ^/ w' _        {: m: w2 F9 Q+ j! X
            p=p->nextarc1;
9 T$ u: ]+ Q) P( J( d! q" W            break;! v. z7 Y+ P( K' [8 N1 s
        }& o' p: U% N' s. U. i( l& E! K
        else if(p->adjVex2==head && p->adjVex1==pre)
6 F6 O6 y0 w; O: \3 q4 }        {
$ w3 R; Z/ m& t; m6 q: ?$ t1 \            p=p->nextarc2;( u! b3 ]# M; Y+ B9 m/ p
            break;! M6 `1 N2 F" v3 V( W; ^) t
        }
; n, G- i2 }6 ], N! b; g/ B* \    }! ?9 ~9 B/ z, ]+ d0 e
    if(p!=NULL)2 \( ~6 W1 U# X1 W
    {  e' }# f+ B/ y& y4 }$ \% n
        return p->adjVex1==head?p->adjVex2:p->adjVex1;
7 G, w  |, P# U* A7 h# I1 T% u    }
" {0 D; N2 k# P7 K! N    else. ^. T2 P6 L' ]
        return -1;
; I4 A$ [8 X3 b7 L; x1 ]}2 k- {+ ?: ]! E" O' g9 V
, s' A# y0 \) K0 A7 o& \

3 h/ A) C9 ^1 i% f; y% Mtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()4 {9 K1 y5 {* a
{2 |/ l' N1 W" x+ ^/ F* y) `# }# \
    stack<int> s;. i% j2 ~: X( N8 U+ X) E
    int p,cur,pre;5 M( M2 Y8 t9 [4 u, P: L  L
    //MultiAdjListNetworkArc<WeightType> *p,*q;
" s7 V" b+ d/ }9 s1 W/ Y    for(int i=0; i<vexNum; i++) tag=0;//初始化+ t. D- R3 f8 ]4 n! _! M5 W$ U; e! F2 w

$ ~! O  N4 p+ t2 O. |    for(int i=0; i<vexNum; i++)
' o* m9 o; z9 `1 I0 a- }4 h. l9 C    {, c& v! l" |/ F9 B/ d
        cur=i;pre=-1;
' |. C: P3 G' F* P. n        while(tag[cur]==0||!s.empty())# T/ A1 d; t0 N3 d( |1 K
        {
( Z# a" A, V0 z8 i" p7 ~            while(tag[cur]==0)6 N  S5 H' k+ R
            {
0 B( U# b6 k+ a! t/ n, g                cout<<vexTable[cur].data<<"  ";
; w7 U# s9 ^. r" I- h2 y                s.push(cur);
+ N! N9 X! Z3 p$ I# w0 q& w- X                tag[cur]=1;
8 z3 k& r7 K1 G/ {" J; v( q8 V. [$ F               //初次访问,标记入栈( I. L9 L% H6 q4 [

9 p' y8 k4 ?1 t/ g$ E               p=GetAdjVex(cur,pre);//p是cur的连通顶点
( K0 s* u9 Y6 T' k5 {0 G               if(p==-1)
2 f8 v. n4 n* u               {
, e* h0 {: g& Z                   pre=cur;s.pop();
4 S( t1 ^, \* T3 ~% \- U                   break;
. R! B+ u1 h9 Y" @               }( [6 H0 s3 w9 a$ m
               else
2 w  }- P* d( F8 G" E9 ~               {4 r4 t0 q/ M9 f/ U; }
                   pre=cur;
+ }( E5 X1 I9 w( L! N- O. a8 T                   cur=p;
+ q. ~. C* u( e7 O& ~               }
6 O7 p/ I# O4 Y9 L! X& _/ y' Z/ J, ?
            }
& C3 E0 S1 M8 M            while(!s.empty())4 w! O3 y. c$ `8 Y
            {* Q) P. f4 e6 Z) p: J
                cur=s.top();* D+ _6 x8 Y" ~% |' N
                p=GetAdjVex(cur,pre);
8 {9 F/ q) C7 O# d! ~- M                if(tag[p]==0)' H  i& d0 Z2 q( u+ K( G3 t
                {; f$ m. B* Z4 n- h5 u. m2 {
                    pre=cur;
- |5 N/ x% y7 ]: ^5 D                    cur=p;/ j: o, P7 ]6 P* l' n
                    break;; w* Q) ?! L5 L7 h! y4 [) }
                }+ x7 M, @9 V2 W4 \( N, E/ D
                else. J: |/ n1 c  q1 \$ E
                {
0 B! z4 w0 ^7 W                    pre=s.top();
8 Q" |3 ]; h- v. Y2 ]3 B                    s.pop();
* ]' Y6 V* z9 f) p( s) t! h                }
2 H: f2 S2 u; i* a+ ~8 B6 v7 F: @% R- Q  B3 s
            }& ^4 h  p" ^% T

+ m% j& c/ R2 p4 J$ ]: p+ A3 P        }
' h! g9 k6 i  _: W0 w" O: \    }: t( e7 ]' L& z5 I, ~. ]- U% e, h
}! c* M% U6 T% T2 N6 W/ u+ U# g' _
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
$ B7 z$ [' x: w2 v; X) d7 Q& K/ ?0 ~  h{
- z2 v* T5 J; V. x# @9 z$ i    for(int i=0; i<vexNum; i++), i" r8 S# c$ N' H: `
        tag=0;! Y! U6 Y3 o, c$ C: _2 N% J, v
    queue<int> q;* V& A5 k1 D) r, }. v
    int tmp,t;
4 M7 V: h! z6 r- f0 k  c1 a, B    MultiAdjListNetworkArc<WeightType> *p;6 G5 `" U( h) H2 z
    for(int i=0; i<vexNum; i++)
( r* I6 s- ^9 _: c) D. N! Q8 W    {
' d* L! @* o. [' p, M! P' z) {        if(tag==0); w# S+ T, C. e% S: P0 t
        {2 R$ M1 P4 P4 G# W2 Y* Z: r
            tag=1;
0 `1 I" B' u1 v' h4 f  I$ e: v; w0 A            q.push(i);
2 C0 Y" S4 ~! E. `5 X" t5 f! v- G4 |7 v            cout<<setw(3)<<vexTable.data;
1 i4 L" G; R) y/ M/ B        }4 E1 }" \( h5 v1 L/ S: B" M. T7 J
        while(!q.empty())0 C9 c* g, Z+ F4 N  k3 Z! w( ?
        {$ ?" @, ^$ r. ?* z# V& K
            tmp=q.front();
& \- z+ \4 C& U. `' a5 Y) [4 F            q.pop();+ A# f% w$ \. e& ]% {: [
            p=vexTable[tmp].firstarc;4 A& @2 ~& r8 c/ z. k3 i2 {
            while(p!=NULL)' c' ^4 l! m: s/ K1 r* Y  Z$ E/ d
            {- e, f; |; |8 R2 V& l- V
                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);$ {! i0 d7 m5 ~  j" u" |: P
                if(tag[t]==0)  O9 A2 q: v; |, u
                {
7 d  C% J+ \& B9 c* @* q. g( z                    cout<<setw(3)<<vexTable[t].data;! I  M* Q6 @' G5 H8 R  h( O
                    tag[t]=1;: h% w" A) o8 R% I) s# [
                    q.push(t);
7 H% l* o0 Y5 E& I7 q) @; Y3 v- E                }( M; J, y+ V) C) j! h0 X
                p=NextArc(tmp,p);  I9 w. x! B  o- f4 }9 k
            }9 D5 i7 B+ w, z( ^/ d) G2 _) r8 a- R
        }2 D8 s; ~# e  |! R
    }) l; `6 G% c3 h' r
}* Y4 x& l) _$ m/ ^+ {9 a
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
8 o; b8 F. `4 a. l{
# I- f6 `( [/ D/ _- t    MultiAdjListNetworkArc<WeightType> *p;/ o* G4 X% e2 j2 l
    cout << "无向图有" << vexNum << "个点,分别为:";
, z% c' T3 r) w8 Z+ V$ u    for (int i = 0; i < vexNum; i++)
& G/ c4 K7 i6 y, z        cout << vexTable.data << " ";  V1 K5 Q9 O+ @& x1 t/ @9 J
    cout << endl;
; B6 L7 r% q' g0 a* l# N! R- R    cout << "无向图有" << arcNum << "条边"<<endl;
2 \& R- V- U4 F1 n- t    for (int i = 0; i < vexNum; i++)
' U5 C) Q  o" }1 b    {
( m0 s! x& c' W; u" V# T! T        cout<<"和" << vexTable.data << "有关的边:";/ ~5 H8 R2 ]4 ^1 T
        p = vexTable.firstarc;
; c; f/ i4 [6 w; ?9 M( @& }% R        while (p != NULL)
) ~4 g. A) i) ~) B; y5 V7 I        {  ?1 x4 [5 H0 k, p% I$ u
            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
9 @" \$ p. V0 ?$ Y3 u- d$ j            p=NextArc(i,p);
& _3 q8 Y9 K2 H* L  m! u8 H        }
& O4 @4 F! y) n2 x+ f        cout << endl;6 H% j/ J( Z3 U
    }
) C/ {6 {8 t8 d! ]5 I, R}
! B& y2 U1 D: `+ }& {' s
' P+ ^& ]' `1 \7 d) b$ P) R* h( O4 M- l, }* r
邻接多重表与邻接表的对比: L$ V( l( N% G3 a) y) a
! r- J+ L8 X1 T
邻接表链接
# n/ S+ }/ l% l在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
1 E  R9 }& O( d0 H) P在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
' c7 B! r, \3 Y  \% D' I为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
4 T) z9 e+ z1 o% A& a5 h————————————————( l" e! o" y" f
版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。- C* T6 m+ p! r0 j2 I
原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958% B% \; \* E" u5 W& q! p
& M- w6 L0 J8 d5 |" D, n5 `
9 |! @5 I! U  t

: U8 y) Y- k7 G. r7 f2 A3 D0 p
) \0 }7 ]8 k' e+ C3 q————————————————
( [; `7 M* y( F- K$ y; y  P版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。% R) y$ x- N* d+ W7 m
原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
0 ]0 N9 U9 [7 L- h- R* `8 Y3 Y+ ]; _2 z, j0 }  R7 h; e+ z- A

: B4 o& b4 a  i  o; E




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