数学建模社区-数学中国

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

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

" [" @* F, ~: }& b6 C/ \图的存储结构——邻接多重表(多重邻接表)的实现
: o0 F% y! @  q1 k4 {: E3 L7.2 图的存储结构9 I( G& Q( F' d  O( z# ?
" l" ]' i7 y/ h0 U2 j
7.2.3 邻接多重表(多重邻接表)Adjacency Multilist; g* V6 Q4 J4 ^! I& L2 ?6 ]
邻接多重表的类定义
; ~! D  B0 z2 A: S; h邻接多重表的顶点结点类模板
8 f+ c% M% N$ h% ^/ ~  ~邻接多重表的边结点类模板
0 n  g* u2 c# a: f" I! G* @邻接多重表的类模板; j( `9 o& _& N1 ]! N7 z
邻接多重表与邻接表的对比
, I* x3 k. K3 |' Q; p7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
- w9 P4 M0 y, w, q  h
  \3 I2 Y/ c$ n& X. w4 g在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
! x# e+ ~% B& o5 M. p4 K在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
6 \0 |- o+ f- \  w7 n9 o
' t& u. v. \/ k3 o  r- T; B- r邻接多重表的类定义5 @& O; R" F8 Z; q7 K" r! M* J
1.png " @7 m4 h" [7 t+ J- {
邻接多重表的顶点结点类模板

对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:+ C0 [% D6 ]+ m& m0 f2 g% o' g
data域存储有关顶点的信息;
; n# S* _! [$ C. \firstarc域是链接指针,指向第一条依附于该顶点的边。) n. t# `0 Z6 y# Z, C5 a
所有的顶点结点组成一个顺序表。

3 o- ]2 I3 E( a; ~; T* Z
( J2 N$ c$ m* ?5 t
template <class ElemType ,class WeightType>
$ f7 h1 S; l4 U3 q. C* U# G7 Lclass MultiAdjListNetworkVex
3 ?: [9 N; V/ S7 P5 t{
: y* R$ v5 f1 Z! d9 U4 H6 P0 Ppublic:
& D( j5 \( i: Y2 R/ x6 E4 c% R        ElemType data;7 _. t4 h& L" T5 b
        MultiAdjListNetworkArc<WeightType> *firstarc;
; s# H1 j9 u0 M3 d9 J0 p4 c$ Y' Q0 C1 c( r8 @9 a' i7 v
        MultiAdjListNetworkVex()
) Y( K0 o3 D. i4 S$ t+ C2 B+ ~        {
3 y8 h9 j! d9 M* {( ?# j: G1 @                firstarc = NULL;
0 o4 Z2 L; F$ K        }
& l7 y' H; `# t8 W3 ]        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)+ g6 m  v/ h6 [* Q. i. c
        {
2 E) r2 R; R% {+ Z4 ~) U+ G                data = val;, `  x# z9 i( V$ ]  j, R
                firstarc = adj;( U9 K8 I8 k1 s' e( P. S; \
        }! M) J3 Q" b' L1 M/ x, S6 W1 O
};: E# v. V  g; p+ [7 }

8 S) g9 V# w% [邻接多重表的边结点类模板* c- Q8 m( _& @1 x

" q* S. G( H# g在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
* i! x0 h3 r9 t$ \0 v% ftag是标记域,标记该边是否被处理或被搜索过;
* s& T. J( U: \3 b3 k) }! Iweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
# C3 @4 g6 x8 b* n3 Wnextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;9 P5 C+ l2 T+ T
nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。+ l! D5 O9 G4 ~9 K. [

' M6 S5 d9 S; {: M  R 2.png
& m0 _) J9 i+ k7 ztemplate <class WeightType># `6 Q' ]7 g( I
class MultiAdjListNetworkArc/ y" g8 B6 B! `7 ~7 H* \
{! j4 |9 p* e; p6 A' @
public:- y* m- j, e8 I4 s, ~
    int mark;                                       //标记该边是否被搜索或处理过# {: e8 R& l! u# `0 Q& f
        WeightType weight;                              //边的权重
& M+ h3 ^" y  X/ h        int adjVex1;                                    //边的一个顶点
" c5 t* m$ ^/ \0 u/ I7 A. T        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1  q6 f" a6 E, ?1 z. j3 u' A
        int adjVex2;, k: J5 C' R# H4 Q! J
        MultiAdjListNetworkArc<WeightType>* nextarc2;
5 F* N+ P% O1 [; J0 A; A( h# p9 U' |5 p- ~( Y
        MultiAdjListNetworkArc()/ X! L9 ]1 x, {+ T( j
        {
1 e& P* K' v: Y& O                adjVex1= -1;8 ^" @6 V/ `' E
                adjVex2= -1;, F$ y$ y* F7 z
        }" h+ ^3 V& J  e! ]' L/ a9 V
        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
( `9 f$ \, p% O2 {5 S        {. [$ h3 N. z! x) A8 W: r; v
                adjVex1 = v1;       adjVex2 = v2;8 M9 s9 t, a" G5 p9 n) i* o' |
                weight = w;
: V! }5 `. x5 r7 |4 K                nextarc1 = next1;   nextarc2=next2;+ Z2 Q2 V! n: [4 y$ V2 }) v  B4 c
                mark = 0;           //0表示未被搜索,1表示被搜索过
3 s4 w7 u% o! N% W, |  ?7 q        }
" X# k: R# R! ]9 X; U  O$ D& `1 K  ]$ ~
邻接多重表的类模板

1.类定义

template <class ElemType,class WeightType>, G" z, B% u. m4 j- m% z
class MultiAdjListNetwork
/ ~) j; B$ {9 s$ {, f{
& @# E. s4 l- ~, I! E  o1 {7 c9 p# Xprotected:
4 M- O4 K1 O& `5 K0 f    int vexNum, vexMaxNum, arcNum;8 a/ {, V# a: [+ B4 e9 T
    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
2 j3 n( V# U2 x* n& m$ \: o, S1 E    int* tag;; ^, M3 D- U. ~5 Q% m* D3 U' V( U! \
    WeightType infinity;0 e/ S! c/ y" R: _9 v- y: A; c/ b! t

  X/ [' u$ D6 f4 X' @public:( ~9 z) F! u, `/ a9 q3 ~% T
    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);$ K* G3 U& z9 u7 M. ]

( G( X# o( _& x- h    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
$ P) [9 m  x- X0 c( Q5 J5 ~/ y; s# I, D( Q1 j  T
    void Clear();  S8 ^4 L0 `  Q  d6 P
    bool IsEmpty()
; S8 A# w' h; s& j5 r    {
  @* `9 l5 Z; Q- d' o1 C- X        return vexNum == 0;
' M0 L  ]; S- d8 A% H! p$ E    }
9 \5 r! F  C& c    int GetArcNum()const
7 B# M/ g0 \/ J    {' z( G) y! Z, V, C2 r0 D
        return arcNum;, I7 o) @0 X2 c& o7 q! D2 `' ^  W
    }( o6 M2 m( R% p3 ?
    int GetvexNum()const
9 R; w% T$ d: x0 Y' b    {# _% d  T" X7 c( v) e3 x8 c7 b2 ?
        return vexNum;
/ e( f3 J/ X( A4 F; z  P( I    }
9 C( g; e, t/ A+ W% [
: l9 n9 S) S% G9 [5 T$ m& r( m9 ?( H% G
    int FirstAdjVex(int v)const;
4 M  j3 Q' Z! T    int NextAdjVex(int v1, int v2)const;) L2 k* E7 Z* v; A$ |% O, k
    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
7 r+ ~' `6 X, P2 Z9 I& k$ a* R    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
( t" }# X9 J. Y& \
6 ?( t' p3 k9 R; ^    void InsertVex(const ElemType& d);
" n( t, @+ ]( |8 p( T' R0 I    void InsertArc(int v1, int v2, WeightType w);+ s' i5 t; }% l1 o7 V( n4 l" j) r
2 ^! d6 y2 r' G: q* F
    void DeleteVex(const ElemType& d);# q  X0 f. z: V" `
    void DeleteArc(int v1, int v2);
" X# w6 m% f" C+ _- J2 a) L5 l; W
( o7 ^: ]% o( v1 n+ D. z' R+ G    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
! |) l8 Z- w9 w7 n$ [+ T    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);& t' v2 l3 y+ U* m; i

: J6 c2 b5 q$ Q- F2 R    ///深度优先遍历/ `: f* B. `! ?0 H$ s
    void DFS1(const int v);5 n, U* d: }' [
    void DFS1Traverse();3 \+ |% ~0 J( W" ^
    void DFS2();$ Z8 A8 r! J; C) P% d8 B- W$ Q

8 t" h8 U8 R( D( d  ]; @    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1! |, D8 Q5 `" D' \5 {6 f# r$ c
    void DFS3();4 T3 M' x3 j' X2 O' S8 a: K' Q* ?6 D

7 H* k, ~; {3 M0 h. m  |    void BFS();
7 a6 g7 j. `* q3 A, j3 j9 U/ x    void Show();
( z" W1 a! B+ B};7 `$ D: p7 ?0 W) ^
! O8 B0 P9 J' g/ V6 O, N
2.函数的实现
+ B. ?$ f( d: }7 t研讨题,能够运行,但是代码不一定是最优的。+ r  K1 t- ~# y& C
6 G" y' I, Z, C5 i; @. P% |
#include <stack>
7 F5 l( ~3 b6 \1 R0 q#include <queue>6 i; g3 f1 P+ c# O2 h1 Q
* z" j* q8 u7 N+ A4 ?  x
template <class ElemType,class WeightType>
6 C0 s' r% C( W/ H5 I; x7 q) l$ jMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)+ s/ I; Y8 J! s% j7 T9 k
{
/ ^6 |( c# f* t% S2 G2 t    if(vertexMaxNum < 0)& s7 \$ i, c! K' H, |
        throw Error("允许的顶点最大数目不能为负!");  V: G9 M" g* A" Z8 u5 E
    if (vertexMaxNum < vertexNum)
7 H2 K. J$ J3 j8 X2 y        throw Error("顶点数目不能大于允许的顶点最大数目!");. r- e) Z* l  r# @0 E9 z- V8 c
    vexNum = vertexNum;
: s/ F& h) a0 u8 N( B* W  ^6 X: x* K    vexMaxNum = vertexMaxNum;3 {( _* A* S: ?# F9 T0 Y
    arcNum = 0;
0 f) A2 P5 S+ K: y) u    infinity = infinit;
9 p% [' H' n( P% S, \    tag = new int[vexMaxNum];  e3 _2 u: E1 b
    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
( N( h" d2 }' s    for (int v = 0; v < vexNum; v++)
; y4 E1 l( h# q* j' q/ V    {
7 \, g4 J) k2 _        tag[v] = 0;
4 q; ?9 [7 y5 ]$ E* ]) ^, Z% S        vexTable[v].data = es[v];6 ?& \* h9 |' k/ [. {: S
        vexTable[v].firstarc = NULL;0 i1 n  ~* V* l+ n0 d- ?
    }
0 l  d7 L+ _4 o, G- I}0 h2 m7 z5 A+ [9 t$ k
template <class ElemType,class WeightType>3 C0 D: |! R, D( v8 e8 c2 m, h0 X
MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
  C- ^- g: H/ o{" @: q( w1 g) n' ^* S
    if (vertexMaxNum < 0)" ?: Y6 A" p  O3 Q' F! a- W
        throw Error("允许的顶点最大数目不能为负!");7 n5 W! ^; |4 V  p. y* e
    vexNum = 0;
; @3 ?  ?- {( d  g0 z$ D    vexMaxNum = vertexMaxNum;: N$ w5 p8 [' P4 v
    arcNum = 0;
7 ]8 ^. r7 C9 [% S, h    infinity = infinit;
3 j. a# `- i1 w    tag = new int[vexMaxNum];
0 X# `, r: P2 p* y; P    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
6 Y; m. R) J. ^! d}: \- p' ~  ^; g$ m8 ^
template<class ElemType, class WeightType>8 k8 S3 k8 G( X2 L  y
int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const, r! b, U, t/ e( B
{
/ k- u/ U( ?& O$ Q+ S    if (v < 0 || v >= vexNum)
0 P0 }6 t) g  e" T) @4 w7 e  j& j% z5 f2 C        throw Error("v不合法!");, {4 q  y! k1 D4 G% S+ F9 M2 {- u
    if (vexTable[v].firstarc == NULL)7 x" G. t1 S& E4 V8 n; ]
        return -1;$ H* u) F  A. L; ^  {
    else+ t+ ^: _" \3 T" j7 v5 K% u
        return vexTable[v].firstarc->adjVex1;
7 @  b* p1 m5 `' Y+ h) j1 p- g}7 H$ `) l* F7 x$ t; ^) z: {

" E4 ?' o; S2 }* B, d( D  r' v$ ^template<class ElemType, class WeightType>
0 J0 b5 w8 m7 d+ W+ ]int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
8 ]/ @8 t0 G! C! Y# s{5 }& v4 V7 S5 y/ n# {- a
    MultiAdjListNetworkArc<WeightType>* p;
5 V5 Y1 `; K6 o( j  T8 v0 p    if (v1 < 0 || v1 >= vexNum)+ ?! G% l; y+ a* s. [0 J3 r4 C' x
        throw Error("v1不合法!");
  ]* K$ b2 `3 @9 m7 B' c' F    if (v2 < 0 || v2 >= vexNum)2 z3 `5 |! s; D# m+ N
        throw Error("v2不合法!");
, x3 [: m2 K# {! `% |- M5 }    if (v1 == v2)
- g* t8 g! F* [+ v- a, |% t        throw Error("v1不能等于v2!");7 K1 T% ?8 r) m- [% W. D* S
    p = vexTable[v1].firstarc;6 L$ ]6 [+ x* e3 X2 m
    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
) w- Q; v. |, ~! U) U: \  v        p = p->nextarc;5 J: J- N+ o# v% L
    if (p == NULL || p->nextarc == NULL)
: F3 v' Z% @9 f: v1 |0 c3 Z        return -1;  //不存在下一个邻接点5 H. D% T& q2 [6 ^# k6 T) ?
    else if(p->adjVex1==v2); w5 c# z0 d8 S
        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
7 @1 |' Q+ F" _  z) c    else2 p7 [% Y/ s) y( Y: e; K. r
        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);2 g3 T) r8 v) S) {3 W- e0 ]
}
* @7 Z7 N3 F1 b6 h4 \! P6 Utemplate<class ElemType, class WeightType>
6 ]& ^8 k# x7 N+ Tvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()- i8 O& a9 O1 ^, X' A, N
{7 E3 d3 Q9 a$ b' U  Q$ N8 e/ {
    if (IsEmpty()) return;
- U9 ~2 S* L$ H, Q    int n = vexNum;3 P1 X* A3 V' y" U/ a8 W( n
    for (int u = 0; u < n ; u++)
3 c" d' p- _1 W+ v+ L- d/ K. |        DeleteVex(vexTable[0].data);
0 B4 X( Z8 ?: ]. H. C- ~, J    return;- M' w1 R% h# b3 E% ]* S* [5 o
}* h) E' G2 \9 i3 t& u
template<class ElemType, class WeightType>& A+ k) }  D/ e' W
MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
3 k% ?/ B" w3 D3 G{
$ z- ~& m+ X1 ~, M    Clear();( _0 w* |" K* Z5 P$ b
}! M# I% a9 a6 t' Y7 j* \
template<class ElemType, class WeightType>/ r7 t& G. s; U$ H+ v3 X
MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)& D5 w5 O/ {  y! C" e2 r
{7 G5 F, }7 v/ P( Q0 G
    vexMaxNum = copy.vexMaxNum;
$ P: W7 H7 D# ~    vexNum = copy.vexNum;
" s9 a" h0 v! v+ q9 ~% ~    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
- V3 F4 u7 R# {* M& q    arcNum = 0;2 l8 ^/ h' V5 p1 _
    infinity = copy.infinity;
# O7 `0 e4 E  u0 l) x    tag = new int[vexMaxNum];: u0 K$ O1 h9 v& [' h5 u: z
7 q( Z, ], ^% {
    for (int v = 0; v < vexNum; v++)
0 ]1 `" K% b# h% P; N    {
7 Q8 Y; t, A/ |# K, k& b1 ]: w5 w        tag[v] = 0;" B* f% l6 @/ \/ V6 I+ v' w( a: Q3 Q
        vexTable[v].data = copy.vexTable[v].data;
. a+ ^, x" z& L. `. T        vexTable[v].firstarc = NULL;
  I. T) H9 \, d$ e; w' q% a+ Y    }+ w7 _# b4 H/ z; X# y- `
    MultiAdjListNetworkArc<WeightType>* p;
/ Y* Y, N# y! J9 I
  q8 R7 L! \0 Y6 G+ \6 I5 T    for (int u = 0; u < vexNum; u++)
$ L9 g: A: K/ q: }4 ?7 T    {  N9 W5 J0 A4 G
        p = copy.vexTable.firstarc;! y! Y- H7 _5 L, n3 c5 @/ u
        while (p != NULL)+ e! O8 H) Q+ C
        {
' `. N' y$ `3 b! U. |8 b            InsertArc(p->adjVex1, p->adjVex2, p->weight);0 R! [9 l+ m  x$ ?3 s5 a( K5 p
            p=NextArc(u,p);
% ?2 j7 f- x1 R" S" d" L+ V1 [        }
! d0 z7 {) o7 k: m% m    }$ L2 T0 }1 o! A; Q' Y
}# N& a. q4 w6 g* z1 d, `$ d
template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
# K" l5 Y' o5 X; aMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)( {, d6 ^6 o6 p, y
{
" I. K8 t; e0 n9 J# f+ Q. k    if (this == &copy) return *this;
' P; {: F# c4 |1 C4 q    Clear();
) F6 S3 M7 {+ j7 j    vexMaxNum = copy.vexMaxNum;
7 Z' J. H: |# h: L+ C    vexNum = copy.vexNum;
" o4 G% {0 J" q5 w/ y, X    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];0 S1 ]( G% ?4 @
    arcNum = 0;* H+ _( k$ [% T! d
    infinity = copy.infinity;6 U3 y; }2 f/ l& ]0 o' ?1 S
    tag = new int[vexMaxNum];* ~- `# [' H6 C% d3 s
2 @" Z) m7 A' ?* _: ?
    for (int v = 0; v < vexNum; v++)
4 w( j% {9 d- z5 P1 |# W& `    {
6 H2 N, l- G# C6 V; ?5 P3 N/ p: X        tag[v] = 0;  C! a0 p1 g; G5 w$ M& w
        vexTable[v].data = copy.vexTable[v].data;$ m, {) V( a! W- E
        vexTable[v].firstarc = NULL;8 v7 v: U5 G% Q. }! O* O. H
    }/ @' R# i  r, t& i; B
    MultiAdjListNetworkArc<WeightType>* p;- e: c* U( A8 `! G* i8 g

( I  Q+ w3 r) \    for (int u = 0; u < vexNum; u++)
+ |/ Y7 f% D7 Z# t% M7 Z7 y& y    {
/ y0 j+ b% W% s1 Z# j        p = copy.vexTable.firstarc;% ]7 U* b* U+ s  g
        while (p != NULL)
3 K( T+ z/ Z+ N' F6 I0 b        {  G" }- u, y- d+ _- a
            InsertArc(p->adjVex1, p->adjVex2, p->weight);* P; B2 C6 K* L# J1 ?' t6 W
            p=NextArc(u,p);
1 U% x! b, D, ~& p4 E2 u$ u        }
" h+ k1 |3 `2 \  i    }
6 [  Y, M2 S" {5 ^+ }) F    return *this;3 ~5 H; A8 X# q% }. s, T
}
, D( ~' S: }0 p5 i( I% ctemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*7 c8 K$ o. N+ {' J
MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
0 g" J4 h( U$ N/ I, H2 |; p{
2 X/ C: Q' ?3 D; M# i2 h; C: J    if(p==NULL) return NULL;
* n! e) |) [! o4 d+ p$ g$ H    if(p->adjVex1==v1)- H. A% w& E, X! [$ Z9 b# _3 @
        return p->nextarc1;; L2 E* |3 N* C+ d- u' B) G
    else
2 H- t/ @, m# B, ?* o        return p->nextarc2;3 }8 b5 K( P: z7 [1 z
}2 R$ S( n0 u, ~1 |8 ?5 J8 d
template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*% l8 \$ L+ v- w
MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
* b( f/ }8 L- K; i) S- i{
7 @2 e2 N& q7 b6 _    if(p==NULL)return NULL;
1 l) y, O; x, Z; Z  A  n0 e  u    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
! ~% b  g. e; Z  S* o3 M    if(q==p)3 E" D0 y, v6 v$ `* ~4 M9 N
        return NULL;) ]* q) ~, i6 H
    while(q)
% z8 C" e" ^1 F7 t6 F$ o    {
. K% X9 [2 d: n' p        if(q->nextarc1==p ||q->nextarc2==p)
9 `% R/ H$ N" W, }            break;
4 H+ u$ _2 _# w7 J" F7 E* \. x        q=NextArc(v1,q);
# g* W9 V) X6 Y8 K; g" V    }
! v* h0 o# F2 |. L, @    return q;
0 R" o/ B) f- m* r}, g1 |- |& T; C! I9 o5 Y) r; Q6 t
template<class ElemType, class WeightType>0 P2 ~  O' X! n
void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)$ K0 U$ m: @4 `- i; u
{
/ v6 p2 \( k; @    if (vexNum == vexMaxNum)
. b( I3 M1 d" j' h! z        throw Error("图的顶点数不能超过允许的最大数!");
  h5 S9 ]! h' V" O+ e) `: l0 a    vexTable[vexNum].data = d;6 q% D! ~' B# |% _+ N  @
    vexTable[vexNum].firstarc = NULL;( F5 v3 ?4 k, d  y* ]
    tag[vexNum] = 0;
4 R% o7 L1 J* d+ i. e    vexNum++;
* e3 W, D( H- a7 Q6 k  ~' k  p, `; S}; z' J/ b- f/ g( b) `9 i" \9 s
template<class ElemType, class WeightType>6 r8 p9 w; \/ u4 M  k& o) C! n! X
void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)! T2 l1 J: C$ {5 w! _( o8 i  u
{
+ X2 L! p5 V8 l2 Z    MultiAdjListNetworkArc<WeightType>* p,*q;
4 A/ h, l, a( E$ S! H    if (v1 < 0 || v1 >= vexNum)
) L0 V/ E" B- q& t( R" h+ U        throw Error("v1不合法!");$ i4 A0 k: o5 P; Z" R+ j, X5 E
    if (v2 < 0 || v2 >= vexNum)
- @0 I+ Z9 \# [        throw Error("v2不合法!");
6 E9 s0 u7 f8 Q4 {! a% o3 J    if (v1 == v2)# I( c/ f8 B1 t
        throw Error("v1不能等于v2!");
; H0 [, j4 `% P$ t+ S7 D    if (w == infinity)6 A1 ~# i  H. M$ o# h+ F; ?# H5 b5 m2 Z
        throw Error("w不能为无穷大!");- a+ \* @$ J$ h- n6 B" b' }: x4 U
; i: X. h1 R. |/ ^
' ^0 }0 P$ a" `3 Y3 _
    p = vexTable[v1].firstarc;
+ L$ Q0 X. V% Y) o- V    while(p)% l& b& D8 O$ ^" X' Q9 X2 ~. u
    {
7 h  Z) {9 R9 [2 t3 d( x        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
, n6 C" w6 M7 Q* X        {! r2 h1 Q. w- o1 c: Q+ d
            if(p->weight!=w)) `$ w/ P8 {. _: ^/ J1 W
                p->weight=w;5 E. x/ n7 k& n& E& [3 ~
            return;
2 z) w) \( Z1 Y- H1 H# I        }
1 O) Q0 i' S  L4 f) M* h! g
% h/ @. l* ?% _' |3 d( p+ y        p=NextArc(v1,p);
! O7 V5 R) Z( b% x% K    }" S4 c& X+ L0 A7 N9 R6 y7 q
    p = vexTable[v1].firstarc;
. L( E  v& O, f# j) y, f% H# k2 \    q = vexTable[v2].firstarc;6 }5 X) ^3 h) Q
    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
# @* d9 v7 U! Z5 c( K" B5 v    vexTable[v2].firstarc =vexTable[v1].firstarc;
; @- e" A1 P$ [  c) ~    arcNum++;
0 U$ A) f9 R0 a6 K1 z/ P. }}
( |; i. _: ?8 c& L- y# H; O, m$ B
template<class ElemType, class WeightType>" X; M' X& \+ e) O9 `
void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
( H& ^- x, n0 o" {{
- S0 V/ ]4 u) a4 r8 q  f3 j" K2 X# C' h- Y
    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
: s; C( b# ^3 R. X    if (v1 < 0 || v1 >= vexNum)
# k3 A& l/ Q7 j) j# x' r- Q1 M        throw Error("v1不合法!");
( k. E+ r7 X) s$ T3 r9 o    if (v2 < 0 || v2 >= vexNum)6 X9 S$ o' L2 s3 n
        throw Error("v2不合法!");. Q/ \( o3 k" t4 |, k' `4 i1 w
    if (v1 == v2)
$ G" @" c) p) S  e$ B        throw Error("v1不能等于v2!");
0 {" H3 s- W! J8 M1 Q+ V1 v2 w' `; f) Q' M, u
    p = vexTable[v1].firstarc;
$ j) X- {9 z3 ^    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
+ i9 w; D  c0 }. d# I9 \    {
7 ~% ^/ D* l3 ^* t$ O6 f' q        q = p;/ H* J- r  K) u; G- m8 r
        p = NextArc(v1,p);$ `! w! p& B) S0 ?5 C! n4 ?. e) ?
    }//找到要删除的边结点p及其前一结点q
; n" M! l  D5 a0 v3 ~( k4 P1 c+ W% X6 ^& P0 {$ N
    if (p != NULL)//找到v1-v2的边
% q) C$ L+ J3 J0 Y# N    {  m' [7 S) k- Q5 l) U* v
        r=LastArc(v2,p);0 Y: K' U  @3 x
        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
5 f; e0 j& e4 t, z5 }% B            if(p->adjVex2==v2)8 L8 {0 j5 \6 Q: }7 f
                vexTable[v1].firstarc = p->nextarc1;
/ r' X9 c) x/ C1 T3 F- }  T, k            else vexTable[v1].firstarc=p->nextarc2;
6 D* |- r9 D+ @2 p5 H* Y        else//不是第一条边
0 x% L! e# V. [1 v3 l        {, x! T2 d3 G0 p) P! i) K0 P
            if(q->adjVex1==v1)
  A$ y* p" r- n9 E# q                q->nextarc1 = NextArc(v1,p);: P% z3 F, X+ @
            else
; e+ `% u3 o1 b! j                q->nextarc2=NextArc(v1,p);* I  \8 X6 `1 d- i; S2 b! X4 W& _
6 B5 {3 J5 o! m1 x3 w; {
        }
. [% H! {2 R* A7 s1 @) \% ^! Y; A        if(r==NULL)4 i( E& d6 @$ q
            if(p->adjVex2==v2)1 X; K) n  v* d9 Q3 U
                vexTable[v2].firstarc = p->nextarc2;! `. _0 A& W+ U( G- m& m
            else vexTable[v2].firstarc=p->nextarc1;! v! |2 L9 J0 u  Y
        else
" J7 G. y. ?+ O+ i" ?8 C, |        {* D" N2 L5 N8 s: G( _. @0 P
            if(r->adjVex2==v2)
3 ~. D& Q& h& Q' d                r->nextarc2 = NextArc(v2,p);
; M& [7 I) F. a            else7 P; C( F( P* t# o3 [
                r->nextarc1=NextArc(v2,p);6 z4 X. y! }1 H7 u( N
        }* x% e2 V+ S1 v8 W& e. v
        delete p;
- o& q/ B: c4 b, _# l" Z: _- l        arcNum--;
( y1 f1 j( ~' H* e, M2 x    }( L) t3 v( J& ~& i( `5 x
3 x6 f& u+ H5 P8 r$ D7 _- O" e0 I
}: I1 S, n& `. B2 n% s, A8 R
template<class ElemType, class WeightType> void
3 U1 j7 r, C( J: m/ o& [MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
, |) Q+ p/ o2 J. t{
7 s" O0 \9 d5 D1 v7 Q8 j: @    int v;( ]8 `" T* m  j. V7 \
    MultiAdjListNetworkArc<WeightType>* p;
, [! ^( A8 g3 X  ~0 a7 Z) _, q    for (v = 0; v < vexNum; v++)//找到d对应顶点
7 W# R8 H  Z' k- o4 u2 J# |        if (vexTable[v].data == d)4 m0 k/ C# x$ H
            break;
0 o0 B2 y, F/ b% J& }& W    if(v==vexNum)& c* ~) F: S! l: M6 G& r  d: a
        throw Error("图中不存在要删除的顶点!");7 p! m" _6 {! d+ j. r$ j% m
% ]# ?- |# H- M4 D2 `5 z- K
    for (int u = 0; u < vexNum; u++)//删除与d相连的边
# z1 z3 k) s& R3 t3 `: K: X  J        if (u != v)
1 E0 C# w5 U  n1 p        {
7 W" {& o& O' {            DeleteArc(u, v);
/ x0 m% R' {# y( X! s& J        }
: @( @4 C  y# e9 m% e. t    vexTable[v].firstarc=NULL;. v' N" A5 {5 i5 F2 g) }9 d
/ K0 N7 O3 ?7 q1 o, i
    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
5 V' A8 q# l6 U7 y: R* \    vexTable[v].data = vexTable[vexNum].data;
6 G4 x! i8 g4 S9 B& K0 P7 ]    vexTable[v].firstarc = vexTable[vexNum].firstarc;+ _' M; w2 G& A
    vexTable[vexNum].firstarc = NULL;) U5 T/ U6 A) C/ U3 w- q
    tag[v] = tag[vexNum];' B' C# v3 M9 X9 p2 w& J9 e# I
    //原来与最后一个顶点相连的边改为与v相连
( i% g/ p8 J( d8 e    for (int u = 0; u < vexNum; u++)
  _, y, h1 C0 {! c+ y+ C7 h    {
& [. n; k8 n2 E        if (u != v)
4 m1 Q( h% h! R4 J$ |+ R5 m1 R        {
6 M% ?' E' g7 V) b+ F0 d            p = vexTable.firstarc;
; A/ Z& {# B$ @, q7 m            while (p)5 s+ K2 J3 l: @, f! I5 j' ^& {
            {
8 S% S% Q6 A# B* U                if (p->adjVex1==vexNum)1 @+ }9 A; q& C0 b5 I# B
                    p->adjVex1= v;
* G7 _3 R2 P( f: k' T                else if(p->adjVex2==vexNum)( j* p/ n% q& ^. g5 Z
                    p->adjVex2=v;. a9 b7 F% K: }$ ^9 D( G2 ^
                p = NextArc(u,p);& k2 Q- k: \6 P% t9 U
            }1 d: ~+ k  b" [  u! {& b3 ~& U
        }
! C6 Z% N/ o! k    }
  d3 s. c7 J; u! Q}$ u2 Q+ Z$ z& n, ]
///深度优先遍历
! p& _* f# s' d" ~  Atemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)3 R' j. U- d) k/ B5 E0 O
{
& f/ K2 t9 G8 Q, |0 m% H) J    tag[v]=1;  i) x8 t7 G" |5 I% [3 S
    cout<<setw(3)<<vexTable[v].data;
$ B1 h0 f- O3 Y    MultiAdjListNetworkArc<WeightType> *p;4 k: ]# ^0 s/ `" i0 O2 J3 A" w  z
    p=vexTable[v].firstarc;( ~. j7 L: i& E9 X$ _6 I1 E0 `  \. b
    while(p)2 m2 S$ X* l( ?- k7 X, x
    {
! Q' \+ i( }# M: v6 u        if(tag[p->adjVex1]==0)( b, f5 D7 }% F+ ^4 `
            DFS1(p->adjVex1);
: S$ q% @* h1 p2 N" x        else if(tag[p->adjVex2]==0)( H' Y+ A. E( F9 {7 L5 X  r  I
            DFS1(p->adjVex2);
9 b3 f+ ?# ~; ^, n" b2 o        p=NextArc(v,p);( F  `& v: F( W* x; O/ }+ g! l
    }
" x5 N- j8 [, ?# ^. m9 Z3 x}
3 D! ]( i5 l# Ttemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
) u$ B$ o: a! J* |  A{
- I" `( P+ G7 |7 R7 ~    for(int i=0; i<vexNum; i++)
; x" t. `, A" ]. U8 }% d; q- N        tag=0;* U- B; x6 ^# D
    for(int v=0; v<vexNum; v++)
$ O$ I. W# h. m, Q: V    {* k1 e# Q7 s* x7 b; {( s
        if(tag[v]==0)
& R. v* a! J: }" Q            DFS1(v);
; ?* D( E' f" S9 n    }
8 H" O" C! u4 z* S0 |2 e}' O9 ?3 |9 w' `
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()8 b# L5 u/ \! Z/ j
{. @& W$ G. z6 v, X- F& }: l
    stack<int> s;5 E+ N# F% o$ w! _
    int tmp;
6 y7 R! n. o2 J/ \: r    MultiAdjListNetworkArc<WeightType> *p,*q;
, g* S2 I$ h9 T- X1 V9 j6 G    for(int i=0; i<vexNum; i++)
7 G- k# ?1 n: _* Q" }, z5 ]        tag=0;/ j4 l4 B& u: @, g& {3 S* }
    for(int i=0; i<vexNum; i++). S# i6 f. R1 r5 I4 K# p0 ^
    {
5 ^( B! I3 ^& M' H        tmp=i;1 X# [! b9 ^% j3 J. S# t1 q0 u
        while(tag[tmp]==0||!s.empty()), `7 D* b/ L1 e+ @
        {$ P$ `; }% u$ e8 f4 B  J2 J4 S
            p=vexTable[tmp].firstarc;6 ^8 e1 U: x$ ^( r! @
            while(tag[tmp]==0)# P. C8 m# u6 {/ G" F
            {
6 p* }% d( M, y  i4 j( R5 k                s.push(tmp);# n+ |: H" |5 i% O
                cout<<setw(3)<<vexTable[tmp].data;: |/ z' k# x: b/ G/ w7 w
                tag[tmp]=1;
* Q9 `! A6 F2 p                p=vexTable[tmp].firstarc;
3 t2 ]" q2 t6 B                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
3 H, {2 ?5 g4 |5 ]$ g                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
$ q! ?: ^* J$ C3 ?* l  c                //cout<<" 1st     tmp="<<tmp<<endl;
4 [( \6 L5 ?; j6 F9 y* j            }+ A7 k* m# o* m% c% _; q- w5 w
            if(!s.empty())- \% M0 j7 l, S7 C* {- V$ ~
            {
& J# N2 V% v0 U) O! _" z# H$ x2 k                tmp=s.top();& ^7 S  }' X* W* H7 L+ K9 i
                s.pop();4 ]+ @' F+ A* e$ L: d9 B. o
                q=vexTable[tmp].firstarc;
% Y" ~7 P. ^8 ^: s                int t=tmp;
7 ]# W6 f$ T9 b4 g4 H; n8 `( `0 L" L                while(q&&tag[tmp]!=0)
+ K% P' d& n( O) Y* j: [+ N                {8 E$ T' O2 _; \, Z9 q5 Q
                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
* u" D+ w! ~+ c6 k+ T                    //cout<<" 2nd     tmp="<<tmp<<endl;3 a  i7 B4 f# O: v
                    q=NextArc(t,q);
. g8 d7 T) p- B0 T                }
" ?* X* ?7 _% w+ _0 d, D                if(tag[tmp]==0)& P0 ]2 o. R' a( t( e
                    s.push(t);
. f; Z! W9 y. ^& W) x$ o                ///1、对应上面连通分支只有1个点的情况
% L" K$ l7 y6 I* ]1 y9 L                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
! o* c4 ]- O$ ]1 v" [% Y% l                ///tmp要么等于找到的第一个未访问节点," _. u3 y0 D- Z( o$ I
                ///要么等于与t相连最后一个点(已被访问过): D, n1 |3 _* f1 U3 W3 P; U
                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
$ Z. m" e8 W; \            }
6 f. }9 @' I+ P3 z        }
5 b4 b# z7 r7 E3 i8 U( c9 k8 q- K/ f    }8 X' ^9 q: a4 V  x
}
( |$ d$ m! e7 B: `8 y//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1% [& Z  g/ D+ J! y7 n* b- _* X! N
template<class ElemType, class WeightType> int
( N- D" o/ y5 j7 r& |MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
2 X" R; g3 O; F, }{
* f6 S, [- f( ^8 {( u    if(head==pre)* {7 [4 K! w" M6 x) k5 w
        return -1;1 t( \! `, [% k4 Q5 _. v
- e1 p* e% c6 ?  m9 M
    MultiAdjListNetworkArc<WeightType> *p;/ a: p( t, x( \7 u5 C: m4 w  ]
    p=vexTable[head].firstarc;
" F& Q% N1 o0 i' h    if(pre==-1&&p!=NULL): ]( A# p! B+ f* i/ E# ~1 ~3 W
        return p->adjVex1==head?p->adjVex2:p->adjVex1;/ N+ R( Y: S0 T3 h* f
    //pre!=-1&&p!=NULL
7 f/ ?; i9 {5 Q4 [* J- N# ]1 K' t    while(p!=NULL)
$ E) }. n) b, x7 X+ ]# [3 S7 f    {
7 c4 F) b) @1 X) c& m" n        if(p->adjVex1==head && p->adjVex2!=pre)
: T# }* I4 U) d            p=p->nextarc1;
( Y3 r6 w1 O( U2 [        else if(p->adjVex2==head && p->adjVex1!=pre)
# P7 B. A/ o" _  v            p=p->nextarc2;
7 l% o3 P- X& F# \/ j6 T8 l1 |2 f        else if(p->adjVex1==head && p->adjVex2==pre)
3 I4 Y$ g1 V! d1 U        {
7 J& Y$ A' i6 i# v- Z: L            p=p->nextarc1;: X4 r7 G8 d; F
            break;2 C1 v# x3 k6 w  X( a
        }
7 v3 Y' Y. Y+ l  _! l! R$ r        else if(p->adjVex2==head && p->adjVex1==pre)
4 s0 X# y  m0 v, [        {
8 w$ _1 p6 Z/ L* E+ o! @            p=p->nextarc2;3 @, M& Y8 Q( G; ?# h# d9 l# }# C
            break;6 l4 |6 ~# m) k; U
        }
2 ^+ s: g0 Y( k) g) v, T    }
4 h' ^& P) d3 @* ~- Y; C0 \    if(p!=NULL)
  J9 E7 Q! S, A$ w    {
6 `( S) L! _1 n. K* b. e) b8 m& l# X        return p->adjVex1==head?p->adjVex2:p->adjVex1;
$ ^) H. t! E* m    }+ ], h2 u* \* C& t  b/ q8 k, a- S/ A; B
    else
# W1 T+ r, Z% j) i* Y& J* P3 o        return -1;
' J* K- o4 S, n" n; A}- b/ [& U4 i' H( ?4 E3 P
0 O# \' i! L; |7 K
! H( i6 w! M# Z. {" W
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
+ w  P/ _6 Z# y6 ]  t  _5 I{$ s( Z! f3 r; Q0 h$ x- p8 U
    stack<int> s;# a- d! j0 \+ H3 {5 b* O' C
    int p,cur,pre;/ T& Z. A! g( j7 S) E. `. M
    //MultiAdjListNetworkArc<WeightType> *p,*q;
3 H% p; [7 V- m* k, k; I) d" E    for(int i=0; i<vexNum; i++) tag=0;//初始化
4 ]: U7 j# _5 ]5 o. D
5 d1 b5 U* N2 ~& t7 \    for(int i=0; i<vexNum; i++)# x6 h& Y' f7 C9 D$ _
    {
' C( b1 [$ Z9 k! g$ C  f        cur=i;pre=-1;$ [+ Z5 ~, M6 B$ f4 i( E- ^3 i6 P
        while(tag[cur]==0||!s.empty())( h( R0 @" z8 O% f( B; E6 D' {2 Q" W
        {
, L- }, ]5 j" E            while(tag[cur]==0)
  O2 G) Y$ ~7 O2 l3 K+ J            {
' n* {) u3 s  C5 P! B0 l* L                cout<<vexTable[cur].data<<"  ";
7 O* P& f& r/ a% T2 x" W                s.push(cur);' C4 k; ^& w" X( N4 ?
                tag[cur]=1;9 O: H  W1 p% V" f" j7 Y3 f
               //初次访问,标记入栈+ k- Z8 ^& e: b5 [8 v, J: Y1 g) V

5 M5 s; z4 c6 B1 v' A& E; w2 M% A" @               p=GetAdjVex(cur,pre);//p是cur的连通顶点
( M1 i% q; ~9 b/ M' H               if(p==-1), F* g( m! O4 f3 X: m3 ^
               {
5 R9 {" I; M& q                   pre=cur;s.pop();
5 D, @& j( j6 k- o                   break;
$ }2 k7 ], i# w6 p" t: N5 D. D               }
" C8 R. R( x7 h7 Y7 {               else
; O! T5 a) `2 A; X0 ?. d& m               {
5 x' b$ [4 s. s9 A                   pre=cur;
8 e  Y* s1 a; y$ i  z: m: b                   cur=p;7 Y' B% m3 @( D$ a
               }
( |& z( Q, v# v7 T* S7 A5 @' X. U6 D$ \- e6 ^
            }
( E( P0 r) }0 ^& Y* p3 @5 [( \            while(!s.empty())1 `$ s5 |4 o9 H; B
            {. T; X1 o: t9 Y1 }
                cur=s.top();
( O! M$ h$ e& u: T                p=GetAdjVex(cur,pre);
, e2 d; [. p+ [) b- _. e                if(tag[p]==0)
" j7 M5 f+ o, @, w* n- @% ^, c                {3 X$ {2 l; o( x0 w, l
                    pre=cur;: K7 t  u* q" Z/ \
                    cur=p;
. n" |: k( V/ j, a                    break;
7 A, o& r& O+ u$ v  Q- t( e                }( Y# }. [2 {  y/ x/ Y. V; {
                else
8 r4 P& }4 j$ b3 D) V5 L2 p8 O                {
5 p  s; \2 V: \( s( G: @& i, g                    pre=s.top();- Q7 T0 a' e5 q" y' P" Q2 X9 ]- V0 V
                    s.pop();
0 f0 J5 [2 w4 Q3 d& c! ]" {                }
) _9 H& W7 A2 E- t. c: b; X& ?/ [# `8 B* G( y; w8 E& U
            }
( e+ a6 C2 o% B! w
( |7 F! W* D& i" ?: D3 |6 E0 V, t        }- r4 Q) r& V0 U( d7 e
    }
2 x' d% m# R# i6 f5 s4 f0 l}+ c8 q) q4 x5 w) B1 K
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()% G. E+ L% T/ @
{* j7 X9 V  U! r. d
    for(int i=0; i<vexNum; i++)
" b! L% A6 Y6 ~2 }) i        tag=0;
0 {2 U" |$ G% @9 Z    queue<int> q;
4 P4 V+ j/ s; M" ~9 t    int tmp,t;+ R0 q( O$ O( v; H7 [) X
    MultiAdjListNetworkArc<WeightType> *p;
) E% \- a" F( Y1 K    for(int i=0; i<vexNum; i++)
) c9 {1 K$ t" w8 x; l8 q8 V    {
$ {- K( N" k( ?" U$ i        if(tag==0)% D# D8 w+ B: ^3 y" ^3 D
        {4 e# d. K3 R* f9 c2 Y, v9 L3 ~
            tag=1;
. b* L- ~0 r% C1 T            q.push(i);
8 Y' g" ^# F1 c' w% D            cout<<setw(3)<<vexTable.data;0 O$ H. A: E/ J0 J' p8 a# p8 g
        }# b! H+ m+ ]0 ]
        while(!q.empty())% m' A) g- M. R$ H6 v+ d& T0 W. w0 k
        {/ m3 y; o% q. X: ~% K
            tmp=q.front();) L) {* h# o* M0 H4 y: ^( r9 Y
            q.pop();
$ w2 B$ ~! m/ N. h            p=vexTable[tmp].firstarc;# X0 A, h0 q7 X" n
            while(p!=NULL)' `& E0 A3 D  m  ]5 J! ?+ J
            {
( d! X) s: i3 s. q. C4 B5 S4 y! k                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
: F: [4 f: O7 X1 }                if(tag[t]==0)8 p+ k* k+ H4 ~
                {% [# n4 T% I6 z7 K( B0 x
                    cout<<setw(3)<<vexTable[t].data;
% n* u& a# Z$ _3 {                    tag[t]=1;' N$ m! ^, O7 ~3 G/ J, R8 t! ]) _0 n
                    q.push(t);4 y$ h3 {8 D9 p1 t
                }  @+ ^) \9 U3 X
                p=NextArc(tmp,p);! h2 v2 E) p7 |& O7 D& @, |% V
            }! j% H6 a/ t( w( I) D( ~0 A& \
        }- @- G7 F; z: z3 E4 J
    }% s/ ]0 e8 `% K: q
}( G, \) L2 j: [/ S/ U! z$ l1 C
template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()0 H" C( P0 P& l1 `5 w4 }$ [
{
. d% ~5 d8 P+ k    MultiAdjListNetworkArc<WeightType> *p;4 `  g3 f% {+ M* y3 m
    cout << "无向图有" << vexNum << "个点,分别为:";  Q6 a# P% I. P; W/ x
    for (int i = 0; i < vexNum; i++)$ b, I. @: X' q! Q4 ~. z) Z
        cout << vexTable.data << " ";* `- h5 [6 \$ r; Y
    cout << endl;
4 l' F  d* C* k, S/ \    cout << "无向图有" << arcNum << "条边"<<endl;. s! Y% H+ H* m2 m
    for (int i = 0; i < vexNum; i++)# r; L0 p6 g' m& E1 X! T# g
    {# |* [- }5 k2 g" e5 Y
        cout<<"和" << vexTable.data << "有关的边:";
0 R( |7 s2 r* r) t        p = vexTable.firstarc;) d6 o: \! y# p" W4 h6 ~% A
        while (p != NULL)) M* A. p0 g1 v
        {
  t- M/ q$ @- L$ `8 \/ P! u            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
8 G7 O  s2 v5 l+ o& Y0 }            p=NextArc(i,p);
* n9 u; T5 g2 S        }
9 v; O% `6 o  D+ k" c. N' D+ z        cout << endl;" `8 o9 }+ |0 H$ x: ]
    }. z) s; U3 k0 _. {
}
  F( O- d, y: R  j, w7 |, c5 g8 b: O. W) @

1 f2 y* h. ~# d1 w" w* d邻接多重表与邻接表的对比
2 Y( Q1 {& X, t
" \1 q; J* g! ^/ [邻接表链接( v2 j: x, h# b2 N" k
在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
( }7 T( ]8 U0 [/ y+ k+ t/ Z2 m! `2 T在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
* [  f) f# C( y( S为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。* n$ h* E& I% t  g
————————————————
( K8 ?! B) ^( r( v% E; N7 T1 y版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
. Z* X6 ]* E1 U% j原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
# e+ g% w* Q5 `+ \* S/ [8 q* [6 [' J  L6 e( \/ I

7 L4 y2 z$ V& g2 B1 q0 |) B! N6 @. B- ~! t- o8 q7 q

+ T  p( q$ ?7 _  N2 s' d! b————————————————5 h1 j) a8 d) v4 N" y
版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。, R! D/ k1 Z  C. ?5 x
原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669582 Y% R0 |# o- C. p' H3 w( D  P
$ O' m$ r! W, B: g4 L- o# c: D
& z5 B8 s, i% I4 }2 r. `0 Q2 v





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