QQ登录

只需要一步,快速开始

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

    $ @% _5 l( g' T4 g  R图的存储结构——邻接多重表(多重邻接表)的实现( \' j' }( @/ y: ]3 n
    7.2 图的存储结构
    % b% a, d& B9 w7 e* q; g! u) \$ w0 Q. i+ L: X9 |: y1 L
    7.2.3 邻接多重表(多重邻接表)Adjacency Multilist* ^$ s; ?6 b3 P- g* T8 Q
    邻接多重表的类定义* d+ J: g7 N- I# p4 @( L
    邻接多重表的顶点结点类模板
    ! Y  o  l7 j/ A" E6 K+ E0 F邻接多重表的边结点类模板
    ! u9 R! N& G; d  V$ C" W% _邻接多重表的类模板
    ; X4 ~& n9 z6 \邻接多重表与邻接表的对比
    & g/ t, x% i# x# s+ v3 V7.2.3 邻接多重表(多重邻接表)Adjacency Multilist: y4 m5 E4 w( P
    - J- u0 b$ Q" s2 G0 V
    在无向图的邻接表中可以看到,每一条边(vi,vj)在邻接表中有两个边结点:一个在顶点vi的边链表中,表示(vi,vj);一个在顶点vj的边链表中,表示(vj,vi)。9 y+ R. [/ C6 b
    在较复杂的问题中,有时需要给被处理的边加标记(如访问标志或删除标志等),若用邻接表表示,则需要同时给表示某一条边的两个边结点加标记,而这两个结点又不在同一个边链表中,所以处理会很不方便。若改用邻接多重表作为无向图的存储表示,则可简化上述问题的处理。$ K/ E) A9 ^# B0 D: q$ E
    , t+ l. E2 \* {5 l( B, b
    邻接多重表的类定义9 f. ~* O6 t% s  ]# S$ y- B# m& m
    1.png 8 I# p: m9 B& Q8 B6 y2 j
    邻接多重表的顶点结点类模板

    对图中的每一个顶点用一个顶点结点表示,它有两个域组成,其中:5 v6 v0 M. b0 C* n- ^, E: v' ]- N( F
    data域存储有关顶点的信息;( q: n8 ?/ ]' p' v
    firstarc域是链接指针,指向第一条依附于该顶点的边。
    2 z4 O( {/ j9 {8 X所有的顶点结点组成一个顺序表。

    8 S, m" [7 f* m# \6 ^% y7 U

    : ^4 |% c9 n# K) w: ztemplate <class ElemType ,class WeightType>
    ' Z/ \0 M% _: }6 w; p6 L$ tclass MultiAdjListNetworkVex
    / p# K, H8 W" {- m{' y7 o9 M. D% G
    public:8 V3 N( @- j2 O; ^
            ElemType data;- ~; J8 F9 P' A9 d8 K% M
            MultiAdjListNetworkArc<WeightType> *firstarc;6 n7 u; V4 p$ \) E8 p' w
    3 R' K( t1 H$ x
            MultiAdjListNetworkVex()
    ( r) s/ f+ O; A6 {' W' N        {
    2 g3 i6 L3 f0 [" x, p& R3 d- d                firstarc = NULL;
    6 W3 q3 J5 t9 y  s, J: V        }1 R4 [8 Z- i; ]; q
            MultiAdjListNetworkVex(ElemType val, MultiAdjListNetworkArc<WeightType>* adj = NULL)
    ) H0 Y7 Y* t& G" Q4 J9 t        {
    % o. G$ i/ f- D; Z; k                data = val;
    . k4 F! ^: t/ d+ z6 l                firstarc = adj;7 z8 o. d) r0 Y( ?; \
            }
    8 @' q! i0 j8 J# V% u3 [! W, |) w};" g& n! B7 Q$ n  T6 O$ v' c

    ! M" X5 s- f& t3 ~" ?- I) X3 n. g邻接多重表的边结点类模板; u; b8 h/ u- F5 O: R4 _

    ; w& y( {! g4 K( j在无向图的邻接多重表中,图的每一条边用一个边结点表示,它由六个域组成,其中:
    % Z# q: z( `* I) ^0 ptag是标记域,标记该边是否被处理或被搜索过;
    % U. z1 P. R) ?- k& @weight为边的信息域,用于存储边的权值;adjvexl和adjvex2是顶点域,表示该边所依附的两个顶点在图中的序号;. e. Y) t' J2 X- |% z5 E! B
    nextarcl1域是链接指针,指向下一条依附于顶点adjvexl的边;
    . J$ @4 G) ^0 h( F3 bnextarc2也是链接指针,指向下一条依附于顶点adjvex2的边。
    ! U+ m  U! B1 ]9 J$ o6 J7 ?; O6 K9 R% Q! D4 A& T
    2.png 8 G5 W# ~, b7 E2 B4 F2 C2 q
    template <class WeightType>
    / H2 G# k! A% Y& q; t) @class MultiAdjListNetworkArc4 m: n0 E# |3 Z8 i* K
    {
    $ F. @6 A& J9 C; g( M: W# z- ]2 C8 wpublic:
    % u' c( N; o8 _: z( O, b0 E; S    int mark;                                       //标记该边是否被搜索或处理过: l; u" Y6 g3 `" ~+ O3 m1 ]" S2 D1 M
            WeightType weight;                              //边的权重
    0 B0 D% h; I6 G# n  t' X6 T$ s1 r. C        int adjVex1;                                    //边的一个顶点& _" l! p! U: u* r% o
            MultiAdjListNetworkArc<WeightType>* nextarc1;   //指向下一条依附于adjvex1的边,eg:1-2-->1-3-->5-17 @% v) V: i" h
            int adjVex2;, q* S* H7 l6 [1 ^* w) n: W1 h4 a
            MultiAdjListNetworkArc<WeightType>* nextarc2;
    2 m+ F# ^) Y. E! n% Y8 `( h! |7 M/ j5 d0 j, p
            MultiAdjListNetworkArc()) j: p: C4 u( x$ _- C0 `" d: Y* n& h
            {* F% L& j/ A- s/ \& {3 A4 L7 o5 O- l# F
                    adjVex1= -1;- Y' v, {: Y1 T: C: {
                    adjVex2= -1;% Q% c! W9 b  R; {/ H  c
            }1 i8 ]) O  K4 V' C; f2 c. S
            MultiAdjListNetworkArc(int v1, int v2, WeightType w, MultiAdjListNetworkArc<WeightType>* next1 = NULL,MultiAdjListNetworkArc<WeightType>* next2 = NULL)
    2 A+ t) g0 J8 F% ?6 Z8 n        {
    0 M' |" C/ Z% u8 G                adjVex1 = v1;       adjVex2 = v2;
    ! w: s, s) B5 s7 Z% w; M, g- k0 t                weight = w;. d6 e  F0 S* A( E
                    nextarc1 = next1;   nextarc2=next2;% L+ g: k, r: D2 J! I* I
                    mark = 0;           //0表示未被搜索,1表示被搜索过
    9 E! N( B5 G. T$ T% {        }: @; E: w2 d9 u) G* w* R

    / \+ h+ I5 D$ q3 i5 z邻接多重表的类模板

    1.类定义

    template <class ElemType,class WeightType>" x- Z4 O% E2 i8 I# E0 D6 T
    class MultiAdjListNetwork9 X! H- I1 N8 X" ]/ S# P& k
    {
    1 Z" p% A( p- Z, a' n- N' y- nprotected:
    2 x5 }4 i) d; ^8 o2 p$ W$ V    int vexNum, vexMaxNum, arcNum;
    ! |/ A2 a, w- J5 {$ O* ~) [    MultiAdjListNetworkVex<ElemType, WeightType>* vexTable;* ]+ U6 e% w4 y7 }" X" x9 o
        int* tag;
    7 T# b4 [! k8 x; i5 @' B  |2 V    WeightType infinity;+ D* k$ b) N# O6 `( ^& Q2 v! U
    1 q6 X! r5 r3 F* o( h" m. o# B
    public:) b9 E; L) f! \/ ]$ `
        MultiAdjListNetwork(ElemType es[], int vertexNum,int vertexMaxNum= DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);
    % D: p4 A; l# k
    % q  n# u  R* c- Y    MultiAdjListNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFINITY);$ S; ^  J  x8 b1 X1 F6 g

    ' q1 |: L* @+ u$ i- e# x9 u  V" J+ F    void Clear();$ z1 @& e8 x: @% a2 g% v# D  J! T
        bool IsEmpty()
    * f- |6 {$ [/ d  M    {
    * _7 X6 G  C) p" o" x        return vexNum == 0;1 t7 U* }5 A6 ?) E$ f
        }2 |" H% U; r) d
        int GetArcNum()const- Q# @3 \  v9 j
        {
    8 U1 [  P. C9 b9 Y& e. [1 a        return arcNum;$ _; u( V2 E& Z4 ~& R
        }# N; E: M7 Y9 B! N, m+ D  H3 F
        int GetvexNum()const
    ( D# u+ h2 O& T, z    {
    ; r9 @6 g+ S  p- z        return vexNum;
    3 w% r6 |8 W. R6 a% x. Q4 D    }+ m8 h2 k* k4 l
    : ~2 J2 C: Z2 d' |* z  l

    9 v7 b1 O0 n/ k) O% i6 @* v    int FirstAdjVex(int v)const;0 H5 Z+ b) f) R2 L7 L
        int NextAdjVex(int v1, int v2)const;0 n3 W/ b9 X# `( s4 l5 j
        MultiAdjListNetworkArc<WeightType>* NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;0 k, O7 n7 p( u1 c0 i0 V# D
        MultiAdjListNetworkArc<WeightType>* LastArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const;
    & C3 I: @% B* ~+ t0 }, `+ O. S5 `8 b; I# t- f+ T& _8 ?
        void InsertVex(const ElemType& d);
    5 T6 w3 b' a' ?# U1 C    void InsertArc(int v1, int v2, WeightType w);: }" ~% n2 t+ o2 o5 h
    - ~( _# P0 q' N  b
        void DeleteVex(const ElemType& d);, M' f1 N2 U$ x1 {/ q- t  `( {
        void DeleteArc(int v1, int v2);
    ! d- t0 k& N; x+ m
    , ]) v2 [! {, S: N    MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy);
    , D0 G  S1 b( Z: |* x9 x9 X    MultiAdjListNetwork<ElemType, WeightType> &operator=(const MultiAdjListNetwork<ElemType, WeightType>& copy);
    + y! x  I3 i, [) L6 n* s: Z) Z+ @1 o9 v
        ///深度优先遍历  `+ X: l0 J! h" B) y
        void DFS1(const int v);
    # q, G4 n3 l3 z8 P    void DFS1Traverse();
    1 Q# h5 P- j8 U6 G% i    void DFS2();
    $ O' ]) d2 B9 P5 K. u: m# s8 f: B) e2 H9 v2 }/ o0 F
        int GetAdjVex(int head,int pre);//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-1  q7 h* N2 s$ \9 ?6 U( |% ]
        void DFS3();
    0 u0 Q( \! z9 |: _9 z) w1 G7 O* B0 H3 O$ d* n% I) j5 N
        void BFS();
    ' w& l& E2 ]0 I, m    void Show();; }& D& f5 p+ `& f
    };
    ; V! t- a) w# B$ q) v2 ^
    5 e! f( n5 H. Y1 M2.函数的实现, b! `/ T/ v3 ?! U( C
    研讨题,能够运行,但是代码不一定是最优的。
    9 Z2 d$ p9 O7 ~; I2 Y( n0 s
    8 G0 H: Z5 ]2 ]# H4 k+ q4 r- z#include <stack>  Y+ j* r0 m, h. I
    #include <queue>. j& Q% O( w6 j
    + C5 ]; t! L  |/ p0 x# L& g0 w
    template <class ElemType,class WeightType>
    3 k9 R: A  v" ]( R. v$ L* e5 |MultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(ElemType es[],int vertexNum,int vertexMaxNum,WeightType infinit)
    3 ]" g& x# U) t( @; ]9 U# b+ R{; ~/ g; R) a& m5 ~3 R7 f
        if(vertexMaxNum < 0)
    8 U0 ?% C5 ]' l0 O# w  H        throw Error("允许的顶点最大数目不能为负!");" C. X  R# f" p: L
        if (vertexMaxNum < vertexNum)# q# u9 n9 N3 Q* o' \# ~' ?! E5 g
            throw Error("顶点数目不能大于允许的顶点最大数目!");& e: A; F% T# ~' A
        vexNum = vertexNum;6 ^+ s7 G1 `& }& K6 j7 w1 N9 d1 G# S
        vexMaxNum = vertexMaxNum;
    " e% @, p1 c  V, p4 i9 |& Y$ I3 d    arcNum = 0;$ @4 K7 f: M* i$ s* Y7 }
        infinity = infinit;
    8 D5 Q1 `/ ]. ?6 K4 i0 }* R    tag = new int[vexMaxNum];
    , u) X# _: j( X" u. h0 R: Z4 G4 T. b    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];
    $ @8 b+ p3 t: H: x! L7 k9 b    for (int v = 0; v < vexNum; v++)
    " J9 J2 ~/ x; a8 R$ E' ?% ]    {( L, r) }' W5 \' C4 T2 c; c8 f
            tag[v] = 0;- Q. ^9 I, b5 r3 U
            vexTable[v].data = es[v];, Y5 ?% g6 p7 h* H2 @
            vexTable[v].firstarc = NULL;
    $ ]: B7 p3 L! b    }) U) C4 ]' W* }1 k" r
    }2 K, z& A. Z. g  Y+ W8 h
    template <class ElemType,class WeightType>
    8 u% p* l, x3 R# [* H8 NMultiAdjListNetwork<ElemType,WeightType>::MultiAdjListNetwork(int vertexMaxNum, WeightType infinit)9 B3 _' U" r- `; P, V
    {$ K. J  v" J1 f3 u" F
        if (vertexMaxNum < 0)8 w# L" O  e: v; V  P% _- z
            throw Error("允许的顶点最大数目不能为负!");* P3 v7 r: C9 j
        vexNum = 0;0 o% v, {; R  l' @
        vexMaxNum = vertexMaxNum;; u: P3 i) D3 \6 m. A2 e8 `
        arcNum = 0;
    # Y; F: ~, q3 Z2 N& N    infinity = infinit;
    - @& A# m) A3 ?8 Z+ Y    tag = new int[vexMaxNum];
    $ U% t! s- H5 N/ f, b    vexTable = new MultiAdjListNetworkVex<ElemType, WeightType>[vexMaxNum];* q0 E7 v+ F& c! M
    }4 _# E9 d) M* v2 ?! }5 K- _1 K; g9 c5 w
    template<class ElemType, class WeightType>
    / G' G3 c" q! Nint MultiAdjListNetwork<ElemType, WeightType>::FirstAdjVex(int v)const
    " ~' o; O$ m& X1 h; d, y3 ?& F+ w{+ i. C+ c) b8 N5 j
        if (v < 0 || v >= vexNum)
    % E; M' t. v% {) R        throw Error("v不合法!");
    , {0 b5 g8 J! O1 ~" S7 |% k    if (vexTable[v].firstarc == NULL)
    / M' ^2 b  V) U" W4 E& t- g' z3 r: T        return -1;
    ( y" g" Y% ^. K! ^    else8 w0 v$ [+ K' f4 T! `0 ~% H
            return vexTable[v].firstarc->adjVex1;
    / H( p( O* m/ N9 v8 }: C}: u0 s6 F+ k( C7 |4 D
    2 E# y4 m3 }( Q6 F
    template<class ElemType, class WeightType>  m# b& U/ h3 y" r# e
    int MultiAdjListNetwork<ElemType, WeightType>::NextAdjVex(int v1, int v2)const4 z$ U, @9 v! Y- |, M- H& h! j
    {
    1 ]$ c0 ^, {# u" d1 n6 p    MultiAdjListNetworkArc<WeightType>* p;
    , T. [- ?3 T; O: R4 \    if (v1 < 0 || v1 >= vexNum)0 t, h/ h% e4 u) D/ i
            throw Error("v1不合法!");  n. M' X; U  S% M8 ]
        if (v2 < 0 || v2 >= vexNum)4 j- a+ i! P7 G5 z* Y0 d+ W# J% b1 o1 U/ l
            throw Error("v2不合法!");3 P, v" R8 H4 L* {) D; X$ r
        if (v1 == v2)9 V* s( X6 j7 v# C- W
            throw Error("v1不能等于v2!");
    # E) h" @& a& }4 R  c* V# A    p = vexTable[v1].firstarc;; H9 H. `8 \9 F- a) |; L0 R
        while (p != NULL && p->adjVex1 != v2 && p->adjVex2 != v2), Y% h. j! x4 M0 X, f9 S* w7 L. Z
            p = p->nextarc;
    3 _2 H8 m, q5 o* ^/ G( m    if (p == NULL || p->nextarc == NULL)7 {! K* E) Z$ _7 H9 T
            return -1;  //不存在下一个邻接点
    6 ]& g6 F" {% B# B+ C' R    else if(p->adjVex1==v2)
    ) o! q. e; d9 c8 x' }3 q% O        return (p->nextarc2->adjVex1==v1?p->nextarc2->adjVex2:p->nextarc2->adjVex1);2 I- H7 @% i; S4 Z: ^) ~6 H5 c
        else
    6 t2 J4 o6 s: R9 `* a        return (p->nextarc1->adjVex1==v1?p->nextarc1->adjVex2:p->nextarc1->adjVex1);  o' o3 d9 g" g3 F5 w  R8 o0 C
    }
    ! J' G0 Q, Z# ~; j4 R; Btemplate<class ElemType, class WeightType>
    2 P7 a6 T5 o5 N% {: i. f8 uvoid MultiAdjListNetwork<ElemType, WeightType>::Clear()
    " J4 \* B0 [: N) b1 j* d  `) k& p{! T6 e' x% X7 J8 [
        if (IsEmpty()) return;! m7 b( a7 S) l. }# a( l
        int n = vexNum;  e& k  g) e' p5 O
        for (int u = 0; u < n ; u++)7 ~5 u4 h6 s8 L9 ?% O2 P
            DeleteVex(vexTable[0].data);& l  G5 \% D! m4 i# q$ @# T+ B
        return;, o- F' l6 m3 ~/ w/ R" E
    }
    9 v2 C; z0 p  ^template<class ElemType, class WeightType>0 f; S+ T( R& l) l) e
    MultiAdjListNetwork<ElemType, WeightType>::~MultiAdjListNetwork()
    ) P3 z4 _/ @7 W, ^0 [% ^2 n{: [3 a3 ~- d! S! f9 s, d0 I* F
        Clear();
    * \6 z0 d) f' s* N}
    5 A5 m8 r# v. m5 y/ jtemplate<class ElemType, class WeightType># E5 d+ w7 G9 ~" a9 T
    MultiAdjListNetwork<ElemType, WeightType>::MultiAdjListNetwork(const MultiAdjListNetwork<ElemType, WeightType>* copy)8 f1 `2 }" R' m/ R8 I
    {
    9 c' C/ t0 Q9 X: S4 Z    vexMaxNum = copy.vexMaxNum;; X3 V( f2 C, C! A0 ^; I
        vexNum = copy.vexNum;$ y6 j3 v3 J5 ]3 C: `1 f0 y
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];" y1 t  z4 e* q( c: |, [
        arcNum = 0;
    # F: _4 B- H+ _* d8 |( Z    infinity = copy.infinity;
    : B$ G3 z) T8 f! m' B    tag = new int[vexMaxNum];
    ) y$ Q6 }1 Z" D" D
    . ]8 ?, _6 L* z, x) I5 K5 H( h& P; C    for (int v = 0; v < vexNum; v++)
    * }; u8 }; f, Q9 W" H    {* d% A* |  \& g
            tag[v] = 0;) {2 v/ B2 a8 Z. A. @7 p
            vexTable[v].data = copy.vexTable[v].data;
    1 K0 k  C5 W9 D# [0 ]        vexTable[v].firstarc = NULL;
    ( N$ y5 b8 B) z4 ^/ H    }
    6 U3 X! N. k) s' Q9 u    MultiAdjListNetworkArc<WeightType>* p;
    / G8 T" D; I3 T) c. `$ }4 }2 E3 t3 C6 r5 o3 \8 u1 o' u
        for (int u = 0; u < vexNum; u++)
    8 \) b1 Q& t4 ]- c    {
    : x6 O# Z- w6 h$ @2 s9 a        p = copy.vexTable.firstarc;2 J# _- u( _: l# m# ?# g+ @
            while (p != NULL). ~* o' X' w5 M: t
            {  {/ Y' u7 V5 o* c; d
                InsertArc(p->adjVex1, p->adjVex2, p->weight);
    1 K. ^& {8 f$ P  [2 [9 u            p=NextArc(u,p);$ V7 u$ V  @/ l5 B2 n* T4 R% l% l
            }
    , J0 a' N6 y$ P% n# R$ X1 d" C# U: ~    }6 _& s* w+ y- v' l- L; X# S
    }
    5 I" q+ ^/ a: f9 _1 E# L& Qtemplate<class ElemType, class WeightType> MultiAdjListNetwork<ElemType, WeightType>&
    / q& e+ m, T- d$ ]) D& c7 fMultiAdjListNetwork<ElemType, WeightType>:perator=(const MultiAdjListNetwork<ElemType, WeightType>& copy)4 k" j; M2 [! s6 K% H
    {" e# \( |8 Q3 Y$ p; o
        if (this == &copy) return *this;7 V1 b- H, n4 t7 e
        Clear();
    * N$ c/ g1 ?9 }% \$ `: t    vexMaxNum = copy.vexMaxNum;
    3 m# M" p2 D/ m* c    vexNum = copy.vexNum;/ Q2 r6 _6 m. g' {6 R
        vexTable = new MultiAdjListNetworkVex<ElemType,WeightType>[vexMaxNum];
    8 u( f' F) y4 v! p; Q" N    arcNum = 0;% c0 ?6 s  U3 n
        infinity = copy.infinity;
    : C% e; |2 D: W" S* a    tag = new int[vexMaxNum];* w; x0 S, c3 E$ o' Z8 P! K" c

    . t7 `6 R8 ^" X    for (int v = 0; v < vexNum; v++)0 U1 `/ m5 Y6 J0 t! x2 O& N
        {
    % T3 x# x# o% \" T        tag[v] = 0;
    7 Q0 Q. Y2 p# f% t- P, @" O        vexTable[v].data = copy.vexTable[v].data;; i" @( V0 `1 N/ N
            vexTable[v].firstarc = NULL;+ r0 R1 R6 M8 c) x2 ?9 ^% _2 s
        }
    0 {. F4 r& y: }  K$ d    MultiAdjListNetworkArc<WeightType>* p;
    $ U, w9 i5 R6 j: S/ k
    ( B9 W+ G; ~5 b: {) A    for (int u = 0; u < vexNum; u++)
    7 x- [) b! W4 ?! C4 j6 D    {8 X5 t: }3 t& m: n. A9 e- d
            p = copy.vexTable.firstarc;7 y7 q' [$ k( w0 ^
            while (p != NULL)
    9 _$ W' n: ~/ y( @/ F9 _        {/ H; B4 j6 p9 W- K( J
                InsertArc(p->adjVex1, p->adjVex2, p->weight);: {& t1 Y" |+ L" Q9 p
                p=NextArc(u,p);4 n+ h: d# j* p
            }
    " F% M  q  Q1 Y7 g( n3 a    }
    4 |3 Y. C. X" o    return *this;2 B7 I1 y% c  |
    }
    " U; j6 B3 f' }7 Rtemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    7 a; r( V6 f# b/ ~2 _6 K& RMultiAdjListNetwork<ElemType, WeightType>::NextArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const
    2 `5 B8 N- u. m{  }" H2 H* n1 c; Z; Z
        if(p==NULL) return NULL;, O2 n) \. G7 ?& |5 H' \
        if(p->adjVex1==v1)
    % g* J$ B& P9 @% c! W        return p->nextarc1;$ Y5 q8 d1 P$ n( s8 `- u- ^5 e% l
        else  E5 @( t  |( e, E
            return p->nextarc2;7 C9 f( {, w) I3 q( u
    }
    4 d0 A. C5 s( L6 Ctemplate<class ElemType, class WeightType> MultiAdjListNetworkArc<WeightType>*
    ) P- o0 Y" K' u- kMultiAdjListNetwork<ElemType, WeightType>:astArc(int v1,MultiAdjListNetworkArc<WeightType>*p)const( I( r8 h( ~* E' l
    {
    2 q+ S) p0 A, t    if(p==NULL)return NULL;2 u/ q, r; ?# U' @! l
        MultiAdjListNetworkArc<WeightType> *q=vexTable[v1].firstarc;8 X- l5 F# d) e+ n. u& Y
        if(q==p)
    # |/ ^; `/ n+ @        return NULL;" w9 U$ O# `0 ~& T7 V( s( \0 f8 Y
        while(q)
    ' u- K; F6 ^3 ~( q) A    {
      E& Z# ^) s! D  e8 |6 ?        if(q->nextarc1==p ||q->nextarc2==p)0 s! Q# t8 q" O9 z5 b  W
                break;: J: X% l/ }* q" b+ P
            q=NextArc(v1,q);
    ! m- _3 \" |& j4 R- r    }/ _2 o/ @1 f6 E0 \% E2 c2 J
        return q;8 u1 Q" v7 P4 h1 j
    }
    ' K9 E2 ?( H7 S* M: q6 ~( Ftemplate<class ElemType, class WeightType>
      s* @* U8 b3 A- a1 [7 Pvoid MultiAdjListNetwork<ElemType, WeightType>::InsertVex(const ElemType& d)5 K( c3 u- O9 @& C" v) f( [, y
    {
    " {$ Z& Q+ i8 a1 j4 G7 e    if (vexNum == vexMaxNum)9 J5 `  E  T  U- }
            throw Error("图的顶点数不能超过允许的最大数!");! V9 U6 t8 E1 @$ ^2 G) z
        vexTable[vexNum].data = d;
    + k3 d3 _: v" ], y( [1 \0 Y) l    vexTable[vexNum].firstarc = NULL;
    , s) j0 A1 f" L; u    tag[vexNum] = 0;) W9 H. c. D7 Q/ b
        vexNum++;
    ' J2 K' I) n+ e4 g+ H}$ W; P0 e) y* U( A9 a7 P) L# H
    template<class ElemType, class WeightType>  Z6 F8 R0 q  L3 Q2 P# R# u
    void MultiAdjListNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w), j# \9 A! c0 g
    {
    0 B, y2 Z# w* N    MultiAdjListNetworkArc<WeightType>* p,*q;7 r4 F& ^6 [3 y/ H: ?( R7 R2 z# B  ]3 G
        if (v1 < 0 || v1 >= vexNum)
    0 v8 N  k* s3 J. X" s  o6 b        throw Error("v1不合法!");) F" Q! e" L+ b
        if (v2 < 0 || v2 >= vexNum)% d1 W* }+ l, u: F) r7 ~. y+ S+ r' }
            throw Error("v2不合法!");
    # U2 j# \! r2 v! R    if (v1 == v2)
    9 L- M& v, h5 G6 {6 e        throw Error("v1不能等于v2!");5 M7 M; O5 F6 G+ o& r) O; j) I3 b
        if (w == infinity)) W' |3 X. q7 Q  O2 U( y
            throw Error("w不能为无穷大!");3 b5 v0 l- s3 {, m" n& \- O
    3 f5 w5 d: U& _9 x# V$ [2 V% v

    % y2 G1 [) p+ U. `. `    p = vexTable[v1].firstarc;
    : ]0 a7 v; w& I( R& Q+ P* O    while(p)
    ) h9 t- e3 ]4 C! [    {
    / u; {  p+ {: z, Z" i# e3 W! t        if(p->adjVex1==v2||p->adjVex2==v2)//边已经在顶点的邻接边中
    / {; z6 S1 x: R6 [0 N4 E  `        {
    8 w1 w) s8 \4 P6 t! u' \/ c, H            if(p->weight!=w)( I, b* }4 ^4 c$ w. S3 I
                    p->weight=w;  h) W$ t5 \1 D' l. a
                return;
      O. w9 E6 X! H: z( {( O- i        }6 A; b, h& O* P& z# b7 M& N9 L7 h
    0 j( S5 y7 s( Y
            p=NextArc(v1,p);: \! t6 y* ~2 a0 I+ ?
        }: ^3 N- C1 O  S% O+ ?+ h
        p = vexTable[v1].firstarc;
    ) S% \2 `5 ~: F% g" W1 Q' e    q = vexTable[v2].firstarc;# S  H( D4 L* @3 v. z
        vexTable[v1].firstarc = new MultiAdjListNetworkArc<WeightType>(v1,v2, w, p,q);//头插法7 Q( y9 e9 ]0 f! b4 C( y/ W
        vexTable[v2].firstarc =vexTable[v1].firstarc;
    $ O3 b/ c$ c9 A; c' H8 {    arcNum++;
    - P$ D) w0 Q3 z2 E}
    3 y; t6 O1 j9 w& ^% ?% x- O
    & {( O% E0 C6 v3 n+ a( o, n9 btemplate<class ElemType, class WeightType>' h& {" r9 c( y* E( i. t4 o+ u
    void MultiAdjListNetwork<ElemType, WeightType>:eleteArc(int v1, int v2)
    7 P. L( b3 k4 F/ o{
    # U% ?* l7 S1 J  M' w5 o  J
    6 i% D/ F& G/ L( v    MultiAdjListNetworkArc<WeightType>* p, * q,*r;
    . l$ l1 H) L8 Q( j, A    if (v1 < 0 || v1 >= vexNum)
    0 T1 F- c# ^) L( V. v        throw Error("v1不合法!");
    " [' S6 g6 p2 t- B2 c    if (v2 < 0 || v2 >= vexNum)8 ~' {1 J1 T( T( y
            throw Error("v2不合法!");. T% @& Z* ]) T4 j1 C
        if (v1 == v2)
    2 G. u* l& q* B1 ]. j        throw Error("v1不能等于v2!");7 u( a) x2 e( f, J+ J

    . o6 y/ K7 S, p7 X    p = vexTable[v1].firstarc;& ]) T! p' v/ E* T+ M% [0 I
        while (p != NULL && p->adjVex2!= v2&&p->adjVex1!=v2)
    0 H# k$ t0 f' s% o# k    {
    # e7 c8 s8 ?* ?! q: X0 `. V        q = p;
    " k/ N' a1 q$ o1 `! e        p = NextArc(v1,p);
    " w7 O) g) @8 |% v: f; s    }//找到要删除的边结点p及其前一结点q
    : w1 b% D4 k, U3 l5 O0 W+ ?
    7 w6 J0 `& E- O! e    if (p != NULL)//找到v1-v2的边
    / d' H$ k, Y0 U5 A1 p    {
      a8 t; P! _% x* [! |5 f& C6 g' Y        r=LastArc(v2,p);
    ; ^8 h$ m# p. m  A/ @# o$ {, F        if (vexTable[v1].firstarc == p)//第一条边,q此时为NULL& g( r: e! Q: [1 K3 x
                if(p->adjVex2==v2)
    * }, R$ Q# |8 G0 @4 @0 m, g* w' k                vexTable[v1].firstarc = p->nextarc1;
    & u6 V$ g6 i: B% u1 s  P            else vexTable[v1].firstarc=p->nextarc2;. m1 D) h" v. }
            else//不是第一条边+ W4 r) L2 _# Z" }+ I6 H9 f2 t5 |
            {
    - \# v3 w; A$ R- s! ?# R- k            if(q->adjVex1==v1)& l: W, a- _% {2 W9 F* e7 c
                    q->nextarc1 = NextArc(v1,p);
      A! Y0 D. ?$ r            else
    8 z: O; s: c6 A, c2 r9 A" X% {. Y                q->nextarc2=NextArc(v1,p);
    0 Y7 V; I5 t  X9 o$ {7 h5 f
    3 T+ S9 q" w6 {; J3 p        }
    3 U" Z) S" ?" [        if(r==NULL)
    2 j% Y: o9 s9 e            if(p->adjVex2==v2)
    1 Z5 m7 n& K9 r                vexTable[v2].firstarc = p->nextarc2;3 \7 z6 T0 G/ ~, ]& z9 z; |
                else vexTable[v2].firstarc=p->nextarc1;
    + J/ r" I: L& z' J1 Y        else7 ^4 e- i: y) o1 _) e3 ~& C& K
            {
    4 G1 _* `% R1 s" G! }4 ]% F* b" Z            if(r->adjVex2==v2)
    3 o4 R! D, x9 v9 ~, d& d) l$ L                r->nextarc2 = NextArc(v2,p);1 B) ?% p+ J, c* F9 l/ w6 j
                else
    $ d2 A& @- U' v5 x6 M- I8 S' {# j                r->nextarc1=NextArc(v2,p);0 j7 y" j3 t/ ]# G, S4 D. a* t1 W
            }
    1 H- [1 \/ _% N7 {- ]9 @$ c8 a        delete p;
    * P/ Q( R2 T* _- g, N        arcNum--;4 `$ z. a  [( {7 Y6 e+ x
        }( K2 a- v7 T, Q1 B0 J
    ! J: i4 F# @7 q& _% d5 W9 W% j
    }; G' @5 Q, ~$ V2 B5 y. U# I* m
    template<class ElemType, class WeightType> void4 h, x2 `1 d; x( y, I
    MultiAdjListNetwork<ElemType, WeightType>:eleteVex(const ElemType& d)
    ; L  M9 h: ~; p) z{6 T4 X8 z5 o4 j* j+ j0 x1 \; k
        int v;
    # ?: v# k1 ~5 a; ^% M    MultiAdjListNetworkArc<WeightType>* p;
    3 m% Q0 `" E3 z4 e6 m& S, [0 C    for (v = 0; v < vexNum; v++)//找到d对应顶点
    9 X1 P0 w7 {( _6 n        if (vexTable[v].data == d)
    5 h  a# `" `# ]' i4 g( y7 f            break;8 ~7 f( y5 r2 G0 q
        if(v==vexNum)
    ' H, U+ p/ ?) |/ K        throw Error("图中不存在要删除的顶点!");
    ; ]! V, J* |( b/ ]( ?( J' ~6 F
    : x( x/ C) s' g: o3 z4 T- d    for (int u = 0; u < vexNum; u++)//删除与d相连的边2 Z' ^  X. {; t2 P+ n7 s! i
            if (u != v)' m% D- w7 N6 v2 P; L
            {) P+ F( g" J6 p5 }+ E% _; C, u
                DeleteArc(u, v);0 V$ L# U1 ]8 F- Y0 X' X+ f
            }: K# Z5 H- f/ {( V. ^) h+ ^, m" X
        vexTable[v].firstarc=NULL;6 r2 V2 [" v. \1 {

    $ Y- e. Z1 f2 z9 m' \; X# i    vexNum--;///将原来的vexTable[vexNum-1]即最后一个节点移动到原来v的位置# S% b/ M! s- h2 T2 ~1 i  F
        vexTable[v].data = vexTable[vexNum].data;$ r# O) k- n0 |+ I! C
        vexTable[v].firstarc = vexTable[vexNum].firstarc;% Z6 v" z- o. \
        vexTable[vexNum].firstarc = NULL;
    ; j# i) Y2 P5 M) {( Y    tag[v] = tag[vexNum];8 N0 A% Z9 }( F
        //原来与最后一个顶点相连的边改为与v相连) Q! b$ e* k$ t  V9 e+ s
        for (int u = 0; u < vexNum; u++)
    % o/ U1 K5 W# i: l; w' a- A- q    {
      O* ]. e6 y' ~        if (u != v)
    $ A% U! |6 m; c$ M; d6 y        {/ {$ ~1 T" a1 m9 Q" i0 T3 F
                p = vexTable.firstarc;
    2 B9 L$ U$ @/ F" _' E  j            while (p)0 h& D  Q) y1 q
                {
    0 ]4 G  g! p4 i' _& Y/ G                if (p->adjVex1==vexNum)
    2 w' S+ D) K/ X: C  V                    p->adjVex1= v;& S& R: J& I0 s* e
                    else if(p->adjVex2==vexNum)
    4 o5 l9 g  O) B: }8 U# |                    p->adjVex2=v;
    : T" V( a' D( }2 }* u* R                p = NextArc(u,p);
    # [$ n( d* }, C: A9 x0 }( _8 y2 W            }
    9 m; p9 Y) |- t: \' r# e$ U; c4 a, w        }- V' W9 {! ^! U+ }$ S3 c
        }
    ; c, p  d& D  q) Y}9 m9 |( t0 a1 v7 l
    ///深度优先遍历1 l" m) d" b& m# h' E
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1(const int v)8 A) c  X7 g. K. J) ~
    {
    , m* J/ j. e0 c9 F    tag[v]=1;; t5 C6 i8 z8 z* `" }
        cout<<setw(3)<<vexTable[v].data;
    * b+ H; R8 t5 v  J0 e    MultiAdjListNetworkArc<WeightType> *p;7 h- W, c" O$ C7 `
        p=vexTable[v].firstarc;
    6 w1 h, @2 H6 y% H2 t    while(p)% u) o9 ]3 K  N* D# ^( C
        {# ^) ]+ P0 Q  E8 h
            if(tag[p->adjVex1]==0)
    * U/ }& K$ w5 ~1 S1 ~* s            DFS1(p->adjVex1);$ O" N# |  ?$ W0 U- G
            else if(tag[p->adjVex2]==0)  Y, V% k7 I+ P; X
                DFS1(p->adjVex2);# v! X! q" ~% ^5 K+ u3 w
            p=NextArc(v,p);
    1 P# |8 J0 ^5 E$ e9 `1 |! E" l    }
    * X) m. ^9 X) a+ @: u& d* ^# w* v3 H}5 c# x8 X, J7 U0 Q4 s5 e
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS1Traverse()1 C0 S' I) D  T! W) l3 |. v& A
    {
    & _  T8 ~0 C" w1 o6 q* f5 U9 B    for(int i=0; i<vexNum; i++)! k, U2 s9 T( p' {2 }' Q2 k9 ~, Z* r
            tag=0;" y% W3 N, v; p
        for(int v=0; v<vexNum; v++)% M! a4 t4 p0 p& q
        {; B$ q9 f1 J# N4 g0 n! T
            if(tag[v]==0)6 O! v3 Y) z& L/ s& B3 u2 }
                DFS1(v);. J, x* X, J  a0 G
        }
    $ R- m2 g( ?& f: c9 K, h' r}
    % L7 X( F! x) M* R! g; [' T/ ptemplate<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS2()' ^8 g, }  V6 {
    {3 w& j% ?6 ]. i# u0 o, s
        stack<int> s;
    8 j0 n' y  t* [2 F    int tmp;
    , Q3 z6 C6 i9 c0 ~    MultiAdjListNetworkArc<WeightType> *p,*q;  g  C4 i9 U: O! H4 a2 q  \) M
        for(int i=0; i<vexNum; i++)+ _* g3 z3 m7 |% x
            tag=0;
    ' @5 }/ k6 O, F% I6 f" o& F( N    for(int i=0; i<vexNum; i++)
    $ U" w% z- u4 J8 U1 E  J% f2 A7 S    {
    ( r# M+ J8 \9 L( z- \8 g4 v# E        tmp=i;
    9 `5 n' i" S' [/ o3 v8 l        while(tag[tmp]==0||!s.empty())
    3 _' e7 ~; Z$ @( ~' Y" K* \        {5 \* u8 k, S3 C
                p=vexTable[tmp].firstarc;9 n/ c+ E8 ?4 H% s
                while(tag[tmp]==0)1 r4 t* O) S# s) H2 ^3 D3 z- `
                {$ G9 ^2 \2 d: O, U7 S8 k* X3 b
                    s.push(tmp);
    4 N6 n$ d! y7 Q$ c" O                cout<<setw(3)<<vexTable[tmp].data;  T1 n2 Q4 S2 a6 m' Q
                    tag[tmp]=1;
    & e$ f$ X- v9 _" z  R                p=vexTable[tmp].firstarc;
    * Z1 k1 Z8 J1 L5 J5 O                if(p==NULL) break;///该顶点没有边,连通分支结束(1个点)先出栈再跳出循环进入for. Y, Y- R* G* Y2 v! T6 M
                    tmp=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);0 H1 j% n* M$ L. r- }& w, p
                    //cout<<" 1st     tmp="<<tmp<<endl;- G& T" ?. x: r. G- b9 F
                }' g5 G$ e* ]$ K: e6 m( c0 d" I
                if(!s.empty())8 k5 b# u6 s# \! d- Z# ]7 g. O
                {
    0 h, C$ d% I+ e8 U9 J7 L, v: b                tmp=s.top();
    # _, H! n2 b* {                s.pop();1 E" u& o% n/ f6 A7 b2 H/ g/ Z$ P2 Y! M
                    q=vexTable[tmp].firstarc;. e, i/ f7 Q& o% ]) F; j
                    int t=tmp;& J! k3 |1 _( @" J2 q9 O! b
                    while(q&&tag[tmp]!=0)
    ' L+ m, Q  z1 K" h                {; V5 ?1 |, Y7 O  M
                        tmp=(q->adjVex1==t?q->adjVex2:q->adjVex1);
    ; ]4 e& b" M& o- A: k                    //cout<<" 2nd     tmp="<<tmp<<endl;8 E& m2 l% P( w. K
                        q=NextArc(t,q);' @: \, W' o# n2 C$ T4 J; l
                    }, t8 L0 G1 _2 M5 n. C  t- E( |+ c
                    if(tag[tmp]==0)  i6 a+ b: `7 ~% E  |. V& X
                        s.push(t);/ H! J% ^+ Y3 P% A
                    ///1、对应上面连通分支只有1个点的情况% B8 T1 p& }. R3 `/ f3 L
                    ///2、t上的点都被访问过,此时tmp是t相连的最后一个点,用于跳过上面while,再次进行出栈
    6 S. Q5 [7 l3 I2 E                ///tmp要么等于找到的第一个未访问节点,
    ( T0 w4 p: @1 [9 }- ]2 `& e. B                ///要么等于与t相连最后一个点(已被访问过)  M5 p8 o7 \7 Z; y
                    ///当连通图只有一个节点时,这时tmp=这个已访问的孤立节点7 f" x4 V0 L" b1 ]7 S5 U% e
                }
    - g2 |: ]" N' g% o/ q$ _        }0 b( `3 o7 V( i2 h  O! b
        }; I$ p* S6 c4 D* _8 B
    }
    ( F7 E4 A4 l' s% K/ ]" w' |" F//从顶点v出发的一个顶点u,返回v通往的下一个顶点;如果没有其它分支或者已经是最后一个连通点,返回-1;如果要取第一个顶点传入-19 U7 Q# b) [8 B* A* I
    template<class ElemType, class WeightType> int
    * @: q6 y3 l! j  sMultiAdjListNetwork<ElemType, WeightType>::GetAdjVex(int head,int pre)
    & y- z7 L5 `8 D# N- {9 M4 R{& M5 n* U% Y* W9 a( w
        if(head==pre)8 H$ M: k: X7 c' ~! M
            return -1;
    % ~" X0 u4 g0 x7 T
    1 r0 ?- D( n3 j) y, [* _. s    MultiAdjListNetworkArc<WeightType> *p;
    8 I1 Z* P1 P( X    p=vexTable[head].firstarc;2 o1 }$ A: X& I5 }/ X. H. j% e
        if(pre==-1&&p!=NULL)& O, ^+ j  N3 ]: w# P! ~" B+ q
            return p->adjVex1==head?p->adjVex2:p->adjVex1;
    ; h: {4 t+ |& x% n, S. r7 {    //pre!=-1&&p!=NULL8 {! ^# n3 D* C: ?$ S+ {
        while(p!=NULL)
    ( P+ S3 P$ O6 ~    {6 R, d9 b* ^1 ^
            if(p->adjVex1==head && p->adjVex2!=pre)1 D/ V4 S! m1 z9 J. I
                p=p->nextarc1;! K3 P5 Z) B7 |+ a3 j7 k5 Q& N
            else if(p->adjVex2==head && p->adjVex1!=pre)
    - n/ h1 J+ `) a6 D) ?            p=p->nextarc2;# U  D( `2 k) W/ r% o5 X9 u
            else if(p->adjVex1==head && p->adjVex2==pre)
    8 @, e+ J6 p9 S1 o' C9 }" w        {
    + G, n# m' O, s            p=p->nextarc1;
    ! m3 w% p. x) A/ y! K" i* u( T            break;/ _+ p8 f! b6 S9 B8 E  R, _9 H* i& c
            }# M8 K9 i5 B& p! }, i' H
            else if(p->adjVex2==head && p->adjVex1==pre)
    5 J/ e6 t# W( b( a1 [        {8 b0 c' j5 t. C' |. E' I
                p=p->nextarc2;, R1 h6 K# r& C- |" L& s- {
                break;
    ( B; @6 O2 s2 @        }( k5 z& l; u6 V
        }
    ; a3 |! a0 Z6 c  }* ^+ \    if(p!=NULL)
    7 A1 g! y/ w5 ?/ u! V    {' V6 ^) G( ?9 d0 R5 L8 H  Z
            return p->adjVex1==head?p->adjVex2:p->adjVex1;2 G. Q) o2 O, b) \! a. ^& Y" o
        }2 |+ N; O1 R3 E3 ]  `
        else
    $ \$ L( z: ]5 \0 J        return -1;7 p, P3 C8 K4 L' g9 i
    }
      h) z8 L0 U. S: n6 m
    # ~2 E8 k7 J" p0 a+ X7 n( n3 ~, i9 b6 p7 r
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>:FS3()
    + Q/ A6 C: \8 I( h1 u& P{% H" G. V) N3 g/ |1 {3 @
        stack<int> s;1 P7 ?8 b* X8 ]/ y- d5 c5 ^7 M
        int p,cur,pre;
    + l% Q4 l. J8 Z5 X; o5 M2 }    //MultiAdjListNetworkArc<WeightType> *p,*q;
    7 M$ T, N0 R- L! q) i: @9 t    for(int i=0; i<vexNum; i++) tag=0;//初始化
    # f9 U5 S* w; r
    5 P1 W7 x; q) g4 i    for(int i=0; i<vexNum; i++)6 P& X8 I  l  E
        {
    0 X/ T) w6 ]5 R  K8 n$ n* s        cur=i;pre=-1;6 `- U! {1 m9 v0 T6 y+ ?
            while(tag[cur]==0||!s.empty())+ J5 ?5 c8 w3 H- C- A$ c
            {
    ) B6 d# t( D; o" |( g6 O) ~            while(tag[cur]==0)! y' q3 c) E7 g# ?
                {
    " P& v5 e% O) d                cout<<vexTable[cur].data<<"  ";
    / @, H* k/ B/ c) B& o, s. @" }                s.push(cur);
    7 K" W6 t7 Y; l/ e9 }, l                tag[cur]=1;
    ; O" F% v4 M0 T1 i& A               //初次访问,标记入栈% g( c1 J* Z# b# [1 S6 x) y; q# q

      y/ Q& {) V" H" G6 j: E               p=GetAdjVex(cur,pre);//p是cur的连通顶点# _  J( O9 H* P1 y! f
                   if(p==-1)! ^9 k! `& U7 P, O6 }
                   {
    / w: T, e) l/ ]6 @                   pre=cur;s.pop();
    7 {) Z, i& x6 F' j                   break;+ y+ R8 _5 L. b- s5 z8 d2 l' b) a
                   }
    ( s  p' h9 }. u' x' x               else
    $ x1 f. e/ s: B" J1 m0 j               {
    . i- v% C% P6 m, i  m9 m( i: S  W                   pre=cur;
    , M* P( h8 n! `6 N. F; |2 l                   cur=p;
    5 G! C+ Z4 j' s3 p4 X               }
    4 D6 q: k9 h! @& A. L: K$ \0 O/ r1 G8 Y- j7 M3 n4 {
                }
    2 z3 O5 c3 C% z6 H: L9 c6 ~            while(!s.empty())
    2 D& U/ p' o* i5 I+ k            {, [( @- e; Z0 T7 V' \2 A, A1 q
                    cur=s.top();
    ! h6 w! c( _3 y# b2 R                p=GetAdjVex(cur,pre);' _# K4 o7 Z2 f8 G, r- L
                    if(tag[p]==0)5 Z* ~  F% x. J1 k3 ~, d
                    {
    2 T/ a) T1 J5 G8 @5 T                    pre=cur;
    ( ]0 `3 [7 f$ [3 a* Q. ?( p                    cur=p;% B2 T% |$ f4 v0 R5 A+ E4 a: k
                        break;
    ) Q$ ?2 H& o$ W3 @4 A                }
      A$ e. a. @* _' W) t7 z% i                else" L  S9 w- r5 v* n& w
                    {0 x3 P7 r0 b9 X4 M, }
                        pre=s.top();
    3 J% t( Y4 l0 m2 o+ |( a. k                    s.pop();* u" r5 ^) T* S4 V# F# o5 P$ @
                    }
    0 E% A* B  G- M. j- Y7 F+ _- H8 Y/ t& D, Z$ ?4 c* c
                }% s4 [1 ~0 y7 |. [5 o4 g4 u

    1 ]6 x( X  x. F- z' z        }! `  [9 t; P" A
        }% i8 @( T; z% [- S; H) I
    }  e7 s# M/ v; D! C' \$ ^7 T
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::BFS()
    7 {  B3 W' C5 \( [{4 g$ Z: I0 F- J3 w' W
        for(int i=0; i<vexNum; i++)' P# N: P/ u  J' L  ~) p- x* s/ g. ^
            tag=0;9 C7 t5 H+ s, S' c+ N- f9 \
        queue<int> q;8 D" E, O2 y3 _4 m
        int tmp,t;
    2 }6 j6 {! G* G/ \    MultiAdjListNetworkArc<WeightType> *p;
    " D5 N1 F/ p" ]! c6 x0 N* C, s    for(int i=0; i<vexNum; i++). ^) v: F) \- Y  Y3 ^8 h
        {6 q' d2 r) A/ H3 i
            if(tag==0)7 R. U& q! V0 b' ?# k
            {3 ]) i/ H+ R4 M7 Y
                tag=1;& D! q# N* S7 {0 O4 Z8 E
                q.push(i);
    4 U: D9 p, n- P% ?$ C* [/ s) L            cout<<setw(3)<<vexTable.data;, }5 w6 _6 h8 \  T4 ]1 Y5 @  I, u. K3 {
            }
    ) I7 `$ P6 t: {& T9 b; F* B        while(!q.empty())
    0 T) Y6 |4 O9 D% Y: ~! d5 |# l3 D        {
    ' m+ C/ J" J6 M; U9 y            tmp=q.front();
    / I4 d+ W7 f6 L            q.pop();* J+ g" I2 `" G! Z
                p=vexTable[tmp].firstarc;
    + F0 w2 q( S: e3 ?" b, w3 u            while(p!=NULL)
    8 y. C. x' z8 W/ W9 G5 n            {/ C7 O) X  v+ p" Q$ x' u
                    t=(p->adjVex1==tmp?p->adjVex2:p->adjVex1);
    " ^0 S( H5 R5 A                if(tag[t]==0)
    / H( E0 D& R% u" q$ p' b) Z                {
    0 e3 r- k8 ^0 s                    cout<<setw(3)<<vexTable[t].data;7 Q; R9 z+ C: U; u6 \
                        tag[t]=1;/ {; I3 I$ x9 x4 j; `: K
                        q.push(t);  {0 D' p' W, m
                    }; d- c/ s6 ?9 W  n" m
                    p=NextArc(tmp,p);
    # B; Z# Y! O* z; n            }' T2 k: G9 T. w
            }; A" r" ]& J/ ^! ^. g4 ~* P
        }) |5 S; ^; \: m$ l* o$ M0 Y, R
    }4 M& m  c* ~$ D, G, w) N1 H
    template<class ElemType, class WeightType> void MultiAdjListNetwork<ElemType, WeightType>::Show()0 z& v: {  {* o; Y  ^( G) U
    {
    ! D4 a0 z; o1 \/ O# \9 U9 j& g    MultiAdjListNetworkArc<WeightType> *p;
    ; d" \  }4 f( N! h1 N4 R( b5 q* W# Y    cout << "无向图有" << vexNum << "个点,分别为:";
    4 I, |# v3 F8 F# O& m2 n    for (int i = 0; i < vexNum; i++)9 O1 D: \3 y! q4 o* k- b5 q
            cout << vexTable.data << " ";, q; H# c( C  C8 K+ r
        cout << endl;
    5 i- C: L; h0 U5 V    cout << "无向图有" << arcNum << "条边"<<endl;
    4 W4 E% T2 q7 l8 W" @2 l    for (int i = 0; i < vexNum; i++)
    / r) @8 [8 r. z7 R9 U    {
    ; u# Y& _' |* q& [5 H        cout<<"和" << vexTable.data << "有关的边:";+ Q. _& k( _  ^% z
            p = vexTable.firstarc;: \9 x+ x3 R8 H
            while (p != NULL)
    ( d* o# h4 X5 V+ S3 r6 g1 P        {8 ?# U1 s" C' C
                cout << vexTable[p->adjVex1].data << "<--"<<p->weight<<"-->" << vexTable[p->adjVex2].data << ",";6 \; B4 d  c& x4 T4 G: f' N
                p=NextArc(i,p);
      V" k+ u+ I7 H        }4 t1 P: @/ a6 X' x, @( T% Y/ n
            cout << endl;
    ( a' A! d4 ]- {! x    }2 a) I5 _' V' ?$ h
    }% S" p  G  J" e9 }# C
    5 E8 R" N! L: H: o, k( C

    5 U2 z% V6 n5 c, r# B' G+ O; |邻接多重表与邻接表的对比
    8 R" {3 s0 E/ M+ z9 s, F1 \9 R% |  I+ Q; }" q7 Z& C( y
    邻接表链接
      S0 S8 o  ^5 E: I# Q在无向图的邻接多重表中,所需存储空间与表示无向图的邻接表相同。  t" D% ~% C5 N5 b" \$ c
    在无向图的应用中,如果更加关注图的顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作,若要删除某条边,需要对邻接表结构中相关的两个结点进行删除,显然这是比较繁琐的。  @! h# h. j: n- M
    为了提高在无向图中操作顶点的效率,又有了邻接多重表的存储结构。邻接多重表与邻接表的区别在于,同一条边,在邻接多重表中要用两个结点表示,而在邻接表中只需要一个结点。此外,邻接多重表中增加了标志域用以标记该条边是否被搜索过,避免了同一条边的重复搜索。
    * G# X# U# q( `% \  o————————————————
    - W  k# J% N  t+ z版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。' e' V! X/ g1 P. H+ Y% U& V/ m
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    . j9 j  r7 x: c8 y* A
    " x7 f, q' A* i, w' e7 L* r1 i! s

    0 R5 w7 O$ m" k7 I) ^* o
    ( M% L* v! e. r. D————————————————
    : V, l2 m7 A2 e版权声明:本文为CSDN博主「lseaJK」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。6 ?7 ?" f3 _' M! B1 R6 s% q, o; q. A
    原文链接:https://blog.csdn.net/qq_43413403/article/details/105766958
    2 M0 A' u9 M% I8 Z1 d
    4 X/ Y) W4 a  b
    ' v9 _% r9 U6 D/ j6 ~
    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-10-31 21:03 , Processed in 0.241169 second(s), 54 queries .

    回顶部