QQ登录

只需要一步,快速开始

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

    8 z. Y0 `& {5 G; L. z/ Y. y图的存储结构——邻接多重表(多重邻接表)的实现9 _! D8 P- H9 N9 U; M
    7.2 图的存储结构) t4 S* _) V8 S9 L" b5 w, m7 V

    + W" ?; }5 E- O! _4 L+ B; G/ C7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    % V* a% x% T1 P1 `邻接多重表的类定义
    - \, {8 k/ ?$ p8 I4 u邻接多重表的顶点结点类模板2 V3 R2 Q; p# _- s
    邻接多重表的边结点类模板
    . E5 M& E7 u" Q; W邻接多重表的类模板
    - k$ e) F' R2 m: p& h邻接多重表与邻接表的对比
    4 N- z9 I" R1 V+ h8 ?7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    : P# A& M+ v: |( |$ w+ R/ g$ n+ \
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    5 y# \/ J$ U* s. z2 i) q在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    2 }$ b0 I% p& l6 ~4 X& [
    8 s4 k4 a0 c, G' A邻接多重表的类定义
    : Z! e* [& E  g/ d0 s. g2 A 1.png
    2 k( D, v8 i# e. d8 H% t邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    ! ]9 n' f7 ^7 u- e8 t! x1 V. ldata域存储有关顶点的信息;& f; {3 `6 n7 E! x* Q; [6 H$ Y0 }
    firstarc域是链接指针,指向第一条依附于该顶点的边。
    ; m; U! [* M1 j. E1 i: ]4 t所有的顶点结点组成一个顺序表。

    - M3 w+ v5 B- G0 l1 L9 Z5 O  B
    # c0 l; \- ~0 G! v" W
    template <class ElemType ,class WeightType>
    ' \. |' O2 t: s- R  u; |. u( D; |( jclass MultiAdjListNetworkVex+ y7 B8 H! W8 Y5 [* R
    {
    9 y6 W/ z6 ~+ E4 {; gpublic:
    4 F( J& P/ K* u6 i; w, q        ElemType data;
    $ n! B4 ?& n* s1 S; o' Y0 d7 ]# r        MultiAdjListNetworkArc<WeightType> *firstarc;* `: d' @+ T' J1 L7 o' j* e
    # y% [1 b4 e2 o% g
            MultiAdjListNetworkVex()
    , E7 r$ o+ }4 k5 k$ t, A6 N        {
    # b* e4 g2 `; I3 x5 q                firstarc = NULL;
    * i. D& |/ _& L2 @) w        }3 G  E/ }; M2 s" a/ h( F, G4 P! D% l% W
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    / k" j9 {$ n% R. _% K6 f: c8 J, t* g        {1 \+ R" L9 m4 x+ p8 ~7 c' ^
                    data = val;: P! A7 F+ ?. B7 ~; \# K, S
                    firstarc = adj;
    ; T# v0 k9 C0 ~+ d: C2 ?: a' `9 c1 m: R        }
    " ]/ _  I8 |2 R' m6 q};
      Y8 n7 B/ W" C+ C  p6 Y! j1 k( F7 a$ u* u+ f' G
    邻接多重表的边结点类模板+ _/ h) l" S5 z- G" w

    ' V. }, |8 d7 ~# B在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    ) l1 Q( m" A% T0 y6 J% w' o2 Ptag是标记域,标记该边是否被处理或被搜索过;
    ; C+ }( h7 e/ I8 Y: Z" wweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    ' g* ?7 I) F- h; Ynextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    5 R: _0 m, l4 P" }5 y1 }nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。% i* x6 m5 e0 Y" k! g* w6 z

    - p7 r! y; [0 w. S 2.png
    5 _1 ?( o, f1 ftemplate <class WeightType>
    7 o1 m% E) O5 {6 Bclass MultiAdjListNetworkArc
    ' X) k9 W* @8 X( l{
    - k! W) B# t; o) g/ \8 Z5 jpublic:
    1 T. O. N7 U0 q. h8 j- [6 v    int mark;                                       //标记该边是否被搜索或处理过
    " t, N% l3 @' ~0 a        WeightType weight;                              //边的权重
    : U0 V6 F4 K) c8 ^- a3 V        int adjVex1;                                    //边的一个顶点
    * M, `7 j- G' u) \5 `" F1 p# `4 p        MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1
    " x! x8 n% w6 V8 `9 W        int adjVex2;
    : o5 R+ v+ x6 \! e" n1 g" d. m        MultiAdjListNetworkArc<WeightType>* nextarc2;! o5 u* Y3 ]+ h: L
    " u5 g7 o4 o+ n) N4 ~
            MultiAdjListNetworkArc()
    & \# z/ {# q7 ^! A        {
    6 V7 a! R! o3 N& x  l) Q9 v                adjVex1= -1;
    , y! B* u: |1 U1 ^9 J: J0 M                adjVex2= -1;, p4 s  F& K3 m
            }1 p6 U+ \% ^* k/ z# T6 \% Y" V  K
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    2 M; C2 O, m' @. c) Z; z        {, U( C% U- n; Y7 d7 I
                    adjVex1 = v1;       adjVex2 = v2;
    " |% y# G! C+ p5 `7 B( P                weight = w;7 D  v, L$ ]" Z
                    nextarc1 = next1;   nextarc2=next2;, n+ t! x) b+ p: o
                    mark = 0;           //0表示未被搜索,1表示被搜索过" t, H- R, U1 A
            }0 s' P/ ~9 O( ~% S! a) Z

    ! |6 {5 p1 O! m- y* O邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    4 i( B$ Y# R, w& u3 I* Gclass MultiAdjListNetwork1 Z. I  H8 }3 e1 A7 D' {, ?: r" X
    {
    ' @3 f% e6 ~: ^9 p# g) Mprotected:
    3 f! H& R. w, z$ t* O3 B! M" N0 D    int vexNum, vexMaxNum, arcNum;
    9 I" p& m0 S. U4 Z: [; Q5 k    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;% r3 m- G, P) W! [0 @7 l8 u
        int* tag;: Y- m: W/ e$ N) I( _
        WeightType infinity;) u# m/ B9 s2 q, h) J
    6 {9 R8 C1 P2 f' X! q
    public:7 \6 |1 I3 s6 B. R) K4 d
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);* u6 @, M0 b% T4 s2 }  X4 i5 w& ?3 H
    - a7 S% [9 R. ?3 U) ?; R, @3 f
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    ; G4 s$ [& c. G: o5 ~
    / {9 t7 C+ n2 X$ a    void Clear();
    1 k. f4 W$ g0 t) K$ w    bool IsEmpty()5 E) H1 U0 h1 D, C7 `! O8 Y
        {: ]  W$ @+ s8 b# _  _
            return vexNum == 0;
    8 l) C7 f- u+ O9 ?# \- [+ X- X. N    }
    4 d! A1 U8 X+ z. t% E    int GetArcNum()const+ e5 n; i& C  b3 l1 z- S
        {1 u5 i! g, K" J6 ]1 ~; f7 k2 K. z# ?
            return arcNum;
    9 \0 L) `) |5 _    }8 G7 Y2 N7 C7 U9 x$ Y& B3 g
        int GetvexNum()const
    8 x$ R$ b$ T9 X4 l6 O    {! R  R$ z4 z" g: j7 z
            return vexNum;
    & _% N% y3 B$ O. p* O' X& Q    }  l6 W: R2 P4 V" V- F8 W

    ( F$ h) j% m) t8 O7 r; F0 U8 A8 b9 o1 X; l8 u3 x, C5 N
        int FirstAdjVex(int v)const;
    . n: ^6 J6 [4 c' k7 z& f    int NextAdjVex(int v1, int v2)const;8 P8 r1 g; b+ F" e% C0 K
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;$ }1 a7 w. F* s6 f
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;: z; ~6 f- Q- P& B
    1 K6 ]6 W+ A' }5 e
        void InsertVex(const ElemType& d);
    / k: I" U* C0 W# \    void InsertArc(int v1, int v2, WeightType w);8 W9 z9 i/ p9 Z# d% ^
    - G7 f) s+ p  m0 l  X7 y
        void DeleteVex(const ElemType& d);$ C; [# {+ t, ^# s
        void DeleteArc(int v1, int v2);
    ! v3 \6 J& G" g3 b5 ?6 F  V; j& b
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);7 ~! g3 u# W2 n/ ~- T! e# i, h: i
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    % g6 X9 H  G# C& i2 ~9 x- b1 I6 |# @& ?* A) M3 T
        ///深度优先遍历
    - R3 U2 a: J: [* D$ f0 S$ w% q    void DFS1(const int v);
    1 k# R7 j" j$ F, H& E! X; P    void DFS1Traverse();
    2 d8 {- H" |4 M; K. H% Z    void DFS2();; ]6 I2 P, {% F2 c
    : {, e; w# \& Y; |  Y# b6 w5 f
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    # O8 I$ _. I% [& i0 Z0 ?    void DFS3();
    : G8 [# M9 `, n: R+ G  Y" q$ X, d% b, z5 X6 ]% s
        void BFS();5 l5 f) @  X9 x# Y8 X
        void Show();8 s- c! t; M. `  D' C1 }* E! [$ O  M
    };' Z7 ~$ R& E- b* x, ^

    / J4 b# t6 F7 q* b: J2.函数的实现+ \  }6 i/ D8 ^5 t
    研讨题,能够运行,但是代码不一定是最优的。
    9 A% A" j8 r; z; C  b# a  N! c
    9 e( R7 }0 x0 W% p/ K5 ?#include <stack>
    9 u2 ^7 \. A! h#include <queue>
      _  ?6 R) k: U$ ^" F! W
    ! I8 K- y+ z5 ltemplate <class ElemType,class WeightType>2 }! b# [) m; J# Z& I' V
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    , L" P4 h2 \% ]& l) @+ S{
    ; f! l0 u' `: Z2 E. ]! a7 }+ r    if(vertexMaxNum < 0)  ^& j& o( B8 O7 i; j7 O* |' t
            throw Error("允许的顶点最大数目不能为负!");- h; i& `% J! [  ~& I  a, l1 T# @! C
        if (vertexMaxNum < vertexNum)
    / x  D4 k: d% w6 y6 i3 e        throw Error("顶点数目不能大于允许的顶点最大数目!");4 w3 m; ~# N0 v  _- O
        vexNum = vertexNum;# f: c" a, Y  v9 ~, q
        vexMaxNum = vertexMaxNum;
    ; r" f3 T' D) N0 B2 |/ p2 o, r, Q" h9 |    arcNum = 0;$ D$ c# F0 [  B9 |* \( F$ Q
        infinity = infinit;8 ^' J$ f# |( Z: S8 G
        tag = new int[vexMaxNum];' ^3 ]9 P% P3 c  p' \
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];: h8 L5 C- N/ \) b) Z- B! d
        for (int v = 0; v < vexNum; v++): H6 M) C; |/ O5 Q
        {% B7 Z0 G4 e( m. T2 [
            tag[v] = 0;" I3 J& x; j; L! X7 \7 d) C
            vexTable[v].data = es[v];
    + z7 g2 W" O- K* ?: X        vexTable[v].firstarc = NULL;
    % \. I% [" @+ p) e% i( L    }0 S/ U$ n, k& ?3 ~5 t
    }
      z. G6 s+ D  K- xtemplate <class ElemType,class WeightType>
    1 [9 z0 C  W6 |+ y' X1 AMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)9 Y! K. |1 M8 f- T* z
    {7 O$ j" v3 o* v2 ^
        if (vertexMaxNum < 0)/ G4 U8 [" X4 |! |; N
            throw Error("允许的顶点最大数目不能为负!");0 Z+ A  R2 M7 u+ @6 B- Y, Z/ t
        vexNum = 0;" K/ @7 o' |- ~. S3 Z: V
        vexMaxNum = vertexMaxNum;" j( y7 S+ V9 E# s' H+ ^
        arcNum = 0;$ H; z: m# [1 w' M) Q9 l0 Q1 a
        infinity = infinit;5 X( s: A/ O+ r) v
        tag = new int[vexMaxNum];( a  m# G+ ?; m
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    5 e5 s4 ~  I% {: Q/ \# N}
    ) F' h( I0 B* N6 T# x7 P# B9 Ktemplate<class ElemType, class WeightType>2 a/ O7 }: U3 L( f" H& b
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    & l' \' ?  R4 O/ V# A& W{, n! s1 y) R8 @$ M5 C$ D
        if (v < 0 || v >= vexNum)0 ^$ D2 W& r! N! i9 q
            throw Error("v不合法!");
    - v  o, g  k1 X1 m  B0 x( i    if (vexTable[v].firstarc == NULL)) s, {& x( P; ?' E
            return -1;
    . T, ?/ k; L' p0 l+ D9 T! Y    else  h! m" D% w0 h, }- ?
            return vexTable[v].firstarc->adjVex1;
    + W  v  L$ d! c' R}
    ' O& j* N: A' y0 U( L1 @. A% Y7 y0 ^) e4 T3 w- q8 V+ ~* l7 Z
    template<class ElemType, class WeightType>' |8 M6 t! S& q2 K
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    $ ~- N6 Q  ^3 T# k; ^{
    * i& C; C- L: |) x; ?    MultiAdjListNetworkArc<WeightType>* p;% K" v0 B& S$ P1 T
        if (v1 < 0 || v1 >= vexNum)
    4 b( T$ }) E3 L4 s+ E        throw Error("v1不合法!");
    5 A  e0 V7 y4 c* O% y  M3 c+ E    if (v2 < 0 || v2 >= vexNum)
    3 y/ Z# F  O9 R        throw Error("v2不合法!");; d  m$ O# _1 x9 \' V% O
        if (v1 == v2)3 Q( ?* r: J( `, d# ?4 f. a
            throw Error("v1不能等于v2!");
    ! ?) @' u; W; s    p = vexTable[v1].firstarc;
    + K1 z# Q6 d" v4 d    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    + w' h* g# w3 U! i  V# a        p = p->nextarc;6 @9 ~" c$ ^% r% r2 |
        if (p == NULL || p->nextarc == NULL)
    4 Y7 n/ |( u; r0 |7 p! ^8 E        return -1;  //不存在下一个邻接点
    $ g+ J# K/ ]) P- U( W    else if(p->adjVex1==v2); v4 v9 J& \* ~) S; k
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);( E, p2 v, F( j1 Q
        else
    1 v( n# K6 c4 {4 ?% u+ r& t4 \        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);% Q" D6 Y% q2 {, T+ z* M
    }) b( G" n' ]: w5 m2 Q) V
    template<class ElemType, class WeightType>
    + W  P( D( ~8 Q# Ovoid MultiAdjListNetwork<ElemType, WeightType>::Clear()5 a; a+ H2 N5 z5 x# e6 D* n9 M$ c$ V
    {
    ' ]: X( n* K' `+ M0 n  \6 O    if (IsEmpty()) return;
      P0 c1 K& x1 e7 U+ F3 l: X    int n = vexNum;& {- Y9 U2 w8 q$ `/ ]/ Z/ E
        for (int u = 0; u < n ; u++)8 |' D9 M6 _- q3 e
            DeleteVex(vexTable[0].data);
    + n4 F: F3 i5 [: ~9 o3 [$ ~    return;
    0 F7 C( H; _# B% t) N}2 \5 c+ t, n5 Z2 B  {3 H% e
    template<class ElemType, class WeightType>- J* P" B& @- S; r
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork(). R3 a+ X4 A* z7 c8 b. f8 r
    {& I  }4 ~1 l" h3 O. ^
        Clear();$ F  ^1 S* [: i) Z0 Q( V
    }
    4 \% B% _) r1 O& l5 o) Mtemplate<class ElemType, class WeightType>; J1 M/ z/ {8 ?/ t1 \9 p9 ~
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    & D2 H5 F& z% h: P{
    & w3 b3 T4 f8 \) i) i2 g2 f    vexMaxNum = copy.vexMaxNum;5 _8 U' c1 f1 `2 m$ V+ }
        vexNum = copy.vexNum;) N7 B7 ~2 K$ {6 P% p: w
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];; ?" W7 z% C7 l+ l- [1 v
        arcNum = 0;( r% k. n$ E6 m2 u5 W. @) E
        infinity = copy.infinity;
    1 s7 r& {! {/ @& s6 }    tag = new int[vexMaxNum];- Y6 d% c% X& @8 I) p6 u

    . I. ^- `) A. o0 c" u    for (int v = 0; v < vexNum; v++)+ l& w! e+ y" F$ l9 Y
        {
    1 G5 r; r3 m+ A$ I3 O        tag[v] = 0;
    7 d) G" e8 _8 i/ l) q        vexTable[v].data = copy.vexTable[v].data;6 W( ?0 W; ?" d: ~% J5 q
            vexTable[v].firstarc = NULL;' }$ I" g+ q0 A2 i
        }# J) L+ i3 {) c
        MultiAdjListNetworkArc<WeightType>* p;
    / J9 y. y3 i& x- l. B! b8 `! f; K  m3 {
    7 j  D: ?2 ~6 s9 P# n9 D    for (int u = 0; u < vexNum; u++)0 u3 ~5 P# }7 W5 U+ m3 D
        {
    ( G4 Y( R' i) r) q( z        p = copy.vexTable.firstarc;  T. K+ z7 u/ W4 M$ W/ S
            while (p != NULL)* O4 z& b1 G( ^4 ~0 P
            {
    $ Y% Z  x6 @: r# @% d. V            InsertArc(p->adjVex1, p->adjVex2, p->weight);+ G. h1 W5 K* H! A! g  c' v: e
                p=NextArc(u,p);4 }. i0 n1 z  ]) }2 u8 a
            }
    9 `/ o) Z2 }( p/ ^! ]    }# b7 S. S$ X$ S6 B% j5 _% @8 Z
    }
    " ?$ _/ i5 p, W& Ptemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&( k/ ]: X/ \- U/ x) ~
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)% l) |' R' w3 G0 D1 A
    {
    2 J" y1 ], E/ ?; ?+ C8 A    if (this == &copy) return *this;7 T+ R: J; p$ o' r0 A! U
        Clear();7 ?) t( [" t9 h/ H; v
        vexMaxNum = copy.vexMaxNum;/ m$ O) W: K- n  B# @8 a) R8 v) j
        vexNum = copy.vexNum;
    " h0 E2 F) D/ \1 Y3 W    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];& x! G( L( e3 R7 I
        arcNum = 0;0 P0 e+ E  d/ z. m# m
        infinity = copy.infinity;
    3 k3 o8 s+ [. v7 v; [7 d1 q& z& |    tag = new int[vexMaxNum];
    9 A2 _# k8 k2 F( w& g' |0 U( [+ P0 w0 P) e9 w5 p) i
        for (int v = 0; v < vexNum; v++)8 j9 X" I4 u) G$ @: t' t5 W! F
        {
    , a; Q) ^/ l; r% r/ }; G/ C+ o        tag[v] = 0;
    0 V7 f" I( h: W6 r2 N        vexTable[v].data = copy.vexTable[v].data;
    8 z# K5 _  I% Y        vexTable[v].firstarc = NULL;! O1 H: t7 f) ]9 k4 c, h5 m
        }; Y5 b* D* ~9 h( {' a( e9 U& N3 J) }7 O
        MultiAdjListNetworkArc<WeightType>* p;
    $ G4 ~* O8 ?# @: G
    - f/ C' m$ O5 k    for (int u = 0; u < vexNum; u++)1 y5 f& L9 ~  X+ g
        {; j) S  u+ t+ X* e
            p = copy.vexTable.firstarc;
    9 H. N) D5 {' e        while (p != NULL)4 ]$ d; R4 i3 z
            {1 B# B; {+ [+ n
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    ) }& f+ i: w& {, ~# A            p=NextArc(u,p);' H' x8 B0 h( C
            }9 t2 X: f5 r' g7 }( _- }$ M( @- I; z
        }
    ; M) ]$ S8 P' g! y/ p- x    return *this;! F6 m- U% d. e4 ~2 \- y
    }
    9 Z7 i/ }* L: \" i, c, [2 g! Y" ~' L/ stemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*/ |( q" ~& t. U7 _7 D
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const1 U7 Q# c" n1 n9 j3 a. e2 E* d
    {7 h; q& I. z' x$ W* l
        if(p==NULL) return NULL;6 ^. a# @2 T& B: m2 S3 J
        if(p->adjVex1==v1)
    3 U, j$ s4 q# u* n" W/ q1 T0 ~        return p->nextarc1;1 ~; O; q# L" j: n$ b  Z+ S6 m
        else
    & O4 D# {3 f5 y8 [  _+ L        return p->nextarc2;
    ! m/ D& V2 j* x" P}* {4 v/ `% H. f0 U5 c5 B
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    2 v; B" H' }; h: s: a+ r" u3 AMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const) g3 E% ~4 S/ Z
    {
    / |5 u& y$ l6 p8 ^; G, w3 ~9 u( m& s0 u; ]    if(p==NULL)return NULL;9 _; N2 C) Y1 J/ B" i
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;, n& A. o) V. O2 P
        if(q==p)
    $ J2 [$ h3 U3 k6 Y! D        return NULL;
    / q% ?% d9 t: G9 L3 ~    while(q)
    * G# ^5 v/ j% u9 U    {; y, l- o6 [1 v5 {' C
            if(q->nextarc1==p ||q->nextarc2==p)
    ; r8 m( V: l! p7 K  D            break;* s0 v  C# T; G. F: [3 n# [: A
            q=NextArc(v1,q);
    0 |1 {2 @. |4 Z$ {" K    }, D( X4 [! S/ e) ~  ?; ]* A
        return q;
    * ?0 n7 l$ _, ]4 p& @8 Y}, c5 U% Z- w; X8 h9 v9 u- E
    template<class ElemType, class WeightType>. u$ A9 i* ]/ N5 D# E% X) s( b( H$ g
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)2 D6 f! u5 e' s- L7 ]
    {0 D9 O; J; T, s( a1 Y
        if (vexNum == vexMaxNum)
    , M9 x9 @: w. o- _* u. C; i        throw Error("图的顶点数不能超过允许的最大数!");
    ( f+ a& G2 t- [. B+ x    vexTable[vexNum].data = d;- u) B* w  @7 C0 l' n
        vexTable[vexNum].firstarc = NULL;8 C; f0 g7 {& L5 _/ D2 [. p' [- i/ _
        tag[vexNum] = 0;+ W, X, ~' [  K. F/ W% P
        vexNum++;
    . d4 y' @7 G0 {2 `6 U- D" @}5 l, a8 e' `) [  u7 h  l
    template<class ElemType, class WeightType>
    , G* v5 Z# c5 {void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)- K. V+ m* C, h7 o; h( |
    {
    ( l9 F9 r7 ~# s2 [) U    MultiAdjListNetworkArc<WeightType>* p,*q;
    7 M5 W4 E( @+ V( N* N    if (v1 < 0 || v1 >= vexNum)
    3 h" k4 A. C9 {        throw Error("v1不合法!");
    ) P: x5 q2 T, A3 s: i    if (v2 < 0 || v2 >= vexNum)
    , s" L8 Y4 E% ]2 B9 C        throw Error("v2不合法!");6 i+ y8 j; ?0 L) |* t
        if (v1 == v2)
    - F4 N3 r! f3 Q( A8 K! t        throw Error("v1不能等于v2!");
    ' k) q' B. O! t4 p. I    if (w == infinity)
    9 ]0 o: n$ ?- I! i1 |5 `6 o        throw Error("w不能为无穷大!");
    0 m+ r9 N2 B" R, i4 @- D- N5 M$ |1 d, c' X

    9 N* ?& R4 d# F7 f$ A- ]4 ~! K! E    p = vexTable[v1].firstarc;; }% v' O; ?4 _1 K) I
        while(p)
    & c4 ?0 S8 K" w0 }' F    {, s. C1 E" }9 z/ @9 `1 b1 }
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中* [* R2 |# [8 x' l1 o
            {
    2 `) f+ A# @9 f            if(p->weight!=w)
    $ E0 @! r) t  |# R, D                p->weight=w;, g2 Y  U( v7 v$ g* X2 g% V
                return;
    4 q+ \7 Y9 C9 B        }, f. ?6 c: h) k8 `4 Q' }

    ( B! F/ y/ t4 y. @. L        p=NextArc(v1,p);3 y6 o' A% _2 \% x" X* w% B1 u
        }8 @: ^# \! C  _& R
        p = vexTable[v1].firstarc;
    1 M+ ^" g7 s& W) x- V0 d( F) Z    q = vexTable[v2].firstarc;7 J6 O0 Z# J+ A0 `( L; V
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    + K. o8 T* Q' L+ h: B    vexTable[v2].firstarc =vexTable[v1].firstarc;- \8 W) x, \4 d
        arcNum++;
    % \& q6 }5 D3 |/ P! _" U/ T0 D}
    1 V) `  g& S- }* y& P# Y" V. L0 k" F& j
    template<class ElemType, class WeightType>: k% W) d+ P/ ^8 `- j
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    8 O* ^+ O" O! z# N5 s6 \$ H1 T{/ U2 W. i, c# |9 ~5 T. j- l4 m/ \
    4 [5 @9 P! R& s- V0 s3 z, m& [( h. e
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    ' W( a4 j$ G1 k    if (v1 < 0 || v1 >= vexNum)
    ( o  J  I9 X) Y! E/ T+ I3 r3 v        throw Error("v1不合法!");  P5 Q4 Y3 I2 c) }3 O5 [2 T+ I8 w# L
        if (v2 < 0 || v2 >= vexNum)4 u7 }; J& z0 c, g) N, F4 y9 A7 j
            throw Error("v2不合法!");$ v3 Y5 n  V, c, {; V& _
        if (v1 == v2)
    ! ?1 I' ?! R: \4 z; @* E4 ?        throw Error("v1不能等于v2!");
    ( u% p( m6 Y) u) u& Q/ w: b# r# P; ]# _7 L. q; g6 x' U
        p = vexTable[v1].firstarc;0 B/ m& C3 \& y4 Y
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    . U3 R9 d. P$ G  O( C    {8 H+ d- a+ k$ j9 \
            q = p;3 g2 W! {+ i1 W
            p = NextArc(v1,p);
    ; }# W' y1 m9 W1 E! K3 m    }//找到要删除的边结点p及其前一结点q0 Z  z5 W4 S. A7 j

    ; S- z  p! O- o  |1 ~- `1 P/ P+ k: Q    if (p != NULL)//找到v1-v2的边
    - X1 F  D  }1 O5 n    {
    - ?0 i9 P" H6 Q3 i8 t        r=LastArc(v2,p);
    3 n+ Q* y! t% ]" H9 e& i* v        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    + j( ]  o+ D$ g1 T- H0 X. e            if(p->adjVex2==v2)
    5 i5 E1 T" y- w4 Z: U: y. ~                vexTable[v1].firstarc = p->nextarc1;* W; n" v9 ?# r4 x( [, X
                else vexTable[v1].firstarc=p->nextarc2;; o. J2 D2 n. }! Q# z5 }- N' b
            else//不是第一条边+ s1 P1 j3 e4 A8 {; A4 {. G) o2 p- J
            {
    4 @" ^0 ]7 ^: Z/ N& P0 X' n: \4 _            if(q->adjVex1==v1)! h/ E. `1 s2 @: `. w
                    q->nextarc1 = NextArc(v1,p);8 c+ @3 G3 q7 P
                else
    9 H: P& y, A, i+ F, c! l                q->nextarc2=NextArc(v1,p);
    1 F- d; |. Y( Y" l  {0 _# M' t9 R  E" o. Z% {
            }  C+ k4 x* m. X7 B9 C; c
            if(r==NULL). m  x" e/ y; K% S6 M
                if(p->adjVex2==v2)
    + e8 Q+ H! ]( _1 O) V* F1 n6 o! u                vexTable[v2].firstarc = p->nextarc2;. M4 Q9 I( o, t2 ?- d
                else vexTable[v2].firstarc=p->nextarc1;
    9 y) ?* @' c; h: Z4 x        else- u# l5 _  j; L. k. j; g
            {6 {8 |8 c. \; D; G0 p- q' E* W# b# ~
                if(r->adjVex2==v2)
      Y' X5 U) X+ @( n% o                r->nextarc2 = NextArc(v2,p);0 t- v' J: x& G& p" d0 _
                else
    % R8 U! l: ?. [7 _9 F1 v                r->nextarc1=NextArc(v2,p);% q9 o; @# @3 }) [- s5 T, h
            }
    $ g0 p) H* l1 \/ ^        delete p;: M: m3 e9 m" d$ ^
            arcNum--;5 q, v0 X: V* P
        }
    " ]! d2 Q" H( o4 n7 e4 |% a3 r1 g  [- U0 T
    }5 m+ N$ B  \: @# S* b2 V
    template<class ElemType, class WeightType> void2 l! P, R7 {2 N. B8 l
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    - C$ ~$ Q3 a* T( q- N, Y{
    " [- B; Q; s+ K    int v;# S+ q6 C5 y# R, n
        MultiAdjListNetworkArc<WeightType>* p;& o: ^7 i+ e; I- {7 l0 S
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    - F4 M$ Z: f3 W- g7 B% `" |        if (vexTable[v].data == d)
    4 |) f; r/ k! [5 j' X0 C+ i% @( v            break;
    8 z4 G  G. v+ E5 C' c* \    if(v==vexNum)
    " B- z- s) F6 `) B        throw Error("图中不存在要删除的顶点!");7 W0 q. U+ D! }

    0 V1 r6 _9 S8 u% L- [1 E( R    for (int u = 0; u < vexNum; u++)//删除与d相连的边$ z. D8 `, o+ r$ ]: ~- t# C
            if (u != v)- l/ V' W6 q6 c+ H
            {
    & j! ]. c" c, m+ n& I! ]6 F1 X% b            DeleteArc(u, v);5 _+ g6 a7 e9 C8 s4 y
            }! y4 v# \4 ?9 U6 }5 |# e2 {1 u
        vexTable[v].firstarc=NULL;, X$ n5 W, U# g+ T& p

    9 n9 u- R% B8 }% K    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    1 c; ]! R3 @: X" S/ f8 J    vexTable[v].data = vexTable[vexNum].data;6 ?$ t4 ?, a7 T* j7 A
        vexTable[v].firstarc = vexTable[vexNum].firstarc;
    ! V/ `2 o' @: ~" @+ U    vexTable[vexNum].firstarc = NULL;' I! U' c, W% f
        tag[v] = tag[vexNum];4 Q6 z" g$ W/ l- J
        //原来与最后一个顶点相连的边改为与v相连
    $ G- d* }% r& k) `5 C    for (int u = 0; u < vexNum; u++)9 z. N# g  ~4 C* ^  \
        {
    : }# o6 H( _7 e3 s) n        if (u != v)
    5 n& R9 J3 \6 G3 Z2 A0 a/ R        {
    ' f7 E( d5 t# V/ U. Z- Z            p = vexTable.firstarc;
    , F9 k; t' ~: Z/ M# _6 `( A            while (p)# M# O% ]+ c' T) h& F/ P/ A1 V
                {% O  R: w1 _" v( U4 @
                    if (p->adjVex1==vexNum)
    * r% l+ X: K' \, d% @7 i& a$ U                    p->adjVex1= v;" V0 \. ?7 ]+ G
                    else if(p->adjVex2==vexNum)$ q' v! ~% M, {2 F3 w/ |
                        p->adjVex2=v;- o; @+ D! r; O0 @/ E4 O' `9 F
                    p = NextArc(u,p);" X) I# H6 A, S
                }
    ; J  L3 f( i5 K! L7 i        }
    ' k: r5 [* H$ N    }3 _* w! `( A5 [: J) T9 K
    }
    ' A+ \* R2 ^1 U/ l% Y  C///深度优先遍历4 e& _& l* C3 j/ c/ o
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)9 ^; c; A8 j- \$ M3 X$ F) b1 X0 X
    {; t+ E3 W' I  j1 J0 @- S; `7 S
        tag[v]=1;; K7 F7 K3 z' O, g, a5 T
        cout<<setw(3)<<vexTable[v].data;
    $ j6 P2 d8 c$ ?# f    MultiAdjListNetworkArc<WeightType> *p;
    ( s# \- _0 W6 C; I$ J- @    p=vexTable[v].firstarc;! [. z( V7 Z1 D7 ^) ?; ^: s0 S
        while(p). N( j7 R2 ~$ X- b- j* D
        {7 c$ \) ?% L6 T% D* z: G
            if(tag[p->adjVex1]==0)
    3 I9 X% |1 ~3 }: `6 W* T            DFS1(p->adjVex1);4 S. `+ z. ~8 j: i: U; b, ^
            else if(tag[p->adjVex2]==0)3 U$ J5 d6 O6 N6 d" p) ^0 S) {
                DFS1(p->adjVex2);
    & p6 }, v  E. |& ]        p=NextArc(v,p);
    4 S% s. F+ K) W& j" R! X    }
    & |7 ~+ J0 \) {3 p( T! ~! U; b9 Q+ F}6 Y# T/ O: m. g+ L
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    ! d' r& s  [' ]' a2 O{
    ) c6 n/ n  }2 Y) u4 k. A    for(int i=0; i<vexNum; i++)
    $ p( r7 b; p6 }        tag=0;4 c1 E$ @8 Y) R9 i
        for(int v=0; v<vexNum; v++). C% U. `0 C1 A  E  s
        {
    . b' D1 b& s. |$ u1 [        if(tag[v]==0)
    ! H1 R/ u0 v8 w2 L& g9 r0 O            DFS1(v);
    ' D3 w5 _2 b3 j    }( V, L) Y& E* W+ c
    }
    4 S1 T4 K  c% L: Q/ I- |template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    - \) L; ]/ `5 \$ L: ]3 Y{( X. X0 A, l9 L
        stack<int> s;
    , I1 {% A) Q. f# X7 i+ z    int tmp;8 j5 P; _  ]8 h. u  I  {) s
        MultiAdjListNetworkArc<WeightType> *p,*q;3 V/ ~% ]2 \. o0 I  I* n4 `
        for(int i=0; i<vexNum; i++)9 A1 O. g1 ]0 r: c, \
            tag=0;7 O% y2 W/ {% y: a0 |
        for(int i=0; i<vexNum; i++)
    + j. K+ r, g8 [7 L2 C8 A    {
    7 Y1 D7 P, ~8 O) |. I) {' X# I" ^        tmp=i;# J+ ]3 S3 C9 t) d  y: Q/ y4 @
            while(tag[tmp]==0||!s.empty())% H' j, r# u/ K7 j( T8 g
            {
    % Z1 D4 D1 p" U6 M/ c$ A. Q            p=vexTable[tmp].firstarc;! C+ t0 D/ m7 l' |/ {, ]
                while(tag[tmp]==0)+ d$ y* Z. B) Z8 M# q6 b; Y
                {8 C/ ~5 b/ E2 ~: s9 t
                    s.push(tmp);' C# D9 X6 z2 |6 H- ^# {. T
                    cout<<setw(3)<<vexTable[tmp].data;6 v1 y2 |+ i* k
                    tag[tmp]=1;) O! p5 h9 `2 w5 J/ f. \5 R
                    p=vexTable[tmp].firstarc;- h  B! U& K* }& R  b
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for$ O+ b( |1 }" r9 q* O( S5 D
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);- l) m( \' W  N
                    //cout<<" 1st     tmp="<<tmp<<endl;" s; z, U0 t* Y! O5 U
                }
    7 F& U1 F- e* Q* }1 n) ?            if(!s.empty()): T+ h; ~/ X' n' p
                {/ _3 ]% g5 k" G$ O% K$ z- x
                    tmp=s.top();
    0 [' @8 s+ p' i1 w) a                s.pop();
    : m) k0 g* C5 I6 |+ p6 F2 c, b0 N6 f' q                q=vexTable[tmp].firstarc;- S9 K9 @/ m+ j$ i0 M
                    int t=tmp;) W6 W1 s. \' i4 N
                    while(q&&tag[tmp]!=0)& ]4 }  V" o0 w) R* D
                    {4 U, f7 e! R# L5 O
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);" l. W6 P8 h% Y9 ^# q
                        //cout<<" 2nd     tmp="<<tmp<<endl;  K- @; y8 b4 I( S; A
                        q=NextArc(t,q);
    0 r% @/ u, X, ~: i( R9 _  L                }1 O1 S6 H7 o, R7 ]
                    if(tag[tmp]==0)
    ; T: x/ c, ?. N- y7 c6 C                    s.push(t);" @7 F9 Z9 M1 F% N$ E
                    ///1、对应上面连通分支只有1个点的情况
    5 r4 L9 b6 q" F* h                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈, {6 B: s; M8 g: ~% h+ ^
                    ///tmp要么等于找到的第一个未访问节点,
    - \+ T- O0 U" Y: D/ U  z                ///要么等于与t相连最后一个点(已被访问过)
    - e! h3 U9 M) @2 V" W. z; Z                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点3 Q# A. M+ I  ?$ l7 c3 ]
                }! l9 g( ]* z  P. S) D  m7 W
            }5 e0 N" b; j1 Y
        }. Q& [! q: a/ C6 p9 b
    }
    ( P* S. d. ^3 E, O+ E- X% X- F//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1) W( u. j. Z- {. ^7 G
    template<class ElemType, class WeightType> int
    9 q/ O: N* I5 {- RMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    $ K' A  L" r' \; T* \. w{
    0 z5 d; T- k2 O3 p3 ?    if(head==pre)
    5 Y7 T3 M& U  U/ c        return -1;
    $ ]! W" Z, V) W7 \5 {- S. F. I
    2 ]% Z: t+ H- B    MultiAdjListNetworkArc<WeightType> *p;
    , z% {5 T( O8 _" Q  e' x% \; i    p=vexTable[head].firstarc;
    - p2 q% o. U/ ?8 t. Z* Q& v    if(pre==-1&&p!=NULL)
    8 x. l% \% c/ d3 s: Y8 v( D        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    7 X8 H; a. J; E1 ~/ C( S7 @    //pre!=-1&&p!=NULL
    ; ]) K: f4 A& z- y3 s! H    while(p!=NULL)/ u; J5 I" h$ ?/ k
        {
    + p# w6 e% h+ ]& H5 H2 W5 n        if(p->adjVex1==head && p->adjVex2!=pre), d2 X  o# Q# W- Z- I
                p=p->nextarc1;
    # i+ ^- x/ Y; {' r        else if(p->adjVex2==head && p->adjVex1!=pre)
    $ `9 y# M8 H: b) \; B  G  j& l7 N            p=p->nextarc2;
    ; j! h3 z! U# D0 N- B        else if(p->adjVex1==head && p->adjVex2==pre)
    ) Z6 D$ P4 J- [, b: [4 Z        {
    , y0 {+ {5 p; p% U  O( {) @            p=p->nextarc1;- b  [* R! i4 R& U7 F9 S6 ]
                break;5 n7 g' r3 ]3 c1 d0 O- h) e
            }
    ; t: Y# N- O- e6 O  ^        else if(p->adjVex2==head && p->adjVex1==pre)
    0 s3 h+ P# i- [0 C) Z  H# u        {
    $ s5 }# Q2 i# Q& Y            p=p->nextarc2;8 d5 j# i+ K! N+ V
                break;* I6 z/ l  b( M: R: k" @9 |6 v
            }
    ' M$ v/ s1 U* v# V  A0 C    }
    2 I( r7 P7 E# c' v! M& a* H' t    if(p!=NULL)
    ; ]. {8 @5 Z( T3 O    {9 j/ v3 x; G3 F) _# O9 @: D
            return p->adjVex1==head?p->adjVex2:p->adjVex1;* J$ S6 [7 i3 M% `: P) C1 e
        }
    & e" n  {: }  {9 z. M, o    else
    5 u4 y- T% H% G( W$ c# Q' c; w        return -1;3 ^3 a1 ^# F3 u. ]! B' F" q5 Y& F9 o
    }7 C2 a& N/ Z* C6 T7 [3 ]

    5 G* f2 j% c1 \& V5 s; Q! e4 m
    ) N) @; u7 }- \- ytemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    " ~& \7 p8 y! I2 s, U5 p' T0 _+ k{6 g! n& |* D% I6 o3 }$ n+ _; [
        stack<int> s;: ^+ Q/ o1 g4 d# }) W
        int p,cur,pre;
    9 E! j) _" s& a0 Y4 ?' ?1 \7 ?1 P9 l9 F    //MultiAdjListNetworkArc<WeightType> *p,*q;5 C% z% {( ]4 J3 ^# a' Z5 h
        for(int i=0; i<vexNum; i++) tag=0;//初始化& j$ ^6 L6 g6 j0 k% L

    * c- `3 o- n- H8 z5 k  R6 y    for(int i=0; i<vexNum; i++)3 R7 R- l4 ~0 J3 x$ h
        {
    & M5 T  J* @. m1 H        cur=i;pre=-1;
    2 ?6 c6 o% Y7 g        while(tag[cur]==0||!s.empty())
    - l1 Y( b) L' }: ^0 P4 E% C        {
    ; S0 Z( t) O# D- h. M) S4 O            while(tag[cur]==0)8 o- Y* |, a# ^( E
                {
    & ~( i& ]& T& p& f" {                cout<<vexTable[cur].data<<"  ";
    ( _6 p! R3 Y- `5 G% \                s.push(cur);
    9 X% R) s" w- P5 C! ^                tag[cur]=1;* F: a' N3 b0 g6 e
                   //初次访问,标记入栈; T) R$ K1 g/ {! m3 O' i) Y

    $ `$ O& b3 J7 ?6 d               p=GetAdjVex(cur,pre);//p是cur的连通顶点
    ; a7 O, d8 k: h& h8 U) f6 A/ R               if(p==-1)/ T; R/ r) R: O2 ]( \) o! c
                   {
    % s$ h7 h; |9 N( w                   pre=cur;s.pop();
    " u8 X( V  |; @2 e                   break;. m! m. N8 S4 m* V# n- S
                   }
    % t  b4 Y2 Z% t8 a2 }               else
    6 }# r( _0 ^' p" [               {0 h0 [' }* u1 _) [1 r; O
                       pre=cur;
    ; ^  l3 X2 j) U. o: v! v                   cur=p;
    ' b3 `. S# z2 n5 w) h# r               }
    ' V. f  e& Q; C1 b2 b2 u. Q0 z& t! D- e. J5 n
                }
    8 {* X9 z- Z/ A  O            while(!s.empty())
    4 F. _1 L  {0 `- b; R- k            {
    & F$ m9 {$ N: t; Z/ W                cur=s.top();
    : ~) h% u/ |6 T- \6 U                p=GetAdjVex(cur,pre);
    9 Q( L" v7 g- L# C                if(tag[p]==0)
    + A) A4 N8 l/ D' `/ U4 u  W                {9 ?: ~+ W% g$ T
                        pre=cur;7 ^) U8 s0 m. T- v% v" d
                        cur=p;2 C" |; ?1 s0 Z) m
                        break;
    " Y' W% |) ~( B2 w* x! G                }
    ; f& Z" U& v4 J                else
    $ ]! u) r) X. e4 w                {$ p6 G! O, g0 p8 F7 [* ^
                        pre=s.top();) {5 j/ f! W' v' z) w3 [4 {
                        s.pop();& C3 d7 t! g5 f" }4 I$ a
                    }" G% r0 `1 G& }; V! m) A
    & w3 E9 N) J6 i* ?! q  b2 E4 U: l
                }% \% p% o" w) ?; Y
    7 h' ~. r6 s. m' v9 u5 _; _
            }
    + ~* G. i3 c! I5 o2 {; p    }: i  h9 w, G: C. B7 ^
    }/ X& [) i- L; m% B6 {; M1 @3 n" C
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    , K5 f# }+ H, F# N/ Z& W9 y) x{  o) q9 E! `/ c! k  X8 C9 r6 X
        for(int i=0; i<vexNum; i++), g$ m7 X2 Q  X
            tag=0;( Z5 H3 q* h% m) {' H  h
        queue<int> q;2 d8 j9 f2 u; s) @( d( a
        int tmp,t;
    : J; }9 z* |0 e0 C    MultiAdjListNetworkArc<WeightType> *p;
    # _' u; n$ s- L; J+ u    for(int i=0; i<vexNum; i++)" f! f: h$ R& g* Z) l
        {
    $ V& v5 n) u/ N' D: A        if(tag==0)% j) A& j+ i% y# r8 ]4 E
            {
    & o& {9 ~/ |3 U2 p$ S            tag=1;
    $ L' i. F9 |3 }5 n            q.push(i);6 f$ |( y1 Q0 ?1 U/ n
                cout<<setw(3)<<vexTable.data;
    % z' f$ S0 r% V& H        }
    . i$ ~3 u+ w: e+ V# }        while(!q.empty())/ p. |9 j2 d+ r" {& x
            {
    $ I4 X  L: E% A. r4 f0 N; {            tmp=q.front();; f* s, q# j+ ?- X
                q.pop();! _6 M: y7 E0 Y* P9 l
                p=vexTable[tmp].firstarc;
    3 M* f7 K" z& A' P            while(p!=NULL)
    # Y) j$ E; |3 ^1 S  `; o            {  s. o8 c% S" a# k( b! S  ~& T" U6 P
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);; ?7 C, a7 p" L2 f
                    if(tag[t]==0)
    2 X3 r+ v% i( n, X: k                {+ G& G1 C" l) f/ O- u9 v0 ]
                        cout<<setw(3)<<vexTable[t].data;% T# B2 w. q" B7 d) |1 l& x
                        tag[t]=1;
      @, a9 m1 c& C3 R6 W+ I8 r6 o                    q.push(t);0 m+ f7 X7 {9 s$ h; P
                    }
    . j' I8 E2 ]1 f$ F                p=NextArc(tmp,p);
    3 L* w$ Q% i; q* t. l- w            }
    & h# |  W+ P: D+ a4 E& |5 z# L        }
    " K" X9 e( m. t8 [* [2 V1 L- G' s    }0 ^2 B5 V" ^0 g8 _# O
    }
    2 p  N: ~# c, {# W2 h% Ftemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    % H, F1 b7 s9 G. O: G; l{) M/ \7 f3 ^! {  T
        MultiAdjListNetworkArc<WeightType> *p;
    $ F3 T: R. y* s( ~    cout << "无向图有" << vexNum << "个点,分别为:";
    8 H0 m7 y  B9 p& K    for (int i = 0; i < vexNum; i++)& K% n/ L; }  @  |$ C6 |
            cout << vexTable.data << " ";9 L# R1 M# }9 k0 z
        cout << endl;
    . T7 k" U. ]) K    cout << "无向图有" << arcNum << "条边"<<endl;7 f9 q  b- w! J8 e& T! K, v: G
        for (int i = 0; i < vexNum; i++)
    5 r! L+ ]; r* L) }7 V    {
    + _) J& Z6 U( l/ ]" @4 U        cout<<"和" << vexTable.data << "有关的边:";
    : B1 ?$ `7 K) W        p = vexTable.firstarc;/ }4 T0 z* ~* z: P# d0 M
            while (p != NULL); u# t: i) O; l. S* p& @* v
            {
    ; J$ o3 C4 p8 k/ e9 g            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    . y3 `# Q% J( R" Y8 N6 k' _4 l2 _            p=NextArc(i,p);$ t" c( f! j/ k" }
            }
    ) `! h3 l. |+ N/ @# b        cout << endl;
    & G4 J" S  S. _0 S    }+ h" n' Y0 Z( b9 N/ ]7 v& Q
    }
    ( A5 [% o) Q& l+ t9 Y: Y
    . q8 `9 r; p& q( F$ T! {9 A, X, }
    0 O# \( A- A- ^* }$ b+ P, u邻接多重表与邻接表的对比
    6 V- }* B; u4 T% \
    9 i# s2 b& o3 v: O) l" u邻接表链接2 M% d% P3 L8 W
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。  k7 P" B8 ~& {4 p( T
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    6 O" c; K: s4 B  ]. A为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。5 |3 T9 v8 ~$ _* Y* D/ o: J" R
    ————————————————
    % y1 k4 |9 S7 Y版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    1 p/ D# [* J* y原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669586 B6 v4 J0 Y8 C7 Q  @
    0 y8 v" E, ]8 X

    4 v0 W9 w& g5 X9 W' h0 M* R
    9 Y2 }$ q; h8 `$ l8 n% w4 K7 u" X1 P
    ————————————————
    & C. D2 H, c! r" W版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ( w% }2 `% w9 U2 K6 x原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958: q. J" e2 a/ q4 n' G" x5 a9 q

    , L5 h1 w/ ^- r3 G) H* g% C* o# O1 _0 d8 J% L6 y7 A; _
    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-9-11 08:13 , Processed in 1.531167 second(s), 54 queries .

    回顶部