QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1564|回复: 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
    $ I$ ]/ U7 k6 d# L8 o) `! j
    图的存储结构——邻接多重表(多重邻接表)的实现
    + G+ g1 M9 L% g& M7.2 图的存储结构
    % L$ q; h7 s% y: o  R
    8 Y7 v! _1 A, F+ J1 D! ?7.2.3 邻接多重表(多重邻接表)Adjacency Multilist' u$ @3 L. b8 r) I
    邻接多重表的类定义
    8 x/ b& J0 n" x邻接多重表的顶点结点类模板
    5 I7 P* Y* n3 L& C- C邻接多重表的边结点类模板+ F" I8 d, R' F( H9 x3 ]* i2 q
    邻接多重表的类模板
    4 {& u" h% H* x  Q邻接多重表与邻接表的对比5 ]/ t& n0 n" e4 P
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist
    6 `2 N) g- t, S3 ]6 [
    - C+ Y6 i9 p% W- V. T( n7 J在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。
    : `+ a. \% K" ~3 \在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。
    1 k: x- k! S3 _$ }, s. \( ~; j) Y( ^0 \( j0 I& g9 R4 w# [8 i
    邻接多重表的类定义) H! D. `) W0 K
    1.png
    . z( b/ c( ]9 s( P* B$ j邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:
    6 V* o0 \' \0 i1 Ydata域存储有关顶点的信息;; ]6 |( I1 T0 T% c" c5 }+ q) k. l
    firstarc域是链接指针,指向第一条依附于该顶点的边。- E5 _/ K& y1 ]; m! Q2 m
    所有的顶点结点组成一个顺序表。

    / l8 c  s  Z$ y- b8 T' P
    : p& P6 R$ |# }" G4 B- L6 r
    template <class ElemType ,class WeightType>/ l# Y2 G- p8 T/ [: k, w
    class MultiAdjListNetworkVex
    ; L( k7 V9 N5 A: y{
    0 ]* C+ W- Y9 U3 D2 X; spublic:5 g: u8 q7 w& l1 ~) _
            ElemType data;0 V; p+ I! X( s4 q4 Q4 `
            MultiAdjListNetworkArc<WeightType> *firstarc;: L5 n8 l2 I  r. ^6 o* V2 q9 i
    5 `% {( W5 x1 P& }' W
            MultiAdjListNetworkVex()" m+ k. Z. U) r, s4 _8 H
            {
    8 I: J3 m( L3 u: a4 {5 b, o4 I                firstarc = NULL;! d' g4 [& T) B. X3 T! D
            }
    + c& f6 U1 ^  ^, I: L        MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)) n5 L" o3 t7 Y/ @
            {
    - E, m% w: P5 x3 Y/ n$ T- t2 ~                data = val;, U* c9 w- s' a0 x* D3 r% z
                    firstarc = adj;6 L7 l3 F; ^! X7 ?  I9 @
            }
    / Y+ W( M0 ?  `: `5 w};! ~: L3 C/ v9 e7 u+ g+ W+ `% J

    . a" X: w4 J$ F0 [邻接多重表的边结点类模板
    $ {$ M! ?. t% \+ a- R, J
    0 G; q! |# ]  H7 V' J$ \4 P在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:  _9 F7 ^. ?9 U1 t6 [7 i! x
    tag是标记域,标记该边是否被处理或被搜索过;
    % n$ b( @3 P$ ^* |1 U: |weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;
    # U, Y+ N6 [2 x3 ]0 ynextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;/ T" u+ q! R" X
    nextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。4 [+ r2 e) Y+ W/ K, G' a$ P
    3 I# w0 _( K0 U& ?
    2.png - V# s9 v0 ]7 r, Y: G
    template <class WeightType>
    8 ^- h$ f/ A1 Q4 cclass MultiAdjListNetworkArc
    % \3 y% r# C) \; q- c7 X{( o1 f+ x" D) S8 W# ]: i
    public:. {) M) T/ P, G0 X" B
        int mark;                                       //标记该边是否被搜索或处理过
    " C' g* o- g3 B6 h4 Q% Q        WeightType weight;                              //边的权重
    : V. ^& _6 ^& C        int adjVex1;                                    //边的一个顶点- ]3 `* g% t5 l2 D/ }, g
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-1( C; F8 _7 V$ A% c2 s+ X
            int adjVex2;
    5 b$ f3 A# G$ _        MultiAdjListNetworkArc<WeightType>* nextarc2;
    : D$ Z. S- }$ }* J9 b) F; O0 Y- K% E  G
            MultiAdjListNetworkArc()
    & T$ W! P# i8 V. k* u" Y% u        {
    0 b+ [8 }: r" H4 d2 P& f, E, [- a                adjVex1= -1;
    " N, f% G+ o) X; {2 w: J- s4 t                adjVex2= -1;& t7 I% e% B& K4 N- N6 S  @6 p
            }
    0 L! {6 ]9 X- ]9 I1 `9 P  I        MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL): ]4 u6 `' n: @4 H' V) R
            {
    4 c( |1 I3 L5 v                adjVex1 = v1;       adjVex2 = v2;9 }8 f) s2 q! R, N+ v) b" P" Z
                    weight = w;  A3 y6 k: ]! ^1 z# {) Z3 S8 K
                    nextarc1 = next1;   nextarc2=next2;! N, Y* w* c' b3 a# |
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    & h1 o3 b0 i/ r8 R, M        }, E, P. x( |! L0 Y9 h

    7 l% w) N/ q4 y+ F邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>
    - ]( C0 w8 K1 t. v' `/ Vclass MultiAdjListNetwork% e: }3 j2 x/ h
    {* k0 R& C; j1 B: o2 ^4 h8 x
    protected:; m4 s! X- }/ F7 e" b& K
        int vexNum, vexMaxNum, arcNum;
    : J( H# D# F7 J. }+ E6 R    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;
    3 @& O# D% B6 V% O/ @8 Y4 c& Z9 ]    int* tag;- S5 ^& w2 Z* W6 u
        WeightType infinity;
    3 G' D1 \. W1 G$ g' ?
    # _# h* k5 c& o8 Y8 `, Y2 mpublic:
    % `/ k( u" B2 `, c2 \3 O+ U    MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    & W' |+ h4 Z7 W9 b' C9 j- k# X; q' N- b0 C' W' ]  ~
        MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    + i- Z6 X7 F, E2 N1 }
    4 Q1 E; A# \4 z' {6 {    void Clear();+ j6 ^" Y5 B! X+ ~' O/ b
        bool IsEmpty()  N- h$ T& M! }4 h' @% j) A
        {) ?# L4 V1 e$ v: D8 @! R; ^+ z
            return vexNum == 0;
    ! L+ n! V$ h7 M2 F. }6 ^! {+ G    }
    7 w; Y  j( D  c& Z    int GetArcNum()const
    8 `  z8 ]' Q" B1 t, {7 I8 C% a    {/ J8 ?- a- j% ?  p! q
            return arcNum;
    5 X  ^1 o5 L8 ?    }$ l4 y$ R) O2 i* g% d7 w
        int GetvexNum()const
    ! L/ j% X3 Z% S. [    {  z6 ~0 x. Z% ~7 ^+ y: @
            return vexNum;
    1 {6 ~9 ~: c) ~4 L; B7 K) D    }# k" u1 U* Z+ U' D4 \+ x

    4 K  w- y; U0 ?2 e2 t+ d* o' K5 l% o
    + G! F* T% W% e/ @* v2 F7 c( U    int FirstAdjVex(int v)const;
    ; j& W7 u: `7 ?    int NextAdjVex(int v1, int v2)const;
    6 T$ q( w2 f! o( Z1 `& H2 l    MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;* K4 R! L7 N7 ^5 V- F2 W' D- P6 F
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    8 d/ V" Y) n1 _( n
    + i% K2 h( i2 c0 O& R, m    void InsertVex(const ElemType& d);8 `" w- d% h+ j% X) J
        void InsertArc(int v1, int v2, WeightType w);
    5 `) h: f, m3 v6 e4 h2 o
    : t) e! f& k3 B* f9 m+ q- s2 y    void DeleteVex(const ElemType& d);
    6 ?# U+ [6 T* m6 E) c6 V- x    void DeleteArc(int v1, int v2);5 }' T. v3 M5 X& T

    , V. b8 F; {) V: B. r    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);3 x9 u0 s: D  w4 H9 @
        MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);+ F7 e8 \! ]# H- k2 ~

    2 c7 H' p8 a0 X' d/ A- D0 n    ///深度优先遍历
    1 ?* Y1 s  f$ m! ?; J    void DFS1(const int v);
    , O$ y& F9 K" h+ ?6 [% [    void DFS1Traverse();8 v) i8 j5 ]! I$ Z) a
        void DFS2();
    / S$ P; ]  a4 C! \( X* a# L1 y9 y
    1 R! h5 W* q( S' o  n, @& W    int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-18 V1 s) ~& |! c5 J" b5 u
        void DFS3();) D! M1 U3 X" Q* }. W3 |
    7 ^" \* s+ C1 H
        void BFS();
    $ b, [( g0 J# I& V+ {. F- c$ Z    void Show();
      t1 H  Q+ h% E/ @4 z( F3 l. M  @};
    7 E' ]* q4 Y: z$ X" {
    : Y7 x; m1 R" n9 O; v* x9 r2.函数的实现$ [$ ?" B& F& f
    研讨题,能够运行,但是代码不一定是最优的。6 u* Z. I9 D$ X6 F" T) K

      f* \* j" N; h: I. U! P* x#include <stack>
    ! C  `1 d' H5 A#include <queue>
    - }% `+ z  i% \8 z! `1 k" _, R& V& r
    template <class ElemType,class WeightType>2 G5 V( s) j1 x9 X* P
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit), E% |2 h# V- b: t. ^4 \# z
    {: f; N2 R6 Q+ C2 _: z1 O
        if(vertexMaxNum < 0): ]/ Z, d; r+ f
            throw Error("允许的顶点最大数目不能为负!");  R- F2 f5 n$ V. N& s2 G4 W
        if (vertexMaxNum < vertexNum)2 g" ^* |- n6 _
            throw Error("顶点数目不能大于允许的顶点最大数目!");
    . n! ^: [4 ?8 Y* i    vexNum = vertexNum;6 V* {3 T& D; ^0 e
        vexMaxNum = vertexMaxNum;0 b) x4 a& ?) Q* l& ^: o
        arcNum = 0;
    : C! v# o( f/ Y! N* a" O, x    infinity = infinit;
    0 T( s1 u) n! Z5 Y% [2 p    tag = new int[vexMaxNum];1 n, H: [# T8 w0 J
        vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    % O; b# k8 u2 y" H# t( B    for (int v = 0; v < vexNum; v++)
    9 H$ G. B" N2 A+ d    {
    ! U# F8 W1 r5 {/ A        tag[v] = 0;/ Z8 i; P9 E$ K1 x- Y8 a
            vexTable[v].data = es[v];2 ]6 Q/ \' ]% i; J& K8 _4 e. Y
            vexTable[v].firstarc = NULL;7 F5 U+ W+ ~8 e# L  i
        }
    1 y3 ^& r; M% u}: S. T! a! ~6 v( E3 {$ |# L+ w+ j
    template <class ElemType,class WeightType>- @3 v* i  ]2 w2 N) R, W7 v
    MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)% U2 U% x- d' c9 X# a* s* A% e
    {
    ; o! G0 B! ?: y- f0 N    if (vertexMaxNum < 0), O2 k# h/ O* l- ^3 J
            throw Error("允许的顶点最大数目不能为负!");
    7 Y& W, Y3 R. T9 C    vexNum = 0;; i3 Z$ w1 c% G
        vexMaxNum = vertexMaxNum;8 n0 I- z7 E: C4 V, q
        arcNum = 0;
    ; ^7 \2 \. |+ J1 z% k2 {    infinity = infinit;' o  K+ ]% `" i! A6 p
        tag = new int[vexMaxNum];
    - b% ]" N8 ^& t& T) N; X    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];$ f! k4 N# L3 e! Y
    }
    - t- i  `( E& ^) R2 s# ^template<class ElemType, class WeightType>
    - }) G6 y0 S8 S, q, M* Y6 i; p; Mint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const6 Z$ \; z! P) O0 W6 y
    {+ _% }; l6 B: w7 O2 ?* _& a
        if (v < 0 || v >= vexNum)/ k. H$ Z5 W  q
            throw Error("v不合法!");6 F6 {8 m# G5 N$ L" {4 G: L7 f
        if (vexTable[v].firstarc == NULL)% \$ b! G: I- ~# t
            return -1;2 l/ R. v% u+ D& s- N6 a
        else: W( T( ?/ b8 i* t2 H4 R
            return vexTable[v].firstarc->adjVex1;
    2 ]8 C0 H9 O: L* u/ r}6 t  [4 j" {& H
    & @$ p) j3 e& W/ }3 X
    template<class ElemType, class WeightType>1 k  S8 X! b$ A# t3 f( R& L
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const
    9 _9 o2 B1 ?8 M6 y! l{
    8 a' z7 j* X9 m2 C    MultiAdjListNetworkArc<WeightType>* p;% V2 F) E8 U' k6 r* n* z" K
        if (v1 < 0 || v1 >= vexNum)
    : ]7 o& M- ~* P% a        throw Error("v1不合法!");
    8 t" ]8 [. c+ k3 P6 @7 t    if (v2 < 0 || v2 >= vexNum)3 `: o& R0 B, z5 M- ~
            throw Error("v2不合法!");
    . T4 U7 l: p" b) ~( s/ U' o    if (v1 == v2)
    1 P& z7 X1 z$ `  `        throw Error("v1不能等于v2!");
    . {% H. t+ h; p    p = vexTable[v1].firstarc;8 ^( \/ Y4 J* K& p& \
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2)$ B3 r9 M: b2 {; o* `
            p = p->nextarc;
    * e# `5 }  Z7 Z8 b7 @    if (p == NULL || p->nextarc == NULL). ]8 A8 R- N; t! U
            return -1;  //不存在下一个邻接点6 s% \4 J* u: e$ s  o& Q' B
        else if(p->adjVex1==v2)
    / I; i& q. B! l        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);$ q* r+ S7 V) b. |0 O
        else/ Q* ?% r: J  z& m
            return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);
    9 R, a5 }& X0 l2 [* J$ l}
    . n9 A# X+ l; O5 v% d- G4 rtemplate<class ElemType, class WeightType>0 q) _4 a4 S- d/ |+ c: X
    void MultiAdjListNetwork<ElemType, WeightType>::Clear(): j9 \  ]7 D1 f% k
    {% h4 s/ R; b) r8 a) [
        if (IsEmpty()) return;& K; u* h$ ^3 D" u! L! H
        int n = vexNum;, `9 A! M4 B" w3 q: f: M$ c
        for (int u = 0; u < n ; u++)6 P- `* Q7 N) B+ y' I2 k. k
            DeleteVex(vexTable[0].data);
    $ _/ c: X  l) ]; f! K    return;
    8 @1 y& \, Z  C7 I/ f# r}
    + V- Q3 w0 A2 \. T% {template<class ElemType, class WeightType>
    , Q- j' \0 _- [4 o# vMultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()3 d8 G* w6 [6 m9 L
    {
    / k1 ~  K0 o3 ^! \* c2 z* x    Clear();
    $ P4 P# M7 N( \2 o6 E: E}- R2 u7 o2 v; ]; R: M
    template<class ElemType, class WeightType>
    & S* M* |$ ^/ N6 M1 ?, x+ T( \  @MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)
    % V) A5 S6 }( M! S$ Q{3 \9 A0 W& [& G: ^! T% p
        vexMaxNum = copy.vexMaxNum;4 y; m7 W. c0 A, p3 \
        vexNum = copy.vexNum;
    + W" `0 ^; J) C, K1 z. J7 n& y    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];  c  @) |; f9 \. Z
        arcNum = 0;
    & D1 n, r5 M3 [' ]3 w, T* @2 k    infinity = copy.infinity;4 S6 N+ i: F1 }/ e' _0 h
        tag = new int[vexMaxNum];
    ! P6 g, k6 g6 ]+ J' _1 H7 V4 K* ~) y* T+ n3 K
        for (int v = 0; v < vexNum; v++)* a8 r% U! B  H  ^6 h4 L3 G
        {
    5 o# Y; J* ?' k( ]; ]        tag[v] = 0;6 Q3 d& E, q. A3 }' O$ h7 f
            vexTable[v].data = copy.vexTable[v].data;# S5 i! z" F# t! _& o+ L
            vexTable[v].firstarc = NULL;
    ( b- [  v# k4 C! I2 F    }
    7 S. J! G9 I% w& ]1 r    MultiAdjListNetworkArc<WeightType>* p;7 q  {# l9 b' V% y% O  }" D

    0 Y- ^. E1 k5 I( X5 s* o    for (int u = 0; u < vexNum; u++)5 _6 z! W& j8 b  l
        {2 z1 q  H8 n3 e- a/ a& u+ l6 y
            p = copy.vexTable.firstarc;
    3 ^4 \1 Z# u$ @1 G$ s        while (p != NULL)" `0 W( K9 c+ G- B: h5 ?
            {% v1 w$ ]5 w2 y3 g) T
                InsertArc(p->adjVex1, p->adjVex2, p->weight);3 Q; w% E$ [) H
                p=NextArc(u,p);
    ( S( Z, q9 G0 o4 H' ^5 ]4 c$ O        }' Z. g$ y; V. \; |2 k3 o$ o: v' W. }
        }
    ( _. D% `4 O) V2 n}
      z& L* D- N! H% l# qtemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&( q9 [) }* o" Y/ I
    MultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)
    . e8 q( w) D8 I7 k5 Y{
    * W' b9 N, ~% ^( X5 I5 u* P) v* b    if (this == &copy) return *this;
    3 D# M! R- r5 O# q1 h& u( d    Clear();$ \& \3 Q( h8 E$ J1 @' j- @. t  d. ]
        vexMaxNum = copy.vexMaxNum;. m' r( G  @* f8 I1 r6 }4 P5 C
        vexNum = copy.vexNum;
    8 I7 o' M$ C8 [3 X0 p4 A9 K& R    vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];! C. \2 f- _9 G: T) w( Q8 p
        arcNum = 0;6 b! P) u1 x2 R8 t, Z
        infinity = copy.infinity;
    4 \  \9 D: c+ G, k1 J6 s    tag = new int[vexMaxNum];
    $ `7 `. Q, K: z* D2 i! `
    1 C% e! Q  [1 G( \    for (int v = 0; v < vexNum; v++). E0 n8 b$ s- A- u  C7 K& Z& @
        {2 o3 y$ f# \# m1 t% H2 a
            tag[v] = 0;
    ( \& n. Z- s4 `& D. _        vexTable[v].data = copy.vexTable[v].data;% v+ j0 U% a5 a6 P
            vexTable[v].firstarc = NULL;
    / X$ Y) }7 j; Q& w- i% a    }
    6 }3 A+ L+ |' o  G0 l! B    MultiAdjListNetworkArc<WeightType>* p;
    " \- V% J' L  r& _% C
    " h% a) G0 J  a' Z- S0 o    for (int u = 0; u < vexNum; u++)
    * b) g  `4 y4 g; U8 n    {
    " I& z, a/ A( ~" G2 i        p = copy.vexTable.firstarc;
    ) o! o% x" ?% E9 S1 _- K- y        while (p != NULL)1 A  w. i2 z: t. {
            {' K  g( i1 O4 R+ p) ]# z# a
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    ( Q- X  L, J( x3 R+ l. o            p=NextArc(u,p);
    + c/ y* x& Q8 V: h1 p( S0 o        }
    0 J8 K2 p5 \! z    }4 \# r& T: A" G
        return *this;  U; b$ S& v8 ]  z2 X" I- a
    }
    ( O9 a4 l. J6 K0 [template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    ) t) v  w, ]1 U; J& {* d% u3 QMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const) y1 W% T/ J1 F) k
    {
      `" O/ Y9 c8 X1 f1 F& N- Z! [    if(p==NULL) return NULL;! `6 f/ p3 C2 S( A5 a0 ^, w
        if(p->adjVex1==v1)& N6 |4 I- c. L
            return p->nextarc1;$ x% O7 |9 M+ Y. }! O- R
        else+ y! t3 K% u# R) K7 n
            return p->nextarc2;
    7 y8 {# p4 u( q9 E0 R! k$ `9 V; A}/ ~: L1 r# h4 ^, G3 i+ K
    template<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*0 [+ o' W- |. y+ Q2 |+ ~* r& b# T
    MultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const$ W0 w- y' U' R4 t4 v
    {  x- U9 d7 F1 H9 X
        if(p==NULL)return NULL;
    8 k3 e9 a- c/ f    MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;
    / ~+ Q# b5 L* H* k* y    if(q==p)
    - M, U  K% B+ I) c) i        return NULL;
    + {, O- `( w7 c/ q5 ]3 P    while(q)
    0 U+ Y$ M/ {+ L    {  M  @( o9 j' T) m, n1 a
            if(q->nextarc1==p ||q->nextarc2==p)! q) C3 V* ~5 g9 q- d# U5 b! ]
                break;
    4 f+ t: T8 ?( n3 f        q=NextArc(v1,q);
    , r0 M# K) L+ X  E, k5 Q    }
    $ L( U5 d. b! A1 k( y0 y2 X* n9 [- p    return q;
    ; a7 z! i6 S, O4 N* z}
    , Y6 y6 z+ `( T4 c% L; ftemplate<class ElemType, class WeightType>
    7 k. u# a+ a' Ivoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)9 k0 L5 o( a, ]
    {7 Q! N) d/ q: r. x* u% d% x
        if (vexNum == vexMaxNum): k" Q& ]; [+ r( H
            throw Error("图的顶点数不能超过允许的最大数!");  ]1 x8 ^5 H$ C2 ~4 V& w- A
        vexTable[vexNum].data = d;& A2 e5 g8 V4 W0 V$ s" O3 `% A
        vexTable[vexNum].firstarc = NULL;* R/ p+ x  M8 v9 D& ^
        tag[vexNum] = 0;
    8 d/ i  ~' d( L! O    vexNum++;# o( ~1 @4 f8 E5 m
    }
    , ]* ?2 ~5 |# [% |template<class ElemType, class WeightType>
    * ]2 }- E) c0 D( A  ~- ?: Bvoid MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w)+ E, r, k/ r% D/ u6 ?* M* q
    {
    9 {: i% _* |8 S# I) H    MultiAdjListNetworkArc<WeightType>* p,*q;
    ; W* @$ J: Z# p4 Q/ z    if (v1 < 0 || v1 >= vexNum)
    - z; Z' o/ B7 b4 c" h8 P        throw Error("v1不合法!");
    : b( b' D# @8 Y$ x9 g% Q    if (v2 < 0 || v2 >= vexNum)% G: [! T5 C/ }2 d$ ^
            throw Error("v2不合法!");
    3 B+ {( X7 C7 S* [5 n, S/ M: C" c( c/ m    if (v1 == v2)( c$ d" n# k; d  g
            throw Error("v1不能等于v2!");" p8 B( z: l) c7 o, S2 \* T6 O6 R6 M
        if (w == infinity)
    7 a" a/ H* M# i3 u        throw Error("w不能为无穷大!");
    ( q% N0 Z9 j% y: Q6 B- B  V. f: z4 E' G, R; [2 h" c' w( e

    9 v. z. u& @/ j* W    p = vexTable[v1].firstarc;
    1 n' A$ u7 V( f0 g! Y    while(p)0 u+ E' d8 G1 j! B' b1 Y8 C+ k6 _7 W
        {
    4 D( X, B$ w, u* t3 e        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    ( Y7 `  |" B# ^: R. u$ \8 O  k        {
    " y0 H% l6 P1 _  k. e7 Y8 }% D            if(p->weight!=w)
    * H% \( Q, z1 F8 m0 S) @* n                p->weight=w;
    4 ~" N( d9 m% H0 I& O* N            return;  m$ h; y  k& Y% v4 f
            }, }5 u7 \4 k8 Y0 W

    ; d0 Y7 T. A" w5 i/ x7 ?7 G        p=NextArc(v1,p);
    : k$ b; D$ B) n6 b1 e/ ?( e    }
    - i' k# s$ l9 d- ~# W    p = vexTable[v1].firstarc;
    , x0 J# S1 C+ ]  F/ E7 Z# ^4 A    q = vexTable[v2].firstarc;8 v0 z' \7 G! s8 {0 {4 e
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法
    4 `) c/ U. @2 T0 i; W' I8 U    vexTable[v2].firstarc =vexTable[v1].firstarc;/ x( {7 z0 v; C% d4 ?/ }
        arcNum++;
    ( m' W" ^6 e' f' L. x}
    0 _+ z) Z2 j; Z- p- ?% g$ N3 C# L0 e0 F2 i5 m7 ]" `
    template<class ElemType, class WeightType>+ k! x& |' {4 f' d$ W+ F& q) W
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    & ?" U# s( V  W  f, X; g! _' \& j{6 |9 g! Q. L5 @/ k0 }' ~- y: `: m

    # e+ o' `; {" e: [6 h! J1 g  m( b, N    MultiAdjListNetworkArc<WeightType>* p, * q,*r;* B& v% B3 v  n% W# [
        if (v1 < 0 || v1 >= vexNum)4 O# @- |' q/ P. t! p
            throw Error("v1不合法!");( z3 D  U" \7 W8 Q
        if (v2 < 0 || v2 >= vexNum)
    ; z$ a; }) Z8 a# _        throw Error("v2不合法!");) _' Y$ `& }$ A( ~2 C, B3 O7 i
        if (v1 == v2)
    ! o, k) t8 k: Z# j        throw Error("v1不能等于v2!");; K$ ^* S- W" Q8 R( E3 \! u
    0 ^: {: h% a2 j4 w* {8 ]  |
        p = vexTable[v1].firstarc;6 |  |3 D3 k+ q+ \7 K9 x
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    & g) {' ]! @- o5 x$ C/ n9 Z- O    {2 `& y! H; `4 D
            q = p;
    9 v: o9 \. C/ N4 c        p = NextArc(v1,p);
    ' Y& M$ ?' ^3 Y9 m    }//找到要删除的边结点p及其前一结点q
    # |8 x& y" }# v2 [& G* p2 h$ s5 n# F
        if (p != NULL)//找到v1-v2的边2 G* p% U: S$ l# R; M+ j4 W
        {
    6 l. v& w& g; D# u2 S4 L8 T        r=LastArc(v2,p);/ R2 i9 k) D4 s  v
            if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL
    8 Z# K) U# X2 e# C8 A0 J1 m            if(p->adjVex2==v2)
    0 a4 o" O6 n( z9 g2 \5 q                vexTable[v1].firstarc = p->nextarc1;
    $ f8 j! H7 K/ K) C, a3 K# `- B            else vexTable[v1].firstarc=p->nextarc2;0 |# ~  S4 w* m1 ^* U8 @, [
            else//不是第一条边
    3 ^$ T- e0 w6 \8 F; V        {7 @) j3 ?* o, k) r2 B
                if(q->adjVex1==v1)+ ?2 ^+ `! V) ~, E/ k8 b
                    q->nextarc1 = NextArc(v1,p);
    8 X+ D! V0 G" d7 k# E: A6 z            else3 A; y# _: C( b
                    q->nextarc2=NextArc(v1,p);
      S8 b4 d/ J5 Q% J2 Q# [. C, W$ I; P5 x1 _9 z1 }
            }8 x. x0 A8 M8 S  H
            if(r==NULL)" t0 B6 A: F5 s/ F9 L: P
                if(p->adjVex2==v2)0 W8 ?+ u; q2 |# l+ [3 W
                    vexTable[v2].firstarc = p->nextarc2;
    7 H; ~& _7 b9 N0 f8 x6 _4 l            else vexTable[v2].firstarc=p->nextarc1;
    ; {& D3 K# G, P        else  d0 J, B5 _' q* S$ D5 g, D
            {
    8 `. D- n0 X6 L% b" A& `            if(r->adjVex2==v2)/ ]3 }( ]3 i  X! z) s5 S
                    r->nextarc2 = NextArc(v2,p);
    5 ~! n% Y0 x# G            else  X4 l* }3 A) n( a+ _* \0 h/ Z4 u
                    r->nextarc1=NextArc(v2,p);! g9 Y& Y7 Y$ F
            }6 u. w2 \3 P6 I7 _
            delete p;
    , c: g$ t( v$ m9 x# E5 i        arcNum--;
    % v  `# u, W5 R5 V+ J    }
    . t( n6 r7 v( D1 C7 h/ _
    6 j5 O1 v2 k5 W5 F; @0 d}
    $ D$ [' Y" g+ }template<class ElemType, class WeightType> void
    7 `( Q  L1 H" N) u; eMultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)1 D9 o) i5 \* |1 q( {
    {
    3 O' G8 L) D; \4 l9 m+ `( D    int v;
    3 g3 c* l: m8 b6 ?) P2 h    MultiAdjListNetworkArc<WeightType>* p;0 ?% O" ^) Y+ y1 [4 v- g; c3 R" R$ w9 r
        for (v = 0; v < vexNum; v++)//找到d对应顶点
    / l8 Q; g8 f4 v# k! d8 k# @        if (vexTable[v].data == d)
    1 F- o! ^* b1 L% @            break;9 y3 O: m! @+ r2 h5 j) J5 b
        if(v==vexNum)
    , `* f9 s& ~/ Y+ G1 V        throw Error("图中不存在要删除的顶点!");
    7 O+ l* \" U& C- J8 F# i
    * U" ^: y% g, t' [) Y' \; W    for (int u = 0; u < vexNum; u++)//删除与d相连的边
    2 \  \8 L: Q! @0 v. n        if (u != v)
    ! L& o4 i) c% c) Q; A+ s- x  e) x/ C        {
    9 U0 _1 a! P% L" X8 _% R. q* v            DeleteArc(u, v);$ Z) Y5 Z) Q) M! \8 ~
            }
    6 o% X0 \6 Y) j9 a, z  e    vexTable[v].firstarc=NULL;
    / f% z* S$ i  u+ _+ e1 W1 R+ X1 _) o
    0 e4 ~3 @7 v4 `. L& p, e  x    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置  w! M9 [  Z) n+ D! O
        vexTable[v].data = vexTable[vexNum].data;" f* Z  J3 g0 z( a& J# s
        vexTable[v].firstarc = vexTable[vexNum].firstarc;4 U& [4 f  `* L  k
        vexTable[vexNum].firstarc = NULL;2 F9 x7 Q6 O1 B: I  c
        tag[v] = tag[vexNum];& c5 E* {3 ^& p
        //原来与最后一个顶点相连的边改为与v相连" Z: a0 l5 p; c, w- R" _% `, I' Y. X
        for (int u = 0; u < vexNum; u++)/ y! H( f$ ~+ ~9 J
        {
    , \1 D$ v+ v( Y        if (u != v)
    0 u+ F5 u- t7 y" |  A) z( m+ x6 r        {
    * t. m2 d! V  X            p = vexTable.firstarc;9 m8 l& c1 J. w. E! s
                while (p)6 R2 _. k( Z7 k
                {
    0 |  a: |: Z# u2 K5 r+ R: z                if (p->adjVex1==vexNum); o8 g  ]9 {6 n% ~* Y5 T
                        p->adjVex1= v;
    5 O' o6 J. a/ g' J                else if(p->adjVex2==vexNum)! J" T# g/ a5 X3 M; d7 j# [3 ]1 C
                        p->adjVex2=v;
    + Q2 y* L  L9 |; }1 t, [. o) J                p = NextArc(u,p);
    / m- d6 w8 u6 D" C3 |8 c/ l            }
    - u. `: [% c: F* H0 Z& {        }
    , @+ Z% O' S# X8 r, I- G4 j8 j" ]    }
    1 d' i: O- @: o& C8 m( w% F0 o" w}
    8 v: c' |( i* V///深度优先遍历0 N) _5 Y/ H5 i2 c
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)! y* S0 {+ x) A0 r% |
    {% Q. a* U& V, t9 o$ \9 n
        tag[v]=1;) q; H9 Q$ \, w) T$ V- g7 u
        cout<<setw(3)<<vexTable[v].data;
    1 O; \4 u- T1 [/ }8 w0 ^    MultiAdjListNetworkArc<WeightType> *p;
    2 }/ D2 p$ N/ P    p=vexTable[v].firstarc;
    ; M, z9 W; ]5 I    while(p)
    5 h2 l; [: _: O" f; q# E# b    {+ ^8 F0 @2 p* O
            if(tag[p->adjVex1]==0)
    - E9 F- z1 ^/ B+ i7 ^, @4 Z            DFS1(p->adjVex1);
    4 e, b- K  M) k* |5 S4 W, e0 h        else if(tag[p->adjVex2]==0)3 ~2 j* q/ y. l$ i
                DFS1(p->adjVex2);
    ) Y! J2 {( o' d( d$ \' s        p=NextArc(v,p);
    ) q! c5 j0 k4 w: t    }3 j- E( S* d& M1 t
    }
    1 Z7 w" @7 K8 ]( X! I: W) otemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()
    " X: `$ R- N9 I0 n{, ~3 S/ ^) T1 H, u& r  E, k
        for(int i=0; i<vexNum; i++)
    - c5 u! B$ o- T* g        tag=0;! @8 {$ d# O4 }" n7 l% u2 H) E* ^
        for(int v=0; v<vexNum; v++). c7 V& q6 B2 L( _- D
        {+ l. u4 x& w" u3 f; M" ]9 [
            if(tag[v]==0)( u1 D: G$ ^0 z6 E- G4 \" N4 N
                DFS1(v);: \' B1 L1 Z3 K, {8 B
        }5 i, Q) W7 w3 f/ Z+ a
    }
    & _9 K6 W4 A) Q+ c& Utemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()
    , O: S3 |' D4 o" {{8 h/ \3 i# k0 @6 C* L5 y
        stack<int> s;
    + i5 {  M; ^8 Y0 T/ U/ W. Y    int tmp;- ^5 V4 Q: ?) p1 ^
        MultiAdjListNetworkArc<WeightType> *p,*q;* _/ P5 b/ \! U- n8 @" y
        for(int i=0; i<vexNum; i++)! V+ Z: B8 p2 T3 @0 f. c
            tag=0;" `2 w7 P( ~) r0 }6 t* w, O+ x
        for(int i=0; i<vexNum; i++)
    * O) \$ o( O$ H- C. d1 ~# e: K    {
    9 m  E. x: u" J4 k" ^, y% k        tmp=i;: {6 R4 z6 D0 M! F! u* V' {
            while(tag[tmp]==0||!s.empty())+ e7 E6 C& ]# Y& M; n+ \# w
            {
    # d" D$ v7 H0 z/ U            p=vexTable[tmp].firstarc;0 P' P8 K* b  N6 t- L
                while(tag[tmp]==0): [3 O; ?8 Y8 |- j' Y* |9 t$ b4 ?6 r
                {
    2 W2 Z3 m- V" z% z  j+ z                s.push(tmp);
    ! v) H# p& |; `9 y# ?: A                cout<<setw(3)<<vexTable[tmp].data;2 Y5 s1 Q0 s0 c. X
                    tag[tmp]=1;7 B8 X7 W  y* K6 s! b
                    p=vexTable[tmp].firstarc;2 m' j- A& F" Z; |2 X6 Y6 g( M
                    if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for
    , S6 T0 k8 C4 ~; a$ A                tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);9 d: o/ o7 N2 a; k& B
                    //cout<<" 1st     tmp="<<tmp<<endl;! w: t8 R' l& Q
                }; g3 Z  X" {1 i* C
                if(!s.empty())
    $ E* d/ y. r/ L# P* L. J            {/ Q/ p1 \  f9 D8 t" _' x) i4 M" }
                    tmp=s.top();" m8 n1 ~7 c; n0 X/ X
                    s.pop();
    3 n& G5 C- ]( R8 M; \) w! ~4 y                q=vexTable[tmp].firstarc;5 `& @9 u* p: T) f
                    int t=tmp;/ p  F; @+ W7 e+ y+ l5 P0 r! n
                    while(q&&tag[tmp]!=0)' O0 g6 q- ]- o3 t) U' u
                    {
    4 h/ x& Y! I/ Q* b                    tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);  b( K, S! Y  r
                        //cout<<" 2nd     tmp="<<tmp<<endl;" p6 p$ ~* T, p4 J7 p3 v( c" u
                        q=NextArc(t,q);" i  s' y+ W6 W4 u! H7 u+ X
                    }' B5 d% X$ H) r$ n
                    if(tag[tmp]==0)
    + `  [. W0 F0 \9 m' ~) W                    s.push(t);7 _, K: X; ]$ v- G1 K% @* J
                    ///1、对应上面连通分支只有1个点的情况
    ; _9 k$ m9 o& P) Q& x) f% b                ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈& q/ h% r- L" D" ~6 F# \
                    ///tmp要么等于找到的第一个未访问节点,
    3 {; y$ c( T. J7 s- }                ///要么等于与t相连最后一个点(已被访问过)) ]# h# G% l, U. o4 w
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点  _5 f8 b% Q- H. f6 f2 w
                }- G; G, I" z1 r1 X# ^( y1 s
            }
    1 M6 v: o0 D# q3 _/ J0 e3 [    }
    ( z8 u, b6 V9 t/ {& ]# t/ O7 C$ X}0 N  \% s/ w- b8 ~1 L; |  ]
    //从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-19 k* m# Q; l& x* i" D+ b) t
    template<class ElemType, class WeightType> int8 u, [8 F; v: O# q7 V" K! @
    MultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)8 h* p" d6 v' F! i9 Q
    {  @5 ]) {; K, r3 S5 G" D( T% ?
        if(head==pre)( a* s' t; D2 y! d$ `9 {1 X
            return -1;3 A1 @  K( G$ _" L

    5 Q6 K- z0 E7 Y' ^6 S    MultiAdjListNetworkArc<WeightType> *p;$ G# ?7 \& m0 K% Z! m) S8 z
        p=vexTable[head].firstarc;. z4 P# ~% Z- w3 j5 ]' F. B
        if(pre==-1&&p!=NULL)
    7 B0 ~6 r/ z6 Y: S/ q  N        return p->adjVex1==head?p->adjVex2:p->adjVex1;( f  D: \- j1 I/ P* g, @
        //pre!=-1&&p!=NULL
    * B% z. T3 L8 L' V    while(p!=NULL), ~! @  P: ?! t# \% L- y: T
        {
    ' F$ ~8 ?* g. p% s7 \        if(p->adjVex1==head && p->adjVex2!=pre)( h: R; |) U8 P( j; D' |
                p=p->nextarc1;
    4 Q6 O) V- z; E9 V! ~2 t        else if(p->adjVex2==head && p->adjVex1!=pre): D8 _2 p/ P, I2 |; ?
                p=p->nextarc2;
    9 o# U) M: k7 |' x        else if(p->adjVex1==head && p->adjVex2==pre)3 u( W3 M5 {2 D% z4 c7 k) E" _
            {; w( [1 }, q8 u0 j" W) H
                p=p->nextarc1;/ X( F0 G' D1 J: }8 |
                break;; y" M- k2 O" {' N# R
            }
    3 B! b) t! e* l. y( x1 o& }        else if(p->adjVex2==head && p->adjVex1==pre)
    3 V) G& S2 _- f/ ~6 m        {
    " N( r0 [% M  ?. Q9 ~4 D4 Z            p=p->nextarc2;8 f3 k6 ]4 g0 Z
                break;
    # C6 B6 A$ I- d        }( T- y0 p3 d2 H. F" R
        }
    1 @4 ]& T5 p3 ?% r    if(p!=NULL)
    - E3 U; k* A* U: S* J- C7 L    {
    " J- ~! e3 d+ d3 N* p; E4 n/ y        return p->adjVex1==head?p->adjVex2:p->adjVex1;
    . Z+ c2 Q( i; b2 D% U6 o    }
    6 k, ]% g" c, R+ k( N& x, e# C% {    else
    " w8 ~* u4 T, |" g        return -1;3 c+ S8 J9 |; G, K
    }
    # Z/ a2 f" s6 {. O) a; ]% |  T) g, E
    + C( j& l1 e2 a/ m% k/ a+ I. G/ ^# A5 l6 V- k
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    ( m+ Y: @1 v& X{9 n+ x# @& ?  Z+ X1 m  `
        stack<int> s;
    4 _* V; D  b3 [: W5 [    int p,cur,pre;
    ) u4 O" r4 \8 F$ |6 P    //MultiAdjListNetworkArc<WeightType> *p,*q;0 ?  Y& X2 a9 P$ Z$ X! T
        for(int i=0; i<vexNum; i++) tag=0;//初始化  }2 E& D% X/ h

    $ W; @) y% l8 f    for(int i=0; i<vexNum; i++)
    2 p# k5 z4 w( s2 i  t# n    {
    2 e. h: |8 Z3 W7 V8 z6 R        cur=i;pre=-1;
    % [* E+ P5 \2 K0 W% s  f/ q" ?        while(tag[cur]==0||!s.empty()). T! A- o$ d5 A4 r; `8 h
            {! ?+ q+ e0 e7 q
                while(tag[cur]==0)  h6 b8 a+ ?8 x; \; |9 @7 C/ \
                {
    . ^9 A. ]- v8 H( F# L                cout<<vexTable[cur].data<<"  ";
    $ k' {3 p1 `7 X) f+ G" }  ^. ^- K; g                s.push(cur);) z  {* k- p  }0 f
                    tag[cur]=1;
    % ^9 Q( R- H- J) T3 h1 p               //初次访问,标记入栈
    0 s  O/ \, b, n+ G. b
    ( M: C$ D9 i+ J' l               p=GetAdjVex(cur,pre);//p是cur的连通顶点
    $ k" n1 G5 q" E1 D- O3 i               if(p==-1)
    " K- [3 T' s8 S" T* d" Y               {
    0 n& u8 r7 B; @4 x' r; X                   pre=cur;s.pop();
    9 u6 R! |" I% j4 z. C& t                   break;
      l& F, |$ h% S2 ]; m& ]               }
    . y# U% ?* @$ H' @0 \& R9 }               else
    ; S- y8 i' M9 q5 ~  s) n0 D               {' e6 c) O" ^- i7 w
                       pre=cur;
      }. o. M: [  L" x4 O6 k                   cur=p;  W& \5 j% F' C# P6 C
                   }
    , A7 D2 ~: a0 y/ C. N6 t
    ( ^6 a9 w, p4 b6 R7 h            }  m( g: @# U' d) U' U2 @
                while(!s.empty())& K# ~& @  _3 E- q# y1 T) O& M
                {
    * S* X- W2 J" G1 g                cur=s.top();
      ^, d  R6 e8 @0 `! Z                p=GetAdjVex(cur,pre);# ?, T2 t" F( m
                    if(tag[p]==0)
    : z# h$ h( ]" u, G& b! k) H& R                {+ F( v1 E7 h4 ]; Z  o9 T
                        pre=cur;1 M8 h8 a8 {$ H7 }
                        cur=p;. u/ N. X1 b" X- I* q, q+ ]% X
                        break;
    0 j1 t/ X+ ^- d, L* F4 W( R                }
    ' J1 q& V) K9 Z5 q! K6 o                else
    1 k: e+ U% N3 H5 ]1 f' K- B+ j  p                {8 A  H! i1 Z4 r6 s/ z2 ~
                        pre=s.top();9 p# e' Z4 D6 Y
                        s.pop();% S% L/ q3 k' {2 {% ~6 n1 q
                    }7 i2 R. k, R2 E) z2 l% e+ S! h/ H, h
    & y* \' i: L& U' j( |3 y
                }, ?2 Z/ I5 F& F1 _5 Y

    * {; }& W1 I0 l" x, p        }
    $ L- T2 ?' q4 D9 [  ?    }% a+ C0 r3 m2 A' w$ A% g& x: X
    }
    & Q2 p% o/ {0 L8 Btemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()  T7 e# l' A2 \3 `$ J' Z2 o
    {) U! w( O7 x( B! ?: I
        for(int i=0; i<vexNum; i++)
    / f" H3 e$ ^0 m6 c        tag=0;
    8 e* W9 ~8 e" x. b( Z. X    queue<int> q;
      d' T# q; }# {3 p5 {5 S) F    int tmp,t;
    $ `3 _3 F: C4 k2 U3 N) C    MultiAdjListNetworkArc<WeightType> *p;9 m9 D* C* ?6 G, D/ I0 O1 w3 m8 s9 z
        for(int i=0; i<vexNum; i++)0 e0 O- N7 x# X( [2 h
        {: q; u4 j# H4 M3 \
            if(tag==0)
    6 K7 N9 \$ f$ y        {- T$ t1 |! I5 E/ l2 h6 N5 Y% T
                tag=1;$ K7 ~" R* \6 f& L
                q.push(i);
    - d: [8 N. L* c; b3 D; y: l/ M            cout<<setw(3)<<vexTable.data;
    6 h+ _4 w, v+ }& f1 x* ^' r        }
    : p  [" ]0 d: G        while(!q.empty())  h0 @; H! a$ h; ?1 r9 F2 W. S; x
            {
    9 V! g$ Q$ R4 n" w- {            tmp=q.front();2 H/ [( r$ t/ l3 l7 q5 b
                q.pop();
    ( f/ {+ ^8 C/ s6 F; @  \5 S            p=vexTable[tmp].firstarc;
    9 t- R8 W0 F9 g5 |0 K* E            while(p!=NULL)
    - S8 |, C% |( _# q            {
    2 Z0 y! {; J) O8 Y                t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);& C- M$ a9 f) {" v* C( o: {5 m
                    if(tag[t]==0)
    5 L8 W, n& W- d" \: H8 E                {# z: N1 ^- T4 h  m' Q
                        cout<<setw(3)<<vexTable[t].data;1 J; }, k. n4 R$ |- P  ~
                        tag[t]=1;
    3 Y+ Y- z% n: Z                    q.push(t);6 U1 A) I) _. H  Y! p
                    }) q7 [2 k. |3 B- z
                    p=NextArc(tmp,p);- J8 H0 f% N9 w
                }5 B  r3 I' }! L
            }
    ! w) f3 Z' `5 [5 h    }2 I; q5 K; y: L5 w- x
    }6 y/ y4 q0 h5 i) E- w) F* q
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()
    ! v7 u% _) R! p  W6 ~# ?{
    & d- F" R1 p, j* y" |4 F! t    MultiAdjListNetworkArc<WeightType> *p;. n& f2 P1 M: x4 x
        cout << "无向图有" << vexNum << "个点,分别为:";
    % f- H" I9 c- p# F+ D5 \& N5 E    for (int i = 0; i < vexNum; i++)4 @! g: G3 V$ \+ |( C, Y
            cout << vexTable.data << " ";
    " u$ ]% V# R7 F, y& m" \    cout << endl;# @: m% b+ b  g- s
        cout << "无向图有" << arcNum << "条边"<<endl;: n! X9 I* N; _6 z% ~* ^5 a: d
        for (int i = 0; i < vexNum; i++)
    6 m" ?* p. y  i9 H2 U    {
    . v" y" m! Z8 s# \' n4 {0 s        cout<<"和" << vexTable.data << "有关的边:";
    - @9 |# o, a4 j        p = vexTable.firstarc;; n+ ?+ R( P& t+ j; o1 ^
            while (p != NULL)
    . L1 S  d: P# x5 J$ ^        {
    % r/ Q* M* p5 U  B8 B            cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";- Y& i+ o* X8 u" W7 z- J
                p=NextArc(i,p);: d, ?6 b6 M* f  \/ V" C. i6 |
            }
    * a, V5 b9 n- h% u6 S" W        cout << endl;6 d2 X2 o3 o2 s! J- p6 X, M
        }
    * Q/ _7 n( n% r$ Z7 Z3 O) C}' _5 Q  H& w2 d5 z9 I6 ]2 C' W

    0 p( p! i! d7 @& m( t7 D9 Z8 q# ?- O1 T1 \/ l, @
    邻接多重表与邻接表的对比* o/ f8 H1 B  x0 S4 C
    # ]1 X6 p9 D" [/ k0 Q+ j& H% F9 ^! g  O
    邻接表链接
      i1 X% Z1 E& o( ^" U在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。5 B  ], \! N! [% E2 `
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。
      o* f% y3 e% J. V为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。7 l# E' d0 M6 K  m+ m' x
    ————————————————
    4 h. T4 S/ D) s# O4 x: |版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。; I: i  |+ U( t/ E% h
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    " K! B* k# M* z7 o( m! T$ c0 I" {$ D. \4 s
    - H$ p  U/ O( ]3 n
    , o5 c" ]5 }. p, I
    7 n* C0 X3 A: ^. u7 p# |
    ————————————————
    , F: [: o* x+ L+ m% X2 L- ~* E) w版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ! ], W4 [( j+ [. V原文链接:https://blog.csdn.net/qq_43413403/article/details/1057669585 X+ f, O! p# a
    " y1 D' w  J" s: Y
    " m; Q# K. T. u$ h5 J1 B2 z1 h
    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-1-2 12:05 , Processed in 2.139487 second(s), 54 queries .

    回顶部