QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1420|回复: 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

    : W" @& r( o4 f图的存储结构——邻接多重表(多重邻接表)的实现
    & G) b. T$ l; I7.2 图的存储结构
    - r  F! Y0 C5 {6 z
    + [4 \* @$ ]/ {9 }3 U! C$ A7.2.3 邻接多重表(多重邻接表)Adjacency Multilist' v  Q/ A; B6 G' y
    邻接多重表的类定义
    5 ^( e: G2 }$ @7 h8 W! q! X" b邻接多重表的顶点结点类模板) q. [& y$ X" m* ~4 `+ v* b3 J
    邻接多重表的边结点类模板3 m8 V) i2 I$ ~$ I* y) ]
    邻接多重表的类模板6 ^) S( l: f1 m) l( ?- V) N
    邻接多重表与邻接表的对比
    ! Z% w# b& Z$ K& p7.2.3 邻接多重表(多重邻接表)Adjacency Multilist. E2 Y/ v" C4 M/ Z! R

    $ |8 L! E. ?* Z# `4 G- w在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    * O1 o4 j8 l6 y$ \/ }) I2 v! S+ R) Z在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    0 h  i  r3 P; j$ ~! O
    % Z7 N8 S5 L! }  G1 f) b邻接多重表的类定义4 ]3 u7 w7 |: n$ w- l4 v8 m4 t/ c
    1.png ( ~) {8 ]/ V; Y  |7 z
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:: t& W) f; K7 Q5 L1 h: A# c6 k" [
    data域存储有关顶点的信息;
    % m' t6 U) `: ?- H) `+ W9 U% ffirstarc域是链接指针,指向第一条依附于该顶点的边。
    8 p2 d4 c& U; N所有的顶点结点组成一个顺序表。

    2 y' F, h5 r7 A/ V- S8 }& Y

    / v$ p9 J+ o# H7 \/ q1 ttemplate <class ElemType ,class WeightType>
    ; X. |) S" n3 }' A& u  H/ [class MultiAdjListNetworkVex- [# u* |1 I& C( O( m
    {
    1 U; U7 Y( ?; `3 q( X. x# j7 Ypublic:
    # Z2 o9 E$ p; f        ElemType data;
    3 D8 B* ], Y& a, j/ N        MultiAdjListNetworkArc<WeightType> *firstarc;
    % W7 q: }7 U% [. z: U" R  I, {! {3 f
    % W) e, T# W7 h; ?        MultiAdjListNetworkVex()
    ' Y- d3 H; l8 g0 U/ O2 H, o        {( u3 m/ B# G% K5 v& k+ H
                    firstarc = NULL;! i# K" ]2 y, k# X! q
            }
    : W+ Y. I% R; W        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)$ ^( i% M7 d& o( b0 H" S! \
            {- e" e: U, j) ]% U; I8 N
                    data = val;& |- A2 d- ]' U7 ?2 l" @
                    firstarc = adj;* d, w0 k0 Q8 t; t& V4 o
            }
    ' b& F4 b" J, J& n& `7 {" y2 G};
    ' q# J+ Y. z# L) R# u5 s1 W4 L% d! Q: l& v/ z
    邻接多重表的边结点类模板
    # a& i( D6 t. D# U# N% Q( A  l# {0 j3 `' T7 p
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    ) O7 `3 W0 z* M% L/ s, t5 N# |tag是标记域,标记该边是否被处理或被搜索过;* I$ G  s6 ~% n; H) M3 A, y
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    1 ~1 V  G4 [9 l# Jnextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;6 Y" O+ @* T8 ?- j0 t& I3 M
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
      Y  A  I( T+ X* c1 S9 N( u- V4 e- T0 _! O+ O, n. p4 @) }
    2.png
    5 i* J1 s) u4 a, Y6 x- Vtemplate <class WeightType># H+ [; {; E0 g: n6 K
    class MultiAdjListNetworkArc+ J3 H0 h+ U* Q- W' ^  V
    {) M9 k5 y. F5 n$ X' D; i
    public:
    ' C/ j+ B3 V& Y7 a- j- y# `    int mark;                                       //标记该边是否被搜索或处理过( y: T( k, U  B; ~# L
            WeightType weight;                              //边的权重; F8 y, {4 d- l% P7 C
            int adjVex1;                                    //边的一个顶点
    * r# ~. R# I1 z* E        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1# c/ S) O1 m+ J+ g2 t! k9 |
            int adjVex2;
    + |4 [  C' F5 H/ _' |" Q6 k! `0 U        MultiAdjListNetworkArc<WeightType>* nextarc2;
    8 ?: V. m5 h5 I$ L
    / |! r9 j. r$ b$ Y        MultiAdjListNetworkArc()( u; s/ q) p0 Q$ R  s  O
            {
    2 A4 l( C: d9 j$ R9 \3 {9 p                adjVex1= -1;
      ^6 u* ~  p5 A; H% a8 @                adjVex2= -1;$ }, i& U: J: i) z$ \" v  Q
            }$ z5 s: j8 d. z) a0 e+ S
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)8 R% y* Q1 d+ z! C  W
            {" r7 }( J7 V& n& ^+ \  h$ C! X
                    adjVex1 = v1;       adjVex2 = v2;7 ?6 o5 c+ y/ E; i5 b! l
                    weight = w;( i5 v5 `  a) Z7 Y  a# @" v
                    nextarc1 = next1;   nextarc2=next2;3 u" _- f3 S: V. x3 l1 r$ z
                    mark = 0;           //0表示未被搜索,1表示被搜索过  X) y9 k* o% d% U
            }6 G4 p! f2 x( v: I' D7 @4 r2 O; O

    ) D) \$ ]& y  L: ?邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    # c# E. A% e0 ~) g- I5 X% ^  eclass MultiAdjListNetwork
    6 d5 Y: Z: D" H, _# h2 \1 D1 H{) _1 z% K- O8 t) @: [
    protected:
    8 ]  _8 j* b" r! T3 n6 F' x8 Z    int vexNum, vexMaxNum, arcNum;
    # x  }0 q9 Z% |; o1 _    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    / \" ]- f( F/ _    int* tag;
    / }1 i1 \! c* q( i6 M    WeightType infinity;
    & @8 a6 I0 W, c8 G- f; m3 p1 {$ A5 W1 {1 `5 ]2 e/ [
    public:
    . z% Z' o2 Z& W% x2 y) W  ]& X    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    2 g8 A( L& u# T6 v7 z: E6 ^$ F! {4 ~0 B1 W; [, M
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    & Z( e& ]5 p9 d& |4 T; E) Z
    $ }6 L6 Q3 _- W; c    void Clear();
    & G) c* r1 c0 |/ `% O    bool IsEmpty()
    6 I* K7 a& x. P9 o9 }7 q    {9 z' ]9 x# \/ N
            return vexNum == 0;
    ) y5 B8 K0 t9 N& P, |+ K" G    }
    6 J7 z9 H( C$ v+ D  K. K    int GetArcNum()const1 T; [: X4 t6 r) ]# ]( y; h
        {
    2 _6 h/ C4 v6 |$ {8 m" U! k; b        return arcNum;
    9 D$ [# ^9 j' n    }
    4 [0 b3 y4 W- I; V( y: Y0 W; _    int GetvexNum()const
    1 p( l! M$ B3 ?! O+ m6 k    {
    . K4 ^0 p9 Y6 N7 c: H" ^3 v3 C8 K        return vexNum;- J$ E% O  F" X8 {4 P- x
        }7 R5 J) |% _1 o! H+ e) n: g! `
    1 P( m7 P( `7 M0 H

    5 C4 e  u; o# {. h# y* O    int FirstAdjVex(int v)const;
    : @! ~9 J! v  i; S    int NextAdjVex(int v1, int v2)const;
    ) p/ ?( F% B+ ~    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;, b4 H" F. A- E2 U
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;2 P* n( p$ x# t! [5 z! G

    / |) w1 t; l5 ?: ?* R    void InsertVex(const ElemType& d);3 ~8 Q# \9 o2 b/ k
        void InsertArc(int v1, int v2, WeightType w);1 E6 l* M2 R6 U( n, x% B: f

    ! i7 m2 C$ ?2 Z    void DeleteVex(const ElemType& d);) r+ `& e% j8 r1 x& W" J: G. h* u
        void DeleteArc(int v1, int v2);/ S9 X# v! i+ L7 b: m) a

    ! k6 m% w3 Z  K  e' `6 n9 r    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);9 F* _9 g) k6 Q2 A# k& Y& W
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    ) ?, R' D: g' d3 j8 ]
    2 S2 @* g* F; [4 t; v' K    ///深度优先遍历- h5 j8 v& u. @, q
        void DFS1(const int v);
    3 S% T8 K- l2 P    void DFS1Traverse();
    ! K; q4 S* [; c5 ]/ w    void DFS2();: t5 `9 W+ I7 n7 l* S0 i

    " L  g% d2 J3 |, x    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    & A% r7 ^3 R" _8 X1 y3 N$ o    void DFS3();7 x, B  A: u; T# a: z$ A

    $ K5 _) s+ c2 [% m; V6 N8 a    void BFS();$ d7 U! g9 t, p9 ~; }/ i  Q
        void Show();
    # @, B( [# t# n! U* f};
    6 @# b" E/ k8 C8 y
    / L- o) l4 a$ l# r& k2.函数的实现
    ' N5 ?; G8 q: I! `) }研讨题,能够运行,但是代码不一定是最优的。
    9 ^2 x% j  o1 V' Y( L
    7 I2 P0 r; v" C. T" O#include <stack>3 S9 d5 k4 {4 u0 m6 B0 ]% e+ a
    #include <queue>9 n3 M) N6 M  {( s5 {' a2 v
    9 A% S' b/ ?& Q$ E! u% K4 z3 c$ y
    template <class ElemType,class WeightType>' m2 D& l, y& K1 g+ a, a
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)) S# \" U4 V7 k
    {
    6 S+ z, x- ]/ {, o& B  o    if(vertexMaxNum < 0)
    1 h! `( Q1 d0 v; ?+ b$ @        throw Error("允许的顶点最大数目不能为负!");
    7 |% Y4 m) O) e: r( o0 _    if (vertexMaxNum < vertexNum)5 i2 a- N, x5 F6 e
            throw Error("顶点数目不能大于允许的顶点最大数目!");3 N5 i/ Y$ V2 D# y& O8 T  P/ X8 K
        vexNum = vertexNum;
    4 U& B6 R) b$ F" `2 X9 ?    vexMaxNum = vertexMaxNum;  ?0 b" M, x# g* l
        arcNum = 0;: K/ t+ Q- v, w" t% O  o) ]
        infinity = infinit;% v. d$ t, i0 ^: s! ^$ X. y
        tag = new int[vexMaxNum];
    3 m3 v. [: F% p9 A" {1 O! a3 L    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    1 }5 S1 z. a' M# |9 \    for (int v = 0; v < vexNum; v++)) M# L/ U) }+ F. ?  r
        {
    + `: s2 j+ }- W. Z4 z/ F/ H4 Q# N        tag[v] = 0;
    + b- q/ q8 E# M! I2 y; {        vexTable[v].data = es[v];# e( F1 X& N' n
            vexTable[v].firstarc = NULL;6 q! p+ T: n7 N/ M8 C6 a% a. C
        }
    $ K7 e8 \. t/ i# R" D}3 z7 o0 Q0 P$ }% X! L3 g
    template <class ElemType,class WeightType>
    4 u1 _* b* P: C0 f3 u1 [& n* wMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
      ^% O' c6 D/ n" c# M: s{5 R4 S0 `4 N7 s0 F6 S" d$ K
        if (vertexMaxNum < 0); {' U) L: l4 e+ ]. j& y
            throw Error("允许的顶点最大数目不能为负!");
      s7 L9 R2 T: s4 H+ d1 L    vexNum = 0;7 @4 Z' r. u  P- u* c, D# E
        vexMaxNum = vertexMaxNum;5 m* v+ N4 K5 E! Y& ^# S& E
        arcNum = 0;
    + L3 @8 C9 v* i4 _% e    infinity = infinit;$ _9 P0 }$ x  [5 F
        tag = new int[vexMaxNum];
    9 ]5 p1 G+ l2 m    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    * i( u% ]: {9 j& a) N( o4 ]}
    , P* s5 M) ~' j' _7 m. x  l( ^) l" c9 ytemplate<class ElemType, class WeightType>$ j/ I! a2 C6 M/ ^7 ?! o5 z5 i
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    & n; E. M* J. _+ Y# q1 Z% v{# a. o9 i6 m* q
        if (v < 0 || v >= vexNum)6 X' u' t1 Y1 {/ X# k, y7 z
            throw Error("v不合法!");9 q7 G: q  D4 i/ A2 G8 N
        if (vexTable[v].firstarc == NULL)0 _) N& U# d6 f3 b  d( d
            return -1;# d9 Z7 ?7 d5 Q* U. b! k# y( k* l' l
        else! C) r( ?( B; h, q3 _* I# `# F+ y( e
            return vexTable[v].firstarc->adjVex1;" N* `  Z! q+ M+ n8 f
    }8 ?: |, d7 M2 ~2 H; M! [

    ( N6 n0 Z3 t* _5 }/ Btemplate<class ElemType, class WeightType>9 v2 {$ Q& s4 Z0 J% W, U' t6 C
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    " b% G7 X' `6 J; _' E& M( p& `{
    , o1 S" [( {3 o    MultiAdjListNetworkArc<WeightType>* p;
    . Y+ W) g( M4 x' J6 `    if (v1 < 0 || v1 >= vexNum)
    ) ]3 \2 Z0 Q2 J        throw Error("v1不合法!");2 J1 @+ J8 U) d0 x+ V% _: X
        if (v2 < 0 || v2 >= vexNum)  b  }. l: i) ]" C' J6 i
            throw Error("v2不合法!");
      t& a. P) [, p, Q    if (v1 == v2)9 s( |$ `% ]3 q
            throw Error("v1不能等于v2!");
    ! ]' I9 m5 e$ w9 l% z    p = vexTable[v1].firstarc;
    / L3 A' a9 F6 H8 a    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    , Q. ~! R% k1 W$ U3 x0 ]        p = p->nextarc;
    2 f" Y/ s/ ^$ u7 I5 x2 @5 t    if (p == NULL || p->nextarc == NULL)
    " N# `  V  _3 C) P+ d) f$ Z' K3 L7 ~        return -1;  //不存在下一个邻接点! [. g4 e& V9 i# E
        else if(p->adjVex1==v2)% a! o: e' K4 H
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    ' \* I* o/ n) \, F    else
    9 \/ @0 x/ x6 @! [% {        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);0 O/ G5 g/ \; s
    }( p9 G) a' B1 o0 H' u/ `5 z
    template<class ElemType, class WeightType>
    ' p9 U8 o2 Z" [, A: Tvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()* t; P5 ^4 o% ?( d  _6 c+ x; U
    {
    ) N3 {, @" [5 L. W2 Q    if (IsEmpty()) return;
    6 L  z- k! h2 B* G  }1 c! K    int n = vexNum;
    ! K7 Y7 [" _7 b2 p9 L) _2 R    for (int u = 0; u < n ; u++)
    * b- I! i6 ?4 `3 j: M        DeleteVex(vexTable[0].data);
    * V6 p  n+ Z; ^" Z- }    return;
    % g1 d* J3 r- I/ l, ?& E6 t' i}2 f7 n8 S# F- W6 n' z# X
    template<class ElemType, class WeightType>  D, F: l! G  Y7 j/ h, l. I
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()+ G* Z4 w& V: {4 n
    {- ^7 _  {. T+ d7 ~; ]6 k
        Clear();
    5 d4 S) K9 u' G' g# Y- t}8 s5 f+ O" Z& O2 G1 J4 b
    template<class ElemType, class WeightType>
    # w8 [" ~1 M+ s% O* d9 ~. w5 mMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)8 w3 v: P: d: O) D  ]1 d, h3 X
    {$ P, \. }1 S0 ?: S0 J' I% W  v
        vexMaxNum = copy.vexMaxNum;
    : t. L/ I3 n; m0 ]    vexNum = copy.vexNum;
    7 @% Q$ R7 O# r+ K    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];+ b. t' j' g* {* H# J/ L2 [2 b
        arcNum = 0;8 p9 q4 b+ Y7 w9 J1 [! n- P0 B# w1 G: [
        infinity = copy.infinity;6 \, n& F' o- `8 q2 p3 }. W/ c
        tag = new int[vexMaxNum];
    2 T( U8 s% E& J; C. ~( v) D
    ' Z' r2 o$ Y" }    for (int v = 0; v < vexNum; v++)- t  R9 l  [7 R" |4 }# |; B
        {# r- V0 y. l; G
            tag[v] = 0;% ^- e9 B1 ?9 r' i2 {
            vexTable[v].data = copy.vexTable[v].data;
    & I$ W- E6 ?$ H% [+ ~% n, {6 P        vexTable[v].firstarc = NULL;
    ! X2 A0 Q+ c6 Y1 J) t/ z/ n2 z' H    }2 r. h3 ^( Y/ O6 n  m$ V
        MultiAdjListNetworkArc<WeightType>* p;9 Q$ x5 m: t8 `: [% C
    % h9 W  z$ W; I# b* E7 s
        for (int u = 0; u < vexNum; u++)
    ! B8 H8 |: H* m) n3 u    {
    . h3 n' E7 h. \! f  u. k# J+ d        p = copy.vexTable.firstarc;
    : ^7 R! @+ a4 `: E7 {        while (p != NULL)
      e, T4 x) S3 h        {
    8 F, X  u; i% P6 I. p. C5 G            InsertArc(p->adjVex1, p->adjVex2, p->weight);
    . t8 g- W" X* P( b0 h; F$ Z            p=NextArc(u,p);
    4 i2 H; g7 j, H5 K4 H        }
    6 y, K" N9 g7 s' J8 n    }0 B! x. `1 W' I' v
    }1 h# v! R) m0 Z7 Y
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    % Q; a9 e; u+ E' `MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)) P4 l% N# Y; e) x# B9 l
    {
    % b  ^1 y3 z+ }6 k    if (this == &copy) return *this;$ g3 @. V6 h3 a
        Clear();" g$ Q+ |; E" y+ b6 G* Q! S
        vexMaxNum = copy.vexMaxNum;
    + f; z! L) n# R( K% M" S$ u    vexNum = copy.vexNum;
      M7 j2 i$ t! l2 n9 K    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    + @, b1 c1 ^) a% M    arcNum = 0;
    ) j3 \& K: L! Q% O: Q( {    infinity = copy.infinity;
    1 r! X  t; [0 w6 b* S, v    tag = new int[vexMaxNum];
      U: I+ I3 o( _3 v0 u. U/ S7 z( }5 Y
    ! J$ L; g/ P2 w& B" E/ e    for (int v = 0; v < vexNum; v++)
    5 d4 k/ b4 g  O    {
    + A! G* b+ \4 I& S        tag[v] = 0;4 k+ T: y. j  o5 {% n& Y
            vexTable[v].data = copy.vexTable[v].data;5 `2 ?% ?7 Z$ ~& e! D9 e' M' j
            vexTable[v].firstarc = NULL;
    8 U- Z, D. p# Y    }
    % b1 q0 Q1 S7 J- \9 H- {    MultiAdjListNetworkArc<WeightType>* p;, Y% n* W" l* n& P

    ! g& G: S2 g: q$ M; n" r    for (int u = 0; u < vexNum; u++); E4 L: U& P; L+ l' _" b5 u* H
        {
    , Y8 O; U4 ^1 ^        p = copy.vexTable.firstarc;% a, B6 L, L- m$ W! j
            while (p != NULL); l( d2 U+ ?2 N" I3 i
            {' h3 M; H/ ^" L8 }$ m  P
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    , Y# o, ?; L4 z" E2 s" `% P            p=NextArc(u,p);
    7 W* ?* w9 e( e. k7 Y' ~8 z# d7 G        }  y1 T: Q& n7 J2 I0 e& J% Z
        }
    ; [' g) o( G: u* q5 a0 }    return *this;2 `% H) y: Y/ B: \8 |  Q5 v, a
    }% m% C. G' X/ E% X1 ?
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*/ i* L' q: [) F: }- e3 e
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    ) ]0 I+ d. A  L! L{, x% N" |* C+ }' [
        if(p==NULL) return NULL;" }+ b# p' I2 y1 C" A
        if(p->adjVex1==v1)/ [8 M6 U! N( D# ^- `
            return p->nextarc1;& q# l& R, H6 G; k6 t2 F
        else
    0 |9 d; J; K; S% w, U# U$ a        return p->nextarc2;
    3 @; m3 t/ i3 ~" @4 {: S}
    . t, Q- e  |# L  {! Htemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*# x: C6 i  e' k( X/ I- ]
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    + Q5 X7 g: U4 n4 O* n{' }0 H+ C% A* n& t* ~( {
        if(p==NULL)return NULL;
    & I( b+ c: D- P; v" B* {. h    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;6 K7 E3 b+ t1 f9 D
        if(q==p)0 C5 w- j' U7 s; r5 A* |3 P! Y
            return NULL;
    5 d2 p6 K! _0 t4 g, C    while(q)
    3 L' _& b$ x6 U5 m    {1 p$ l9 J8 u3 {  c% ]/ x
            if(q->nextarc1==p ||q->nextarc2==p)
      T9 p" U& F) `% g8 S* V            break;
    $ s, o% \% V' h6 J0 S6 V        q=NextArc(v1,q);  P9 C& P9 i1 S5 X% S
        }
    , V2 L$ q. S: c1 N5 F7 E# P& k& s) a    return q;" C7 l7 b2 l' j- f! x
    }
    ( v$ ^2 L( \5 M" ntemplate<class ElemType, class WeightType>
    ) ~9 \4 z9 Y! D2 n( Svoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)) L! J- x) g  R) ^
    {
    ) w5 R1 s: ?# F) K. a, e& N    if (vexNum == vexMaxNum)
    ' o# J" ^9 z$ d( m. ?$ e3 _  g        throw Error("图的顶点数不能超过允许的最大数!");8 G3 V/ O. Z- Z2 j, r) z5 z; y
        vexTable[vexNum].data = d;
    2 E! O0 a  @: Q$ }    vexTable[vexNum].firstarc = NULL;
    6 K! y% o7 S" d3 I    tag[vexNum] = 0;
    & _: N- e% r4 d& @: P    vexNum++;  g* B, h3 M, F% }: T; `( u
    }
    1 n3 S( C$ Y. g. X& ^" o) Ptemplate<class ElemType, class WeightType>' b; Z* R& Z% O6 L! k3 x% n
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    # [$ @, L+ B+ t0 ~{
    * h: m) ]' T7 {7 }/ }$ L9 [% v& o    MultiAdjListNetworkArc<WeightType>* p,*q;- m4 I) G5 `& D0 ~0 L/ m
        if (v1 < 0 || v1 >= vexNum)% B9 k& w. Y1 p
            throw Error("v1不合法!");
    0 j, }+ m6 }' \  a2 @' U    if (v2 < 0 || v2 >= vexNum)
    3 h. P* i2 I$ q- V" M  L8 T- ?3 ?        throw Error("v2不合法!");' R) L: o. J, I0 p* ~
        if (v1 == v2)
    $ k6 P1 u5 _/ y/ q/ B        throw Error("v1不能等于v2!");3 @& ~& p$ q& ^; G7 W" y* D1 @9 N
        if (w == infinity)# R2 d+ Z2 b. s$ P# m
            throw Error("w不能为无穷大!");* L$ a2 D7 u8 r: C

    3 o$ E; u5 W" D% B' v& }8 k& m4 V9 y( d7 ?
        p = vexTable[v1].firstarc;
    / h9 _" p' X$ H/ D7 u7 R+ O    while(p): o3 }; \# R. j, p: k9 {4 I
        {+ y1 E1 ^9 i7 ]6 {1 j* ]
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中" e/ d  e8 B$ ^8 ?, `, L
            {
    / @: @: ^7 J1 Q2 S( Q            if(p->weight!=w)
    $ m, b7 H5 k- {$ x, B% x7 t0 N+ Q                p->weight=w;; e. ^$ q  a6 [8 i6 s
                return;
    6 f, U+ I/ O" Z6 H3 b+ X        }( A0 L- @. M: l) z. J! l  Z' i

    9 q3 V. c! F# y% H* E. j6 h        p=NextArc(v1,p);1 L/ N' g$ u  S1 I6 b) w! k/ G, W
        }) q0 A1 q* X) Z4 S
        p = vexTable[v1].firstarc;
    * q3 Y& C6 C! x) G; W, C# a5 L4 U    q = vexTable[v2].firstarc;
    " F; Y, S" n2 [: G    vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法$ T/ O& I! y3 ^0 L
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    ) g# q/ s9 g* a3 ]$ N" }9 t    arcNum++;
    6 _2 S9 _9 n" a' U6 `}3 o* a  J& ?1 q
    # s8 t+ l& q* d3 y# ~
    template<class ElemType, class WeightType>" G+ c/ }! M$ g- I
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    " j! Q3 G- W2 ~; t7 h{3 h' _; A) h0 i
    3 @4 \3 M( @; f: o0 A
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    4 r6 w6 s+ m" {1 ?( e( n0 V    if (v1 < 0 || v1 >= vexNum). e- d6 a. b# t5 O4 R7 P9 B3 n
            throw Error("v1不合法!");! r' j; u1 z+ @. j. a8 M
        if (v2 < 0 || v2 >= vexNum)- x3 p6 S; s6 j# n( P/ b
            throw Error("v2不合法!");' U6 r" |$ U0 b$ E' X+ C; J
        if (v1 == v2)! h+ V8 w5 v( [! C+ K( V4 L
            throw Error("v1不能等于v2!");
    ) D. W& {/ v5 i* a; \" z+ T1 R* z" Z
        p = vexTable[v1].firstarc;
    6 K$ m# y; y7 d/ G  V" U    while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    9 x) Q* x( b" f; m0 L    {
    * n% S" k! T/ F        q = p;
    2 r* l/ u9 F3 `0 i        p = NextArc(v1,p);
    # D2 H) N$ h4 y0 N, Y8 b' u    }//找到要删除的边结点p及其前一结点q
    $ W( q! Q$ L& B6 l% J: P2 q' Y  s3 I2 H) J) o
        if (p != NULL)//找到v1-v2的边
    - q5 n$ W( L8 c5 L- r& _) Y    {% h) |, [% c- p( y4 o' [* M
            r=LastArc(v2,p);
    & U# @$ ^. k) P6 g" {1 G, L$ i        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL- _) p4 L) i* T- m2 v6 B4 A
                if(p->adjVex2==v2)  @, f/ s& |1 T7 B* Z) b
                    vexTable[v1].firstarc = p->nextarc1;
    3 f" u# Q  Y  \# c& \$ n, ?! n            else vexTable[v1].firstarc=p->nextarc2;
    . r1 K: _' \' Y, l* |  {        else//不是第一条边
    ( H+ ]# O* F: u& i" i        {
    * y0 R5 F2 o, ?            if(q->adjVex1==v1)4 x. P3 [7 m! |
                    q->nextarc1 = NextArc(v1,p);
    ; U' P9 o: J+ C( @6 [  {            else
    : w8 T8 U4 v! e' H3 n                q->nextarc2=NextArc(v1,p);/ k! M3 O' a5 g. }4 z; T

    3 M2 L- O1 N: b        }+ Z' ~' m% S9 e' M3 ]
            if(r==NULL)
    9 w8 W% z7 x$ ?- I            if(p->adjVex2==v2); w" t2 t4 i# O
                    vexTable[v2].firstarc = p->nextarc2;
    + C+ S) K# J$ u# I' I9 K            else vexTable[v2].firstarc=p->nextarc1;
      A) O7 Y# O3 K9 c# `        else2 X7 ^1 u: O- u5 Q8 g8 S
            {
    9 ~' k- Q# F2 D            if(r->adjVex2==v2)
    , L  k  S& ^% r8 O                r->nextarc2 = NextArc(v2,p);
    ; e3 q% H6 k* t, {            else, Q  t& n3 `6 t( f/ ^
                    r->nextarc1=NextArc(v2,p);
    . Z) E. L! j$ D* b% ^6 M% M5 N3 e! X        }
    / W; Y8 W6 A9 \9 H        delete p;3 A& d% G+ ^  a  D. p7 s  l
            arcNum--;
    # j7 J( U! ^+ e8 Y# u    }+ q) x7 Z2 p3 b) E

    # S' D" W. P. q3 t% k}/ N$ P3 C) P1 a* R+ Z' c& Z
    template<class ElemType, class WeightType> void- B, Y: f, p0 M$ B+ a
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)3 W! t) a) k: j  B( K( p* I
    {
    $ g& {% ^' H. k7 t    int v;
    ) u, {7 h1 H% F! U4 e    MultiAdjListNetworkArc<WeightType>* p;( h% `5 N, L3 M" y/ `
        for (v = 0; v < vexNum; v++)//找到d对应顶点. D. {+ k+ _/ w- u+ `
            if (vexTable[v].data == d)
    : ^$ R& F4 d0 V- s0 g% V3 R, q            break;
    * T/ C$ v0 Q1 {" E8 \; ~    if(v==vexNum)& A6 e- V1 b1 ^1 Q, ]
            throw Error("图中不存在要删除的顶点!");
    1 c: ~0 t, A5 Q) ^' f2 d7 y4 d+ f
        for (int u = 0; u < vexNum; u++)//删除与d相连的边* m* F( u* I; `" X7 `
            if (u != v)
    8 E+ Y: x% }) w" W        {
    + P* T$ ^5 f9 ~2 ]            DeleteArc(u, v);
    ' O3 H+ o! d8 @9 j/ Z- ?) a        }. G' F2 m5 m5 D9 C
        vexTable[v].firstarc=NULL;3 r1 ^+ n3 @( ]! R

    % }8 v3 h. Y1 y9 O. E  z" D4 k    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置, L8 ~7 L# u* C) }% @0 t
        vexTable[v].data = vexTable[vexNum].data;
    $ y" e, K' e& m0 s    vexTable[v].firstarc = vexTable[vexNum].firstarc;) f& \4 A! M6 e0 W1 z8 g
        vexTable[vexNum].firstarc = NULL;
    ! U) X+ Y- U4 ^% K- ?" J    tag[v] = tag[vexNum];9 Q* _% a3 O2 M: v
        //原来与最后一个顶点相连的边改为与v相连8 v( ?, o, G) B( N( X
        for (int u = 0; u < vexNum; u++)- a8 p- r* N& J1 O7 e5 l
        {
    & a1 h8 X5 N, ^4 e& Y1 i" ^* M8 f        if (u != v)
    % E/ l( a9 N) s% e7 N6 z; ^2 @        {
    ( R0 I& X5 T0 o! D            p = vexTable.firstarc;) X) @' O4 x( ~8 K
                while (p)
    ! W2 T' M$ W0 d3 ]5 k5 w2 l* C* g            {6 R% Y+ _5 i. I% J
                    if (p->adjVex1==vexNum)
    : p" R0 `7 j9 J7 P% H                    p->adjVex1= v;0 h, ]% ]; b: h0 F( \% a: Z0 y
                    else if(p->adjVex2==vexNum)( o3 O4 M2 Y4 p9 w& E3 ~6 g
                        p->adjVex2=v;
    ' y, q7 _6 s, O5 i                p = NextArc(u,p);
    3 t7 e, f+ r( k! z$ @, a            }
    " `' m7 B. P1 C$ ^8 Y* s        }' V5 {4 J2 B) p
        }
    8 x2 D% U) a5 R  Z}
    1 c3 y. C* t, _1 O. K///深度优先遍历9 L  C7 q! P" }
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v). m2 n! m: Q1 x' p
    {" }& l3 X0 p+ H8 |, v- @
        tag[v]=1;/ a# q6 y' Q+ j. D8 Z' s
        cout<<setw(3)<<vexTable[v].data;
    0 u+ P$ Y' b! H6 c# r    MultiAdjListNetworkArc<WeightType> *p;
    % i0 k  T' u5 w4 M    p=vexTable[v].firstarc;
    , o! ?' n. L6 T1 k* T3 s6 J+ e1 W    while(p)5 p& b& N1 j6 w
        {
    3 W' ]1 C2 D) F' E        if(tag[p->adjVex1]==0)  P. I4 N4 v; ^4 t. }
                DFS1(p->adjVex1);
    4 M; r% X5 G6 ^        else if(tag[p->adjVex2]==0)
    8 j' I2 ?( f5 F& Z0 R0 {            DFS1(p->adjVex2);1 E9 |" U2 J; k$ ~
            p=NextArc(v,p);
    ' X9 M) o/ H9 ~$ {3 T    }
    : k' G' v1 T3 l3 y( v2 |}
    9 A" Y+ N( l5 ~; G& @* u+ Jtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    8 \- y# D0 P* s4 R{5 [4 N9 P2 A" l! P9 l* {
        for(int i=0; i<vexNum; i++)
    ' ]( f- d7 f+ s2 ~/ ?; v  w$ f        tag=0;
    + ^- r7 D" v- o/ F    for(int v=0; v<vexNum; v++)
    3 B! ?# G9 F/ E. D0 w    {
    * }6 B6 L1 ^/ c- H4 G; i! X" w5 u6 s        if(tag[v]==0)
    ( M! W! `2 }/ ^1 u& f            DFS1(v);
    4 ^+ r9 ]0 E. E4 Y    }; A! D2 d! Z. |9 Y
    }
    ! ~  b, `' ?. f& |. rtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()1 b& _3 A  w$ Z& Y$ q% ^
    {+ f! T3 [/ V7 A, o  Y4 D
        stack<int> s;
    4 J( K0 \5 w  O6 V8 z" N    int tmp;0 p5 W# C; o. G# i" w) N
        MultiAdjListNetworkArc<WeightType> *p,*q;* _: j. P* n. Y8 r
        for(int i=0; i<vexNum; i++)
    9 d+ W9 v/ [% U+ t, L( J. S9 t        tag=0;4 m* [( @! G" m9 }, W
        for(int i=0; i<vexNum; i++)
    + M9 X* a+ p" E: E; w8 u  c# I    {
    4 p* M" h. V. h) H9 a! m! E  S4 `        tmp=i;2 w% R; g! _+ D& M/ U$ Z
            while(tag[tmp]==0||!s.empty())
    5 n- {8 P( ~* {% p        {
    7 V3 `/ `2 \) m; U9 [: r" I            p=vexTable[tmp].firstarc;1 L5 O% T+ q3 i. [" f
                while(tag[tmp]==0)
      B5 n. j! I5 C$ P- X/ Q            {$ y4 ]  J" ?) v& w
                    s.push(tmp);# R$ i3 O5 x# s: s0 q
                    cout<<setw(3)<<vexTable[tmp].data;5 }* t4 m! C- Z  N
                    tag[tmp]=1;
      [8 b# B. e1 p: f" k1 o, y                p=vexTable[tmp].firstarc;
    3 {3 ]0 J, T1 Z& l                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for6 E1 F; Z9 a2 G; Z
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);2 G; X1 P5 i3 [. ]- A  h( }
                    //cout<<" 1st     tmp="<<tmp<<endl;" s* L7 e! B; v: H. P, S
                }- M* X: q  Z% a  |: W2 l/ b
                if(!s.empty())
      w/ ]2 L! [' v! ?% n            {0 Z3 W6 k  y: T
                    tmp=s.top();
    7 V9 r; ?3 c/ h                s.pop();
    6 x/ |1 E) [0 a8 y( a, X4 Z                q=vexTable[tmp].firstarc;
    , V# `2 G( _) \; W" n# G4 M9 m                int t=tmp;
    ) G( |- H9 E2 h5 [                while(q&&tag[tmp]!=0)- O4 j/ Z2 B: G2 H) O) j/ F; d
                    {9 A: Z7 m  @. s1 `0 d/ _
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);; j  ?' a* R. u3 G/ A9 ^. H; \% u
                        //cout<<" 2nd     tmp="<<tmp<<endl;
    - U' b9 _8 a1 E                    q=NextArc(t,q);2 x, `, }9 i! a* K! L2 ]/ I6 G* K
                    }
    # ?# |2 M* E# A  M5 F                if(tag[tmp]==0)
    0 @$ s' |2 [& z- u                    s.push(t);
    9 k  R$ k% X5 e2 q9 {' t% j$ R# l                ///1、对应上面连通分支只有1个点的情况& t( U7 P0 p0 i
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    3 w5 Y% C) x  V                ///tmp要么等于找到的第一个未访问节点,
    * j9 Y2 S+ ^4 u4 P8 H1 F+ w                ///要么等于与t相连最后一个点(已被访问过)( Z% ]! C  F2 G
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点8 z+ d9 o# z- l* j9 ]7 G& B3 i
                }6 i* i( k' F& O
            }
    ( L1 i4 G5 q9 q8 K& H7 A2 |    }
    ! f9 b( h' a2 \# L; Q# ^* i}$ l" {& E! r; ?1 D2 T: `+ C
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    8 @5 O  i5 G+ wtemplate<class ElemType, class WeightType> int0 D( t' z1 ^% E" i/ c! u1 v
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)" q+ }5 R5 b9 w5 d7 m$ G1 P
    {
    * Q0 c) f  s; q) J9 I    if(head==pre)9 Y; t7 c+ T6 I0 {5 l
            return -1;
    . j' [5 m9 R. T9 e! M1 E, P
    2 C5 d* v6 t' l$ ^3 J$ t0 v    MultiAdjListNetworkArc<WeightType> *p;
    " {  L/ W  h3 J6 P* V" u0 q& ^' k    p=vexTable[head].firstarc;
    % n( ]6 }4 `( X0 y    if(pre==-1&&p!=NULL)
    ; M2 B  O1 o" [& c. E7 F" Z/ O+ H        return p->adjVex1==head?p->adjVex2:p->adjVex1;, p. |0 x: I% [" W
        //pre!=-1&&p!=NULL
    2 F3 N  w7 k: R, K$ M( D( e& \    while(p!=NULL): L3 _# [6 F- M' x" f3 e5 H
        {
    5 Q" `; _1 ^8 S, l        if(p->adjVex1==head && p->adjVex2!=pre)
    ; ]) s8 I0 A; W$ g6 N            p=p->nextarc1;) a6 n" F  ^) \. t# s
            else if(p->adjVex2==head && p->adjVex1!=pre)( u$ ]& p) ]6 k) {1 x
                p=p->nextarc2;
    ! ~2 N; h0 K: @. E( x2 o. c* B        else if(p->adjVex1==head && p->adjVex2==pre)
    ' @) f5 W) n% u) J' R9 X+ ^6 b        {
    ! f7 D7 q! f2 p1 I2 X; H' G( Z            p=p->nextarc1;$ v! U7 x1 m# v( K( e1 D
                break;8 a$ Q7 U- a6 L! _$ j
            }6 H, y" L$ r& M8 j& z) M' Z' H
            else if(p->adjVex2==head && p->adjVex1==pre); N! I9 _# T) k2 V
            {
    , y3 S6 [4 W" N) V0 m5 o) R% x            p=p->nextarc2;
    ( Y4 d. y% J8 w" z, n6 N% I            break;1 L5 m$ K% c9 N7 {) U: O  e
            }
    $ ]% R1 l+ e' ?1 o" b  |' Z    }. y* W2 |5 @# l. o) U1 u
        if(p!=NULL)
    $ H5 S9 B, ^7 l4 o    {
    , U- \: p+ T2 V8 Z        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    # N! {% Y& |4 m- {$ @    }/ N# Q8 z$ X7 ^* u3 n
        else
    1 a2 t" q3 B  t! p; r3 g5 N        return -1;- c0 J5 v. f9 q% M/ n5 V5 Y5 B( Y
    }/ R' M3 Q. ?0 C+ w9 s/ v

    2 U- Z/ s& `$ ?  D0 H9 H# n5 W" q4 z2 N( t
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()% v; m( {  A% G( V
    {
    % p. O: Q! ]  \( h; m2 U    stack<int> s;& i2 J) q, f1 O* m0 d
        int p,cur,pre;
    ) {, C6 P/ r, [$ Q% M& H; N    //MultiAdjListNetworkArc<WeightType> *p,*q;
    9 v8 a4 ^; w7 |0 i- ]& e    for(int i=0; i<vexNum; i++) tag=0;//初始化/ U! V1 U( T* E2 R6 P3 [

      C9 n" j1 D4 L+ r4 |# ?7 e    for(int i=0; i<vexNum; i++)
    8 Y5 X6 u! i! R& N) n    {* k- p, ^' y2 {" ]
            cur=i;pre=-1;
    2 B& x  C- w) {& [2 ^% \        while(tag[cur]==0||!s.empty())
    2 c9 `! l& N4 ]5 `. ~        {
    9 N* b4 N: h8 i$ c, H8 K5 X+ |            while(tag[cur]==0)+ Q1 ^3 w( T3 q: [2 f  T
                {
    ' ?/ q$ v; B. Z5 d1 k) [! A$ D                cout<<vexTable[cur].data<<"  ";
    " k- C8 U4 F; H9 k- ?- ~                s.push(cur);0 O" K% x$ }$ z: U  K
                    tag[cur]=1;: w+ F  ~6 v+ J* v( E4 ]+ ?
                   //初次访问,标记入栈
    / }9 q, J" J- C: X$ r- P% Z% q/ o* }' G* j$ l( ]* |; C' [; Z9 F+ ]
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点, l) f, W' M0 V% D. h% f5 I
                   if(p==-1)
      r+ E! T# c/ p  P" [               {
    4 L, y! j1 `9 k/ I. P! I                   pre=cur;s.pop();
    * x7 c0 U, P& J- e                   break;- P$ I' r4 t6 ~# z
                   }3 U/ Q3 p8 X; K* c6 s  M
                   else0 s2 Z3 N/ p( P$ x$ @7 r
                   {( u7 N; J1 s: O7 z  E* J
                       pre=cur;
    % B* n( E: i8 ?% q6 {9 D9 y                   cur=p;
    9 m. w, Y+ t, `; ^8 ]               }
    * ^* _+ G# E  s2 u! D5 e3 r
    ; Q; Q9 H) \& L7 U: F1 {8 C            }
    9 w- w( P8 D; ]3 a            while(!s.empty())
    / g4 z: \0 F9 r' e2 `' W4 p: A" M            {' c" b; K8 N7 u: d( P4 O! N5 N' x5 d
                    cur=s.top();4 ~' m, X  I* A  a5 d
                    p=GetAdjVex(cur,pre);2 [- n$ m! e7 [9 D$ O
                    if(tag[p]==0)
    " Z7 J2 h6 p" d7 ?                {; B1 w" D* \: g- ^8 a0 K1 t% j
                        pre=cur;
    4 _+ Q0 c5 e2 h5 c$ i; a                    cur=p;+ y5 \5 p  Z; G4 L3 Q* N  z
                        break;
    + d1 l  S/ r9 u) k! n                }& N) k: d, [9 U. [! y4 N: Y
                    else) }$ U0 z8 G; z1 Y+ c2 O6 `
                    {
    5 e  R1 S0 G  k  x$ u( N* t                    pre=s.top();: f% i$ a1 l* t1 f+ E
                        s.pop();
    2 V8 k/ ?/ b' R                }8 u8 x% [7 Q- N, }/ ]
    8 \3 a* F5 H  n7 i  c8 r+ ~2 e2 P4 [
                }
    % M& A, v  O9 `9 ^9 o7 s$ y8 g2 Y1 H  x$ ?6 f6 k
            }
    ( p1 K2 \' p8 U& L4 x; g  A! g    }
    7 C# ~1 I- J: _}7 Y& R- c& J2 K0 J# B
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()& o# h0 M3 h; R/ o. B
    {
    5 n" I# y3 C7 w: D4 Z4 s! o" ~    for(int i=0; i<vexNum; i++)1 K  \5 N: S& p9 F
            tag=0;
    6 b. ~' D  }( H; c! n    queue<int> q;
    * L+ o. |  r* U& [: I    int tmp,t;
    - E$ f6 A; n9 J- h! ?1 O0 p    MultiAdjListNetworkArc<WeightType> *p;
    7 a* T% F& d  B* k+ l( e* Y( g2 e    for(int i=0; i<vexNum; i++)
    ( Q5 P, J# Q; W. Z2 @6 m    {
    6 S' D0 o9 _6 ?9 T        if(tag==0)" `" i) k! j1 U& s* X6 H
            {
    / }4 y/ t) F0 p            tag=1;
    - y6 \0 m/ X- F2 q, H% b3 j5 J            q.push(i);
      z  F- c+ s. F- h1 I9 T            cout<<setw(3)<<vexTable.data;
    9 T/ w8 N; c  I4 |& Z1 s9 G        }
    1 i# B- B: E0 _* C        while(!q.empty())" J0 z, I. u4 k( s# A. g
            {9 `0 r- \! F3 Q; q% D
                tmp=q.front();! v* l3 A# o! F8 I( c; L
                q.pop();7 _2 Y6 {1 o! O
                p=vexTable[tmp].firstarc;1 M1 e! t, q! d9 E$ v
                while(p!=NULL)
    3 H+ L# [. P4 n5 y            {- s# g$ b' ~! D* x
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    / W( F  P  J+ `. g' F! ?                if(tag[t]==0)
    + h; f. v- T$ q                {- b6 ~8 g' |1 [+ P4 }3 A6 t  A5 y
                        cout<<setw(3)<<vexTable[t].data;
    & q+ t6 u: k3 t2 U                    tag[t]=1;( j5 r* |$ E' h) }: r& B  ^, R# r
                        q.push(t);
    8 Q3 z/ S! j0 A( {- u                }6 M4 D) s, C% _' h( P- {
                    p=NextArc(tmp,p);1 @8 D' e" C6 [1 S. S, N7 f- ^
                }8 |9 @, N( s  {% ~
            }
    $ W$ Y' E. Y' j    }
    4 i& ]* `1 H( w}
    8 K, |8 @" u! g3 |' Z$ p; f( \' ~8 Mtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    % {) l7 K! f/ H2 E{) `2 f! H- ]: F  b* [
        MultiAdjListNetworkArc<WeightType> *p;
    & b' {4 d5 T' s/ J" ^; N    cout << "无向图有" << vexNum << "个点,分别为:";  A/ k% c; o7 c
        for (int i = 0; i < vexNum; i++)
    5 E! g0 Y0 n1 k$ `8 ~2 ~( S2 K        cout << vexTable.data << " ";8 c- i5 s# C7 y
        cout << endl;
    0 O+ R- e) {; `/ g    cout << "无向图有" << arcNum << "条边"<<endl;
    6 \2 X6 C- q8 U! c+ K' \" H    for (int i = 0; i < vexNum; i++)
    9 W+ }/ Y1 U" ?    {
    / {0 V' g( ^2 d6 m; d9 D) X        cout<<"和" << vexTable.data << "有关的边:";# Q! l1 {6 Q3 V7 Z+ i! d0 u
            p = vexTable.firstarc;' Q! R; [9 d; P5 n
            while (p != NULL): Z5 x9 m' H  X4 R
            {1 B6 t( S8 i, f. c0 K* Q  }
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";6 I. G( B* X8 b9 p, v7 n, ?. ]
                p=NextArc(i,p);& r6 g: X( [+ V4 d' K
            }
    + m' y  R0 w  s1 v* G8 j, ]1 k, ?8 V7 l        cout << endl;- {2 j, j1 _4 F/ H; E8 @
        }
    $ H0 w% b: ?; n0 R" U8 Z}
    ; r% k: M7 t3 b9 a2 e. C
    1 [2 y( h& G  t9 ^" B7 Z
    , P8 ]+ p; l. s; y" v1 Z, L邻接多重表与邻接表的对比/ @7 s/ U! C4 |0 M! z  L' V- J

    6 ^$ U( t  ]' T+ Y" V邻接表链接
    . i' e& a/ k' s2 H& c1 T/ I在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。+ U1 U. M# W' y1 Q2 X5 Y9 a
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    9 Q: A8 q0 c" L% B  z7 K" u9 [为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。, r: D4 G: v% Y* W: e- s, p+ @
    ————————————————+ I- H/ h* }$ d& [% G( n
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。0 B! ~) T# s) S1 R# _1 G
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    ( S" N- W$ K. R, i+ y2 `$ l6 l8 O
    ) A) D, F5 a( S5 y, X" h( Y% p% p# n
    & b, |& \1 A4 V' L2 k

    ' K) |% g; B& @( D' k8 U————————————————
    7 l- N) ]' ]; d/ z' @, c版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。) \/ U9 `2 R8 z$ E
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    0 @( R9 R+ i8 R; c5 l# r, i+ _
    8 g8 [& I# H. M+ z( l: }, J$ C" a2 y6 ~
    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, 2025-8-19 21:56 , Processed in 0.486689 second(s), 54 queries .

    回顶部