QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1538|回复: 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
    0 V. j" t! B# Q" o
    图的存储结构——邻接多重表(多重邻接表)的实现
    ( `6 _5 D4 F7 U; f, p7.2 图的存储结构5 M- O2 n8 i/ @  I+ }
    , m$ b8 q' p5 ^2 P+ J) e
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    4 u9 U( X) v# X7 s  n* L邻接多重表的类定义
    $ f' q  T: B0 K2 f; v邻接多重表的顶点结点类模板  u6 B, a. d1 v- s# N
    邻接多重表的边结点类模板
    1 N, @4 K+ b/ V9 y  P) r+ c邻接多重表的类模板! v3 Q# y* e4 E# n2 K! K
    邻接多重表与邻接表的对比9 Y% ]5 D2 j# Z
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist  Y! E0 d, e5 Y1 k# q6 G( F( d

    " p+ i! R- h, D  o7 ]在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。  P! X7 y/ y/ }& R: x* l4 e7 ]( z
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    - I7 p$ `0 e$ B5 w% {; U' W$ o9 c8 m: W' b9 z7 E
    邻接多重表的类定义/ V) i2 U, l. ~, M! {0 z; H4 c
    1.png ' c% s1 A& J* E$ q/ @7 L! R- F3 _; Z
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    3 g! d  C1 A1 ^2 W+ Vdata域存储有关顶点的信息;
    3 P5 Z9 F! ?, l& T% efirstarc域是链接指针,指向第一条依附于该顶点的边。7 U. u' z5 |: h
    所有的顶点结点组成一个顺序表。

    3 e" q1 z, P- R" @* ?; E$ |

    ) }; v/ n8 w/ F9 Atemplate <class ElemType ,class WeightType>! @3 q- i8 U: x" R$ h4 @! j) y0 C
    class MultiAdjListNetworkVex
    5 v1 I- N! x% F5 {. A' n{5 T& F9 z6 [( K3 F
    public:
    ; x; X8 l) q0 B5 B  u        ElemType data;. Z6 b+ U: m9 N. {4 |. H& {
            MultiAdjListNetworkArc<WeightType> *firstarc;
    ; q- D6 O$ B; O1 b5 K" h% Z! K! D- z! D6 j" T
            MultiAdjListNetworkVex()
    6 S! V# W" n& H4 b; }        {6 g9 o& N  d, ^# R9 h* U+ L
                    firstarc = NULL;
    8 O* f. u  c4 h  x/ k        }' r. j/ @* B1 g# s% S# Z  r8 c/ a
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    1 V/ e, p. J0 e- b        {
    * Y( n& E3 m1 W: X5 |! q2 R$ d                data = val;
    ) j; F0 J6 s8 \+ r7 k, o% v7 u& Q9 H                firstarc = adj;
    + o, {6 o7 `% C4 j0 ]/ j! m        }! W" N" V2 f* `" g& {& z4 U# _
    };3 K, K: }" B1 h% V$ d' p
    7 m0 k0 \" s7 F' T
    邻接多重表的边结点类模板
    6 Z$ l: G- I0 g- |2 B9 k7 o! H  `/ P! N) G" _3 R; e# v& `4 @# y
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:- V/ m& `: Y. u5 m% A  P: [' L% Q
    tag是标记域,标记该边是否被处理或被搜索过;
    4 H7 \8 t* A7 m" Z2 @, Pweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;' Y! L. L2 u0 P6 g
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;1 m- R. d8 @: u( \% u5 v
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    - e: ]9 Y1 d; T/ n8 y
    & ]  E% e, O: ] 2.png
    8 n7 v& C5 c6 k- K. L/ T- h; Btemplate <class WeightType>2 C( G* g: p8 ^+ N  N  D: n
    class MultiAdjListNetworkArc& M( }2 B7 P  Q3 n% O1 ~1 |( w
    {
      i( B9 Q! d5 g& g7 u7 F4 C! rpublic:: h  a! Z0 z3 K' S: `* ?
        int mark;                                       //标记该边是否被搜索或处理过4 x3 M$ g) X7 j! @- C& D
            WeightType weight;                              //边的权重5 Q/ P7 R$ o  l. A4 k
            int adjVex1;                                    //边的一个顶点/ \1 x! o9 W0 a
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1$ T/ {1 T" r, _! E  G5 T
            int adjVex2;0 n; q) n+ W3 e% m" c
            MultiAdjListNetworkArc<WeightType>* nextarc2;. N6 v! J2 U- Y6 `- l0 t7 C

    ( _$ [( ~. K0 ?- S$ E& E        MultiAdjListNetworkArc()' o; o5 u; x! ?' w0 x& d- E
            {% F& N! X8 Q8 I
                    adjVex1= -1;
    * F, O& J, p1 b: n                adjVex2= -1;& D3 x) ]8 c3 ~! g$ @1 i$ v& v
            }
    3 ]9 K# D' L- X( w, k( A        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)/ S* y( s$ N- B/ H& T
            {
    " p! k) B$ q( c- M                adjVex1 = v1;       adjVex2 = v2;
    2 I. F( q: p+ p2 I& {                weight = w;
    . D. q9 ~1 w, h7 m" B                nextarc1 = next1;   nextarc2=next2;0 t6 l& X9 F; B- L4 ]
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    + }$ O" p$ v0 ~6 n; E        }/ c2 X3 B5 q3 M/ n% Z
    2 H; G' C( |2 \( \$ {( B( T* {
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    , ]  `4 Y) I. Y1 iclass MultiAdjListNetwork1 G  {" k# E; }$ G
    {9 k$ E( Q7 H, U
    protected:; o/ j0 y2 @' P4 v7 R
        int vexNum, vexMaxNum, arcNum;/ t& Z! J+ s8 I. F3 e/ _
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;2 n) R2 Q# b1 B% c7 U/ f
        int* tag;
    ' |! T3 L" o2 x! Y" Z    WeightType infinity;
    # m* Q' h: N4 E# i# S) I9 Z6 o
    * y+ V/ L4 {. [& X" spublic:7 E) l  a- v% B( T
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);" A6 |3 ~. n/ L* }" v  U4 p

    3 k/ l, |1 U* U8 k3 L/ v# e2 N    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    6 G0 R8 ]' }7 z4 `: J! M" Q+ N- q' t% j
        void Clear();
    & s+ B0 w/ J- ~' o    bool IsEmpty()- Y$ t9 _8 I  |. ~/ z3 {5 b
        {5 Y9 I! F; V0 A& S8 V  |, M) ^. L
            return vexNum == 0;
    - L5 E) a' G% i% R    }  T+ W; |% K: ]0 B8 ?6 E) c6 H
        int GetArcNum()const2 k: n- }! g  |( b: p5 P! z: w
        {
    2 g# }: e# v* a( t        return arcNum;
    " g$ |' V( _8 p+ n: b  w0 l    }5 l7 k" q3 t3 @  G7 F: \
        int GetvexNum()const
    8 V6 Y# O& S0 E    {( d2 n2 p: v" _( ]+ Y( ]5 E
            return vexNum;
    * e- Y) a7 y; X1 z, Q" ]7 M( \: @3 x    }% `" p0 R( \: \! M! h" H) {
    % X8 s- ?$ p5 A& K! H1 k  i% T3 e

    * x' d# T' t' U) l; D    int FirstAdjVex(int v)const;# b. D2 o1 b( a: Z
        int NextAdjVex(int v1, int v2)const;5 z2 A/ `5 U. w$ t( W
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;* ~1 V/ ^4 F+ H9 d+ E, I
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    " P: T  l# E; E" b+ s3 s: G) s% J: V" n1 i" a" m( S$ u8 ?( q
        void InsertVex(const ElemType& d);
    2 ?) G% }0 V9 F% i6 c$ u! ^$ o2 f    void InsertArc(int v1, int v2, WeightType w);/ u5 L" D2 ?( ^, M; T! [

    / r, {3 E7 K8 X# u    void DeleteVex(const ElemType& d);! W( C; N: K* q, H
        void DeleteArc(int v1, int v2);2 t+ H$ l/ W$ i/ q- O7 ?0 R: u

    : w/ ^2 ]: }& s8 r. r9 H2 |    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);* U) ?4 B% R5 {, f: f$ n0 N
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    6 m3 H! H, r8 k; w* H3 a+ [; ?, Z5 D/ K( q. _$ b! ^. M
        ///深度优先遍历5 [9 M9 y2 \! Y$ D! u/ c
        void DFS1(const int v);
      @& s: e2 `0 K    void DFS1Traverse();
    ! N# X! ~0 }9 j2 W    void DFS2();  y& a$ T. A4 O( z+ O9 p
    8 _+ j0 A) k: _- a. D
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    + ?0 j4 ]- x6 z    void DFS3();
    + t- ]" p7 n( ?0 {8 k; Q5 m
    ; B! U+ `' t% n' v    void BFS();
    - T) J1 e: P! ?) y  A+ z    void Show();& N! K  G% H9 E/ E2 U0 Q) z
    };
    # t7 I- f6 e4 {( U" q  V$ L; k; o- K3 {+ E. o! t. }
    2.函数的实现
    + @; T: j" u- t6 F研讨题,能够运行,但是代码不一定是最优的。) W7 ?3 _% e8 m# J2 Q

    * j' ?+ w. i3 F2 W6 \#include <stack>
    2 Y1 W+ F4 o, Z3 @, [#include <queue>
    2 G# A2 H# U- U5 X3 v' Y' B0 C3 `7 b) k
    template <class ElemType,class WeightType>
    " H/ n& r- W4 x' S' kMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    " H$ n7 Y) s* p, u: L{
    * n/ Y! D- R. N: E  {    if(vertexMaxNum < 0)2 l* K1 i& ?/ l/ L9 Q6 _& M
            throw Error("允许的顶点最大数目不能为负!");
    " [3 v4 V+ `5 }0 @6 y    if (vertexMaxNum < vertexNum)- \1 @" M2 X" H- H1 k! S& x
            throw Error("顶点数目不能大于允许的顶点最大数目!");
    4 S) k$ \0 Q6 K( ~9 i    vexNum = vertexNum;% `5 w3 u9 z/ J8 y" |/ a$ {2 D
        vexMaxNum = vertexMaxNum;
    : K3 Y' q& q) l" d0 b/ M    arcNum = 0;: N6 s  ?0 P/ z+ I
        infinity = infinit;. N& t2 q7 Y1 Q% ^) E" B
        tag = new int[vexMaxNum];2 J% w/ u1 W0 t7 t7 @
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];% w5 {7 N1 j" r
        for (int v = 0; v < vexNum; v++)9 _! e9 a% [0 S, e+ y% [6 r
        {
    " r* ]& U# \8 l- ]. I        tag[v] = 0;
    & U( l0 z+ Z* k+ U$ P        vexTable[v].data = es[v];: p2 m/ f* G  u6 W' X* i
            vexTable[v].firstarc = NULL;7 f0 \7 Q  j+ H) e$ C
        }
    & E' e; E5 ^" g6 o( }0 P0 }}! \% E) N  b5 T% }+ ^' J, B$ D/ z
    template <class ElemType,class WeightType>  y, j0 r* O$ Z/ c$ Q4 X' K
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
    ) C: F  B* u! R{
    $ m% B4 Z# ^9 [9 r' _    if (vertexMaxNum < 0)
    ' V4 ]" {( L8 r8 J0 a7 U( ?7 _        throw Error("允许的顶点最大数目不能为负!");
    . v7 M# m! u3 p- `1 {: g! B* N- X    vexNum = 0;2 W! S, d$ |- R" ~0 P" b
        vexMaxNum = vertexMaxNum;: {$ @0 C% m+ l# q3 }7 Y
        arcNum = 0;3 Q$ A0 R2 O% D/ n0 _4 I- B+ A
        infinity = infinit;
    + n; C& R+ x6 B1 Z9 v    tag = new int[vexMaxNum];+ p0 {: ^5 W' f" O
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    - ]' P8 c2 F) j# @3 B, t) p5 W! o4 G}4 U8 b* l% l. }1 v" m
    template<class ElemType, class WeightType>- J4 e  N2 x. t7 C" F( F& Z; v
    int MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    4 k# H* e- m& i0 U3 N{' Y* `3 c: M* ^
        if (v < 0 || v >= vexNum)! V) g" }5 _: k; E! ]
            throw Error("v不合法!");
    - m/ Q/ e: Q3 p3 t  c3 S2 k- ]    if (vexTable[v].firstarc == NULL)  Z3 U4 A/ O+ O' n$ N! t
            return -1;
    " R2 I3 i' I" R0 P5 E' @: v4 i1 `    else" q' ^- B# H7 @( q% }5 C* U
            return vexTable[v].firstarc->adjVex1;2 `: P( L# _+ T
    }
    9 ~1 C; j! {. g/ H" _4 e4 a( ?* b
    5 l( q5 X5 h+ b: a) g( k8 |" @template<class ElemType, class WeightType>) Z; E4 f) n- k0 a& N
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    7 y( @% }6 Y1 [8 Z. a4 y{$ {2 J7 u# X1 R/ q/ R) l% z3 ^9 C9 _
        MultiAdjListNetworkArc<WeightType>* p;
    $ X0 K6 y8 s  [) i( U    if (v1 < 0 || v1 >= vexNum)
    5 ?: w  i& n7 X  n  W' q" x        throw Error("v1不合法!");9 Z! t8 d3 o( e; [, ?
        if (v2 < 0 || v2 >= vexNum)8 k1 C1 w& m7 e
            throw Error("v2不合法!");
    4 X1 r/ e' C, P" x& ~/ S% V; f    if (v1 == v2)
    1 ?, Z6 Z+ ?# [% o4 H        throw Error("v1不能等于v2!");, T. u+ c8 R9 q: ^0 A+ F8 Q
        p = vexTable[v1].firstarc;
    ! W; [6 w9 [# l. c! r) U7 d8 t5 h    while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)% k2 Z4 D+ G, p$ F3 A3 ]
            p = p->nextarc;2 u" J4 |# i- j& o& e
        if (p == NULL || p->nextarc == NULL): [% J5 u6 s" G  s$ ?4 d! F  T
            return -1;  //不存在下一个邻接点
    ! g# g$ b3 C/ x    else if(p->adjVex1==v2)
    7 G7 [, N; _& [7 w  O' Y" E        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);
    & ]/ s2 G) o0 t: `: S: [7 i/ L: l8 a    else% K5 R8 M/ T3 l7 n, P5 A" Z
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
      ?1 g; w" ?2 o% A/ [4 ]}
    . O# t" j( l) N- l- wtemplate<class ElemType, class WeightType>% W' {6 F4 f" W/ M" q
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()
    2 _, f5 D7 _2 f8 {& G. H{  p/ d  p2 D7 T" ^
        if (IsEmpty()) return;
    & H4 x, Q2 R( o) w; [- C8 f    int n = vexNum;
    2 y7 [: c: N7 m7 d/ c8 E    for (int u = 0; u < n ; u++)8 U9 ^  ]6 {& x5 m( h$ o
            DeleteVex(vexTable[0].data);
    - K/ i6 P! f, H, B( t$ G6 |    return;
    / L: U% X- Q5 W5 J/ y, N}
    3 s# c# r5 r/ jtemplate<class ElemType, class WeightType>9 k3 L, E. B. f& N* x: N. x9 L1 I9 q1 M
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork(). L. p- J" m; O
    {
    + E9 P6 n7 B) H/ r2 A) b( h1 z+ ]+ \    Clear();
    % Q1 f, M+ N: T' b1 Y) o+ f}" g; r/ m0 w% A8 h: T' B. V4 u
    template<class ElemType, class WeightType>
    " p6 g' S) A1 `2 I# F; wMultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)! [# p2 o0 Y. k3 m% u
    {
    0 j( o* m; g* E" S    vexMaxNum = copy.vexMaxNum;& X" _, ~" X8 ~* ~
        vexNum = copy.vexNum;* ?* Z1 y- L, I" R$ U( K3 x# ~
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    + J- v% o) s9 n" h, X& C2 I% I1 b    arcNum = 0;
    , \2 \8 B4 `( u* v7 }8 [) x    infinity = copy.infinity;& U7 b& v1 C7 h9 C8 A( E0 m
        tag = new int[vexMaxNum];
    2 Q6 n: C2 i: K' K, ]5 {. S
    2 m1 m0 K' X8 f! M( q9 z( Q; a* ]    for (int v = 0; v < vexNum; v++)+ M! q6 t( P" L2 [" V- [
        {
    - h1 v( j0 r+ `! k; W' ~: K        tag[v] = 0;
    ' E5 \5 d1 a$ F. e" s3 X/ w9 {        vexTable[v].data = copy.vexTable[v].data;
    2 h2 D3 F) f& x. e( U7 M& ]        vexTable[v].firstarc = NULL;- c( j# H9 o& C8 @8 b/ T
        }& ~- V+ @4 u" k; A! |/ R# X% m' U
        MultiAdjListNetworkArc<WeightType>* p;; x* x& H+ h/ {; v! |) ?
    6 @3 y0 o% ]: C- B/ o
        for (int u = 0; u < vexNum; u++); q$ t' I* j8 T& H& O9 L
        {
    2 Q9 v1 e1 x: k/ c        p = copy.vexTable.firstarc;+ T% `9 c) Y. B: I
            while (p != NULL)! x  V' @/ [! E$ l7 U+ K
            {& H- m8 ?  K1 t4 q9 ~9 Z$ w' V
                InsertArc(p->adjVex1, p->adjVex2, p->weight);: Z9 l2 H* d4 [1 D6 i
                p=NextArc(u,p);
    % w9 N' ^; W: Q: \# R        }
    4 A: w5 |7 |2 ~0 t6 w! l% f    }
    : X4 Q% P/ x7 W% S; E7 r}$ @- j2 m4 a! ]+ f7 ^" R
    template<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&! X& V* T! d$ Z
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    7 T+ ~  {* O" V{0 B# [/ y. _/ t- k7 A# G; @# P  F
        if (this == &copy) return *this;3 u( w- m* Y6 c2 r7 o9 N% Z
        Clear();
    " ?" u5 p' d" O" q% M    vexMaxNum = copy.vexMaxNum;
    6 o! X. w  M: l5 A7 L    vexNum = copy.vexNum;' T9 W/ A, X  K1 I* r
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];4 A2 Z- x( z9 a$ b# k4 L" j
        arcNum = 0;7 f, t& h8 X! ?8 J" I& R9 L
        infinity = copy.infinity;. l- o* T4 S3 t" e) M9 Z
        tag = new int[vexMaxNum];: d% o$ b' `; c% L; w

    8 v) x6 b: c% h  Q4 R+ z    for (int v = 0; v < vexNum; v++)# E7 u* L- n3 e$ v; G% W. W; Z
        {/ R0 q+ t: K8 m3 j8 k2 M3 q- F
            tag[v] = 0;* j7 [3 u. r) Y' K4 |
            vexTable[v].data = copy.vexTable[v].data;
    . S0 j3 K: ^1 j5 m        vexTable[v].firstarc = NULL;
    $ q( s. j2 t+ r/ A    }0 K/ D( o1 `# S4 f& b3 H+ r- H
        MultiAdjListNetworkArc<WeightType>* p;
    2 O" a% |* L  W$ c* [0 `" T; _
    0 f5 s; U6 a. P    for (int u = 0; u < vexNum; u++)
    : c* e7 n! p& f  n4 J1 u    {/ ?6 s/ h$ \+ ~  Y6 `5 k
            p = copy.vexTable.firstarc;' i9 N: N9 a0 F9 p% V
            while (p != NULL)# z0 L4 }+ n$ ^& J1 A
            {3 w3 P. t  B6 d& Q' F: r
                InsertArc(p->adjVex1, p->adjVex2, p->weight);3 I, r( g  ^8 K. D6 M
                p=NextArc(u,p);$ a. }4 C4 {8 e9 i. }. _: [
            }; S3 [* z$ {" D( L
        }
    . _$ e& \7 [  ]0 `    return *this;
    : {; o5 G! q/ g1 s/ N}1 [/ W* ?! ~* S8 s; q$ T
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*8 \6 x7 P% }. z: c& {6 ~; d6 f8 U
    MultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    * U9 }' Z- U( s7 W' R5 X! N{
    + `. F3 G9 j. {: |6 ~% I    if(p==NULL) return NULL;
    " j! r& }( `: ?( Q5 p% d0 z) A% I; n& X    if(p->adjVex1==v1)
    + Q4 Z' ^" L& g, j* S% j5 W5 C        return p->nextarc1;2 a0 v7 w  ]- B9 y- `
        else
    4 z0 v* s9 c% W; N        return p->nextarc2;+ U5 _7 V/ @$ r6 @% u5 D
    }$ a0 m- ?4 k3 t% t! l
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*& p+ O+ j6 K. C- `. h
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const1 H8 F: d4 i( L2 r
    {5 R! `' x9 R( n( \: p) L2 W
        if(p==NULL)return NULL;2 q& ^; `9 r' `1 A& n. Z7 }
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;" m( _  U: p6 [% f3 U
        if(q==p)7 p" X2 x6 X$ p8 y2 q0 z( e* e
            return NULL;" w' ~- _% C8 C
        while(q)
    6 V/ R7 Y+ h( b  h7 ^" Y  N    {
    4 l" s. u7 p9 j- q4 C' b/ `        if(q->nextarc1==p ||q->nextarc2==p)
    6 C& S8 a& r' H            break;/ d1 t  h7 \  `/ d$ ^
            q=NextArc(v1,q);
    $ Y2 O: k9 S) Q    }2 }0 J, H6 d1 y
        return q;; M  g* ~+ O* N$ K' `8 R. {5 o
    }6 m7 ?" A- F6 e* W
    template<class ElemType, class WeightType>
    2 F+ U& w6 {! I; m& Gvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    ) k% r1 z  b1 q& e  J  K! R, y{) l$ P2 o' W7 L) A$ R
        if (vexNum == vexMaxNum)
      I. I9 d, Q8 U5 z0 N% U        throw Error("图的顶点数不能超过允许的最大数!");
    : L( @  T; K& u* n3 ]9 ]8 w    vexTable[vexNum].data = d;5 \! n9 p8 w" H
        vexTable[vexNum].firstarc = NULL;% Q  d5 Q  `6 D& n2 t, R
        tag[vexNum] = 0;
    3 F0 R* N+ q1 b+ p; H+ u    vexNum++;) x5 P; D2 P% R
    }2 h4 c: t" M4 j
    template<class ElemType, class WeightType>  @% f" y" _) x- M/ d+ J8 B
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)
    0 j) J' R: P# a& y{5 j% _' L' d8 ]) ]+ q& m5 g9 [9 o
        MultiAdjListNetworkArc<WeightType>* p,*q;
    ( R, D0 b* r) b& q2 L    if (v1 < 0 || v1 >= vexNum)' S6 Y9 q0 s) x( ]8 t! F4 ^; t
            throw Error("v1不合法!");% S' O* H% @) O4 n3 X  n3 f
        if (v2 < 0 || v2 >= vexNum)
    1 A: W3 X5 F! A* I9 J+ C        throw Error("v2不合法!");
    / K5 R! u" O" t( ~8 h: ?    if (v1 == v2)
    5 E# s+ M! j7 r  M; e9 k        throw Error("v1不能等于v2!");. x, H3 x2 E5 |+ ^
        if (w == infinity)
    1 b: j9 ^7 }) e8 f* s+ D        throw Error("w不能为无穷大!");) R7 |: G. T7 F$ i/ X( y6 q
    2 ?% N: O) @9 _, j( d+ ~

    % C' S+ b, ?5 e3 k) C  U: T    p = vexTable[v1].firstarc;# E7 V; A7 P" v7 ?
        while(p)
    + Q: G' a: `0 H1 m/ j( T    {9 S+ a/ a  G" C, S+ h$ `
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    8 O8 g: Z: w' u) E4 a7 X        {* |  y* P! ?1 w: [. e% _" N
                if(p->weight!=w)
    5 _" r5 X( Z3 k+ Q- U                p->weight=w;- H* o( a0 F- X2 v6 j  v& m" ?
                return;
    % V, F( v% T2 j8 J) p        }2 B: N1 c/ V# H2 ?  H
    $ s$ ^- q+ G& ]5 N" F
            p=NextArc(v1,p);
    5 v( v1 A6 z  M+ R6 U% b/ V    }! N( r2 L- f+ y9 N8 s& G" B
        p = vexTable[v1].firstarc;: B, P  |; d! q0 y6 X% G
        q = vexTable[v2].firstarc;8 o' u, P$ c! K# Y' h1 p
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法4 @1 I+ i' W. U, e$ V5 k
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    8 a* t' w  o+ C5 |1 [    arcNum++;! G$ q$ K2 o. N- V
    }
    " e' d+ S+ J* S8 A) M8 v) j
    + L  i5 J2 Q2 K$ e( D/ d6 J+ ytemplate<class ElemType, class WeightType>* S' Q5 s6 x9 J* {) C. n
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)8 U9 |( b0 I  a0 T0 H- A6 E
    {
    1 W, p5 h/ E, w$ O( i7 n! n6 C% E2 u' ]& A7 g0 f
        MultiAdjListNetworkArc<WeightType>* p, * q,*r;4 f+ {$ |4 ^9 E3 w6 \
        if (v1 < 0 || v1 >= vexNum)/ ^$ G$ _+ ?( W* f  F
            throw Error("v1不合法!");
    6 s* z3 I3 d# t6 M! A    if (v2 < 0 || v2 >= vexNum)( p* R' U( @0 M
            throw Error("v2不合法!");
    6 R& R8 I, S) X) d' z+ j    if (v1 == v2)
    * A. x1 u- M! G. E/ p' W9 b        throw Error("v1不能等于v2!");
    2 V0 @$ n$ }& _' a+ K8 i2 h0 ]
    ! T; O- r0 E) w$ R, o) d8 E    p = vexTable[v1].firstarc;7 r, {8 ~& I9 [! ?+ C7 X- M2 V. t
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)2 u- S" F" f2 @6 B' H" q* D. Z
        {: X+ i( `  H6 I" M9 a, R5 A
            q = p;
    ) {* W5 ^* x0 B# [& J3 ~! ]        p = NextArc(v1,p);- m6 q* P/ M4 A( X" F* ^
        }//找到要删除的边结点p及其前一结点q
    2 [) I- ]( R" O
    6 {  C) C( f1 H3 ?+ ^7 y    if (p != NULL)//找到v1-v2的边) p/ D# l3 `0 N4 y5 {. Z
        {
    + |; Q9 k) R7 M- s% t" Q$ F        r=LastArc(v2,p);
    4 }2 ^" r! ~  z& P& H        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL2 N; i7 I3 ^: U5 [! E
                if(p->adjVex2==v2)
    ! ^, l2 _- m" W8 k1 m3 g                vexTable[v1].firstarc = p->nextarc1;3 K) k7 R' E" e! I) Z
                else vexTable[v1].firstarc=p->nextarc2;
    ( U0 a# N0 n! V* v6 Q! w5 o! [        else//不是第一条边
    $ [/ }1 u1 L. k2 T9 o5 ?        {" B8 l4 Q. |% x6 a
                if(q->adjVex1==v1)
    7 r5 O8 }& s. J- Q                q->nextarc1 = NextArc(v1,p);' u; ]3 `7 B% M3 T% a! `
                else
    6 _3 u0 u4 S8 F: y3 R% @                q->nextarc2=NextArc(v1,p);: H. p& g: o! H9 g9 _
    3 \8 K9 p7 M) W# @) q/ L1 R
            }
    1 [' v5 {" p) Z; U6 I: h4 X" H        if(r==NULL)
    + G( O7 o2 o2 O' x4 k' b            if(p->adjVex2==v2)3 X: }0 n6 \# P
                    vexTable[v2].firstarc = p->nextarc2;
    ; m4 j2 }. B9 u$ g3 v; v            else vexTable[v2].firstarc=p->nextarc1;4 N/ |5 E; ]0 ~, i. G0 K- {6 G, t+ x
            else0 F% J- w7 M3 ?9 P& c3 g8 h
            {
    0 I4 n# C! m8 O$ O) @            if(r->adjVex2==v2)% n( H/ L# J  s' u  Q
                    r->nextarc2 = NextArc(v2,p);+ F% G6 d8 c- i6 B5 V* E
                else
    7 [) h; K" v. ]9 m  N: o$ l) Z                r->nextarc1=NextArc(v2,p);  o2 M( C; ^* S# W( F# k" ]
            }4 |4 B) p/ B& N( z8 |8 [3 T
            delete p;
    " R5 R6 {+ k3 S% o6 D        arcNum--;
    + \$ U* X' D2 Q) p, ]; B& y    }
    # Y+ G0 k5 G2 c% B( ~' S) t. R  k9 j; l. m0 `9 y$ v1 U( C
    }8 b: Z- q8 b" t7 Z/ u8 _% q
    template<class ElemType, class WeightType> void
      l& P* m) L$ X& @. W, @0 kMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    6 h* t7 t9 p" ~: X/ i0 I{' U8 K: J8 ?0 j2 _. y) a: _& f
        int v;! A3 V* m' O- ?. |& }1 ~( Z
        MultiAdjListNetworkArc<WeightType>* p;
    , N+ l8 d2 n5 V  O8 X) X    for (v = 0; v < vexNum; v++)//找到d对应顶点
    % T6 V$ s/ l3 @) t1 l) @, E$ X        if (vexTable[v].data == d)
    8 r/ `5 \! }' F+ c            break;
    % O! H( @: d  _    if(v==vexNum)
    : N, D; H% b& R        throw Error("图中不存在要删除的顶点!");
    1 x8 V7 W  h+ u" r! U  o- v6 X8 o7 V* C% F- b
        for (int u = 0; u < vexNum; u++)//删除与d相连的边* }% M5 d/ y' `, l7 W$ N0 J
            if (u != v)
    " o8 z2 g! J" T        {
    1 E" j. v1 y3 X* R            DeleteArc(u, v);
    ! P) [8 c7 N9 v* Z" w; \0 p        }$ @6 t: u" k7 K, V3 U" |/ a" m
        vexTable[v].firstarc=NULL;
    2 J" g7 {  @/ V: [. ]" P6 B
    8 w. a5 B$ ]; V2 q: c" p    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置
    ) t& [% M- Q' O. H5 I    vexTable[v].data = vexTable[vexNum].data;
    / b  q; [% F! b* O    vexTable[v].firstarc = vexTable[vexNum].firstarc;! ?4 A0 K' M, v' c/ l$ r, U. b
        vexTable[vexNum].firstarc = NULL;
    & f. N) W/ @5 l" Z    tag[v] = tag[vexNum];
    7 n2 @' Q: V. d9 h- r    //原来与最后一个顶点相连的边改为与v相连
    1 J, l1 G+ ?  O0 y# K0 D1 W9 T$ W    for (int u = 0; u < vexNum; u++)
    5 E9 ?5 a; ]6 I. G, p    {
    ; D! J! m6 ~/ @, J5 B! A: H) T        if (u != v)
    % k! b9 u4 i& u+ g3 t7 I7 Q        {
    . V  `' E) k1 U( h9 ]            p = vexTable.firstarc;
    8 g% r1 T6 f) y5 {% P. b6 K2 w            while (p)4 q4 U9 u5 O: L6 ^5 A
                {
    + ?1 c8 o* N' X. X                if (p->adjVex1==vexNum)
    / L  j7 Z$ I2 T5 i, P/ I* j0 n                    p->adjVex1= v;
    + j$ c) _3 T4 u1 a* b% T9 g                else if(p->adjVex2==vexNum)! f" |: w0 I1 _$ @
                        p->adjVex2=v;; D% b7 M7 W3 t+ V9 T4 H# k
                    p = NextArc(u,p);
    % F2 A! a  n' |' F1 J& q' D4 H            }
    3 W: X# b5 h: R        }) `$ x2 z' [& i* e
        }
    6 E6 `4 S* j6 C/ ~% ^5 }}# T  x" \" ^7 m5 U6 s
    ///深度优先遍历, T. S( o+ s, C( j; D' P
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)
    - ^3 X/ r5 w9 o/ p4 i$ o{
    * V. n/ a  `, L7 ?, B    tag[v]=1;
    + ~# ~. m1 ^  l! U    cout<<setw(3)<<vexTable[v].data;% m- e. m5 h/ i: w, @9 t6 J! X
        MultiAdjListNetworkArc<WeightType> *p;- b8 N+ ~" A5 ^0 J
        p=vexTable[v].firstarc;
    , p0 `  R' z$ r* P% S0 `    while(p)' L) N* f7 r- l! d
        {
    - j& J+ l1 @0 u, `! ^7 x        if(tag[p->adjVex1]==0)$ e, z2 r; H9 d+ g9 E3 @
                DFS1(p->adjVex1);
    & r& a. y1 n! `3 M        else if(tag[p->adjVex2]==0)2 D) m; [9 r% h8 p; F: R: d
                DFS1(p->adjVex2);' N0 W0 ^, R' X2 E: ^& u& \  z
            p=NextArc(v,p);7 {0 X2 n* ^! z! Y6 m& V
        }
    $ [( a$ ?9 |$ n" j8 X  M2 O% m}
    9 w. K2 [' |, a, ^template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()7 J$ i; I+ u  f# b6 f  z$ t
    {2 @9 I, \! x: c0 `4 X7 h* O5 a# [
        for(int i=0; i<vexNum; i++)
    5 o# D8 B6 o$ O  a( o4 P        tag=0;
    # l7 F+ _4 n* X: t, c    for(int v=0; v<vexNum; v++)
    8 q; E) E, n+ e9 ^    {
      a9 [& t; |% h2 ?: Y- x        if(tag[v]==0)" Y4 m) O7 W$ @/ M5 N
                DFS1(v);6 x% V- i% ^% F1 [+ s/ n
        }
    ! T7 K) `$ m) M8 s( ?}* j9 ~9 m; F! K* }; d' [) f
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    1 [7 a* e2 R7 c4 W{
    . }3 L0 _+ g2 M+ N. \    stack<int> s;0 D4 p3 ]( c; ?5 l9 u
        int tmp;
    & v! E0 o9 l( k6 Z1 y( I; S    MultiAdjListNetworkArc<WeightType> *p,*q;
    / `8 M0 Y; A* s; X    for(int i=0; i<vexNum; i++)
    ) D- L! E( J; \        tag=0;
    ) L4 ?9 S* u6 T( a3 t3 j1 X3 M" E    for(int i=0; i<vexNum; i++). F% f/ V% ?' _2 ^- J; t
        {
    2 R# I3 v/ A6 j7 C" e2 C2 w        tmp=i;( a0 W, a, W3 |( w
            while(tag[tmp]==0||!s.empty())
    8 ]0 Z$ x1 @) z3 m  `# |        {
    $ I6 o' c9 x5 x0 J4 }* Q9 `            p=vexTable[tmp].firstarc;
    + V- l5 \4 Z" z            while(tag[tmp]==0)0 P$ O1 ]; B0 T
                {* A% O5 @, \+ d. t9 r
                    s.push(tmp);
    5 y7 F6 |& ~, ^& }. A+ f                cout<<setw(3)<<vexTable[tmp].data;7 l6 E# ?- c! R, e: R  V% f
                    tag[tmp]=1;
    9 a2 ^- i& q9 P, _# I  I: \7 r                p=vexTable[tmp].firstarc;
    - B* ^* m% N' M5 q6 H3 K5 o. V                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for  L! b' L8 a7 M* R
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);% U3 H- O& C( ~7 N: w7 V% f
                    //cout<<" 1st     tmp="<<tmp<<endl;. k3 [* w+ B: R0 v# F$ h( ^4 p1 n
                }
    . ^  U" O2 g0 V) D& ~* k' |7 ]            if(!s.empty())' x" A1 e7 O. \* q
                {
    2 i4 f# L! h3 {2 h, o: _                tmp=s.top();/ a7 t2 \- B& d4 k' m+ j4 e
                    s.pop();/ j: [) P# b. p
                    q=vexTable[tmp].firstarc;$ w6 B9 c4 X& u: w
                    int t=tmp;
    1 v4 l8 N: n8 n2 v                while(q&&tag[tmp]!=0)/ d8 [$ n; {3 \
                    {" d; s' J; a  d2 x. M
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    : J( k! o& i2 ]5 }                    //cout<<" 2nd     tmp="<<tmp<<endl;
    0 I3 v1 h& Q. G+ ]                    q=NextArc(t,q);# y7 Z+ `! d/ c  r
                    }
    5 O- t. N- P! p$ \5 p8 g                if(tag[tmp]==0)
    % e, `6 w( o) S1 H" l1 y                    s.push(t);0 {- A1 c- t: ^, L+ ?
                    ///1、对应上面连通分支只有1个点的情况
    ! \( a) ]$ J4 z' F0 u2 N                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    : A$ q2 C2 {0 R9 `2 u1 t* o8 n0 X! t                ///tmp要么等于找到的第一个未访问节点,! K3 P" t) e! _$ `
                    ///要么等于与t相连最后一个点(已被访问过)
    . F8 o  z+ E  Z( z                ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点2 b  w$ c; a- @, Z* K: h9 v# Z
                }
    9 o( y- l2 f! p3 }        }
    * h0 Z; Q9 o8 D, b/ S8 c! N    }
    0 o/ P. D* D2 ?# v! H" v$ U}
    * F* R1 k0 u  Z2 S/ [//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    " k7 o) s+ M3 c' ]1 f0 V3 e; Vtemplate<class ElemType, class WeightType> int
    : o5 r) w$ M3 c6 MMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)2 v9 s: v& ^& Z; V! C! ^# }
    {
    ( O: I4 B+ b: J$ Y# L! ~+ C    if(head==pre)3 G9 h' G8 a1 {- t' ^2 ?% C
            return -1;  ^7 _, P; g' T; ?

    # L' _: `5 s5 `( h$ R    MultiAdjListNetworkArc<WeightType> *p;
      b, @. h( ~8 C9 ]6 T& L3 k% I    p=vexTable[head].firstarc;
      U9 t) s* W/ ^3 q4 v    if(pre==-1&&p!=NULL)5 T' c; p$ V4 N* |8 t
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    9 v8 ?. V, n( A1 A+ J; l0 C9 n    //pre!=-1&&p!=NULL
    - g, O. Y9 }' f8 u4 H* W! M7 Q    while(p!=NULL)7 o, X6 m+ L) Q
        {
    # y  O$ ~- Z! Y3 A* E* u        if(p->adjVex1==head && p->adjVex2!=pre)' @: Y( A' E. U5 E" l2 j
                p=p->nextarc1;
    : c% m# {1 j; y* K8 v        else if(p->adjVex2==head && p->adjVex1!=pre)
    , K* B" X2 u: c: |5 ~4 f            p=p->nextarc2;+ C* D0 U. `8 w
            else if(p->adjVex1==head && p->adjVex2==pre)/ U  y3 e2 t) z1 Y! i- W7 t
            {
    ; D8 F3 Q5 K1 K/ {            p=p->nextarc1;
    6 l4 d# V* w% s9 o            break;+ @  N1 D5 X  f! K
            }
    + V9 }# F1 r3 ]; n6 y& O, B        else if(p->adjVex2==head && p->adjVex1==pre)
    4 `1 C6 u  \1 |0 c/ e        {: m+ Y4 V. j6 @* A
                p=p->nextarc2;
    / m. x% U# H- l  ?- f            break;3 H2 \% k" K; L1 Y3 x$ t
            }% z7 \. V2 g" s. ^( a$ ^
        }0 F1 L3 v- t: F* ~; `* z
        if(p!=NULL)3 R2 c8 h: A/ I+ S0 |! o/ l2 i
        {) y  @, a  z; f7 w1 ~: s1 K. B
            return p->adjVex1==head?p->adjVex2:p->adjVex1;4 T) ~+ ^1 f/ D0 V6 O
        }
    $ H, u$ y0 ~+ s    else
    - o0 z0 J+ ~' @1 J        return -1;% Y/ @$ l$ f$ v: u4 C' L! }4 U- v. t' c
    }" f5 _) L( M9 z$ W- f8 j4 k
    / h. Z! d1 b8 l/ V5 {/ |7 G
    % v& N( E1 W. l1 ?( U, H
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()* a% M$ A0 `9 A5 S, @2 D# R/ y# K
    {
    * q3 z( m% M/ e. K2 G5 U1 s! ~    stack<int> s;6 F& G. k  b+ |$ I
        int p,cur,pre;3 c. m' p: P- A! B/ `
        //MultiAdjListNetworkArc<WeightType> *p,*q;
    4 _0 o) {3 K( [6 P6 n( _    for(int i=0; i<vexNum; i++) tag=0;//初始化9 d  \$ E7 w$ \4 U3 U) x
    " H& j- a/ u2 G6 q
        for(int i=0; i<vexNum; i++)
    4 a7 }5 S- o! X' l# p    {
    * r4 l9 G. ~; {4 c  K! u7 V        cur=i;pre=-1;
    " d0 a( F! X  \& u1 e+ ]        while(tag[cur]==0||!s.empty())- g( @4 m0 x) o; e2 q: {
            {
    1 T+ R$ y; d0 Q6 f- `            while(tag[cur]==0)
    ! c1 E4 r: L. b# q& s: n6 z$ t            {# A; }6 i1 o% X" H
                    cout<<vexTable[cur].data<<"  ";$ J7 o) J. q2 |9 g* }
                    s.push(cur);! d6 B2 l% [2 a7 l5 Y+ K
                    tag[cur]=1;
    ' [5 ?; f* N% v$ g2 U& M               //初次访问,标记入栈
    ' S  {8 n& ]3 n  O  z3 L% y$ d) `6 d: m8 w! A3 O4 R! O1 p$ `
                   p=GetAdjVex(cur,pre);//p是cur的连通顶点
    8 i9 o6 ?* O4 x# n* z0 Y               if(p==-1)
    . M3 Y6 u: {8 L- M5 z               {
    9 c0 O% E+ Y, Y( b                   pre=cur;s.pop();
    6 B8 y2 Q7 C$ l                   break;
    , P7 X& w$ U' Z5 P               }
    / C/ u# l7 E+ |/ p6 y               else
    ( l  A9 _1 N( q3 J. j6 u               {8 U7 e# O- i( }. ^) w9 T2 L
                       pre=cur;
    4 ~' ?" H. c+ V& ~; t( [% d                   cur=p;
    7 t. }: U4 w1 m               }' L+ J) C( h- I0 C3 T9 J

    ; d3 M5 r9 N5 ]- s0 t9 r            }
    : m; g6 g3 L' m9 d" r$ S* P            while(!s.empty())
    . j7 Z# X  ^8 F! I5 s            {
    - F' @1 b; N1 b6 o' A                cur=s.top();
    / d) ^( @7 T( y  x                p=GetAdjVex(cur,pre);
    8 f/ n% P0 s  [                if(tag[p]==0)
    . p  R. B2 S; E$ h6 w- \7 F( i$ _# d                {' D% b( w0 H% D0 C( Q, U' G
                        pre=cur;9 |1 j, ]' o* \0 w6 E0 a6 o
                        cur=p;8 i; [2 g. o) C4 a0 O  o8 o
                        break;: y! k8 }6 k  m* u3 d. j1 E3 b
                    }
    8 {" A4 m0 U  Z3 L+ f# t. _% \" J# l                else) E1 x' l$ J3 a: S
                    {
    ! b$ O5 V8 g$ s) u2 u0 \                    pre=s.top();3 c/ J( |+ r7 E5 T9 V8 z" k3 {
                        s.pop();
    6 D3 i8 m* q) z: q  Z& f6 {( N                }/ T. Z4 r# F; y
    6 [6 \( |  i1 w/ g
                }
    , M2 }5 b, _9 f" r- Q' e4 M1 H" L! ], A6 f& g' H4 k# s
            }% l, r8 T5 N& E0 n2 U
        }
    & K: p9 X, j/ _( u}; F3 ]+ s+ E, u* l2 D1 C
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS(), v" V& G/ Q0 X6 J
    {
    # }) U' w" d* n8 a0 _    for(int i=0; i<vexNum; i++)
    5 l  j: K9 K- h4 \        tag=0;
    / F; R' h4 Q& c! t- C; ~/ g    queue<int> q;9 o1 X. W) B- t" A) D, {' k
        int tmp,t;; A+ m( l0 [% }+ l8 F
        MultiAdjListNetworkArc<WeightType> *p;7 f- a: O0 v" ?
        for(int i=0; i<vexNum; i++)
    2 `# {6 y5 ~) G& V    {, P% A; B8 E" G  Y& p  @
            if(tag==0)
    , L% W7 S1 ~/ T  u% y+ q1 g% L0 z) U2 K: n        {, w5 X, D3 u, Z% Q! p. x- |
                tag=1;
    ; a/ o4 f2 q4 H, P2 I$ B* Y  }" M6 {            q.push(i);9 k: z  ]: R) G6 _0 H4 P# [# h* w  y
                cout<<setw(3)<<vexTable.data;# Y; M% n! u* B
            }& S, W* \! }" y" u  o
            while(!q.empty())# b) o+ S! j* y7 _- l9 C
            {% w' ]; k, e; }5 X" t5 T- p- J
                tmp=q.front();
    ) M% F  Z  T0 B* d$ j5 L            q.pop();1 f" H3 F; R: g/ [* ~
                p=vexTable[tmp].firstarc;
    / K  W; R9 ?' H) P3 l            while(p!=NULL)
    - K8 E4 U+ Q7 |" j( h# P. q            {
    / D+ |+ |5 k3 {; u" N                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);$ W2 G. c( ]* o0 }! E! K; `
                    if(tag[t]==0)
    , I1 _) @! p0 r7 Z; N                {( u! u' I$ W/ V# a0 o
                        cout<<setw(3)<<vexTable[t].data;$ f# J! F' b! V$ P: I+ x; K
                        tag[t]=1;; u# {" w( v. C8 `" X8 Y! J
                        q.push(t);
    . z5 Z8 v3 h7 q9 N7 p8 S. q                }1 _* x4 F5 @3 `5 J! ?7 [3 ^9 b% z
                    p=NextArc(tmp,p);
    * G4 U( C& K; C4 x8 {' n! G            }9 d8 m  y  K- }  ^
            }, \2 j) G$ b, p* C, R
        }- |7 i$ w7 W9 @7 W
    }0 x& O9 I0 d2 t4 [6 E
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    - q9 s  f1 |% v, u" H  U{& h/ e9 E, _. a- a) s
        MultiAdjListNetworkArc<WeightType> *p;
    ! L+ r# p8 B* l2 k- u" y    cout << "无向图有" << vexNum << "个点,分别为:";4 ?3 C8 s6 |3 R& T& b* p4 Z
        for (int i = 0; i < vexNum; i++)
    6 D4 o% h3 k0 E6 N        cout << vexTable.data << " ";
    : V' L& o+ [6 W% V7 S    cout << endl;
    9 @- G6 J% L6 T  R    cout << "无向图有" << arcNum << "条边"<<endl;+ v' u8 f+ Y( k# Q- |
        for (int i = 0; i < vexNum; i++)+ s$ Z$ U2 p( _* S; D) _
        {
    : M4 r' v+ @/ R, _' @        cout<<"和" << vexTable.data << "有关的边:";; k( Q6 Q' q; J- k
            p = vexTable.firstarc;
    4 ~  ^8 @/ Q) L        while (p != NULL)
    5 B/ f* D: j! C3 @3 D8 `        {* r6 p5 Q, L& g7 a
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";
    7 }: U0 R" B4 z: Y" i# I. Z            p=NextArc(i,p);4 x) L; v! y" k! p+ H
            }- `% b8 k# U" e8 F9 A
            cout << endl;; u: M$ d1 ~: l3 f8 y9 V9 h
        }
    & k, i( C. l7 p- X}
    5 D. p) T3 A4 W' y2 _8 O- y  s1 T3 k7 s4 s9 q# g8 A1 a

    $ \/ _8 K& _. f" H4 T' q0 p邻接多重表与邻接表的对比& _2 ]. z8 L! @& x. }

    ) I  |+ t4 n  p3 C1 Y1 p  P8 g7 g邻接表链接
    5 e5 F! e: G' F8 G% [1 W+ |在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。
    % o# J1 x7 t! |: k- O3 u" `+ ~在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。, X! V3 j. i6 x/ s. G0 _6 C
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。6 |% m* d! ^$ y
    ————————————————
    + R7 ?- O9 x% l3 P$ q) _版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    * v! @0 M; [; z; r0 S: |8 ]原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958; s3 N/ b4 f: c8 j8 S- Y7 n( _% s

    5 K8 K- H1 W; A6 U& A3 Q4 N( V" b7 t" @% U( V; M
    # G5 \+ q1 r- _) A! S9 e$ r; @
    & r( \$ A9 _7 O1 ?$ |
    ————————————————. k6 I8 p# T* c. i, k2 ]
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ( g. e; @( F) a7 w原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669581 p' X+ q! z& R/ D/ H! p8 s1 W! @& ?
    ' [' \; ^. C5 q8 z8 {9 E: J/ h) c7 S

    & T6 ]& T( \3 P, l. ^) ]* w
    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-12-17 06:34 , Processed in 0.553022 second(s), 54 queries .

    回顶部