QQ登录

只需要一步,快速开始

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

    " I5 \$ B/ o) a1 C8 o) n图的存储结构——邻接多重表(多重邻接表)的实现
    3 p/ m9 u6 @1 \  u1 x) ], V$ K7.2 图的存储结构
    ' L, U) v2 }9 o: }) Q% e% B" s- L% V. J5 m& H2 p
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    1 s4 K  p# Z: h# C( i( B邻接多重表的类定义! X* E0 g) `' p) q5 `
    邻接多重表的顶点结点类模板
    ( E2 F- K9 s2 X3 o* ~2 ^& H邻接多重表的边结点类模板
    9 ^- a4 \/ E0 s+ r; W  }. e9 q邻接多重表的类模板
    : L, }, s: z! r5 [1 Q邻接多重表与邻接表的对比) t  K" V$ H) T) k1 X$ x
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    + G& X1 \% f- ]2 @/ M0 Y) k& ?
    # M& h% G+ E: f" w7 b& O. ~在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    , R, ]$ Y  Q- j- N2 f. A3 r3 g在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。) m2 Q5 z' r2 ?7 n' m- Q2 j  N
    ; f3 W; C6 o' Z& }. p5 E1 U# j
    邻接多重表的类定义
    & b& a6 O0 x( w6 @6 ? 1.png
    : ^, M( J9 p% ^, i; ?* x8 \# m邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    ' n4 {9 x  D5 P& kdata域存储有关顶点的信息;8 D9 V9 D0 G9 Z9 E. Q% W" M
    firstarc域是链接指针,指向第一条依附于该顶点的边。& p. e+ ]# t$ ]' E" I
    所有的顶点结点组成一个顺序表。

    * k2 `; i2 q0 _- A& Z9 s! O

    6 q  D  p" z$ Ptemplate <class ElemType ,class WeightType>, I/ w9 r( B' k" \
    class MultiAdjListNetworkVex
    - Z4 x8 T, x. w. Y{
    ( p* f3 Q: i' w4 b1 }! ypublic:
    ( E# j/ D$ P; s3 t$ `7 j        ElemType data;* N7 D& T% u8 M6 W( x+ R
            MultiAdjListNetworkArc<WeightType> *firstarc;
    - g% H" P% K$ b) I, u$ S* W: t+ I0 T+ W: ?
            MultiAdjListNetworkVex()
    8 [' P& @. ]6 E, R        {+ e4 C! y6 d2 F% Y
                    firstarc = NULL;
    0 x6 _3 s0 `2 L- [/ P6 B        }$ R- j6 Z/ h5 R6 V4 |  f
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)+ z% B: y. w9 u/ V+ D
            {
    : i/ e) ]. y" K. h                data = val;: x( {! f4 Z4 D& M4 W8 f# [2 P
                    firstarc = adj;. `8 J: P- ^- {; J/ F
            }* s! j( A, T" s' H, ]
    };
    3 _. T+ U: m# d% ?) U) X# |! b+ X2 W8 `
    邻接多重表的边结点类模板
    , J% O' c# _0 ]" t
    7 H# [! |# c  u/ w9 H7 a在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:2 }4 {5 K' ^6 f, {- B7 ]0 j: r& R
    tag是标记域,标记该边是否被处理或被搜索过;7 E" g1 v+ \$ ^3 `
    weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    , g" U* S0 s6 j5 u7 A# R, Onextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    7 |/ j0 U6 G7 b, @$ l3 lnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。$ n4 j& h. w& B6 j- V2 j, D$ S% v) J
    4 Z% f8 J+ b' K0 T! h- W# v! o
    2.png # W) J! t' i& u; E1 S! q7 H9 v9 v% w* R
    template <class WeightType>! R" W) J' r% c7 a% a2 M0 ?
    class MultiAdjListNetworkArc" R4 V) M7 g: m
    {
    + C: z! Q. Q( hpublic:
    2 O# o* ~3 {5 g- j( J    int mark;                                       //标记该边是否被搜索或处理过
    4 T5 Y0 v7 w) O/ M: ?$ X4 _+ T1 \: |        WeightType weight;                              //边的权重  h$ q/ S5 P" H( B( _5 y
            int adjVex1;                                    //边的一个顶点, w. b7 L- N" e" c( S1 K
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-18 j# O- p1 ~  I, f) T
            int adjVex2;8 d0 u/ ^3 B" ^$ ^  O. u% F
            MultiAdjListNetworkArc<WeightType>* nextarc2;+ Q% `% W7 i% Y8 {6 i
    ( R! g6 L4 ~2 w6 ]' Q' r8 n
            MultiAdjListNetworkArc()
    * p$ L3 u& q$ @5 I        {
    " I0 u( Z7 S4 O: U# y5 Q                adjVex1= -1;
    , J, v0 I$ ~! Q  B                adjVex2= -1;/ m3 h" s1 ~0 _8 H& ?/ t
            }! F+ }* }6 ]! G$ D7 J$ I
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)1 e5 S# j% S! z+ [& q
            {
    - }! z' k7 c' J2 t& h. @% I, X                adjVex1 = v1;       adjVex2 = v2;
    9 J5 L: U$ ~5 i+ G1 g                weight = w;; r$ `) O. ?9 M: u
                    nextarc1 = next1;   nextarc2=next2;- T# ?5 ?6 M2 O! v: K- H
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    / J. a; H& t8 C# a: i% @        }: \2 C$ `- L4 u0 j4 X. i

    2 _  M* j) W) O8 o4 \邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    + f  V0 V! u; d8 o9 Rclass MultiAdjListNetwork2 @: E! v1 j, i, @& h
    {
    - o  b* f" J4 {protected:& u! Z: w% x7 }5 e# z6 S
        int vexNum, vexMaxNum, arcNum;
    ) U1 B% X, ~# \3 O4 T8 s    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;" \1 s: K8 p" Q+ I$ J2 u4 T
        int* tag;
    % f! w) D0 E0 x- Z    WeightType infinity;
    6 z+ r: m+ p" b% x9 w' y" Z" t+ w
    9 ~. v4 \6 x" K! o- g! Cpublic:& q% {  j2 |4 m8 ^# [% v9 D; L
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
      {" j9 U9 T- o0 x+ t0 t( I/ X. r5 e- j' R, n
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);( k( x& n7 p9 L
    " r# J* i- p. ^, q+ m
        void Clear();, ]% |, o. G3 |" o, I1 p# Q' J: F
        bool IsEmpty()* _4 ]1 T2 {# J, i# q5 U& w
        {
    8 Z1 @8 R8 _. G. r9 y& ?5 [        return vexNum == 0;! m3 g+ J: I# l
        }5 p* b9 x4 H( k( c# `& c: ?, W
        int GetArcNum()const
    8 _0 @8 \. C- {2 \1 Z2 [) e% N    {1 n' p! ^8 x& ]" K3 L: `
            return arcNum;0 e. W7 @4 \6 ~7 y+ x' c. o
        }3 a, v7 q* f/ J9 |
        int GetvexNum()const
    % ?8 n1 o- [7 e8 v: D    {
    , ~% m" f/ _2 u1 c$ P5 r: j$ e1 }        return vexNum;
    . G+ x% G4 O* c7 b7 p$ t    }
    7 B1 `7 G0 }% _6 L& N' `+ E) z$ q- U

    & @* b$ X; t+ r! U6 g    int FirstAdjVex(int v)const;
    " v0 P8 ^* ]7 F# H' ]- h    int NextAdjVex(int v1, int v2)const;
    4 h6 ]6 g# c; ~; T/ J- s, R3 S    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
      Y/ `, s( H" b4 m4 P& ?& Q    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;7 l  T1 V, s/ y% A( x8 E& Y
    2 p8 J. v) |4 X5 R8 L" s! E% X& Q# ?
        void InsertVex(const ElemType& d);
    2 {: h! K5 |9 ^) F( f    void InsertArc(int v1, int v2, WeightType w);( N/ m; {- d7 K$ M) C# j+ j

    2 E2 Q* O% o, a    void DeleteVex(const ElemType& d);
    7 x3 G" s' s) l! E2 q7 I& C# ^0 H( s    void DeleteArc(int v1, int v2);
    / l3 o  k3 Y' K( U' U( T% c9 p4 I, |4 C8 ^& E
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);$ D4 ~( V# o& R$ h' G& q
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);5 l. d) t% o1 t* C

    / x( d1 T) d" U! k7 ]4 D# V; c    ///深度优先遍历
    1 C8 g2 i5 y# g) |4 [3 [    void DFS1(const int v);/ E1 y1 e9 g; h7 p
        void DFS1Traverse();
    ( f: f6 S/ P6 C( N9 N( z( T2 Z' i0 Y    void DFS2();' A2 C) _9 d4 P  W' c! _2 i

    5 X2 [* ~0 U% ]! v) x  d6 M    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    0 _& L  l# ]7 p$ v' ^6 u    void DFS3();  e2 e1 u3 f# r$ E3 ~. A; j% p

    / N8 g3 V: X# q6 ]( O6 c; j    void BFS();3 x' h% A2 e7 Q9 a) `) N. p! A3 E
        void Show();9 r4 [+ Y" g5 o$ |6 f. {
    };
    7 X" g' P3 A  v4 ~& f. }3 G. M+ y/ J
    2.函数的实现9 d5 c) w, o4 g3 D- m
    研讨题,能够运行,但是代码不一定是最优的。0 F" ~+ P) ]% w' p/ q4 t( I. _

    / g5 K5 e; _4 `#include <stack>) `5 s) y' \) w8 c+ J
    #include <queue>
    5 ]1 G" e5 U- c& V
    1 g8 v1 q! p& L2 E; Btemplate <class ElemType,class WeightType>
    : D9 Y# @6 Z" |1 b8 H8 ~7 eMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)! s4 s/ o. w! |  r0 Z1 E1 |
    {
      U2 E0 p; ^2 m+ D8 Y* q3 V' N    if(vertexMaxNum < 0)
    % N9 A% `3 S8 Q' v8 N& e  I        throw Error("允许的顶点最大数目不能为负!");1 @0 T4 T) m- [! F% F6 n
        if (vertexMaxNum < vertexNum)
    6 y( p2 ]7 ?# W% R        throw Error("顶点数目不能大于允许的顶点最大数目!");
    " o/ ^& a0 m9 x" W& |+ o    vexNum = vertexNum;
    + I2 F6 k/ `9 I% E5 Q9 Z    vexMaxNum = vertexMaxNum;: V- P1 {! a# q, u7 S+ U
        arcNum = 0;) w7 Y: r* J& v7 v# |6 {$ c
        infinity = infinit;
    : J/ p+ B" V6 P; @0 q. a2 o    tag = new int[vexMaxNum];5 y2 m  r; q+ A7 Y' _$ `( f1 E
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];! T# k8 k8 L3 `$ A8 P) m
        for (int v = 0; v < vexNum; v++)
    & ~* Q5 X5 |% b2 h9 R9 I    {
    ; V9 p8 D$ j  ^8 W$ F( p        tag[v] = 0;
    . w# x) c! N* t! d        vexTable[v].data = es[v];5 e: S% l" L( }% Z5 ~
            vexTable[v].firstarc = NULL;
    4 A! d7 J8 r& h2 |    }& u. q8 B  k' i/ m
    }
    . l; {- n5 l( ^template <class ElemType,class WeightType>
    6 _# c: o% z' j) C, DMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    7 S8 v# H$ [; @  V" M{
    9 S: f/ D: m1 u0 ]/ }  {" ~    if (vertexMaxNum < 0)
    % [3 G0 ~! w/ k' R+ G# p4 E8 N4 B        throw Error("允许的顶点最大数目不能为负!");+ F* q. Y, |+ a2 O1 h. h6 x) m) K
        vexNum = 0;
    + w$ s" ~) ^$ j3 }) {% H- l4 r  U4 ^    vexMaxNum = vertexMaxNum;9 M* W1 j3 M5 A. k
        arcNum = 0;- A, R7 B3 i/ y2 ^2 [0 [
        infinity = infinit;& Z/ B0 z% `' `' U1 B7 u  ]
        tag = new int[vexMaxNum];
    $ B) g, V+ Z. ~" q3 u4 t    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];$ h- g& j4 u3 F0 ^; @9 ]: ^, ~
    }) b# V/ U$ ^6 w# n& j
    template<class ElemType, class WeightType>
    ( V$ X/ u/ `3 E1 s1 e) G/ q" Xint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const3 C% D% _$ V( e# }( Q, Z
    {) Q8 b  b) P% q6 w1 s7 O; J
        if (v < 0 || v >= vexNum)$ n! A3 n/ M; h1 w
            throw Error("v不合法!");6 Y/ ~$ E$ V! i
        if (vexTable[v].firstarc == NULL)
    4 F) w$ T& \$ L0 k) I        return -1;
    $ D, L% \* A/ [8 M    else
    ! Y: {0 q! d2 B7 j        return vexTable[v].firstarc->adjVex1;
    ; ^; ]: v7 j& \; i3 }" k' l  H}0 M8 C+ d' G9 J
    ) e( S# P0 L# b* V+ g9 t) b0 j5 x
    template<class ElemType, class WeightType>
    & u1 A: a$ o" h  kint MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    : a0 p4 }6 p$ s2 \) M{
    4 Q% z9 f/ |- h' p, q) I    MultiAdjListNetworkArc<WeightType>* p;
    5 m; \  u3 E  D4 K3 w5 T; \6 I5 F' o    if (v1 < 0 || v1 >= vexNum)
      c4 e/ G6 k" I+ T( Y$ N8 d$ X        throw Error("v1不合法!");+ J: R6 p, Q; C
        if (v2 < 0 || v2 >= vexNum)
    ) u1 p% e% ~, F* q        throw Error("v2不合法!");& A" k  L' i" d$ S! o/ m+ K0 H) d$ J' \
        if (v1 == v2)
    ) d% O7 E! w+ L2 V2 [4 z1 A8 y        throw Error("v1不能等于v2!");" o( I2 L1 Y0 a8 E; _9 v
        p = vexTable[v1].firstarc;
    3 d  _# V6 i- P0 G/ n5 c7 b9 s    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    - f3 d2 g; ?, A; K        p = p->nextarc;& a5 [+ Y" ?0 w8 k% X" o2 ^
        if (p == NULL || p->nextarc == NULL)
    & i, u9 k& L" S' {& {+ W        return -1;  //不存在下一个邻接点2 X% J- F" U1 S' B
        else if(p->adjVex1==v2)
    , L5 |6 J. X2 u. u3 l        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);* B/ }# G* M. N/ H9 M+ M4 @! x1 G
        else
    " v4 Y4 I7 Y: b! N        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    5 I  W' b7 I+ |7 N" @}
    : {' ~  P' k5 [. d6 [; k; W' dtemplate<class ElemType, class WeightType>
    6 b- ]( z6 q$ Svoid MultiAdjListNetwork<ElemType, WeightType>::Clear()
    " m$ D6 t3 G" _" n0 S% b6 n& V{
    ( g% B: G6 a4 C: a7 f- N& E    if (IsEmpty()) return;( Q& h' O/ F' a" n% N+ \
        int n = vexNum;
      J" i: n& `' ^  V/ O    for (int u = 0; u < n ; u++)
    . n1 p* C) x- K        DeleteVex(vexTable[0].data);
    " C9 M& M7 X; v    return;
    3 A7 r2 w6 \4 O6 r8 C! X. f}- A/ L/ z) T7 ?7 H2 M6 E
    template<class ElemType, class WeightType>
    ) p' v( f. P/ y3 U4 bMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()7 N. ]9 `5 I' h! j8 U$ ^) d' D, e
    {
    + s0 L) @: i, c% B5 F0 M! \) k, d    Clear();  h5 R7 F( ?7 Q4 q( C  n
    }
    ( u: D% z% x2 x4 R2 ^) F% Mtemplate<class ElemType, class WeightType>5 z6 T9 W( x8 D. z8 Q
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    ( X4 e9 A3 Z* n: V{
    " I4 {9 P. D8 {( z, `    vexMaxNum = copy.vexMaxNum;
    0 \$ P/ ]; c5 ]    vexNum = copy.vexNum;8 X6 r! Q8 M/ `# c2 K2 x  b& P# |0 ~8 l
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    * D3 g, T8 G) z. J7 @! U    arcNum = 0;6 L) _, L+ K+ S# e6 W
        infinity = copy.infinity;
    6 }& }* {! ?2 W+ W3 ?/ D+ v/ v    tag = new int[vexMaxNum];
    $ C  L$ t" _' Z5 n! ~0 _
    . r2 P/ f' j# Z) s! n0 e. d8 e# x5 D    for (int v = 0; v < vexNum; v++)/ H$ a9 K6 F& k# r. M2 O3 R5 F
        {1 ]! I, J7 y" b2 R4 w+ b
            tag[v] = 0;9 y7 B3 p: x2 w4 X
            vexTable[v].data = copy.vexTable[v].data;$ F1 S- u) m6 _& Y: D, r
            vexTable[v].firstarc = NULL;1 m( C; t/ Y# S* |& _( r
        }( `. K; N: I6 j- h4 Q
        MultiAdjListNetworkArc<WeightType>* p;
    ; Z" d  B1 p$ j* B' v
      d6 a. ~5 @# J1 l- G$ Z/ S    for (int u = 0; u < vexNum; u++)
    . L) X3 c2 ^4 m    {
    ! D0 e! z$ j/ [/ v        p = copy.vexTable.firstarc;5 @/ ]1 r, i% ~$ S" _
            while (p != NULL)9 A! d: b7 X8 I0 y
            {
    : \1 b- l; V* z0 N4 Z5 E            InsertArc(p->adjVex1, p->adjVex2, p->weight);" t  \" ]2 X4 H! y) N
                p=NextArc(u,p);2 x; s1 n% ]. c! s
            }
    . L# N6 C- M' R    }9 s, v! r9 Z/ w$ m# @
    }( M. _1 F* M. l
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&3 K' {. }+ f6 q( w+ a
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)4 q" U0 Q! h6 l8 j, V, _
    {/ M7 `( G5 T* f$ Y
        if (this == &copy) return *this;
    3 D4 _: M3 B1 J8 J: J" M    Clear();3 m9 l% ]% l, W6 i. J( H( R5 f* i
        vexMaxNum = copy.vexMaxNum;* s# j/ q& d( J  g9 H( k2 V/ I
        vexNum = copy.vexNum;
    . j* j2 `) H$ ^    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    ; z& y: o* Z7 v' ^  _    arcNum = 0;: ^( j- l- U4 z4 w5 G% X) D
        infinity = copy.infinity;2 m/ G4 W/ M* B) E( c4 t; p, w
        tag = new int[vexMaxNum];
    % i2 A; p' D  B8 F8 X4 e  F) ^# O/ u, j- B( ]. u9 }2 |( E
        for (int v = 0; v < vexNum; v++)7 K! [% T# ^% g) R5 W4 @& M/ j) c$ \
        {1 h) X2 K" L$ ~% G7 j  o
            tag[v] = 0;, ^4 k! F, Z1 B
            vexTable[v].data = copy.vexTable[v].data;
    9 t5 F* H& x- T# n' h        vexTable[v].firstarc = NULL;
    . M$ l3 G8 A4 u* V    }9 f9 X6 ]2 O  E* _7 T
        MultiAdjListNetworkArc<WeightType>* p;
    5 n8 R, O% D2 ^) B" K
    ) |+ Y+ F) Z! J. p( y; b    for (int u = 0; u < vexNum; u++)7 _1 S% l6 E6 S# `- d/ B1 k
        {& T5 j* \( V, H5 l8 j5 A9 K: |" j
            p = copy.vexTable.firstarc;5 s8 {, l% O  q
            while (p != NULL)
    2 @: o" h3 j; S; D  E        {9 u' W. U# l5 R9 q4 y! g, w
                InsertArc(p->adjVex1, p->adjVex2, p->weight);2 r- W) l6 q0 w9 \7 j# C8 ^
                p=NextArc(u,p);; W5 F5 ^% ?/ z2 y
            }+ `  Z8 C( q' o9 p: p/ q7 }+ n
        }' e0 y" B. V, L8 S, G# B
        return *this;$ m. S( `( V; q3 b
    }9 r$ v7 d; h, m( C# O
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    ; W- O! k% d6 U3 ^" KMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const% W$ B$ R2 C- B6 o4 y
    {+ ^& [7 _, v% H; y
        if(p==NULL) return NULL;+ O# s& x7 E$ y3 k5 i, v% F# h4 s+ V
        if(p->adjVex1==v1)
    4 Q0 ~9 G6 M9 h/ h* K% E8 r2 e, q        return p->nextarc1;/ G9 H7 O* `9 Y( [8 ~
        else. @' r. m0 m. }, g5 y  `, p7 I* C6 u
            return p->nextarc2;' J* x7 {9 u4 P. ]
    }
    * X7 Q! M0 b" u/ T# M8 gtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    ; G& b% _- n- n, Z$ \% ~MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    ( z9 o' k: _, |1 L; w{- X  d7 X2 X- D1 x
        if(p==NULL)return NULL;
    7 r! \' L- _, U5 j1 B* f  ^    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;6 r% O/ a' U. @6 D( X
        if(q==p)& i, ~: _9 g6 Y2 O+ ?
            return NULL;3 }. ]+ X( [6 L5 S
        while(q)4 l6 K8 ~+ T! V. R- M) Q
        {
    * f( Z! B+ U  _3 o7 ^- H' c        if(q->nextarc1==p ||q->nextarc2==p)$ F: g( [# X7 g( B; k
                break;4 j( s. {  H% n/ W1 C8 V' t0 y3 y  U
            q=NextArc(v1,q);7 C1 e5 d  W# x: ^. |) [
        }
    2 r% i: l0 K& s$ t# c6 M+ ?    return q;% H1 _6 Y2 N: U3 H
    }
    8 t# e) K0 X7 P7 t) r6 otemplate<class ElemType, class WeightType>. H2 L# U0 o2 R, P& z! y7 u; p
    void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    " z" Z5 N, N3 Q  t: }{
    2 q: G# v' h0 P7 r7 [  N  h. f    if (vexNum == vexMaxNum); U4 E  p( A* ^2 B0 ~; e: L, x
            throw Error("图的顶点数不能超过允许的最大数!");
    ' W+ a* L$ j. \& [  v/ _0 D& ?2 G    vexTable[vexNum].data = d;
    5 j3 x3 y! j* h/ h7 \    vexTable[vexNum].firstarc = NULL;
    ! U" r& ?0 K( j0 Y/ h$ e    tag[vexNum] = 0;/ r, u+ Z6 `& `% L2 s2 B
        vexNum++;& C! ]0 `$ Q$ [' Z9 p
    }
    # }9 c3 ~1 L, q7 c) N+ Mtemplate<class ElemType, class WeightType>
    ; s6 o7 m' m2 `7 lvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)' i7 B$ h3 u5 T' n* `5 M5 X6 N
    {! X9 M& e5 ^3 v0 ]! g
        MultiAdjListNetworkArc<WeightType>* p,*q;/ z$ J9 A$ }- M) J. ~
        if (v1 < 0 || v1 >= vexNum)
    $ u' G9 i" a3 o# S& V1 x% ^" C        throw Error("v1不合法!");
    7 G* h( Y. O& F' d# h    if (v2 < 0 || v2 >= vexNum)
    9 U! R, q- v5 j, `5 t        throw Error("v2不合法!");& }, k# Y2 J/ g" b% F
        if (v1 == v2)0 \" T6 ~. I+ M! s0 a
            throw Error("v1不能等于v2!");
    1 x. c% w  d! \1 y    if (w == infinity)
    1 j  {$ s- u' f9 R! h  H6 A        throw Error("w不能为无穷大!");0 J4 d$ W  L9 |# `* J+ O! ^- ^. V, m
    # ^5 F6 n6 V  k& s& l6 e, ^

    " ?6 f! d$ [* Y5 i3 S' g    p = vexTable[v1].firstarc;9 N* J6 {5 b: b5 i, Z/ A* k% h: n
        while(p)0 Y+ X. O& I8 S2 i
        {
    % e0 z1 {$ J4 ~4 |' C        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    . _, j3 S2 P+ j  h0 n5 z        {  ~/ i6 E, {; p0 j* O8 D( d: L
                if(p->weight!=w)/ a4 z7 u5 T% h4 D6 e3 P+ W4 p
                    p->weight=w;) T9 z3 b0 k' b1 O6 s" k
                return;6 i/ r2 N' F3 l% o5 a: I5 b/ g
            }
    ! I2 @0 o9 u8 o& |8 M; K; \8 Y5 r  J& ]9 V! c: R
            p=NextArc(v1,p);! _" F$ f, t0 g4 o) W
        }
    1 y6 n/ U( W* {0 y) t4 @- z    p = vexTable[v1].firstarc;. O+ w) g, t" e( X
        q = vexTable[v2].firstarc;9 ?/ H! {; P: o
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    % A; R( _  {' L, @; Z    vexTable[v2].firstarc =vexTable[v1].firstarc;; j9 b0 t: [9 u3 Z* V) E7 @
        arcNum++;  t+ B& d- T. E
    }
    ) K8 o( w3 n$ z2 U2 h
    6 ^* a2 a3 t' x) F  k& A( Qtemplate<class ElemType, class WeightType>& y3 }: g0 U7 Z8 z9 K
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)* o* v5 B7 o+ W
    {
    0 ?  }0 j- i4 \9 p: a
    ( Y0 ~; W% L! I7 g$ M    MultiAdjListNetworkArc<WeightType>* p, * q,*r;; o9 c# j# M& I, f, ?; p
        if (v1 < 0 || v1 >= vexNum)
    # ^# m* z/ G1 L/ ~        throw Error("v1不合法!");
    % t& M% P/ u, v. q4 ?; v- H    if (v2 < 0 || v2 >= vexNum)
    : a+ k/ y( Y* B: X2 Y! d3 i        throw Error("v2不合法!");8 ?8 S5 h; j, N3 F
        if (v1 == v2)
    6 W1 ?: m* S! N1 @: Q) O        throw Error("v1不能等于v2!");
    2 h3 W  i: X! Z0 E0 a  I' ]* G( U7 o( c. g% Q2 }6 c; p
        p = vexTable[v1].firstarc;( K$ I: F4 v# ?9 C
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)& c9 S2 E% U! y+ ~  l/ Z
        {( f1 m2 A, E8 E( |
            q = p;
    ' X6 [. @9 V* M- t3 ~& z- Y        p = NextArc(v1,p);
    # A. _& Z  l7 @5 g3 @, |* F# N% b    }//找到要删除的边结点p及其前一结点q
    5 x8 h) Y2 T% T2 P3 I) N
    6 h4 t, J  n- k( Q& }- }4 `$ V    if (p != NULL)//找到v1-v2的边
      ~! i6 D: @4 m    {
    4 x0 }+ C' {  U6 O  F; w        r=LastArc(v2,p);
    ; p+ R4 A' [% r        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    0 m  X0 T% k7 z9 X1 X* u            if(p->adjVex2==v2)
    8 V' b2 L. V1 M, Y+ }/ j1 @                vexTable[v1].firstarc = p->nextarc1;
    ! d  C( c. N' N/ s6 G& a( Y0 h* j            else vexTable[v1].firstarc=p->nextarc2;
    ; a7 G. k& Z: S# u$ ]& v& Z        else//不是第一条边) l* ?% ^% c- q! ^2 N
            {( Z+ K1 C- ^% L, F
                if(q->adjVex1==v1)
    & H' r( r( b+ Y" m) e1 E2 H                q->nextarc1 = NextArc(v1,p);- B" n% u" r$ b+ D( G$ M0 l) [
                else! G6 D* L1 v1 N* _: h  V- b3 a
                    q->nextarc2=NextArc(v1,p);; G5 _4 g6 q; i0 l& f
    / \5 L2 Z$ `4 t
            }
    " [. S; z/ \$ V; A5 f% l! j5 P8 u        if(r==NULL), t8 a; s4 z) j  Z3 Q  T# o; R
                if(p->adjVex2==v2)/ E5 Y; P2 l5 i+ D) X8 t
                    vexTable[v2].firstarc = p->nextarc2;5 s' M, l$ ~# z4 @& k
                else vexTable[v2].firstarc=p->nextarc1;
    ; `0 q, V3 D2 H6 Y* z" A" ~. T% [# y        else
    0 l& S; N6 j, j1 U- X  ~        {. X% k4 H/ u  Y% J: `
                if(r->adjVex2==v2)& t! p7 B3 E' v) s
                    r->nextarc2 = NextArc(v2,p);( P, L9 N$ v2 a# p  U$ v
                else6 y8 o$ T7 Q8 q+ D' I( N/ S
                    r->nextarc1=NextArc(v2,p);0 I6 }7 E8 \4 m
            }6 M4 ~# @( j; Q
            delete p;8 V3 Z$ R; ^2 u. d
            arcNum--;
    8 P  y# y  c5 d) W- p; a% c0 I    }
    0 q# W8 [) l4 T
    ( Y6 `/ ]. ], v8 F& Z" _  s}
    . o" z( M3 l5 ^1 |template<class ElemType, class WeightType> void
    , [6 N5 z/ L/ I1 l" PMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)5 h" V+ l$ s" v& b: f! |
    {& S- u' |- A6 V
        int v;
    : A, W6 F* C3 J& h+ c    MultiAdjListNetworkArc<WeightType>* p;
    & K( z: P- r4 n2 F5 y    for (v = 0; v < vexNum; v++)//找到d对应顶点+ E5 Z9 r# }; @9 k0 V6 t
            if (vexTable[v].data == d)
    ( B+ @9 @# O+ f7 t) A            break;
    ; B% R( l* K* ?9 n" v5 M+ f    if(v==vexNum)6 Q+ [4 Y; S( h6 q/ N
            throw Error("图中不存在要删除的顶点!");
    1 x$ {: F3 o8 F, V# U
    " V+ z" E! h9 d. @: `/ q, D  w* l" f. r    for (int u = 0; u < vexNum; u++)//删除与d相连的边: j+ Q3 \) U, l+ R
            if (u != v)- s* ?9 J" G8 S2 t
            {
    7 U$ q4 I6 L, D" a            DeleteArc(u, v);
    , x! k8 d5 r$ y' w9 o; ~        }" }+ J1 p$ A% Z- h
        vexTable[v].firstarc=NULL;
    . O) I) \' l+ ~# Q: d3 N5 c; V4 K
    % F+ B2 w6 A9 N# v  Y    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    9 @3 G/ p5 `2 }! e    vexTable[v].data = vexTable[vexNum].data;& B- U. @8 f! p5 I& S4 G( g" Z0 N
        vexTable[v].firstarc = vexTable[vexNum].firstarc;1 Y1 [4 N( O! z4 i) k
        vexTable[vexNum].firstarc = NULL;
    $ a( B5 P. \) H( z+ _, A    tag[v] = tag[vexNum];
    , J- y" ^% y* f    //原来与最后一个顶点相连的边改为与v相连- F& o3 |: r3 M# l" j! Q
        for (int u = 0; u < vexNum; u++)
    " }& p0 Y3 d, p; F% H  j4 Z    {
    , E- R& }3 P, I1 |. S) ]  ~        if (u != v)
    , _# n5 n3 f- ~! |' ]4 D        {; P  Q/ O5 v% q! f# q% _& A
                p = vexTable.firstarc;5 m4 E: Y) A2 i; |( z9 s* S! d
                while (p)8 H) _6 [& l# t. w8 A
                {
    0 h: ]3 |' U# m; f2 [# l                if (p->adjVex1==vexNum)
    ; S, Q0 A1 W5 G) z# N                    p->adjVex1= v;' {) P! B' r/ G) ~! W; u: N
                    else if(p->adjVex2==vexNum), p7 b/ |+ ]  O* l; K# g6 t3 O4 o
                        p->adjVex2=v;' S* C: J& w' }+ p3 N# y
                    p = NextArc(u,p);
    0 C$ A3 M$ O, J6 N5 l/ ]            }
    7 P# W* g7 l6 {# T+ _5 W" F        }+ ?& r* V% p/ F. s! R8 i7 U
        }
    4 @/ m; z* Z  C}
    ; k% y( B9 }! {, g7 e///深度优先遍历& y! p: Q) C7 a( ^# e* c/ E
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)4 W. w2 f# u3 H# G8 g( j: P# d
    {
    # \8 s1 V* X$ u' I6 u/ P1 k$ V    tag[v]=1;
    , B  U6 T. h4 ]    cout<<setw(3)<<vexTable[v].data;) I5 ]1 j1 {' m  I7 v
        MultiAdjListNetworkArc<WeightType> *p;) C+ E0 w. Z1 ~* ?# m
        p=vexTable[v].firstarc;. l7 Q; g' i8 M- s0 ~4 _" s/ {0 m8 B
        while(p)
    5 r" x, {( f2 |" z1 S3 u* ^    {# Z+ u/ S$ t5 ?
            if(tag[p->adjVex1]==0)5 C6 @2 m9 f+ B: K7 e/ ^
                DFS1(p->adjVex1);
    ' N8 R, b% G5 x0 q: X6 d5 G        else if(tag[p->adjVex2]==0)
    9 Y, q! E- D3 M1 N  R  |            DFS1(p->adjVex2);! p5 M- R5 e7 b+ ~8 }+ L4 d& i1 E
            p=NextArc(v,p);
    ) l0 A4 E- ~" E; l9 y- U    }
    ; m4 m. @" X! P3 H0 a9 G8 y}
    6 P: w8 Z" J. k. d8 p: Ttemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    * b+ ]6 V) ?) g6 ?7 Z& k{
    + s8 k: J4 {5 ], x    for(int i=0; i<vexNum; i++)
    ! A: |7 a% P' V        tag=0;. _" c8 `/ O' F/ n9 y
        for(int v=0; v<vexNum; v++)
    8 ~9 E  X1 f) b6 ^    {) ^/ {  U- L7 J( c' v- `
            if(tag[v]==0)( x9 K* @. a( w: C* e
                DFS1(v);
    1 T( a! Y& ]! T1 h- Q! r9 H9 h    }
    1 C: ~5 E, E4 Y; h* I% G' M- S}* o% w+ }7 l5 C+ @
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    ' _7 B/ p9 f/ Q( V7 s5 S{) H- e" L* R( g
        stack<int> s;
    ! T/ J2 B, u9 C2 u: H$ N    int tmp;
    ( T1 u) w* V' V, @0 ^' [" x* `    MultiAdjListNetworkArc<WeightType> *p,*q;% y! E' h9 z5 R4 i! d
        for(int i=0; i<vexNum; i++): B$ {/ Y: I) ?; r" n  Q0 r
            tag=0;# t5 W7 P' X' g1 f1 f' r5 _2 z3 ?- K
        for(int i=0; i<vexNum; i++)& ~: R$ x: U& _' G5 c  V% q+ |
        {, P6 w" V1 c  q8 o9 Z* O* K& o) S
            tmp=i;3 K2 t" k' T7 y7 I
            while(tag[tmp]==0||!s.empty())
    3 s; \4 o+ R, a; c9 j) E& {        {
    ; L5 j$ i+ Z8 X1 j; A7 d1 l, z3 A5 L            p=vexTable[tmp].firstarc;4 e7 i3 \1 [$ W  D- Z
                while(tag[tmp]==0)# U! P& L: r: A" Q4 ^! J
                {: p% l% e% H+ E: D4 `( ?
                    s.push(tmp);  b, E# h4 j. T3 \# R
                    cout<<setw(3)<<vexTable[tmp].data;- V+ N# w& W6 C$ `
                    tag[tmp]=1;
    3 }6 V  w  J" P7 k! P3 ?; _8 h  P                p=vexTable[tmp].firstarc;
    * x. m( t4 H: i- b6 t                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for; x" V1 `) V' R7 t0 W+ R& `: S
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    ( @$ ^7 m- J0 i1 X( t                //cout<<" 1st     tmp="<<tmp<<endl;
    ; ~- J% p" P& Y" g8 u! ^, n            }
    ; v- E, s! C$ n            if(!s.empty())* H" H3 x' }  k, ^% }( x, y
                {0 P% O4 @5 w$ O9 B; k0 w
                    tmp=s.top();
    ) g5 O( ]3 W6 D5 p9 O" H                s.pop();
    + J4 e8 Y2 r1 t2 y0 X+ ~                q=vexTable[tmp].firstarc;
    % G) g) h3 ]  D/ N                int t=tmp;  L0 N8 _# t# f$ G: i
                    while(q&&tag[tmp]!=0)
    ) C* o0 j5 w0 Q% D                {
    . Z& G3 k9 g: ~! m) q                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);& |2 Z  q* L" u" n
                        //cout<<" 2nd     tmp="<<tmp<<endl;
    9 j2 D) q. |6 Q1 T# L% W5 [; Z                    q=NextArc(t,q);
    , ~' [' E, R/ n6 z6 P/ m6 z. \                }
    " C( z% Z; s* d' O! `+ i9 ]                if(tag[tmp]==0), b1 r; B- d0 @  q
                        s.push(t);
    " T4 R: C+ O' E) b. H& M" K                ///1、对应上面连通分支只有1个点的情况: z, [+ `7 L) V, p
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈6 m0 C; U& O2 `! {5 v
                    ///tmp要么等于找到的第一个未访问节点,
    3 O* ~" g: z# k& S8 \' L3 L                ///要么等于与t相连最后一个点(已被访问过)+ i  f3 m5 M, J% }8 f9 {. C" H+ y6 X
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点
    " S4 {2 Q, d. V! k7 V: s            }
    : E/ C( E; J8 i, ]. S! O* h        }; w9 o/ @& y2 O
        }
    ( A, f1 L" Z8 m& R/ j}
    4 Y! o2 g- b1 Q+ \//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    , L- t' _* h( H6 i/ _4 vtemplate<class ElemType, class WeightType> int
    : e" K$ ~; R: ^' U$ R9 vMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    & I6 c, b2 \7 q; T" z' r{* D9 I9 i7 f6 E7 t( d1 G
        if(head==pre)
    . s( E7 M" g! D        return -1;
    / n3 O. [/ c3 U+ K9 `0 N0 Z6 e5 k* P+ T4 }* J
        MultiAdjListNetworkArc<WeightType> *p;, R, \& s- R8 K. k+ r9 S, Y
        p=vexTable[head].firstarc;+ ?4 s9 S4 N: N
        if(pre==-1&&p!=NULL)
    $ Q1 @1 y- R5 v2 S4 r4 f        return p->adjVex1==head?p->adjVex2:p->adjVex1;% v: `: g/ g( j$ V& h
        //pre!=-1&&p!=NULL
    ) _2 M% l( V/ l& U: y, i1 X    while(p!=NULL)4 k6 c: \6 f+ X
        {
    ) Y7 z* F+ v0 }8 N% T1 e        if(p->adjVex1==head && p->adjVex2!=pre)- Q7 b/ ]6 I( u% l
                p=p->nextarc1;
    * G  d+ c' {) f  r% L        else if(p->adjVex2==head && p->adjVex1!=pre)
    2 {7 P+ o) Y1 I/ l- _            p=p->nextarc2;
    & u% @2 ]7 f* |" G# o5 X1 p        else if(p->adjVex1==head && p->adjVex2==pre)) T; A- d; t& B- i* w
            {
    $ R$ p8 o$ S2 ~5 Q' |* {            p=p->nextarc1;  z$ D1 m( D* g
                break;
    3 Y* M  v& l, T# G        }
    " y$ ~, V* o: n# @8 B2 ?6 b        else if(p->adjVex2==head && p->adjVex1==pre)
    1 @" w7 D2 R2 l+ c% ^( l8 Q$ H8 w        {
    " y  x% B; Q/ j4 t4 w2 E0 v1 e8 ?            p=p->nextarc2;
    4 J) a2 a% e& z3 B$ P4 y            break;
    / u, M& ~1 _$ `& H2 I$ g        }6 E/ q! n7 S7 E6 l; b% Q$ D! I
        }
    ) b% N" j/ n/ F, I    if(p!=NULL)- g& ^0 |& Q" {; k( j
        {
    9 ^& e$ O# }4 P0 O4 d        return p->adjVex1==head?p->adjVex2:p->adjVex1;
      u' `$ O) I6 N5 o( K3 x    }& ~7 H/ M, Y- ]5 V
        else
    ' Z( c- y' D) b+ s" D% y. U        return -1;
    & c( M) \2 G& H" _8 B$ a7 T}
    " ^( q+ W, n2 N  }' X1 m: J( l7 ?* v- J0 C
    3 _1 w) Q" [- \7 `; [# \# Z' @% o' {
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    9 s, A, p& O) P& E& f+ b, r{
    ; c) O- Q8 k1 f    stack<int> s;
      q# F) P. o7 u" W8 u0 C    int p,cur,pre;
    " l  ]/ O2 Z# S" e+ p0 j    //MultiAdjListNetworkArc<WeightType> *p,*q;
    - g6 z3 q. _7 p7 @" J, H" F    for(int i=0; i<vexNum; i++) tag=0;//初始化
    $ R9 N. P$ i& y6 r1 M- Q# h% \% v7 |$ e% L7 ~
        for(int i=0; i<vexNum; i++)4 P& C$ V- B3 X% G
        {
    6 g" D" a; S6 i5 M- u        cur=i;pre=-1;
    ) X7 I& k1 g' K  h, M        while(tag[cur]==0||!s.empty())
    / L7 @( H# F& ^5 ?" w- Y        {2 l8 `6 t8 ?3 z0 u8 |* y
                while(tag[cur]==0)
    + F, w$ j) r$ [# X1 g, b% o            {
    ! e) _3 {; l  b7 E                cout<<vexTable[cur].data<<"  ";
    7 v8 g: K% |# e( T2 }1 w9 c                s.push(cur);
    9 o7 R0 a' v5 T$ s$ ?8 t! r# j- }                tag[cur]=1;: L8 t) l' ^6 ^' x" U0 Y3 Q
                   //初次访问,标记入栈
    6 A6 F; |1 m1 T6 B8 Y$ e0 T* Z/ q9 h; s7 a4 _& ^8 k# i& ^+ M7 O1 K" f
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点7 L: P: j$ _' K2 h
                   if(p==-1)
    $ Z' \% a7 j0 ~# r               {6 u8 S* i# o" c3 D! T) W* J& l9 D
                       pre=cur;s.pop();) A' O9 n( t" \2 K. U9 P
                       break;
    & u% e+ m# C. I* u+ d               }7 G  W7 y  |' P! r! T+ U: k
                   else7 U, w! q/ i, i* J& i
                   {
    / s9 F2 M1 w0 R$ ^, |6 r  ~                   pre=cur;, @; y" Y; ~- L: q$ g8 R
                       cur=p;
    # R$ V7 w' s* k7 I2 S% [9 l               }
    6 i# D0 K" S% s; g' G
    % m- W" z3 }$ A2 \1 S& M, S) d            }0 e1 ^' P& v7 ~; @4 |
                while(!s.empty())
    " t) ~" U; i! E& h$ X9 |- C            {
    ; M/ I, A% ^- w6 v                cur=s.top();1 t0 C$ A/ Q8 l; C8 [
                    p=GetAdjVex(cur,pre);! x+ [, a8 z' d: h0 K3 }) ~" N
                    if(tag[p]==0)9 A" Q( P- R/ c# `8 M* V8 t* a) R
                    {
    6 R9 `, R, K% u7 o/ @; M. @9 h( S. {                    pre=cur;
    * B3 c1 u" v' h6 r                    cur=p;
    5 a$ V$ |3 C4 |! h" B! E0 y( @/ a' u                    break;7 p, x, }( E+ y" |
                    }
    8 z. x4 u' X8 Y. m# r6 W                else
    & I9 n7 K5 o$ e8 ^" t2 N3 Q3 O* H                {
    : a- g; x$ V. K                    pre=s.top();+ j& H# b4 l1 I7 U$ o
                        s.pop();" r0 M2 H) ?, H+ ?. S; [1 e
                    }  B' z! u; E+ O2 l5 K2 P
    0 f& s3 o/ l# W8 e, B, ]
                }6 ~2 c7 N  R, u0 a
    & z+ k& V/ _+ O5 i; x7 J3 C$ o" W
            }- T8 K: R9 \" P* m3 M
        }4 _  L$ I; J- l; E
    }
    " @: L- B/ h6 K" b/ |& Ktemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    8 X" u6 U/ L' P$ w1 D{
    8 X1 G( s! H: X: u' R    for(int i=0; i<vexNum; i++)
    # \5 {3 I7 F6 _; i& c        tag=0;
    ' c- V8 D% A) `! M    queue<int> q;; v$ M7 U5 J1 I4 s
        int tmp,t;
    9 P7 K4 `% L& W) A    MultiAdjListNetworkArc<WeightType> *p;
    7 X: ?' S0 w: z; D; B) L& _" Y4 }    for(int i=0; i<vexNum; i++)
    % U/ k  ]8 L" Z9 f+ J6 R    {  J& x4 Z2 r8 N9 `2 Z
            if(tag==0)3 m# F' f0 L$ P+ x( I4 K
            {
    ) M, c- ^% I/ l0 v! [$ c) f) y( m            tag=1;
    0 q1 [0 f* p8 ?3 r, k            q.push(i);+ \/ Y: Q& Z, E
                cout<<setw(3)<<vexTable.data;
    8 @+ v1 U7 X0 _. j  }  e+ l        }7 }7 G- e* i2 J# E
            while(!q.empty())8 `: _! O8 O% a7 {; k6 p, z
            {
    & j5 E. k( c6 `- @5 T5 ?            tmp=q.front();" o* p0 S8 B* ~3 O) r1 j
                q.pop();
    % m& l% B  p! I$ u4 W3 O            p=vexTable[tmp].firstarc;
    2 B- Z' f" h6 ~            while(p!=NULL)
    8 J0 p" _, |* i% r            {
    " U8 t6 L& h6 B7 ?" z" P8 i                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    ) K: s& A% f/ a; O                if(tag[t]==0)
    . t- `1 T# N8 U8 @  z: I" H                {5 Y- j0 U5 d3 p, H- Y4 O
                        cout<<setw(3)<<vexTable[t].data;
    0 ]; d  ?) w5 k- h/ X                    tag[t]=1;1 F* _0 _0 {2 t
                        q.push(t);
    ! e1 M  W) H/ U* ?9 w                }
    ' }! p$ q8 v& w9 D( R4 i( H                p=NextArc(tmp,p);
    & r: G; q' ~$ f            }
    9 b6 N+ i3 ]6 C  f/ j: X; ]        }2 B0 d, ^4 g3 b; N: s
        }
    / o: \9 \& n+ N! ^0 o& R" U}; L/ R6 _* W3 |  Z, ~$ L
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()$ T  @3 x2 |/ N/ z2 G( f: K
    {
    ) R8 n* R% S+ }    MultiAdjListNetworkArc<WeightType> *p;( U$ O* g2 t- A, T2 H& s  k! z
        cout << "无向图有" << vexNum << "个点,分别为:";9 I4 u, {7 z1 s$ U1 _
        for (int i = 0; i < vexNum; i++)
    0 ^( ^# Y1 |- @4 D) N0 E8 B        cout << vexTable.data << " ";
    1 B3 M$ A( `* P$ e    cout << endl;% i6 i  k( k6 H5 e  S
        cout << "无向图有" << arcNum << "条边"<<endl;+ R0 o& Z: |0 J1 p5 |7 @
        for (int i = 0; i < vexNum; i++)6 u6 u0 m) o- y0 V( H/ Y& y) U4 B7 T7 ^
        {1 q/ a5 L. n* G$ G
            cout<<"和" << vexTable.data << "有关的边:";; A2 ~- ^' u3 r8 k, Q
            p = vexTable.firstarc;5 h# w; [& r1 _  B+ f
            while (p != NULL)) B% Y- {' d2 k! Z; ~- x
            {
    . \( Z) ^+ `- b: d: F            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    ) k: l1 {4 }+ X7 R: r            p=NextArc(i,p);& `* L/ D2 Q* y) I" N
            }+ E* [! e, B" q6 h3 `1 A6 ]
            cout << endl;3 E) Q) c3 j$ u6 L' ^& a
        }. |1 @# n! g: e
    }
    # f' B- w' B+ b$ D! a8 I. s) r, \& [7 d( g; H* t6 l+ z
    1 p" q6 o# z" {8 I
    邻接多重表与邻接表的对比
    ; K. [* |" m' Q6 j( ~3 d: p7 [: ]5 d- z- {$ z. p- g( n, y+ U' }: q
    邻接表链接
    1 _8 s/ s; k, Q+ A: G! _在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。1 [" r# V& m- q0 U. B8 ^6 a4 Y  `
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。+ q4 f# e+ O, _$ J4 [0 ?
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。! w* a$ T% ^( f' i% }, m. y1 i) \
    ————————————————
    7 \( `4 r& }0 E% C版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。. K9 f4 T9 K. j" Z9 i, P! F3 O6 W
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958, i# i+ y) K1 I9 C
    ( }1 R! ~% _2 |1 s4 `

    2 r2 k6 h8 `/ D9 \
    & b# y' R. o4 J8 \6 ?% M4 V! W; Q) G9 y+ i
    ————————————————
    4 v! H( R0 W: C& L. @/ |版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。8 z6 Q) ^" Q9 o2 v9 E
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    9 E, i3 M4 A3 H2 Q% O
    6 z( W( G, C6 w- q% d5 p, Y5 U$ i$ ?# O0 G
    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-7-25 05:07 , Processed in 0.731953 second(s), 54 queries .

    回顶部