QQ登录

只需要一步,快速开始

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

    / c# m# _; \$ k4 H' a- T+ x图的存储结构——邻接多重表(多重邻接表)的实现! N' z; U/ x7 H# u" r9 L
    7.2 图的存储结构5 B, \5 c! w5 E1 O
    8 q/ m) R5 c/ Y+ E
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    0 ^* Q1 r: J' U. i& [邻接多重表的类定义9 z$ f' w! `1 }3 q" D, W
    邻接多重表的顶点结点类模板  ?  m; {9 L( ~& U
    邻接多重表的边结点类模板
    . d& Q9 F* u: n# a) N1 {0 A, ^邻接多重表的类模板
    - H6 z9 V+ c& i5 c" j4 o邻接多重表与邻接表的对比/ j7 l# ^/ v. Q, }# n: I
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    3 J# T+ A9 O5 s& _4 s, `
    4 O# {" q" u  R" g在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    % i6 ], q/ s# t+ _' g+ L在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。4 B& K/ x: Q* O8 q

    & S" }$ X1 t* M1 W4 W邻接多重表的类定义; F; S, P: l$ m: d+ i
    1.png & _. B& n. _+ i: s
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:! J  G6 U  b# j; G- s  d
    data域存储有关顶点的信息;
    + }/ _/ H) h6 U) `% }& Kfirstarc域是链接指针,指向第一条依附于该顶点的边。9 S$ n& L2 b% D8 k/ F+ J
    所有的顶点结点组成一个顺序表。

    - s3 q% u2 ~$ Z8 l4 d, C2 z

    ) @; H; M/ r+ v/ o  gtemplate <class ElemType ,class WeightType>
    ; p% c1 ~* Y1 e8 M" W6 n( P  ?class MultiAdjListNetworkVex
    2 c# V7 ]$ K- w* f{
    + _  c* D1 d$ f: u6 @0 Rpublic:, K. e; B- Y: D0 h( E
            ElemType data;
    , i6 T4 c$ Z2 O" e        MultiAdjListNetworkArc<WeightType> *firstarc;
    6 |/ J: M. m5 }, G& I( }+ h9 z1 ~3 _5 f
            MultiAdjListNetworkVex()8 j  M- I( D% y; t
            {* H9 q" W3 a* L' M7 a/ g$ s
                    firstarc = NULL;7 s  e5 a8 E& E2 I2 n
            }
    8 p1 v$ V  M8 P' O6 [% D  ]        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)6 V8 {/ I6 V8 y% L& H
            {
    ; g# B: S6 O0 t                data = val;
    ' x# `1 H" }% K                firstarc = adj;7 \( [9 [: P. [9 p& {2 v* N" _
            }4 i# U8 `% J: G8 C5 _4 c8 V2 T
    };
    3 g# e5 ~8 p7 n$ T7 ~( ?# L! J1 w- O, Z' O8 Y
    邻接多重表的边结点类模板
    , w# g, Q  I/ w% q7 u" ^* o% S7 d) o0 V
    在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    0 I: b7 S) M0 ~- m3 _$ b: \tag是标记域,标记该边是否被处理或被搜索过;
    # b0 k% x$ e% C( p$ Jweight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    5 K) h( H9 j) Y, m/ E4 wnextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    0 H1 I' [' x, I0 t9 {5 Q$ K; R; {nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。, O8 [; Y" G: t/ N

    ) l  f0 U. a; n& e  u7 Q 2.png
    % |' Q8 g( Z  z3 h0 g* S! ytemplate <class WeightType>1 d5 u8 U  L3 v9 d5 N: D& e
    class MultiAdjListNetworkArc1 k. r8 u- J" {8 O
    {
    " I+ J% F- ~! a2 e& ~public:
    1 |8 R) U# A# d! x" O; r( S5 y4 ?0 r    int mark;                                       //标记该边是否被搜索或处理过& `5 b8 f8 K# m0 q5 N
            WeightType weight;                              //边的权重$ `- r0 Q7 G6 G
            int adjVex1;                                    //边的一个顶点8 k" ^/ Y! O. T! u
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-13 J9 {( u* Z: F) V. Y) {
            int adjVex2;# k: g$ P. @2 B. u! [$ g2 v: Z+ u6 ?
            MultiAdjListNetworkArc<WeightType>* nextarc2;
    : J" y2 Q* _$ U, J# Y; t
      X  N' i: W6 L2 P+ m        MultiAdjListNetworkArc()6 J8 K1 [: r( S( ~
            {
    7 d8 Z2 N) ^6 N4 z                adjVex1= -1;
    / E- T  i6 Y; U* U, t7 [                adjVex2= -1;" @& E: d) U' q
            }
    1 t( j* _7 g% O% f2 F& }+ j" q! ]        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)3 m2 H4 g# o9 V3 Y3 C9 e; h
            {/ K- P- c* ]3 E+ ]7 b
                    adjVex1 = v1;       adjVex2 = v2;# q$ ]" r, _- x6 Q' L: v* ?# J: q
                    weight = w;
    - M' F+ w$ j( G. z  k  C                nextarc1 = next1;   nextarc2=next2;
    5 h" X6 P' E$ x  H8 ^                mark = 0;           //0表示未被搜索,1表示被搜索过
    . p; J0 R6 J4 l9 Q1 Q& ?        }
    , z. B& ]. \7 S' G& [' N- K) L" u7 K8 U- j- q; U
    邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>: k8 q1 y* h" L
    class MultiAdjListNetwork
    2 Y9 b- l# S! v) _' N3 C$ U{
    ! L8 r7 @  Z. ~, Lprotected:
    * }& n+ @# v; l  a( u    int vexNum, vexMaxNum, arcNum;; B* S- Y# j6 t5 S" K( Y6 J
        MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;- |! J' Y5 f6 F
        int* tag;
    8 W8 l' e' F1 L5 F3 i    WeightType infinity;
    * A! @+ ?. k3 v, B' L) l- t- n  P; X* k. ?" G; v. z. a
    public:5 f. F1 w5 _. ]3 C- _* T
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);8 P  U2 S" ]' g: D/ ~8 |
    . K$ v9 G, Y+ i; J3 W8 m
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);' H, B3 F+ p0 ]' ?
    ) V* ?. {0 B1 C( J! s3 z" _
        void Clear();
    " L$ e  y1 J: W: Y/ l    bool IsEmpty()6 u- H" p; r' k" k
        {
    . I& t6 v) ]: j        return vexNum == 0;
    - ?) `, E: w  c$ m    }
    0 i2 X$ D/ {/ u8 i! ^2 o- u    int GetArcNum()const
    ! D0 b& b6 @5 K* L' ^    {
    9 V2 O9 k, P) {8 C: p& M        return arcNum;
    ) a5 x$ G9 T, @: Z  [# `- ^  A7 A    }
    8 e$ {6 b6 O. W  P6 S7 d& f, X    int GetvexNum()const% m; x+ t5 _/ c+ x4 h  m
        {9 b8 u  N. S' c5 M2 q. v
            return vexNum;  O3 u$ u  H# k' J& ?# c# @- X
        }% z; x) }' c' ^! v# j. E. p: ~1 l1 c

    4 e3 p  }1 o- U- b, s8 L+ _
    7 ^+ O: {) V* k9 D3 o6 t    int FirstAdjVex(int v)const;
    & `5 ~8 I. w7 b+ `$ L2 f    int NextAdjVex(int v1, int v2)const;0 c0 Y( m5 `' \0 l6 f3 I, ?
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
      c0 B0 y7 h' w    MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;) I% l/ O; V& V' }
    % q5 r# ]  Z! J
        void InsertVex(const ElemType& d);; d( z8 d3 C6 B: ^2 s# m
        void InsertArc(int v1, int v2, WeightType w);
    + e9 o* h6 C, p# W; E2 z  x& ]& E& U- |0 T- o$ n
        void DeleteVex(const ElemType& d);
    ; ]0 G6 N4 }" x. ~    void DeleteArc(int v1, int v2);* c0 F& B2 u" K" h; i
    # Q: n4 }5 c5 T
        MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);6 x8 V8 }! F9 W1 w2 h  T
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);# O/ ]- T2 M; @% T( O3 w8 k) W

    2 a' }3 L5 {5 q9 l; h    ///深度优先遍历  G1 r- @, q0 V
        void DFS1(const int v);+ f9 A6 g, b3 q. `
        void DFS1Traverse();' h$ J6 V- ^  y( ]  l
        void DFS2();
    1 j5 a2 t, X) ~& J) R$ y4 K0 P7 L2 Y1 p' C" ?# ], E) Z" Q0 U
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    / h" a! M* E+ A( m, h7 ?    void DFS3();: j( p' V: F: U1 n1 s

    : V9 `2 D! Q8 R" m1 M$ `. e    void BFS();
    7 ]: |0 m& u, J; p& D    void Show();
    " @0 U0 R/ K* M" K5 Q};* n, r3 a  G4 x0 M
    3 A: Q! G0 J. X- o1 Y; N
    2.函数的实现& T$ W) O) p% W
    研讨题,能够运行,但是代码不一定是最优的。
    & d' C0 J! `9 U' t  _& B  q
    ' S  Q4 K6 `5 Y/ ^' ], F#include <stack>
      T" _& d: p0 F$ c4 F#include <queue>5 F# x1 L$ T3 w/ I# y

    : i3 O) R7 B$ ^" atemplate <class ElemType,class WeightType>/ b# a1 f% {0 `( y
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)8 w. V0 S' C! V5 v' T7 x+ }
    {+ C  ~0 c9 M% b: t7 f
        if(vertexMaxNum < 0)9 D9 P4 T' v( e
            throw Error("允许的顶点最大数目不能为负!");
    2 J* J8 c9 I' \8 n, `8 t+ G+ X    if (vertexMaxNum < vertexNum), ?$ c4 W" R5 k! Z. E7 u8 ^: {! \
            throw Error("顶点数目不能大于允许的顶点最大数目!");1 r/ ^0 {  J( p+ ?1 L6 q- q
        vexNum = vertexNum;
    5 E2 h; T1 o+ }    vexMaxNum = vertexMaxNum;
    3 \* `7 N4 ^; @7 e0 I4 Y    arcNum = 0;
    - z3 B8 D# E0 a    infinity = infinit;
    * o% K9 a/ y" Z; r' O: n    tag = new int[vexMaxNum];
    5 e- ^  v5 X7 v4 e: W0 e( s    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    ; y' x: M; |6 x    for (int v = 0; v < vexNum; v++)4 q6 p7 v% b6 ]' a$ i
        {3 r  D, r1 a' [  L/ ]! X$ G
            tag[v] = 0;
    ; B3 Q8 B. P4 Y8 y0 \# h, E' H9 g        vexTable[v].data = es[v];- ^5 B6 q6 G: I' |# }% g8 Y
            vexTable[v].firstarc = NULL;. o: G4 r" M8 r
        }
    3 N& n7 C8 ?# h& D7 k/ Q7 K6 \}4 y  P) d, O, W9 `6 K9 z- U
    template <class ElemType,class WeightType>
    1 f% |8 P6 K0 ~9 t1 d0 a$ aMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)
      t7 E1 `' X3 v5 F7 n1 b4 ]4 }# E{
    . r* Y/ c$ |* T( B: |4 z2 c    if (vertexMaxNum < 0)0 x2 Q: }* E) F, _7 w" W* V
            throw Error("允许的顶点最大数目不能为负!");& w6 W% t8 w" W0 W, a
        vexNum = 0;
    + L/ [6 q. f: x6 ~; q1 b# H    vexMaxNum = vertexMaxNum;
    5 k+ e. ^5 m% ^9 Q! A! ]    arcNum = 0;5 L- B. m* L7 o' u/ T
        infinity = infinit;* k, }  F5 ?9 t( b' l
        tag = new int[vexMaxNum];
    5 t% n4 n- G* [3 O0 C5 @' o    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];+ A1 d! [' K3 M+ u4 u
    }' L3 w  M' C0 b" g4 ^3 P
    template<class ElemType, class WeightType>
    3 f9 Z9 J" B2 f' @* gint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    2 I" i/ r& c0 s0 I8 g{1 L3 k' b1 h, P) U- e0 v% _5 {
        if (v < 0 || v >= vexNum)
    ( H" E- o) K4 b5 V, ?        throw Error("v不合法!");8 S, \" n* r0 c$ k
        if (vexTable[v].firstarc == NULL)
    0 p* ^9 u9 g- G        return -1;
    - ~1 e! Z6 u4 c  h  B( u    else
    , k& C* g, E1 {2 x        return vexTable[v].firstarc->adjVex1;" R1 `# ?: t$ Q" l
    }+ w- T% l+ T% [$ K. c# |9 g
    - s% Y" e, ~- w
    template<class ElemType, class WeightType>1 \% O  U1 n* c6 S
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const% L; a. J9 x  S
    {% b) J! T# e6 v! Y. ]  u
        MultiAdjListNetworkArc<WeightType>* p;
    4 p/ Q' w% d# x    if (v1 < 0 || v1 >= vexNum)0 G, `$ b: v' F; C" ~
            throw Error("v1不合法!");
    8 x8 |/ x" m3 F% s. M    if (v2 < 0 || v2 >= vexNum)
    / e1 ~% E# |8 Q% g        throw Error("v2不合法!");- o2 V  E9 r5 ]6 o! p
        if (v1 == v2)
    # y5 u5 E7 D; `2 X8 l        throw Error("v1不能等于v2!");$ g% w: s% u6 N) L3 }1 A/ T
        p = vexTable[v1].firstarc;' x2 F  Q; P3 \9 Y
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)
    / |' b  k, @  W% S        p = p->nextarc;
    5 b, l# a1 V, `    if (p == NULL || p->nextarc == NULL); |8 P; W$ B) X
            return -1;  //不存在下一个邻接点
    9 I; U1 G( J" F9 m    else if(p->adjVex1==v2). s- U' J: N5 y3 _
            return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);+ Z! H: ~0 ?' j, |' o* U2 I
        else( w1 [% ^# x+ s  A3 V3 J
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);8 a+ E# J5 ^# z) v% l+ v
    }
    2 Y+ Q& z" d+ Q; k  E# q! itemplate<class ElemType, class WeightType>  b9 ?. c8 ]$ Z' H( p/ R
    void MultiAdjListNetwork<ElemType, WeightType>::Clear()- F  c, Q! H% w- c- x
    {* S, i( u" R# Z2 J& ]
        if (IsEmpty()) return;
    . m+ T6 O# |1 v) z    int n = vexNum;
    1 m$ l; E/ ^7 r  X9 u% ~- u    for (int u = 0; u < n ; u++). {* X5 _: V- i0 j4 u
            DeleteVex(vexTable[0].data);
    - S# X( i: N  a. b" j  j# u7 K' Z    return;
    ( g, f6 r& J2 I3 D& {6 P) A( J}
    * O7 J0 k2 [7 f1 ptemplate<class ElemType, class WeightType>7 T& D: f! [& b( j
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    3 l5 a$ E' A! f+ y' A8 Z{
    6 s# [, C) ^& ?4 x/ P7 S    Clear();9 n5 c* q' E5 f# Y) z& m8 ^
    }
    9 G3 T; j. b6 A' G$ @  D! etemplate<class ElemType, class WeightType>
    3 O( O$ O, O/ b: Z4 n- }MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy). [' f8 J" V9 k1 {% M* S
    {1 D3 R9 L- e# {2 y/ {
        vexMaxNum = copy.vexMaxNum;
    + G* M  g8 z1 F4 N! H    vexNum = copy.vexNum;5 D# O5 E1 g$ w5 X4 M
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];. r6 _9 _/ s& C- A- ?
        arcNum = 0;
    . Z! u, r# B5 @' s: U1 H    infinity = copy.infinity;1 P& F7 V: c; b! Y8 {* m
        tag = new int[vexMaxNum];
    3 r0 p  V! Q: D( j, H# r9 U3 s
    & e* |$ P( B, \. u  |9 Z) s. S    for (int v = 0; v < vexNum; v++)" Y8 b$ V7 w/ W/ R- Q
        {
    5 z7 |' ^# R; h" f  R        tag[v] = 0;
    ; r) N9 ]6 l% @& W! ^9 h( q" o4 L        vexTable[v].data = copy.vexTable[v].data;
    % b* U9 q! H& z" q7 d7 f        vexTable[v].firstarc = NULL;3 ~- S2 O! F3 w# u
        }
    1 E9 @# W! E2 n/ r0 j+ R    MultiAdjListNetworkArc<WeightType>* p;* g, K- j) ?5 R" d
    & x& Q1 @7 S# K2 c: J% t
        for (int u = 0; u < vexNum; u++)
    6 ?( t( g& O# J" }    {# o! U" U1 a" S7 P5 I
            p = copy.vexTable.firstarc;
    , M  u( f; s; W/ j2 j        while (p != NULL)8 }  o4 p1 g7 i5 d' E
            {
    & w- n/ I7 h5 D            InsertArc(p->adjVex1, p->adjVex2, p->weight);* o% W  B3 W) {  T3 U5 o) X/ f
                p=NextArc(u,p);) D) Q9 q! v: {: b$ d2 F  I" T
            }
    3 u# B; I" j1 @6 W    }0 ]! u/ k3 G$ l
    }
    9 v( d* I* \4 i5 n  Atemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
      t. `' |' p' h3 ?1 T: WMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    / o$ x' P" u0 V{3 V: T# l$ J/ z& t: a' V
        if (this == &copy) return *this;$ L6 }2 q2 @/ ]
        Clear();4 v  C" a& `  m# N  J
        vexMaxNum = copy.vexMaxNum;
    9 Y$ c+ u" ~1 l) |0 ]- }    vexNum = copy.vexNum;% F2 A; \! c, w# q+ q2 {
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];* h2 w! c* Q7 E4 H, G
        arcNum = 0;
    8 K) [! G9 m  \$ o    infinity = copy.infinity;
    : [/ n. O! {" q; P    tag = new int[vexMaxNum];, \5 s2 [: B$ S5 s% F

    / m. H5 i; v2 U# j& T* g2 B    for (int v = 0; v < vexNum; v++)
    % K7 q9 E& h$ n0 ?% [7 t# K9 i    {
    6 ^* n. D0 H5 e& j! V/ I        tag[v] = 0;, v: \, k- E5 H8 }# p
            vexTable[v].data = copy.vexTable[v].data;
    7 x8 E! m: g; N1 o        vexTable[v].firstarc = NULL;
    3 j8 e6 A. }! z, @+ L/ G  g  A* c    }. E* \0 L' d: G0 a
        MultiAdjListNetworkArc<WeightType>* p;
    * y5 U1 [; m( T
    $ x, x' L9 ~; V- ]- M/ R    for (int u = 0; u < vexNum; u++)
    2 H; c% X6 T& {7 z$ ^& \& @    {3 Y% z+ A: E0 k) {8 n$ Z  ^
            p = copy.vexTable.firstarc;
    3 j2 D- @7 n# v5 [3 G        while (p != NULL)
    * c* |# ?& C2 R        {" ~! x7 H3 E4 S! p9 c3 \7 m
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    6 y- k; g4 x2 X            p=NextArc(u,p);6 M! x: C! J+ H8 O3 h2 Y' ]) j
            }% F1 b/ H8 o$ a1 U, O" c; a
        }1 z2 o) ]# j  R2 q
        return *this;
    % }+ c4 m4 f" `& G# Y}
    + J3 s2 J  g( g& w9 w% Ltemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    : x2 G& y: {% G5 Q  T& ZMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const: y; Q! q! {- O8 ]
    {
    2 F# G9 Q3 q0 @( G8 P; x7 y    if(p==NULL) return NULL;7 [6 e* a) m) z1 P' {) j* _* R" C
        if(p->adjVex1==v1)+ v$ y. B& q0 E, |1 Q
            return p->nextarc1;( [: M9 U; j6 y
        else
    ! R- z+ x5 M7 B* C" k8 D$ H        return p->nextarc2;2 o* M4 A9 k9 H/ W1 F
    }
    ! \7 V$ n6 |% x# vtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*  B+ D7 C9 [7 m$ Z7 f9 t
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    % G0 z4 f8 P* I- l/ @$ P{
    $ @9 K( e! c1 Z1 u0 B    if(p==NULL)return NULL;
    1 u( {2 i' z, M& a  F& y* t    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;& F% [* k5 l8 e4 z6 E
        if(q==p)) f9 b+ l/ Z) V. p- k) U
            return NULL;
    ! G* p* H- f/ M0 }/ f! h5 X- ^    while(q)
    : X2 l3 N# [# J7 V    {  ^" y8 u4 y0 J
            if(q->nextarc1==p ||q->nextarc2==p)
    * q% T( D1 G8 K9 x            break;; ^4 r4 V$ |/ U! F" q+ T
            q=NextArc(v1,q);+ k$ L: x( u+ x/ r
        }: A& U5 i' U1 F& T# R  L% l
        return q;
    ( m6 G/ E6 y5 a}5 e0 @4 S" o& z  k4 a  v
    template<class ElemType, class WeightType>
    1 i6 u+ L3 D  }: ]void MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)
    ) q, Y* Z: c( a1 g9 y4 @3 F{/ G- D8 _6 K  e: r  [% {0 w. x7 \
        if (vexNum == vexMaxNum)0 O) a8 ^' O2 [/ R8 B0 l. k1 _
            throw Error("图的顶点数不能超过允许的最大数!");
    " I& z. L9 d/ G3 g4 o    vexTable[vexNum].data = d;  b0 X3 Q$ L# O' e3 e5 [& q
        vexTable[vexNum].firstarc = NULL;) D% `$ N- N# `: L6 G
        tag[vexNum] = 0;5 K- S- @) t( Y, Z" o
        vexNum++;
    # r. f: D% ^# H( k. w' y}$ @0 L- z& v1 _6 h8 _" q7 `' [8 E
    template<class ElemType, class WeightType>
    9 s. w) M+ P3 Y; _void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)1 V) |4 s  d1 a
    {
    6 z4 ~6 {5 F' ^* v1 O" `. [    MultiAdjListNetworkArc<WeightType>* p,*q;
    ( e7 {8 n, J5 W. `; w0 T+ E) t0 _    if (v1 < 0 || v1 >= vexNum)& y/ L. J& m/ u: m
            throw Error("v1不合法!");# I" B8 Q" o- k" @, P5 B
        if (v2 < 0 || v2 >= vexNum)3 L1 ]( ]8 I6 ~! O  w( p5 ~' h
            throw Error("v2不合法!");9 d( E. Z% h' c8 ^2 c5 V1 b) @
        if (v1 == v2)% Y! `" r/ |0 J" F% g: T- o1 e8 k; g
            throw Error("v1不能等于v2!");; i& J' I. a0 j+ k+ n
        if (w == infinity)
    5 s7 n! p5 I: e/ y& z" @# u        throw Error("w不能为无穷大!");
    & a9 D6 \  i1 I3 c9 n5 u
    - O8 l  a% E' I1 c/ B
    + n2 z! x9 B# F* s3 n6 D    p = vexTable[v1].firstarc;& [8 l  X' \" {7 V6 f
        while(p)& g2 k8 H5 _) k/ f2 v. H
        {: y- K& B7 p9 R4 O/ C8 x1 _7 q
            if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中8 c+ j, o7 C; g! d. H. H
            {
    ! V  {6 n( J9 Z( S# _+ f            if(p->weight!=w)* }9 W! ]6 }3 ]# F5 f- G1 B
                    p->weight=w;; W2 y* e, {; ?* L
                return;4 Y  k, R  K! }: M/ S3 Q/ }$ u5 S
            }
    5 `7 v( X+ w" x3 b
    6 P% b/ s( l# ]4 M3 ?- t! C        p=NextArc(v1,p);9 B9 n. X% c2 o) @
        }
    ! v: h; d# j0 L0 K$ }  d  @, E    p = vexTable[v1].firstarc;5 Y  B, y) r% K) w
        q = vexTable[v2].firstarc;: w- W7 w# J4 w0 @
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    : B, Z/ _& V9 ^4 @+ E    vexTable[v2].firstarc =vexTable[v1].firstarc;
    : Z4 @" ^8 [( o. l$ ]% J& V    arcNum++;
    * p- H" e6 F# D# z}
    ) z( |6 N! X7 ?, Z
    * ^5 B+ A4 C8 q3 p' M% O$ y9 btemplate<class ElemType, class WeightType>/ b, j" @& s. j1 y8 ]4 b
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)8 g$ A/ Y1 \. V6 B2 ]. q3 L" p& o
    {
    ' X5 w) ^: H( Z% T. K
    4 c5 O* Q6 R7 ~, N5 Y/ k- }    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    " `$ d4 ~6 ~0 }    if (v1 < 0 || v1 >= vexNum)
    5 Z% i+ y+ Z- s: v3 C+ r. g7 l7 {        throw Error("v1不合法!");6 T' S) ?8 H( _
        if (v2 < 0 || v2 >= vexNum)$ e4 q8 m# y' v: k
            throw Error("v2不合法!");8 [0 o3 e' R, n- Z& X
        if (v1 == v2)
    * _3 v( a2 b" R. u0 [        throw Error("v1不能等于v2!");- ?9 ]( H3 q) f. J0 G, g% }8 M, h! h
    : Z0 C$ v" X8 s9 W0 |
        p = vexTable[v1].firstarc;% d, \1 ^* ?# _) J
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    - Y. z& Q4 y1 X$ o    {2 N1 h* k7 n0 v% h4 b
            q = p;7 Y7 Y. F7 e7 F  R8 m6 J' ]; m
            p = NextArc(v1,p);
    4 o  }4 Z  F  }0 Q    }//找到要删除的边结点p及其前一结点q
    " N% }2 Z% Y& j: R, B7 J
    + N5 {- a% [0 v" R2 n- f8 a1 L1 z) U; I    if (p != NULL)//找到v1-v2的边9 `* E! M1 ^# p$ e2 ^3 C" L/ v7 \
        {
    ) E! M. h5 u# A8 Q; F- K1 }  J! b        r=LastArc(v2,p);
    9 h) x3 g/ q& e1 H) r7 y0 ~  s        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    $ j8 c$ F; C, s# V2 _            if(p->adjVex2==v2)
    5 f) _2 |, o' M& U/ Z& g  k                vexTable[v1].firstarc = p->nextarc1;
    - q* J9 B& v5 z& z* h4 t, K            else vexTable[v1].firstarc=p->nextarc2;
    + r' r, W2 j0 r+ I4 j* r" ^; m        else//不是第一条边
    & u2 E) u, }5 B& b% W; i# `        {
    " `, `( Y/ v- g/ K            if(q->adjVex1==v1)
    7 {& s% p0 X; u. u: P) k4 g                q->nextarc1 = NextArc(v1,p);
    + R: t1 l+ a3 T8 K  `            else
    ) q. J8 S# p9 E! j- r* r$ l- o( w& s                q->nextarc2=NextArc(v1,p);
    * U, ]+ c9 F% q6 o+ V0 M9 n% A$ t* D8 G7 t
            }
    * K) [1 f: _) H/ ~, i        if(r==NULL)
    6 P' l: {2 P# ~: Y- M5 L            if(p->adjVex2==v2)! N$ [5 e" e8 Y' ~/ V" P
                    vexTable[v2].firstarc = p->nextarc2;
    + ]4 a4 E0 x2 O3 L3 H/ p: f$ u6 c            else vexTable[v2].firstarc=p->nextarc1;
    0 `, p5 g+ S4 v8 Q        else
    6 ]+ a  w% h4 F. v' D        {3 B: b/ N# p" n& p
                if(r->adjVex2==v2)+ S5 J" I1 w, X/ a: e
                    r->nextarc2 = NextArc(v2,p);
    0 Y5 X, _% Z) [9 E% s  u# g            else
    * {, B1 Y5 g3 \0 L' U                r->nextarc1=NextArc(v2,p);
    1 s, P: }$ p3 D2 B% F! R0 U/ v        }
    5 Y* ~! Z4 `6 b2 M" N  P        delete p;( H# o& G; o, L# J
            arcNum--;4 ~5 V5 y! T( y
        }
    2 u8 P1 q# L& k4 R/ t
    5 {# l: v1 y6 n# T' R+ L6 g}- D/ F7 f8 z* M, O% z0 N
    template<class ElemType, class WeightType> void2 @0 p, W( i/ g( U  j& A4 g3 z
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    ) L1 w$ z  s/ o" H+ C6 [' c( Q9 y{: l4 x3 g( t/ q  a; _- t
        int v;
    0 z( z5 ^0 ?% L    MultiAdjListNetworkArc<WeightType>* p;6 ?; q) K8 o5 {5 h0 h$ l$ X
        for (v = 0; v < vexNum; v++)//找到d对应顶点' U/ ~8 i- m  E7 F  B
            if (vexTable[v].data == d)& ]$ L5 a6 i* Z$ z6 y) P" m
                break;
    2 \: d$ A! u) \/ X! C2 L( G+ _    if(v==vexNum)
    ( S$ o9 M3 P( e        throw Error("图中不存在要删除的顶点!");
    + D, n3 \1 O; p) q) l
    ' ]3 v+ R  B/ k5 A  E4 k  y    for (int u = 0; u < vexNum; u++)//删除与d相连的边
    : Z& j1 d; g! C9 L! v7 F* H; E        if (u != v)
    / O" l- V7 f: C9 g7 @. ^2 j        {& z) A+ l! N+ d9 V4 `+ K! H% @
                DeleteArc(u, v);8 Q+ @0 Q: m2 P2 X8 n
            }! h5 t' G7 S6 q9 o% Q; H8 I
        vexTable[v].firstarc=NULL;
    " k. V2 G0 b% P/ x
    7 I; o+ o  N/ |2 N8 r3 ]1 H    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置% Q  h7 Q+ \6 z
        vexTable[v].data = vexTable[vexNum].data;
    9 l( S) W5 [% z! n$ D" C    vexTable[v].firstarc = vexTable[vexNum].firstarc;
    # k) P9 T. v; `0 K5 u    vexTable[vexNum].firstarc = NULL;, l9 X! h% ~) \
        tag[v] = tag[vexNum];
    0 D8 V" T+ N) x6 A    //原来与最后一个顶点相连的边改为与v相连# t; u  @6 c: ~0 }1 M6 Y/ m
        for (int u = 0; u < vexNum; u++)
    $ T: I" ^* K% h+ y- w/ `    {
    2 T% m1 R; p% L  l1 _) z) Y& Y        if (u != v)9 s5 x8 r0 D2 ~" e2 e( {! `2 u
            {+ V: H! G) S; s' D6 e- B
                p = vexTable.firstarc;
    * N: y( {4 F; N' ?% ]            while (p)
    * x& [9 ]- S, u            {
    . a+ [0 l# k; Z' m+ r                if (p->adjVex1==vexNum)
    & }/ P/ r$ p2 c" X' ]                    p->adjVex1= v;2 u  i4 h2 K! s3 Z
                    else if(p->adjVex2==vexNum)
    ) k4 D5 O$ F& W4 D2 P                    p->adjVex2=v;
    ! m# G1 e( n& c/ p3 E                p = NextArc(u,p);: U; v9 ^6 a9 U, C+ A$ o
                }- E1 l$ M7 f# L3 \: ?& T; ?# H4 G
            }
    9 a) R! ^, {% ~: }" X5 s/ n    }
    ) [/ i. n$ m+ V" Q}
    : J; V3 h4 q9 }0 e* ]; B; M///深度优先遍历/ ]* G1 @; N) G( K; D% Y
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)& }& I) H0 g* j+ E' D$ t
    {2 e6 m4 o: q+ V: _7 r. P! R
        tag[v]=1;& O+ {4 _6 Z' B
        cout<<setw(3)<<vexTable[v].data;
    / A9 X( }% L, g( P/ X5 o    MultiAdjListNetworkArc<WeightType> *p;
    . e' B7 P" y& S( {    p=vexTable[v].firstarc;$ Z3 K: u6 o) _* I: a4 D
        while(p)
    ) C$ f( y5 c& N# b1 ^5 S    {
    # z; f/ B5 R9 v. i8 c* l        if(tag[p->adjVex1]==0)
    7 g. H' o% z5 c" \4 U            DFS1(p->adjVex1);
    5 \0 a' L& |$ T        else if(tag[p->adjVex2]==0)
    # x  p- I4 Y8 D  a: g5 M3 d% K            DFS1(p->adjVex2);
    ) _) ?' A, e- b5 |' `- Z! s8 U        p=NextArc(v,p);8 F: L8 f( |" P* {% O: f0 Z. Z5 V
        }# A' P, F% d0 _/ K9 j" w
    }
    ( k/ X0 o8 s) `6 \template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()6 }. s% b  O) ]' k$ z: m
    {
    ( m+ U( N. G! K, H  Y    for(int i=0; i<vexNum; i++)
    0 b3 t3 O) i5 a' l; b, U! a        tag=0;
    + j; L# K( i+ O2 b; V    for(int v=0; v<vexNum; v++)0 U* X) V$ p( L" o6 K0 l
        {
    & [/ [  l5 a( T5 o, i        if(tag[v]==0)" R, n, Y, d6 v$ j- R
                DFS1(v);
    6 f" H/ k5 p  r, {    }7 H4 b6 [# ~2 d( F
    }; ]7 `, p7 T, O3 Z  T
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    / \- x, N/ D3 {- W) r$ E$ z{
    $ I* F  o' x, ?- A. K# M0 |) @    stack<int> s;4 e9 p/ D5 D7 S) F% `1 {
        int tmp;7 F/ ]+ k' o* F; X) \: O9 A
        MultiAdjListNetworkArc<WeightType> *p,*q;& ]9 D3 t% |( ]
        for(int i=0; i<vexNum; i++)
    0 N& T2 N+ U( A' E) c8 @6 `        tag=0;
    7 U9 y7 }  R% H  B2 m5 g    for(int i=0; i<vexNum; i++)
    ; b7 B# e: O, U- z# e' m    {$ V" \: M: p4 N3 Z6 z
            tmp=i;' |! R8 K/ x2 [. ^' y$ [
            while(tag[tmp]==0||!s.empty())% k& |# }; g  O
            {
    & t4 c# {  x  G! H& f; B$ j            p=vexTable[tmp].firstarc;
    ) h4 M: J, W- d/ B; n            while(tag[tmp]==0)( e: ~  f/ R! S7 m, P
                {8 y9 E0 f+ ^! H$ y! q# L+ W
                    s.push(tmp);
    % ]# g- P5 Z3 ?& I% U8 C* @                cout<<setw(3)<<vexTable[tmp].data;# ^; t. D) l- r
                    tag[tmp]=1;3 V5 w. R" N  e' e; _
                    p=vexTable[tmp].firstarc;
    . z! N/ M, c# V: Z& n9 |1 N# [2 z0 |                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for6 f. E  j) x3 B- Z) Q
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);5 ~8 \" y) G8 Y& n" C7 X$ a- F
                    //cout<<" 1st     tmp="<<tmp<<endl;
    + d" L$ D" z, }5 G0 T            }
    ( w1 y: j5 r$ L5 U% f' e            if(!s.empty())
    7 |# y2 W+ \. g            {
    & \/ O! _* ~9 N$ G; X                tmp=s.top();
    % y# z4 I; m; B3 Q4 x                s.pop();: ~7 b. D$ C7 y' t* w
                    q=vexTable[tmp].firstarc;
    5 S2 F$ `( Y) F6 i                int t=tmp;( H1 y* `0 V$ z6 @4 Z
                    while(q&&tag[tmp]!=0)
    0 y; s1 M4 Z: u, ]  N% c" ~9 E# q- s                {
    6 r0 X9 i& T4 S" K                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
      J: Q6 o8 \  W$ W8 w" w                    //cout<<" 2nd     tmp="<<tmp<<endl;/ t3 V9 G4 C8 F- d
                        q=NextArc(t,q);/ M1 f: s) W( D2 p. ?1 U, d
                    }
    1 [; g5 h+ o+ o9 C: m                if(tag[tmp]==0)
    1 E8 g5 {$ E/ Y! o                    s.push(t);
    3 E! E, N) b0 }& o, m1 Q; [2 Z                ///1、对应上面连通分支只有1个点的情况8 e& I# h6 n8 {
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    $ o  x0 x5 f# P  s% f+ M                ///tmp要么等于找到的第一个未访问节点,
    ; L+ |- H4 H5 q- ?# d' V                ///要么等于与t相连最后一个点(已被访问过)8 y2 D) N3 |9 C3 z
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点0 E$ t5 ^: ]5 J8 e& F9 X+ f/ v+ N& J
                }- |4 K0 ]' c* ?. i; j" Z
            }
    7 Z' ^) F: ~0 Q# l8 K. `    }: r: p# w/ o$ s
    }& y3 Y* g! K) ^1 }
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1
    $ u- C) b$ |% H' x# Vtemplate<class ElemType, class WeightType> int( h/ Q5 m6 ?7 Q/ d' o
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)5 Q+ `7 d8 b. m4 x0 t2 i
    {* O9 r# G9 `" x) Q
        if(head==pre)& l+ D% J: [8 c5 k0 c
            return -1;
    - ~! @8 Y* T' n
    ' m2 X6 E$ X3 J  b' V$ i- I9 `1 y/ U4 g    MultiAdjListNetworkArc<WeightType> *p;
    * \2 t+ d1 J) x$ F& `8 F    p=vexTable[head].firstarc;+ n1 Q- E) `4 c8 f% }. n  `$ Q. m
        if(pre==-1&&p!=NULL)
    7 D' l( O6 }  t# o1 Q- X7 ?& e        return p->adjVex1==head?p->adjVex2:p->adjVex1;; Y: U+ G0 v5 X2 ?' q+ \
        //pre!=-1&&p!=NULL
    ) `  K- g- \7 e1 j0 f3 E9 r    while(p!=NULL)( X6 Z7 D6 d/ X/ y
        {  D2 M, P7 `# U' y  `3 k+ u
            if(p->adjVex1==head && p->adjVex2!=pre)1 n: z" E9 ]6 b) D! U! x9 N" R
                p=p->nextarc1;
    6 p5 C8 V& U, C6 Z) N" v        else if(p->adjVex2==head && p->adjVex1!=pre)5 x$ {( p( c/ ^2 A
                p=p->nextarc2;7 t1 c' R& H! ?
            else if(p->adjVex1==head && p->adjVex2==pre)
    3 b& G1 N3 w: H( s  U/ E8 y0 \! P% r        {
      L1 O# v# [% u- r3 v            p=p->nextarc1;
    : `' r# M  X0 a4 G; Z0 s" @            break;: e6 \: {/ K! ~2 d; f
            }) ^/ y1 n- q4 V( `3 c% l( s* b
            else if(p->adjVex2==head && p->adjVex1==pre)
    ! S$ B& r4 r3 t& M/ ]        {2 Z) `. F8 Q0 ~' @! s- F
                p=p->nextarc2;
    * A$ w$ _# @6 p4 u' I/ `8 D            break;2 c6 T  F/ H: w
            }
    # V8 E- l4 K# G    }9 K, M* }9 y" e3 q" Y, i- H2 d
        if(p!=NULL)" n7 k, e0 o3 r7 M7 U- r$ t
        {
    ( u. v& w4 c+ k        return p->adjVex1==head?p->adjVex2:p->adjVex1;- D/ K1 D" o4 D3 q& S) f& C0 ^; R
        }0 f, y' E* h/ j3 x
        else5 M4 y9 G. u8 p2 v
            return -1;
    4 v3 {+ G( T- K# y5 H}
    " P' ?' C' s; B" Z6 M; w  t! @% V- @5 M2 J  u: i5 G% ^( S

    - S( h1 n, P# M0 t% d0 `template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    2 @3 E0 w7 X, J1 _+ f{. Q$ T& Y2 X2 T8 V% y$ |% C
        stack<int> s;( A4 f$ i  \' P
        int p,cur,pre;: u% C* M; o% r6 o
        //MultiAdjListNetworkArc<WeightType> *p,*q;, e8 Z. |* b2 U1 {, A- {
        for(int i=0; i<vexNum; i++) tag=0;//初始化
    & T7 n1 A* @! z. Z1 K
    7 p% I; u) R3 \8 B5 ~    for(int i=0; i<vexNum; i++)
    : T& N/ x' r& k" |    {+ l/ \# N9 q" q0 Q: n" p
            cur=i;pre=-1;, b0 ]3 n- t. J7 w
            while(tag[cur]==0||!s.empty())* F( U! B. W# E, Y# ?9 m
            {
    # G' H, ]! T7 N% Z1 W' l8 ^2 w            while(tag[cur]==0)0 ]* Z3 w  u7 |+ Z4 ]8 V
                {$ m2 s, k3 A$ Y3 f
                    cout<<vexTable[cur].data<<"  ";
    % B) |8 q- X5 L( f' Z                s.push(cur);
    ; O2 m8 I1 Y( A7 |6 ~+ v                tag[cur]=1;7 D. J4 f% G, L0 _4 B; C- I
                   //初次访问,标记入栈
    9 h# v4 `1 G/ f0 n5 c2 U% J& \( ~9 x2 N
    , s- C% a* |& N) a7 t( b               p=GetAdjVex(cur,pre);//p是cur的连通顶点
    8 K! z: M) N8 f% r6 ]1 ]# @: S/ [               if(p==-1)" g+ J- F, U) R
                   {
    : ?* r$ H+ V: g* x/ ~- O! o+ _! _                   pre=cur;s.pop();
    # f! c8 h  p& d2 o" w7 p                   break;7 y/ e* `* Z9 u
                   }
    ' L% r: W7 q7 c8 v: }; [- [# y               else0 C6 `& Q5 ^5 `6 l" }# x5 W
                   {9 L$ l. h/ z0 }
                       pre=cur;
    ) d+ m$ Z2 K# n; @0 ]6 S                   cur=p;' t/ d! z# b/ c# U9 `6 y' W
                   }" }. E8 [" y; J3 \

    4 y( ?8 w: i* G% \: e% u            }% x, t" d/ Y2 i) y# h
                while(!s.empty()): X, {# W+ g$ w4 B7 q, _) @5 T
                {
    / ~' h" u1 {& Q  t                cur=s.top();
    $ n/ ^) O# u# a: B                p=GetAdjVex(cur,pre);4 W; \7 e) C. ?, I$ f
                    if(tag[p]==0)
    5 [4 z9 [" D; F2 `5 \                {1 {5 P: x0 z" B5 A+ p7 d" U5 g. i8 G1 u
                        pre=cur;
    ( B4 e1 K3 J, K9 ]                    cur=p;
    1 |' v- Q- v3 W/ E                    break;4 ~; G' m2 f3 F$ h  l
                    }
    7 }# X: D4 F: x7 |! X- s) S! L) u                else
    / g" P  W5 J& e) `% G. q9 h$ M                {
    & d$ o: ^) @9 o2 @                    pre=s.top();
    " z  S3 s% c$ {- x* `. ^                    s.pop();5 _# Q. ?6 J7 G
                    }9 [- K) t  \) q3 \, |, G

    3 B7 u5 e( J6 o            }
    # E2 o$ U3 Z. C9 W& o% s
    5 x5 i7 ?$ V; c8 {* U" G        }' c- Y6 w2 |3 c7 ?9 P7 u
        }7 m% K: @' S) H% N* x. U
    }' }- U- `' v8 U7 f0 E
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()% X0 Y# M: }6 ~4 ]6 K; M' `2 b
    {
    * P6 F3 X. n7 L2 v. D    for(int i=0; i<vexNum; i++)
    : T5 F' n% i4 x/ x) l1 M8 T        tag=0;
    . r$ C* n! C7 D4 G0 o  o    queue<int> q;
    4 s7 I% l; k7 Q: K    int tmp,t;
    5 U8 y! b. C4 ?3 ^  A    MultiAdjListNetworkArc<WeightType> *p;
    $ v' }& {) h, L4 D1 ~+ k2 ?2 t2 `, v    for(int i=0; i<vexNum; i++)
    " u2 i! D# c8 F    {" O& u6 M5 B8 b7 r
            if(tag==0); p7 `5 p5 B, a6 R9 y& b+ h
            {
    7 d/ I9 I! ^: @/ Q) ^: c  w8 p            tag=1;8 }) a5 F: G: H; U  v$ p
                q.push(i);1 o3 Z: Y. r3 m# \" b3 D6 f
                cout<<setw(3)<<vexTable.data;& {) Q% ~  G6 z* g6 j
            }9 a, h5 X* p1 c4 v7 n
            while(!q.empty())
    , d" Y- o3 p' N% x! }+ [6 ?; g        {
    ) A# n9 b$ V5 g2 Y4 H/ [. J            tmp=q.front();
      B9 y: l0 ]5 e1 N            q.pop();, {" k! e5 B( V- ?
                p=vexTable[tmp].firstarc;
    * G8 W0 s! G) ?$ l            while(p!=NULL)
    , `; Y; C4 ]: n* R: _& `& @, F            {
    0 @. e0 I! E5 i3 H. G                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    0 ~: }, P1 R( h3 h; |9 Z                if(tag[t]==0)" Q/ e- V; Y3 K0 q$ D3 p
                    {" s+ [( Y; l- x2 `! a/ c
                        cout<<setw(3)<<vexTable[t].data;
    ) k8 i6 X; Z: g4 L( s+ p. y                    tag[t]=1;
    0 B4 i% @2 |- ?/ Z. s                    q.push(t);$ z% s0 d- n/ ^9 x" w
                    }
    0 [- D5 O1 T# i                p=NextArc(tmp,p);
    + F; @" @( [+ H! e9 A; o. }# [- c            }
    6 H! k) T- i: a* x: L        }! x& Z7 ]4 I( {5 p2 E
        }  T3 b! B  K. w" ]- r
    }
    3 n' ^# R+ f& W4 I. mtemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()" z9 m' Q& A2 k/ N7 @
    {$ g# b' s$ f8 _1 B" F6 F# F( `9 c
        MultiAdjListNetworkArc<WeightType> *p;, g- @8 i$ ~) \! w) H
        cout << "无向图有" << vexNum << "个点,分别为:";: {( D. k* G5 Q# \, U; B6 Z3 [
        for (int i = 0; i < vexNum; i++)( Y# ~- P/ g  r5 ~
            cout << vexTable.data << " ";
    5 G* }/ w3 V/ i. z    cout << endl;
    / s% g4 X2 l, i# h# g8 r    cout << "无向图有" << arcNum << "条边"<<endl;
    " O  M. z6 Y$ {2 V    for (int i = 0; i < vexNum; i++)0 Y" \8 [! J7 D" p9 Z% b0 L3 X/ E; B
        {+ o9 f5 E* h; N0 B
            cout<<"和" << vexTable.data << "有关的边:";
    1 T* U6 J; H( T* x        p = vexTable.firstarc;; j4 H$ T& \1 u" x9 I" B
            while (p != NULL)
    & {1 k% T7 C' T+ I! l        {$ a# ~& D& D# o' l, [8 X2 f4 W
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";; X# r% S' s3 G% m: m
                p=NextArc(i,p);/ y. m; G1 @- V( I
            }
    * @' _+ c7 E+ N" ~$ ]; N( `        cout << endl;
    . v0 Y) e3 G9 p* O. C# {) W) S    }
    6 `* q- o# Z. T& h}
    " Y3 w5 P4 w. r) b
    8 z7 d/ M$ c' j7 S  }
    ! t$ W; j1 b5 F9 V邻接多重表与邻接表的对比" ?% w, t7 _7 P9 l! I( V" c
    / X) y! y: V$ v/ |) E* {! R0 j
    邻接表链接! t) D/ n8 B' s: n) }! R0 A
    在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。' M7 r' S! y9 ^
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
    4 V( s% N' s& s# T为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。# K; @1 ^5 \/ V/ |( b$ {7 s  j) ]
    ————————————————
    6 _4 {/ w$ N& x- H: O版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。; c- u7 L5 m9 Y: u$ V5 ^
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    6 \3 ]. L  a- @( K) H) h# y
    / K" U7 b1 m+ o2 C
    0 P/ h. O! Z6 V  T( ]- r* q8 p# @3 `5 _5 b- S/ y

    8 Q9 R1 s4 u/ {- ]. z4 J: Q8 w4 L————————————————- P9 g% y! k  i9 w
    版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    5 @* O3 j! G8 @; H原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    0 W& Y3 |1 |. F& W4 J4 I" y" O5 R' u+ T
    % `# j0 Z6 V0 Y. V  T
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    fastpost qq
    收缩
    • 电话咨询

    • 04714969085

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-11-1 08:14 , Processed in 0.261370 second(s), 54 queries .

    回顶部