QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1568|回复: 0
打印 上一主题 下一主题

图的存储结构——邻接多重表(多重邻接表)的实现

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2020-4-26 15:26 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta

    7 ?& U5 k5 e. L  p9 T8 L图的存储结构——邻接多重表(多重邻接表)的实现" v& J9 p" m$ C& C; r8 _
    7.2 图的存储结构# f- l' J" d2 y0 e3 b7 c, z3 o: s
    ! B2 F; s% b* r
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    * H- I- q0 d  k& G, }0 j% S邻接多重表的类定义2 h9 {2 a/ G9 S) n8 _
    邻接多重表的顶点结点类模板) ], m) _8 M( G: z+ m4 a+ P* p' S
    邻接多重表的边结点类模板
    ! g0 ?, A1 P% a3 Q邻接多重表的类模板4 v- R- ?+ W' U: h
    邻接多重表与邻接表的对比
    : Z8 O, b3 ?6 l$ D3 ~' i7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    2 u9 p2 E9 g# d# g
    ' l$ A! ~" a1 R2 J* t) o在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。, G# b' Z/ w5 l; ?4 V
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    ( W9 u5 H7 b$ q# a& N
    & W0 d5 h2 N# w% i邻接多重表的类定义
    * D9 l2 Q! ?% M+ u- S 1.png
    2 X# ~- V  Q1 t5 D2 u3 M邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
      F5 ^  _3 x( K- f6 c3 f/ edata域存储有关顶点的信息;
    3 f" S$ y5 q; X6 B1 jfirstarc域是链接指针,指向第一条依附于该顶点的边。# `7 B! S% U( C
    所有的顶点结点组成一个顺序表。


    / E' V. T( j* v) t( b
    + c- g9 n" L: Ktemplate <class ElemType ,class WeightType>' r* n0 D0 i* }- Q. V
    class MultiAdjListNetworkVex
    - S  s4 e( f/ \. r, P{
    , W. j. i: \8 n6 ]! [public:
    2 _8 r5 f# z/ [& ]" f        ElemType data;* l8 T$ T& Z% O9 O8 I& c
            MultiAdjListNetworkArc<WeightType> *firstarc;: l  L. Y( M5 H8 B6 `! e% p
    1 C) p8 ^5 }  p% B
            MultiAdjListNetworkVex()
    2 ]" Q' b( H1 l        {& a( S, m: Q/ _" u0 w) o5 I3 N
                    firstarc = NULL;
    - Q# c, H  b7 h4 s4 X" p& f1 f0 n        }
    1 {. O) i7 P% @' N+ X* U% |        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)0 y/ I' n. n  B) P& b) k
            {
    ; h: U! I! q! |# \" z                data = val;
    # u% a/ Y+ G$ c% B; L                firstarc = adj;- ^" q% ]8 z% K+ |6 J
            }
    5 C: E/ l9 P. Y/ k};
    ( I  R1 a  f  E) Z' c0 j. F% C! _1 z3 s2 [" l, d
    邻接多重表的边结点类模板
    - P5 k/ t; ~2 ?' W0 W$ z2 w# r: c# V8 m* n! P
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:! K. P$ T( C" s1 L( h
    tag是标记域,标记该边是否被处理或被搜索过;( |0 E3 i+ y* e% _7 r' b# x5 ~
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;" G3 C* O8 Y% r& V% m" A8 @/ J
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;! ~, l5 s$ G2 i/ A/ P  X
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。0 [  i/ S- F9 l+ L2 M

    3 W/ ~+ K- ^, G, k% z 2.png 1 C" O* k, a2 A  ]) x: \
    template <class WeightType>$ L# l6 ^+ T- \$ ?4 u: ?
    class MultiAdjListNetworkArc
    : |* ~, A6 s7 _{
    % y6 d- |% v& F5 k* [public:, g4 y5 R! |$ H- H$ R4 L
        int mark;                                       //标记该边是否被搜索或处理过
    % k5 I- g; k/ k" m. ~7 e        WeightType weight;                              //边的权重
    / j/ F: |# v% u8 ]  Y4 Z9 N  A        int adjVex1;                                    //边的一个顶点
    ( d' K4 ~( X! W* g- Q$ y        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1! j7 B: G- ~) P& y
            int adjVex2;
    1 X* F  H  |! k1 q7 |        MultiAdjListNetworkArc<WeightType>* nextarc2;5 [, H/ ^$ p( R+ T
    . }8 w. k) U. o4 H( N6 q: C2 @
            MultiAdjListNetworkArc()# P. X5 z7 V' p7 ?
            {
    1 u6 D. U. v: _+ B* G( h/ A                adjVex1= -1;
    ; w; R3 W* t$ x) p! \* o                adjVex2= -1;$ ~& D$ S; [* U% X8 r$ ^
            }& z+ @' C) w# W! P
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    , N; w) W! I) f" q9 y        {
    $ j% E' X8 ?6 H. W: p9 m" @' K                adjVex1 = v1;       adjVex2 = v2;4 x2 W7 Q2 B( N  D' J. Z' B3 F% K
                    weight = w;
    " c/ x; L4 e4 [& M1 M                nextarc1 = next1;   nextarc2=next2;' o0 z5 q, G; b
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    . q% x0 @) y& [$ \% M2 ^' B        }! m' W; l/ {, B- B  _$ N4 m
    ( a3 K& J% W0 T5 H- N! [1 q, h
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>0 u  R$ ]! T# ~% y
    class MultiAdjListNetwork" ]4 q; o" ?& C' k2 w
    {
    " \( r  y- {; H# _protected:
    $ U) W: l1 ~2 C" B    int vexNum, vexMaxNum, arcNum;9 I; J, f5 m2 G; ?% i
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    . n% N; ~. S6 c9 O" A& a8 n. Y% O" Z' l    int* tag;% j" I1 A; w* U% a6 S
        WeightType infinity;
    8 t1 T0 x% w+ m1 T. `8 K
    1 n* M4 f7 X0 k4 Y9 Y' L5 `# O5 Upublic:
    1 w1 e' [9 n! K' z" s" b( i8 B    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);$ k+ {* {4 x2 T0 e8 p8 }( y

    & {5 [; T4 F' p3 o. [6 Y    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    ' A3 U2 p1 t& x1 z
    4 O. M$ p" {( L' s; n' y    void Clear();
    * Z! @8 k1 T4 k' U6 v. E    bool IsEmpty()  Z7 r6 J9 x: V/ u6 @
        {" H/ r9 ?* S5 T; W7 @* L" }, k6 `
            return vexNum == 0;
    * J* h6 ~0 Q% \    }
    # b0 y. }  J7 m3 T* _* F* A) m    int GetArcNum()const0 v; C6 D7 o7 V  T7 ^6 H/ e* R
        {
    " N7 }; M1 V- I3 w0 z7 R6 e        return arcNum;8 c( g' G" ]9 i' e7 Q' l/ X" o
        }, F! b9 u3 g3 I. h! j6 Z
        int GetvexNum()const/ O3 Z5 X  w  d! n$ n
        {
    1 z4 p' z9 P2 ^8 J: y7 ?4 b: ~        return vexNum;* D) }: h9 {9 X/ G
        }! a+ L" B' c8 e2 M2 y! Z

    9 h) c" z& |0 W/ e0 K8 s' P0 Y
    ) F5 t1 M' G8 C4 x. Z    int FirstAdjVex(int v)const;" q# s5 M  w* m
        int NextAdjVex(int v1, int v2)const;$ J  H" M7 B6 I( F
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;2 N" K4 ^: H7 j  F  A3 {5 m
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    5 p# y8 C5 f6 x4 W* o
    & _# t5 H# Z- w  d/ u# ]! {) a    void InsertVex(const ElemType& d);' Q* Q/ H6 ], f8 O' {5 f' a% j3 k
        void InsertArc(int v1, int v2, WeightType w);/ c8 O# R1 Q! g" a& {9 P4 d; O
    2 F- d% d; q# B- m0 `
        void DeleteVex(const ElemType& d);
    4 b2 F, O7 G0 r3 e3 E; P' H    void DeleteArc(int v1, int v2);
      V5 |7 x* G* K" w/ e2 A) j! B1 L3 V) J' V1 I4 k0 ^
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    + k* ^4 `, F$ p7 p. \    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);; E6 t" s! }1 u7 ?7 S8 H
    8 s# |/ R/ L9 l) z
        ///深度优先遍历
    . l' ^0 M+ R" L8 _/ C    void DFS1(const int v);
    $ z1 W* O. f4 s& ~3 ^( f7 @% Q    void DFS1Traverse();! M7 `6 m. q  l; T/ s- b8 i
        void DFS2();
    : y* [3 S" _5 C, f8 b$ z9 `- _5 w8 \0 O5 j3 [
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    $ ?& z& g& q* j5 F* K( e, L# r& e) V    void DFS3();* f4 G& w: b! k+ R/ y0 q% `4 T
    - C- |6 `; O% U: q; ^
        void BFS();
    6 p" L$ X' f+ Y  `    void Show();- V% \6 v7 m) M' ~3 B
    };; Z# s8 C. o8 H2 o. l# z4 m5 h
    ' C5 R) N& y+ Z8 M% e$ a8 L
    2.函数的实现
    ! F6 T) G7 h7 F7 g8 |. N3 c1 {研讨题,能够运行,但是代码不一定是最优的。* o% W4 E9 t. b; B+ d  Z

    # Z4 S5 t- t3 i, R#include <stack>( K& k: w" `2 T2 H2 m# }
    #include <queue>( Z% ~, e4 p( Q: D: {/ Y$ R1 M5 [
    & ]6 h" E2 P- u$ _. W  ~+ w$ T8 x
    template <class ElemType,class WeightType>
    ) T3 E6 A; s9 y7 GMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    - |$ c/ p5 a, \{
    7 H( ^3 ~# B, _: ^7 n- p1 |    if(vertexMaxNum < 0)- |4 l8 v: A! W* ]
            throw Error("允许的顶点最大数目不能为负!");
    ( i' x# z! @8 n# z    if (vertexMaxNum < vertexNum)& i4 j$ x$ L" [+ V8 K8 Y
            throw Error("顶点数目不能大于允许的顶点最大数目!");6 Q9 p* |4 X  g( ?* u
        vexNum = vertexNum;
    7 E' k5 a9 J" Z: s1 e2 N7 o    vexMaxNum = vertexMaxNum;
    . A% a  Y  l) f7 R2 J( G! j    arcNum = 0;$ N) K/ y% q2 e2 t' ?! |' q; n% h- b
        infinity = infinit;
    / t+ J" T) C+ `+ ?9 ?    tag = new int[vexMaxNum];( j' s6 v; r7 @0 D
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];' Q3 l4 h3 S6 o& R
        for (int v = 0; v < vexNum; v++)% Y( h( ]) M$ `* q8 b+ m
        {
    1 t/ Z% m! w- j        tag[v] = 0;
    ; O. c9 N" q1 B" ^: w& Y        vexTable[v].data = es[v];3 z5 k) E$ ]% k' c" ]
            vexTable[v].firstarc = NULL;
      ~- ^! V- x6 p5 `7 |    }
    3 e9 t1 G7 p7 J# C}
    6 f4 r  I" ~: B% Y8 ptemplate <class ElemType,class WeightType>
    1 \" w. w9 s2 t0 `: q# K) D- i( `MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)# {+ Z5 X2 _0 L+ W! c
    {1 g* J& \/ e# v
        if (vertexMaxNum < 0)& f7 f8 I- K( _' S% g! g
            throw Error("允许的顶点最大数目不能为负!");/ ~; ]! R! r! Z  X8 O
        vexNum = 0;' {: N" @/ X$ X* n1 k4 o2 c: |# I- ~
        vexMaxNum = vertexMaxNum;( V  I+ |. m3 C' w' p' [2 G
        arcNum = 0;8 D+ W2 B8 E! I
        infinity = infinit;7 S1 `4 Y  ?$ g: u
        tag = new int[vexMaxNum];
    . x# h* ^9 ?3 T- J+ i2 Y    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    & @$ m" R! O/ a8 B}: F" c! ]% V8 F9 M
    template<class ElemType, class WeightType>) j9 y: E9 z/ w  F7 Q' [  H
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const7 g- i, v% `. {6 x
    {
    , p0 U4 J9 u) ]' n7 T$ @6 A4 m8 `    if (v < 0 || v >= vexNum)
    . a# h5 `( z1 c6 n- ?& C8 P8 g        throw Error("v不合法!");8 x' q8 g% d  n
        if (vexTable[v].firstarc == NULL)
    3 \. b# B1 Y* o: z0 i        return -1;5 c4 ~7 K! _2 k- ^2 p
        else/ e  E" _, x2 H. D& e
            return vexTable[v].firstarc->adjVex1;
    : T2 `/ B, m1 W$ {, Q6 o}. w( t; k& r4 Q! h, Y7 x3 ^3 h+ `/ n
    , S' s' a! T' o
    template<class ElemType, class WeightType>0 \+ j& W' F% c
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    $ Y+ R8 t4 l1 P  b" w: X5 {{
    ) }: H" d* Z/ W! f/ {. g    MultiAdjListNetworkArc<WeightType>* p;8 v8 X" {* j. z( z$ o; H7 P
        if (v1 < 0 || v1 >= vexNum)
    ( `  ^6 K8 z7 `: E: M' Y- n" f( ~        throw Error("v1不合法!");$ k3 D$ M4 J2 y) g, R
        if (v2 < 0 || v2 >= vexNum)
    ) O. F$ w8 e) C6 ^1 l: J5 h        throw Error("v2不合法!");
    & _  x8 w1 |, c" ]( U5 i    if (v1 == v2)& k  {, g. b! |
            throw Error("v1不能等于v2!");
    6 ]) W% }$ U( V+ j) e    p = vexTable[v1].firstarc;- r( _4 E2 H3 ?2 T  E. L- j2 k8 k
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    2 i( t7 \) z- I' q        p = p->nextarc;% s$ U" A3 v2 L; J# G
        if (p == NULL || p->nextarc == NULL)- F! K9 _  @7 {6 X( l
            return -1;  //不存在下一个邻接点6 b) j: }. v0 e9 U+ _, ]. y
        else if(p->adjVex1==v2)8 }' Q. a) u2 E' t% C9 k. \" Q
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    0 p, q/ H. {0 S    else8 v  q  p" i$ u- [- \
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);. q, t( b' E) P
    }
    8 }6 N$ i5 I  z4 p/ Xtemplate<class ElemType, class WeightType>
    6 l# X7 x5 l+ t0 |void MultiAdjListNetwork<ElemType, WeightType>::Clear()9 j7 k' e/ _1 q2 E, p
    {
    0 O3 k7 Z( J0 X8 i! d) {    if (IsEmpty()) return;
    2 q8 v1 M, X1 R    int n = vexNum;
    , H9 a! \+ I) g" d: J" D" C    for (int u = 0; u < n ; u++)
    ; S! ^- l7 K0 _7 M, V4 }        DeleteVex(vexTable[0].data);0 F: z$ w1 l/ f4 n
        return;/ O' b& r  \, G1 ^3 L2 I4 Y) J7 {7 p
    }
    6 f: h9 u6 n6 }: G  e6 Atemplate<class ElemType, class WeightType>  f1 y0 w) R& V- z; M4 N
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    ) ~) Y. k3 |! |5 z4 _4 y{" A# x5 U1 F/ H. l. b: ?
        Clear();: I$ v- W1 ^) c/ k1 K% ~; q1 J
    }9 M6 @2 l* S" L( o6 d1 v& R
    template<class ElemType, class WeightType>
    ) z( t1 r" g: W4 e+ V% QMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)4 d" F3 x  l" m. Z' C
    {+ L/ c( U( f0 s' b* h; D
        vexMaxNum = copy.vexMaxNum;1 |( X9 k; q6 W: E2 b
        vexNum = copy.vexNum;0 x- o( ]) x/ M8 h
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    ) D" H. _9 X/ q2 m    arcNum = 0;  U, p+ Q, g! R7 b+ @: d6 t" A6 b; v
        infinity = copy.infinity;0 C  J' ?+ I: f7 a& P* G, O
        tag = new int[vexMaxNum];
    $ n6 {* p0 V$ T3 l' a4 ^6 H
    - r$ U6 m' s1 Q; @    for (int v = 0; v < vexNum; v++)
    & d  S' R7 A' ?' t, i    {+ u1 p6 o; R6 B1 r) g3 P$ r. Q
            tag[v] = 0;
    5 ~6 l% f3 q$ ~0 q' t        vexTable[v].data = copy.vexTable[v].data;# T8 P* E# q0 h: k8 B: K
            vexTable[v].firstarc = NULL;8 ^0 {) I( k& ~3 X& k4 P
        }
    9 {( ]- b- ]1 }, |6 G    MultiAdjListNetworkArc<WeightType>* p;
    , }5 @: l, V# P4 T! g7 d& `( X* G" Y  ~$ O4 u2 h; R2 C5 i6 N$ [8 U1 a0 V
        for (int u = 0; u < vexNum; u++)
    / [; ~1 j4 l* d, S% [2 f4 P' ~    {
    ! b  D5 [$ M) P! E8 S/ D6 ~1 I  h        p = copy.vexTable.firstarc;. _2 S9 b# d! G. t2 f8 e7 }
            while (p != NULL)
    ! \) v+ u% L3 [. M        {6 o: \( S% m$ P; |4 @& v" r9 l. K
                InsertArc(p->adjVex1, p->adjVex2, p->weight);( O0 g' l  P& u/ @  F2 z  o& b
                p=NextArc(u,p);: f) O- p, d: a( R  T' g7 x/ k" \
            }
    8 i! v0 S2 U4 K0 Z    }: h# W9 s/ [: @4 p0 Q
    }
    ' R& d- B. s: _2 m: _2 ftemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&! C) R. V3 A3 f" i9 _2 V' O0 T& q0 u
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    2 \6 K4 @/ M6 n% z; r3 J{
    0 X" O2 Y: c# Z" y% z- ^    if (this == &copy) return *this;' C/ s8 |+ ]0 _0 j7 `# e
        Clear();1 i  ^( y, b! Y) P+ j* c" L
        vexMaxNum = copy.vexMaxNum;
    3 ]' Z' h2 ]- h* s5 @    vexNum = copy.vexNum;
    # Q) o+ [# A7 ~) t    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    3 U1 Q7 f5 \) P2 ~7 h    arcNum = 0;
    ) U' F) f0 e& f4 i  \$ W+ o    infinity = copy.infinity;$ R, _5 `% X$ ?- w, x# O4 h
        tag = new int[vexMaxNum];
    $ e) j* x& q: ~5 t1 w, w" \
    # |% J! H( P5 ~" P# C, M- a/ N    for (int v = 0; v < vexNum; v++)" G0 i7 W5 |3 A/ W
        {
    * z7 A" S3 g! V1 g  D# P        tag[v] = 0;+ S( i' G( Q0 [
            vexTable[v].data = copy.vexTable[v].data;
    / e9 G7 @. c. z) t; C        vexTable[v].firstarc = NULL;
    # ^% z: n& B" ]; U# G9 W$ k( T    }
    ' U% I) V% s& }; y    MultiAdjListNetworkArc<WeightType>* p;
    ' ^; i1 o; p" N, W
      C( i" B; n6 n    for (int u = 0; u < vexNum; u++)
    " i0 I" u1 Y3 R# f+ L7 Z3 V% ~    {
    5 I' F0 Z* W' j6 }        p = copy.vexTable.firstarc;1 r. _3 O9 Y: z4 d8 Z6 R/ j
            while (p != NULL)3 \+ J5 H) i  P) E- w* @$ O
            {* U. _( l3 n+ l; i% ]  h
                InsertArc(p->adjVex1, p->adjVex2, p->weight);+ Z- R0 @5 M' A& S' @; o+ ?
                p=NextArc(u,p);
    $ W4 `& \: H; a! \/ {        }* {" m, Z9 P, X+ w
        }5 @) R2 A( e7 ?
        return *this;0 y2 Z2 h& H% n! Q
    }0 y: s" T: X& g9 d* [: j6 z. b
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>** k4 _- o( }4 n5 S( @* a
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    ' N& |1 t+ p& [; D' o) G) V{' Q0 L5 ~/ W- ?
        if(p==NULL) return NULL;5 L: S# s7 _5 s. d, C+ g
        if(p->adjVex1==v1)
    ( d* g7 I  X2 a4 y9 m8 E        return p->nextarc1;
    # ~# C6 N0 h. S$ ~2 b' N& e    else
    . u2 E5 S5 P9 y; L        return p->nextarc2;: e! p- B' w, J; v) H5 [& |9 g
    }/ b6 c: d2 q6 _# X3 Y
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*( |" D7 z& Z7 w, }
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    7 A( A( j% d" f, I! E{  p0 P, f" t% L% o1 Q  F
        if(p==NULL)return NULL;
      G' J. Z# `" Q3 E4 l, Q    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    % ~/ A# B- y4 N" H/ x$ A1 }    if(q==p)
    * [3 k( W3 h, U6 ?. K" j' U  o0 ~        return NULL;! Z/ O* t4 q/ P9 e% U
        while(q)
    8 v6 j8 o$ G* g: D( m" S8 B    {, D7 G7 M7 r$ @9 y* r
            if(q->nextarc1==p ||q->nextarc2==p)
    9 W' |; l1 T6 j! |& O/ }3 L7 X            break;; t$ X5 y; v' O: G: E; c9 M% w
            q=NextArc(v1,q);5 p6 L% Z* ?9 p  E
        }
      T% j) y; X. _2 `& q$ _9 v    return q;- e* M5 t  e, [& [
    }/ j9 ?/ c. \. N, ]
    template<class ElemType, class WeightType>* z- r4 D$ Y9 l: H& {5 X. N. i- Q
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)( Y, A& d8 U2 M) w+ h6 h7 E
    {
    , \" r' [$ V% I9 k$ Z, E    if (vexNum == vexMaxNum)
    % d! k3 z' P3 m+ o# f        throw Error("图的顶点数不能超过允许的最大数!");% k, y: e* T0 z+ E! C* c3 |
        vexTable[vexNum].data = d;
    , ^. [1 k- [3 x& I3 J  P6 I! D( I    vexTable[vexNum].firstarc = NULL;' O  T1 l! W) W1 t
        tag[vexNum] = 0;
    ! D  b: X% b+ I! f    vexNum++;3 E! D" a9 v9 [' b
    }/ w1 a8 K2 B7 B
    template<class ElemType, class WeightType>
    " h8 S$ H0 i1 Kvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)' J; }* @3 e& x1 v, t! Z/ E- X9 n
    {; D- ?' r; }: l: F3 q
        MultiAdjListNetworkArc<WeightType>* p,*q;
    - l5 Z9 V" D) u( S9 h4 m  c    if (v1 < 0 || v1 >= vexNum)6 p/ X! U! P3 H% Y
            throw Error("v1不合法!");
    ) p2 I# Z' j' ~0 [% }9 H    if (v2 < 0 || v2 >= vexNum)) e7 R1 v/ g3 @$ ^
            throw Error("v2不合法!");1 P" H) z- Y* R' G. k8 `
        if (v1 == v2)
    " R3 |: g8 P" ?        throw Error("v1不能等于v2!");
    0 e% I' ^6 B  x    if (w == infinity)
    $ p1 s- a2 z9 Q9 J' _/ [) r+ V        throw Error("w不能为无穷大!");
    ) S: C! a/ q6 t7 {8 [9 J# W& z3 T- V+ K& {
    " S: f2 B" F* @
        p = vexTable[v1].firstarc;
    , p9 ?0 y# I" o/ D. C6 k4 Z6 B    while(p)
    + G! P9 @2 q. V    {
    : C3 }' M9 G, J0 A/ O        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中( o, F9 {2 O+ ~* g! R; |( W
            {1 Z: L4 e; x" q" t" P2 {) L* O
                if(p->weight!=w)
    , B2 G7 e' b& [6 Q( X! f9 W" X( {                p->weight=w;
      D3 q  W4 N* Z- D* m0 _: B            return;: B2 G* C# Y% ^4 C
            }7 d4 ~+ g9 K# |1 N. B* T

    ' p: Z% \. R* B7 u7 `        p=NextArc(v1,p);% x$ r* g$ c0 }7 ~3 O: }
        }
    ; x, ?2 f: K% S3 ^( R( C* W    p = vexTable[v1].firstarc;
      s+ [) x- z# Q    q = vexTable[v2].firstarc;
    : B+ ]6 m) [' i9 A6 _) a' k* \: z    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法! D8 l; u. p/ w4 t; {7 f
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    " h' [1 R3 W, z    arcNum++;9 n/ L2 @) ~9 P9 P" m& ]
    }
    ' b8 R2 |; P) L
    9 k# i7 U) \6 q' ^+ V( k2 K( n+ [: Dtemplate<class ElemType, class WeightType>
    8 e& _, b6 Q4 B' {1 yvoid MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    ! M) q) |2 t) l{1 }& ]. z$ x2 Q* j( |

    ) \. x: y! W$ ?9 ]" o    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    6 y9 j. d1 K: j    if (v1 < 0 || v1 >= vexNum)
    8 G6 ?1 f9 v- b# ^- S, }( A        throw Error("v1不合法!");1 c+ _$ k; g4 C- R. M) u; O
        if (v2 < 0 || v2 >= vexNum); i' E" V. e' ?% Z+ j
            throw Error("v2不合法!");/ |7 J# ?% g3 C
        if (v1 == v2)
    ! h, }% i3 @9 g        throw Error("v1不能等于v2!");  U# C& R% ?; N1 [( `4 L$ n6 _; g
    8 P% o# c0 J+ @& Q* r
        p = vexTable[v1].firstarc;3 x. w/ X# {; ~" {6 D
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)3 U* y& E* e0 I+ r0 \7 ~7 t
        {
    2 p; v3 Z# M7 I3 ~$ b7 C        q = p;( ?3 D* t# q' A3 v4 n) p/ j
            p = NextArc(v1,p);$ c6 I5 e2 G$ O; R! P( `1 Q. _7 n
        }//找到要删除的边结点p及其前一结点q( {& x' S0 F* W5 h

    ) q( Z/ T. t6 E& N8 `& }; z2 j3 ^    if (p != NULL)//找到v1-v2的边
    ' @  a& x3 d9 d: b7 x. z) c    {1 G) N: _, l! [7 C* P5 \, C
            r=LastArc(v2,p);
    0 \* T  `1 U* {' n/ G% ^6 C        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    2 ~, S9 R, A. O8 z2 L  o            if(p->adjVex2==v2)! E8 Q- d2 w" [* g4 D' _# Z: A
                    vexTable[v1].firstarc = p->nextarc1;
    / q+ t' p# ^* G+ p            else vexTable[v1].firstarc=p->nextarc2;
    3 |* z8 O4 L- M9 i7 l, Z        else//不是第一条边% ~& p: V" ?7 K$ x
            {
    2 i- d, k6 ~+ X$ _# I: ]            if(q->adjVex1==v1)8 }4 t0 M: b5 n1 b( G
                    q->nextarc1 = NextArc(v1,p);6 ^# H- B& M. e7 d% P
                else- g/ |7 G, Q9 o- _; `
                    q->nextarc2=NextArc(v1,p);: S) i# D- f+ g3 `0 N! p

    3 P9 q: \0 i+ g* i+ c1 A# ^9 C        }
    0 Z2 g& H0 S. I& U9 N. D        if(r==NULL)
    % ~( u7 g, K7 X' E            if(p->adjVex2==v2)# S2 @) \' R; |" I- s4 e6 f0 P
                    vexTable[v2].firstarc = p->nextarc2;0 b7 u8 B. y- g/ |, k4 y  V) i# W  d
                else vexTable[v2].firstarc=p->nextarc1;* s3 b- ~3 H$ _% i/ t0 ]4 A; f8 n8 k
            else0 v) G" L, M4 {% R0 s
            {
    9 F3 v  I/ `9 T& E, Q  c+ R            if(r->adjVex2==v2)
    " q( F5 z$ B2 B& j, Y                r->nextarc2 = NextArc(v2,p);
    ' [4 k, |& t, I1 S+ V. B! I            else; s  Z/ n3 C) a. b
                    r->nextarc1=NextArc(v2,p);5 l$ x! B. R: ?1 O  q4 a% k9 n: o1 l
            }
    * p% W) i0 Q, j0 ]9 N. s        delete p;
    # Z3 i3 E0 {$ {/ a+ p        arcNum--;
    2 G" a# K" G' Q' W3 o    }
    - t" g' x2 h, B/ ]* v
    ( W8 X- A$ E1 l6 Z}/ b* H  c( Y4 I% }) g( f! V
    template<class ElemType, class WeightType> void
    ) S, @/ X: J2 R* ~9 q% HMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    1 O4 K- \" n: `1 b0 L{$ h6 M( I0 |: C% [5 L
        int v;6 D# [+ x/ l. J* y3 \, k* w' W4 s
        MultiAdjListNetworkArc<WeightType>* p;
    7 n$ m4 X6 w/ r' F    for (v = 0; v < vexNum; v++)//找到d对应顶点. P% m2 R, w# V8 F; O) F+ S+ M
            if (vexTable[v].data == d)
    : O. ^$ U3 }3 u* y! Z            break;! \4 x& L% k# t2 W+ x
        if(v==vexNum)( y( w* ~( J9 d* \9 L3 z0 Q
            throw Error("图中不存在要删除的顶点!");
    * ?( t$ O( R4 E% T# N) A6 F! V  l8 j/ l, B8 w# C! c
        for (int u = 0; u < vexNum; u++)//删除与d相连的边
    / m4 r$ U! B: X/ t+ z! H+ {        if (u != v)9 N- S, l, w: V5 Q1 E: E: v* U% m+ l
            {
    9 v# }* w" y0 v* I            DeleteArc(u, v);1 z  f# u, o" H' |* W
            }) M5 }3 J& S! u' i* F
        vexTable[v].firstarc=NULL;7 H( t* b# s5 R/ s4 J' v

    5 `$ N  Q% M2 V& n5 w  H% e    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置9 G" T1 V. o% B# o" O
        vexTable[v].data = vexTable[vexNum].data;7 @2 {' i  J7 G+ |3 S( \; U
        vexTable[v].firstarc = vexTable[vexNum].firstarc;
    " z7 N: |7 e  ?7 N3 b; H: s+ x- t    vexTable[vexNum].firstarc = NULL;9 Q0 {; k1 Z% q" U
        tag[v] = tag[vexNum];
    3 }9 J: P! j  c, V% A    //原来与最后一个顶点相连的边改为与v相连& i, Z( R3 p- Z5 |; B3 ~0 C! J
        for (int u = 0; u < vexNum; u++)! M% O1 S% _: B9 l
        {  m2 b) T. _* F/ y3 q* b
            if (u != v)
    4 X0 V4 ^* _) u: q5 Z        {
    6 T/ N, J  t* o2 q            p = vexTable.firstarc;
    8 m) |) ]* n) O# x            while (p)4 z- e2 _# h0 j% _" X
                {9 p" z; F3 Z: y/ ?7 v" w! ~
                    if (p->adjVex1==vexNum)0 s* ^' V8 A( M7 |' M
                        p->adjVex1= v;
    # {) k/ B3 [7 i  l) [& R+ n                else if(p->adjVex2==vexNum): K9 z9 r# t$ b+ V
                        p->adjVex2=v;3 v& v) U4 n+ o$ y
                    p = NextArc(u,p);( X0 I: |1 T" L% P4 C& i
                }
    : u( d8 O8 m8 e8 |        }; P: l/ n+ {' L: t) M: S: a- [
        }5 }, Y/ Y$ O2 w% l0 y/ W; y4 X: m  \
    }) b2 ?" u" M& q* w5 R7 q) b1 M
    ///深度优先遍历
    3 k( k9 `0 J3 K1 x7 ^template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v); i8 k6 F7 D+ w8 U( o
    {
    , O; R, c$ R2 m    tag[v]=1;
    0 D1 |9 F- R  P# n& z    cout<<setw(3)<<vexTable[v].data;# A- i( Z+ d5 P+ \4 j; n6 @
        MultiAdjListNetworkArc<WeightType> *p;; J) b1 y2 K/ g2 V1 S) F
        p=vexTable[v].firstarc;% m7 G: f7 Z( q* P
        while(p)" h) R4 k% M8 [9 Y' c
        {
    : J% R+ t* B, N  }: t0 @        if(tag[p->adjVex1]==0)
    , Q4 g6 U$ ~, p  n  n            DFS1(p->adjVex1);4 l6 b$ F0 K9 e
            else if(tag[p->adjVex2]==0)/ x) Q8 o7 ]2 Q" s# r* J
                DFS1(p->adjVex2);
    8 r7 s+ [* I7 C- p! I        p=NextArc(v,p);" I5 d. _3 o+ H( a* q% k- }3 v
        }
    6 a1 ]; [6 e; C& M/ z5 w9 T}
    - C" @- Z8 s1 w3 n. N; u, K! ntemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()3 d! \( ~7 j$ j' ]+ E4 B) f
    {0 o/ \0 d) k( D* M4 [
        for(int i=0; i<vexNum; i++)6 D& R, |7 w  ~4 E4 _/ E1 z
            tag=0;
    9 w5 G. L" ]6 ?6 H9 q3 S9 E/ D% F    for(int v=0; v<vexNum; v++)& R1 a) I' u$ _6 S# ?
        {. l; g- H, U; T  b, i
            if(tag[v]==0)
    + @9 l$ Y; ^. M8 S# |0 r+ Q& `2 X; S            DFS1(v);- l+ x6 u% x$ [' F, V
        }
    . x# n  Q3 D6 C& V! R' F}
    3 ~8 D3 ~2 w/ Q, z" |4 A8 ztemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    3 Q8 l2 m/ G2 P3 w{0 U+ `+ f) b: i$ g" P1 r9 h0 ^
        stack<int> s;9 Q( x) J4 Q3 P2 k) I
        int tmp;! {7 u3 j) \1 R  t2 j/ x: X
        MultiAdjListNetworkArc<WeightType> *p,*q;3 X* A& ]6 o5 ?2 X
        for(int i=0; i<vexNum; i++)
    , Q; b5 Q1 u0 j9 p8 Z        tag=0;
    2 I) r; G7 O% N+ p% d. x    for(int i=0; i<vexNum; i++)
    $ A% p1 u; H/ x9 l4 K4 R5 l    {& d& E( O( s4 [! S0 s  [% {
            tmp=i;2 z' y8 B* w+ y( j) S) D" }
            while(tag[tmp]==0||!s.empty())- ]0 U9 d" E  {* _; i0 a8 E
            {. x* \/ a4 n3 O% n( E
                p=vexTable[tmp].firstarc;( P" U) r. ^  V7 v2 Q
                while(tag[tmp]==0)
    ( U& j4 s5 g7 o$ i6 G: L, v- s            {: Q) y5 Y+ J1 b' U6 W1 x
                    s.push(tmp);9 w0 a' e6 {* g) T4 I
                    cout<<setw(3)<<vexTable[tmp].data;4 h# j9 r' X. Q8 A* D1 S* Y3 I
                    tag[tmp]=1;
    9 Y1 ]3 u! H! a' c* K! T' Z) w                p=vexTable[tmp].firstarc;
    1 v) I# r* d  \                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for, H8 O" _7 r9 q+ b4 k& v, v4 F
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);4 j8 I; {% z: o0 m6 r, s5 U
                    //cout<<" 1st     tmp="<<tmp<<endl;/ O& ^  p6 S* y, n8 q7 z: n7 G! q" N
                }6 L- U8 R! C: A+ U: F" z
                if(!s.empty())  w* `$ S2 `  y% V8 `0 _6 y
                {
    4 O* @: z8 A- N: a                tmp=s.top();; G6 a4 H3 t0 U6 F+ X6 m/ J' U
                    s.pop();( X/ s8 y% O# |# i8 X7 B
                    q=vexTable[tmp].firstarc;
      X  D; X$ O* \; h; b8 Z- \/ t0 e# d                int t=tmp;  ~+ |3 R+ V' z( ~7 I: j  q
                    while(q&&tag[tmp]!=0)
    6 q  ^3 w6 a! O& ?                {
    / t5 |0 H+ ?! g9 \5 h                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);1 x9 l0 M7 N0 L+ K$ V
                        //cout<<" 2nd     tmp="<<tmp<<endl;
    ' g3 h4 Q$ ~# N1 j+ e$ A: ^                    q=NextArc(t,q);
    ! v0 C& x! ]* Y4 ~0 p                }0 Q! w( ]+ g$ }! D/ w( M( r2 V& F1 G
                    if(tag[tmp]==0)
    / Q+ ]3 o+ @, p5 \' T- K                    s.push(t);
    ' {$ P9 v  q8 ^1 p& j2 ?                ///1、对应上面连通分支只有1个点的情况! v7 `' ^  Z/ f* `9 ^
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈/ N: E8 Q  B+ e  h, |. L+ `5 M
                    ///tmp要么等于找到的第一个未访问节点,/ H2 {. @* C& ?8 [
                    ///要么等于与t相连最后一个点(已被访问过)
    , W3 V" s- }1 ^$ F) \                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    , y, J% `: B; M+ W            }: e2 G. N+ g6 M6 F' c% }- s( Q
            }
    3 l+ B. @0 l( F) H    }+ ], v4 }, d" _) K2 a/ @
    }
    % y1 x1 [: X( i$ i6 Z//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    ( H% V& M& V! Q6 U% d. z! Wtemplate<class ElemType, class WeightType> int
    4 B) {7 o1 f) _MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    - l# x0 r) H* Y9 x( @& G2 S" U( q$ `{+ \0 m3 p- q' R  |
        if(head==pre)0 }* g, h3 i2 {
            return -1;
    ; b# z5 S+ K3 P& O8 [  G
    . O( p, r' A6 ~. n, K8 |- ?& s/ K    MultiAdjListNetworkArc<WeightType> *p;
    6 ~0 v" H6 Y" u8 n  k    p=vexTable[head].firstarc;
    ) Z6 r( u( Y, f" }+ ?2 Y3 L2 a    if(pre==-1&&p!=NULL): ]7 s9 Z. {2 C4 ^0 J5 c
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    ; M8 e6 k+ }1 H+ @- y/ P1 g. C    //pre!=-1&&p!=NULL) ~: E9 P& O, n) X9 X
        while(p!=NULL)4 g, a& |4 n9 G3 J# @
        {' b, _' @- C: L" `' L
            if(p->adjVex1==head && p->adjVex2!=pre)/ n3 z" z& Z- a/ p
                p=p->nextarc1;8 E1 g/ E8 `$ g/ _) _) @. T" U
            else if(p->adjVex2==head && p->adjVex1!=pre)2 o. l$ W' c% m/ h- f
                p=p->nextarc2;
    * E; F8 t2 z7 m0 o  g+ L- Y7 e        else if(p->adjVex1==head && p->adjVex2==pre)
    4 \9 a4 x* b; u# u6 S0 \        {
    ( F7 G) t+ A& o6 i+ F            p=p->nextarc1;
    1 r9 T- q" J# ~3 B            break;
    9 i; O# y+ x* k  r4 O  Y        }7 k. ]; D/ Q  Y* m' X; Q/ T; E' t
            else if(p->adjVex2==head && p->adjVex1==pre)
    : i4 s  ]5 {% Z% Q: q# Y        {
    3 V' A9 L- l% Z4 X4 W- G            p=p->nextarc2;$ v+ _1 J) I0 m8 D; x$ r3 O! Z
                break;$ T- e* F, K( A( A! h0 E  u, H7 b
            }5 A6 y6 {, }! s$ M* M& z
        }
    $ T& C/ i; S! i1 k& R    if(p!=NULL)
    / I+ `1 C! K( C7 R7 N    {
    4 X/ [/ w) h; Q$ ~: |0 X9 ^8 t        return p->adjVex1==head?p->adjVex2:p->adjVex1;+ s3 d/ _$ B# `) {) e
        }" J4 o  w6 V3 B( d9 @/ R4 v
        else
    3 t$ W5 c$ x# S- I5 I1 o2 V        return -1;8 p: d9 S2 ~4 r& L0 ?1 w. ^
    }7 j; m* |% P8 z1 o: R
    ; a! w' n+ b8 t- I# N+ v7 I& q
    * ^# e9 R" q  o
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    $ J5 c: u: c+ Z% j6 x{
    ; Y# `2 W5 R1 w    stack<int> s;
      V) f7 Z: q' Q- J4 [    int p,cur,pre;
    , E9 X8 g' g5 M/ c$ y4 X+ u    //MultiAdjListNetworkArc<WeightType> *p,*q;# i! f% y6 b. F$ p
        for(int i=0; i<vexNum; i++) tag=0;//初始化& z8 m: D# F' q8 @: G+ b+ v) h

    1 }5 B! D- ~& w8 U    for(int i=0; i<vexNum; i++)3 ~) f1 ~. J: D- s0 O
        {1 a/ `- G  i5 @
            cur=i;pre=-1;( {" j8 O1 E1 s
            while(tag[cur]==0||!s.empty())4 F# Y" Z* n( F) B& Z" o" z
            {
    : a  Y. k+ |4 E, M, U+ s            while(tag[cur]==0)
    - Z  K) w; d7 I) O6 c            {0 Z- t) R3 r6 I/ O4 }$ m
                    cout<<vexTable[cur].data<<"  ";
    " k6 R& o) z8 {( p; _; C& p                s.push(cur);9 n3 _$ F2 w1 r# s0 k# p! ]
                    tag[cur]=1;: W' Q1 m5 S( L: ~6 r
                   //初次访问,标记入栈3 W& I& u( d/ K0 t% B# l

    7 m# F$ D" P+ {# ?, L) Q               p=GetAdjVex(cur,pre);//p是cur的连通顶点+ W2 z, b# W; y, M% K, ?
                   if(p==-1)+ G9 N+ q" Q2 f/ R1 H! c* P+ `6 {
                   {; w- _0 }* o% K$ Z, n" a" F! D
                       pre=cur;s.pop();$ A0 S- R4 G; E7 t& ^$ h. ]  H
                       break;% c  b' q- W; j& g: j/ x
                   }  J4 z7 S8 s2 \* U0 j' R9 B
                   else
    & o+ V, V3 E' `) r  b  S               {
    + [% r, E, m4 V' Q& T5 w) l8 [                   pre=cur;8 A0 I' ~' S/ K" I$ |+ r5 J
                       cur=p;
      l$ P! j2 d: ]; i               }/ v7 K& G1 \1 I) T, g3 X3 X
    ! O8 f4 t/ P3 e9 [! [8 G
                }
    3 o" M) N/ i& p! c+ `            while(!s.empty()); `# p& y; J* p8 y+ t% a
                {
    / c' [9 P( t  @, k7 r2 a2 X                cur=s.top();, {  p# {$ K3 L( \1 X4 n3 U! l: C
                    p=GetAdjVex(cur,pre);
    4 D0 V+ N" j6 \  J                if(tag[p]==0)
    ! G8 h' |- O2 ~9 h& k                {" ~' q* A* F( _" C, `, U$ v6 I
                        pre=cur;
    ; C! i: X/ [( d! e6 r% O                    cur=p;4 V3 U& g& K+ k
                        break;
    ( B( Y. m$ P- p3 c4 Q3 ~+ G                }
    + V! {: j/ M+ T. T                else
    # P0 q) e, K) k& X! K8 i3 c/ j4 W                {
    ) f2 m( |4 [' P( M+ e* S* K                    pre=s.top();
    - p% Q0 }  A, N% P* E2 U! R                    s.pop();
    0 Y" r% P+ A1 R# `! S% o# G                }, r* u' ~  M+ M+ ?9 h' p! o% P

    , _4 f3 {' |. U, Z9 L- t/ B9 _/ ^; [            }
    ) O$ i$ c2 _  a
    ( ^  o2 H4 S7 \$ H$ i# d1 O        }
    0 y; Z/ ~, ?3 c    }
    , u+ m6 {3 u1 P/ F2 b- r) a}
    3 {" S/ v2 N; Q. H0 u% O2 t" Ltemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()5 C" _# A! q/ H/ ^* l
    {5 S) t. Q( Y' P! t- z  W* U
        for(int i=0; i<vexNum; i++)
    / u' r  }, s: ?        tag=0;. \* E9 |2 L% u) X2 Z
        queue<int> q;* v& J5 C7 n. O/ z
        int tmp,t;) ]: a, F1 O! W) v( _( \( G% i7 o
        MultiAdjListNetworkArc<WeightType> *p;
    1 V- n. ?: p  ], z4 f8 b' s! ^% a/ k    for(int i=0; i<vexNum; i++)
    # K+ l( k" q" Q5 D# ^2 t  j4 c    {( h  u0 h4 b8 ^, G
            if(tag==0)
    + s4 P+ j2 Q( X        {
    8 r8 z# b4 T0 i3 M* N            tag=1;# ]/ `" s3 ~; y0 Z5 o* d: y- s9 H" L! _
                q.push(i);
    ! V+ G& o0 l( \, ^( l  k4 d4 O            cout<<setw(3)<<vexTable.data;
    1 D/ T8 y- j/ T1 n        }
    % `# l. D0 Z, ^9 M        while(!q.empty())
    9 i- C& X; T1 H! j+ B        {8 `" ]& ~! o  e
                tmp=q.front();6 o# o" T  D* J4 i1 w8 Y1 J
                q.pop();
    3 h5 t1 ~7 a# n& p$ H            p=vexTable[tmp].firstarc;
    # y9 j( D7 r; l$ M# Z9 c( o1 f0 ^: h            while(p!=NULL)
    2 @# D$ K! T4 n: Q4 X            {8 ]9 {% j: F, R' [  j
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);: H& A+ m( v" _3 h4 e
                    if(tag[t]==0)
    / R  l* e9 V5 C2 N: ?- Y$ j                {# u2 k+ a$ v5 F+ S- `- ~" O
                        cout<<setw(3)<<vexTable[t].data;& t  r& T7 p# {; X
                        tag[t]=1;
    * d1 ]; s1 ~  n& `% M4 R6 F& R                    q.push(t);4 K% q2 l+ R1 O1 E9 L6 x; F0 f! j  g
                    }
    " `4 T9 N  r; y) s$ C1 g$ ?% c/ m                p=NextArc(tmp,p);7 ~1 O5 |5 Z% ?5 W" I  L& F
                }- Z6 [8 Q( P! I, N9 O5 I
            }2 U) K' Q/ I9 a- Q7 D
        }/ H3 I) H& z6 J0 p. Z1 C& {5 i* J
    }
    9 u6 O1 t" a1 Y9 itemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()$ m! N0 V$ g  |- {! b$ k3 t: S
    {% N- P4 T7 ?8 D, S+ k$ l: m1 U
        MultiAdjListNetworkArc<WeightType> *p;" ~7 ]  r! ]7 Q  W( r7 T/ m6 P( g; j' p
        cout << "无向图有" << vexNum << "个点,分别为:";
      x' f7 |: ~4 E% ], X, ?    for (int i = 0; i < vexNum; i++)
    6 o- G/ z( U, D# ^4 P4 T* }/ l. l+ b        cout << vexTable.data << " ";
    # m6 c" [+ |! I, x/ c* y9 W    cout << endl;
    0 P4 l/ i: P2 C    cout << "无向图有" << arcNum << "条边"<<endl;
    : s6 t6 N+ J" a! U) A, A    for (int i = 0; i < vexNum; i++)  w. h7 H9 M  N& ]8 D6 |% O' A
        {. |1 \* U4 f  Z- F, m% ]
            cout<<"和" << vexTable.data << "有关的边:";
    1 p- M# X( @% {& g' b3 p& _        p = vexTable.firstarc;- t5 I* S" {( X  ], G- T
            while (p != NULL)
    " n' D9 q3 h2 F* W1 V        {
    ; }( y3 M" e3 T) Y8 T; i& B            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    " g- C. {1 \7 {& R, ]' I            p=NextArc(i,p);* m) y% W+ b6 n/ ?% b( o8 A8 u- _' I
            }! a% }' M7 j) t" k) X; Y
            cout << endl;/ F7 Z9 A% [" X' d
        }/ t% ]4 N  M: B/ K
    }7 e; G9 m& O4 R( Z7 e$ X* [

    8 R, s4 Z! K/ V% X& u+ N7 j  j
    8 a4 W2 L3 P1 h邻接多重表与邻接表的对比2 X: ~' A: A3 v* V6 ]/ i

    0 ?" g; M/ Y: i& I( ]( L邻接表链接
    ) c1 [: X# X3 A) u" W# s在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    6 I4 ?7 Q# ]6 n在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。* G1 i+ C8 g0 E. k4 j
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    7 ^! r: o. Y- r————————————————: Y! T- q" R" z( a/ t
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。% G4 D6 ?: s% `7 b2 d$ q1 k
    原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669586 D' M/ J5 a- a: m2 i- }

    $ v1 ~' u2 Z2 p' s
    - U+ F: F/ D, s0 F2 t4 U- l& d( h+ Y! N' D* Y. L

    ! j3 T7 v" F  s! X: U1 T& d8 W————————————————6 h  V. `8 Y' l! g6 r
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。/ _  k0 k) S+ x0 r6 X5 }
    原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669588 Z- z- w$ T. r+ t% r

    ( ?' }" a' u" n
    * f3 D8 j9 D. t9 O1 u
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-1-4 05:44 , Processed in 0.754544 second(s), 53 queries .

    回顶部