SlideShare a Scribd company logo
1 of 53
第七章 图

7.1 抽象数据类型图的定义
7.2 图的存储表示
7.3 图的遍历
图的结构定义 :
     图是由一个 顶点集 V(Vertex) 和
一个边 集 R 构成的数据结构。
     Graph = (V , R )
其中, R = {<v,w>| v,w∈ V 且 P(v,w)}
  <v,w> 表示从 v 到 w 的一条弧
(Arc) ,并称 v 为弧头 (Head) , w
为弧尾 (Tail) 。
         V        W
这里的弧为“ 有向边 ” 因此对应图为
有向图 (Digraph) 。

例如 : G1 = (V1, E1)
                     其中
        A
                     V1={A, B, C, D, E}
B               E    E1={<A,B>, <A,E>,
    C       D         <B,C>, <C,D>, <D,B>,
                      <D,A>, <E,C> }
若 <v, w>∈E, 必有 <w, v>∈E,
则称 (v,w) 为顶点 v 和顶点 w 之间存在一
条边 Edge. 无方向的边构成无向图
(Undigraph).
例如 : G2=(V2,VR2)            B   C
V2={A, B, C, D, E, F}
                        A           D
VR2={(A,B), (A,E),
 (B,E), (C,D), (D,F),       F   E
 (B,F), (C,F) }
名词和术语
网、子图
完全图、稀疏图、稠密图
邻接点、度、入度、出度
路径、路径长度、简单路径、简单回路
连通图、连通分量、
强连通图、强连通分量
生成树、生成森林
15   A     9
                              弧或边带权
                  11
B        7   21        E   Weight 的图分别称
    3                      作有向网或无向网
         C   2    F
                           Network 。 B
                             B
设图 G=(V,{VR}) 和                              C
图 G′=(V′,{VR′}),                 A
且 V′⊆V, VR′⊆VR,
则称 G′ 为 G 的                  B           E
子图。                         C        F
假设图中有 n 个顶点, e 条边,则
 含有 e=n(n-1)/2
 条边的无向图称
 作完全图;

 含有 e=n(n-1)
 条弧的有向图称
 作 有向完全图
 ;
若边或弧的个数 e<nlogn ,则称作稀疏图
Spares Graph ,否则称作稠密图 Dense
Graph 。
假若顶点 v 和顶点 w 之间存在一条
  边,
边 则称顶点 v 和 w 互为 邻接点
  (v,w) 和顶点 v 和 w 相关联。
 (Adjacent) ,
和顶点 v 关联的边的数目定义为顶点 v 的度

 例如                B   C
 :
   ID(B) = 3               D
               A
   ID(A) = 2
                   F   E
对有向图,
          A           顶点的出度
                      Outdegree:
B                 E
                      以顶点 v 为弧尾的弧
      C       F       的数目; Indegree:
                      顶点的入度
例如                    以顶点 v 为弧头的弧
: OD(B) = 1           的数目。

    ID(B) = 2         顶点的度 ( TD) =
                      出度 ( OD) + 入度 ( ID)
    TD(B) = 3
设图 G=(V,{VR}) 中的一个顶点序列
{ u=vi,0,vi,1, …, vi,m=w} 中, (vi,j-1,vi,j)∈VR 1≤j≤m,
则称从顶点 u 到顶点 w 之间存在一条路径
Path 。
路径上边的数目称作路径长度。
  如 : 长度为 3 的路径
  {A,B,C,F}     简单路径 : 序列中顶点
                不重复出现的路径。
             A
                        简单回路 Cycle: 序列中
    B                 E 第一个顶点和最后一
                        个顶点相同的路径。
         C       F
B   C
若图 G 中任意两个顶
点之间都有路径相通
,则称此图为连通图       A           D
;
    B   C           F   E

                若无向图为非连通图
A           D
                ,则图中各个极大连
                通子图称作此图的连
    F   E
                通分量。
对有向图,              若任意两个顶点之间
都存在一条有向路径,则称此有向图为
强连通图。
    否则,其各个强连通子图
 称作它的强连通分量。
        A                    A

B               E    B               E

    C       F            C       F
假设一个连通图有 n 个顶点和 e 条边
,其中 n-1 条边和 n 个顶点构成一个极小
连通子图,称该极小连通子图为此连通图
的生成树 Spanning Tree 。
         C         对非连通图,则
   B
                   称由各个连通分
                   量的生成树的集
A            D
                   合为此非连通图
                   的生成森林。
   F    E
图的抽象数据结构
ADT Graph{
数据对象 V: V 是具有相同特性的数据
元素的集合 , 即顶点集 .
数据关系 : R = {VR}
VR = {<v,w>|v,w∈V 且 P(v,w)
<v,w> 表示从 v 到 w 的弧 ,P(v,w) 定义了
弧 <v,w> 的意义或信息 }
基本操
     作
结构的建立和销毁
          对顶点的访问操作
插入或删除顶点
          插入和删除弧
对邻接点的操作
          遍历
结构的建立和销
    毁
CreatGraph(&G, V, VR):
 // 按定义 (V, VR) 构造图

DestroyGraph(&G):
 // 销毁图
对顶点的访问操作
 LocateVex(G, u);
 // 若 G 中存在顶点 u ,则返回该顶点
 在
 // 图中 “ 位置 ” ;否则返回其它信息。
GetVex(G, v);   // 返回 v 的值。

PutVex(&G, v, value);
 // 对 v 赋值 value 。
对邻接点的操作
FirstAdjVex(G, v);
// 返回 v 的 “ 第一个邻接点” 。若该顶
点
// 在 G 中没有邻接点,则返回 “ 空 ” 。
        A
                     若 v=‘A’
   B             E
                     则
       C     F       irstAdjVex(G,
                     v) 返回‘ B’
对邻接点的操作
NextAdjVex(G, v, w);
// 返回 v 的(相对于 w 的) “ 下一个
邻接
// 点” 。若 w 是 v 的最后一个邻接点
               v
,则           A
// 返回 “ 空 ” 。
    w
      B          E NextAdjVex(G,v,w
                           )
        C     F
插入或删除顶点

InsertVex(&G, v);
// 在图 G 中增添新顶点 v 。

DeleteVex(&G, v);
// 删除 G 中顶点 v 及其相关的弧。
插入和删除弧

InsertArc(&G, v, w);
 // 在 G 中增添弧 <v,w> ,若 G 是无向
的,
 // 则还增添对称弧 <w,v> 。
DeleteArc(&G, v, w);
// 在 G 中删除弧 <v,w> ,若 G 是无向
的,
// 则还删除对称弧 <w,v> 。
遍   历
DFSTraverse(G, v, Visit());
// 从顶点 v 起深度优先遍历图 G ,并对每
// 个顶点调用函数 Visit 一次且仅一次。

BFSTraverse(G, v, Visit());
// 从顶点 v 起广度优先遍历图 G ,并对每
// 个顶点调用函数 Visit 一次且仅一次。
7.2 图的存储表示
一、图的数组 ( 邻接矩阵 ) 存储表示
二、图的邻接表存储表示

三、有向图的十字链表存储表示

四、无向图的邻接多重表存储表示
图的数组 ( 邻接矩阵 ) 存储
表示
      图由于结构复杂 , 无法以数据
元素在存储区中的物理位置来表示元素
之间的关系 , 即图没有顺序映像的存储
结构 , 但可借助数组的数据类型表示元
素之间的关系 .
一、邻接矩阵
                        0 (i,j)∉VR
定义 : 矩阵的元素为 Aij=    { 1 (i,j)∈VR
                A   B   C   D   E   F
   B   C    A
           0 1 0            0   1   0
         B
           1 0 0            0   1   1
         C
A      D   0 0 0            1   0   1
         D
           0 0 1            0   0   1
         E
  F  E     1 1 0            0   0   0
         F
           0 1 1            1   0   0
无向图的邻接矩阵为对称矩阵
A   B   C   D   E
        A           A   0   1   0   1   0
                    B
                        0   0   1   0   0
B               D   C
                        0   0   0   0   1
                    D
    C       E           0   0   1   0   0
                    E
                        1   1   0   0   0

有向图的邻接矩阵为非对称矩阵
邻接矩阵表示法特点
:
1 )无向图邻接矩阵是对称矩阵,同一条
边表示了两次;
2 )顶点 v 的度:
无向图中等于二维数组对应行(或列)中
1 的个数;
有向图中 , 统计第 i 行 1 的个数可得顶
点 i 的出度 ,统计第 j 列 1 的个数可
得顶点 j 的入度。
邻接矩阵表示法特点
:
3 )判断两顶点 v 、 u 是否为邻接点:只需
  判二维数组对应分量是否为 1 ;
4 )顶点不变,在图中增加、删除边:只需
  对二维数组对应分量赋值 1 或清 0 ;
       A   B   C   D   E
   A   0   1   0   1   0           A
   B   0   0   1   0   0
   C   0
       1   0   0   0   1   B               D
   D   0   0   1   0   0       C       E
   E   1   1   0   0   0
邻接矩阵表示法特点
:

5 )设存储顶点的一维数组大小为 n,
  则 G 占用存储空间: n+n2 ; G 占
  用存储空间只与它的顶点数有关,
  与边数无关;适用于边稠密的图;
typedef struct ArcCell { // 弧的定义
    VRType adj;    // VRType 是顶点关系类
型                              // 对无权
         图,用 1 或 0 表示相邻否;
       // 对带权图,则为权值类型。
   InfoType *info; // 该弧相关信息的指针
} ArcCell,
AdjMatrix[MAX_VERTEX_NUM]
                  [MAX_VERTEX_NUM];
typedef struct { // 图的定义
    VertexType      // 顶点信息
           vexs[MAX_VERTEX_NUM];
    AdjMatrix    arcs;   // 弧的信息


    int vexnum, arcnum; // 顶点数,弧
数
    GraphKind kind;      // 图的种类标志
网络的邻接矩阵

                  W (i , j ), 若i ≠ j且 < i, j >∈ E或(i, j ) ∈ E
                  
A.edge[i ][ j ] = ∞,          若i ≠ j且 < i, j >∉ E或(i, j ) ∉ E
                  0,          若i == j
                  
                                           0 15 ∞ 9 ∞ 
             15   A     9                  ∞ 0 3 ∞ ∞ 
                       11                             
                                  A.edge =∞ ∞ 0 ∞ 2 
                                           
     B        7   21         D                        
         3                                 ∞ ∞ 21 0 ∞ 
              C        E                   11 7 ∞ ∞ 0 
                                                      
                  2
图的链表表示
l 图的复杂结构使我们考虑用多重链表 . 多重链表
  由一个数据域和多个指针域组成的结点表示图中
  的一个顶点 , 其中数据域存储顶点的信息 , 指针
  域指向其邻接结 . 点但图的结点度数的不一致性
  , 可能会导致空间浪费或操作不便 . 实际应用中
  , 通常是根据具体的图和需要进行操作 , 设计恰
  当的结点结构和表结构 .
l 常用的有邻接表 Adjacentcy List , 邻接多重表
  Adjacency Multilist 和十字链表 Orthogonal List 等
  结构表示 .
1       2

二、图的邻接表存储表                      B   C
示                   0
                                                3
                        A                   D
0   A   1   4
1   B   0   4   5
                                        E   4
                            5   F
2   C   3   5        同一个顶点发出的边
3   D   2   5       链接在同一个边链表中
                    ,每一个链结点代表一
4   E   0   1       条边 ( 边结点 ), 结点中有
5   F   1   2   3   另一顶点的下标 adjvex
                     和指针 nextedge 。
有向图的邻接
表       A
                    0 A   1    4∧
B               E   1 B   2∧
    C       D       2 C   3∧
在有向图的邻接表            3 D   0    1∧
中 , 不易找到指向          4 E   2∧
该顶点的弧。
A
有向图的逆邻接
                B               E
表
在有向图的邻接             C       D
表中,对每个顶   0 A       3 ∧
点,链接的是指             3       0 ∧
          1 B
向该顶点的弧。
          2 C       4 ∧

          3 D       2 ∧

          4 E       0 ∧
弧的结点结            adjvex nextarc info
    构
typedef struct ArcNode {
 int     adjvex; // 该弧所指向的顶点的位置
 struct ArcNode *nextarc;
               // 指向下一条弧的指针
 InfoType *info;   // 存储和弧相关的信息 , 如权
值
} ArcNode;
顶点的结点结                 data firstarc
  构
typedef struct VNode {
 VertexType data; // 顶点信息
 ArcNode *firstarc;
          // 指向第一条依附该顶点的弧
 } VNode, AdjList[MAX_VERTEX_NUM];
图的结构定义
typedef struct {
   AdjList vertices; // 顶点列表
   int   vexnum, arcnum; // 顶点数和弧数
   int   kind;     // 图的种类标志
 } ALGraph;
邻接表表示法特点:

1 )对于无向图 |V|=n,|E|=e. 其邻接表需
  要 n 个头结点和 2e 条边 .
2 )顶点 vi 的度:在无向图中等于第 i
  个链表中的结点数;在有向图邻接表
  中 , 第 i 行的结点数等于顶点 i 的出度
  ,在有向图逆邻接表中 , 第 i 行的结
  点数等于顶点 i 的入度。
邻接表表示法特点:

3 )在邻接表上容易找到任一顶点的第
  一个邻接点和下一个邻接点 . 如要判
  定任意两个顶点是否相连 , 需搜寻第
  i 个或第 j 个链表 .
4 )设存储顶点的一维数组大小为
  n( 顶点数 n), G 占用存储空间:
  n+e ; G 占用存储空间与它的顶点数
  和边数有关;适用于边稀疏的图;
三、有向图的十字链表存储表
示
     有向图的十字链表 Orthogonal
List 是一种将有向图的邻接表和逆
邻接表结合起来得到的一种链表 .
     每条弧对应一个弧结点 , 每个
顶点对应一个顶点结点 .
弧的结点结
构
弧尾顶点位置 弧头顶点位置                              弧的
相关信息
               指向下一个            指向下一个
               有相同弧尾            有相同弧头
               的结点              的结点

typedef struct ArcBox { // 弧的结构表示
   int tailvex, headvex; InfoType *info;
   struct ArcBox *hlink, *tlink;
   } VexNode;
顶点的结点结
 构
   顶点信息数据
      指向该顶点的            指向该顶点的
      第一条入弧             第一条出弧


typedef struct VexNode { // 顶点的结构表示
   VertexType data;
   ArcBox *firstin, *firstout;
} VexNode;
有向图的结构表示 ( 十字链表 )
typedef struct {
 VexNode xlist[MAX_VERTEX_NUM];
       // 顶点结点 ( 表头向量 )
 int vexnum, arcnum;
      // 有向图的当前顶点数和弧数
} OLGraph;
0               1
          A       B



      2 C             D 3

0A              0 1         0 2

1 B

2C        2 0                     2 3

3D        3 0   3 1         3 2
建立有向图的十字链表算法
   输入 n 个顶点和 e 条弧的信息 , 构
建有向图的十字链表 .
Status CreateDG(OLGraph &G)
// 采用十字链表 , 构造有向图 G ( G . kind =D G )
{ scanf(&G.vexnum,&G.arcnum,&IncInfo);
  // 读入图的顶点数和边数及相关信息
  for(i=0;i<G.vexnum;++i){        // 构造表头信息
     scanf(&G.xlist[i].data);    // 输入顶点数据
     G.xlist[i].firstin = NULL;
     G.xlist[i].firstout = NULL; // 指针初始化
   }
   ...
建立有向图的十字链表算法
For (k=0; k<G.arcnum;++k) { // 输入各弧构造十字链
表
 scanf(&v1,&v2); // 输入一条弧的起点和终点
  i = LocateVex(G,v1); j= LocateVex(G,v2) ;
    // 确定 v1 和 v2 在 G 中的位置
    p=(ArcBox*)malloc(sizeof(ArcBox));
    *p={i,j,xlist[j].firstin,G.xlist[i].firstout,NULL}; // 对弧点赋值
    G.xlist[j].firstin = G.xlist[i].firstout = p;
    // 完成在如弧和出弧链头的插入
    if(IncInfo) Input(*p->infor); // 若弧含有相关信息 , 则
输入
}} //CreateDG
建立有向图的十字链表算法

l 在建立邻接表或逆邻接表时 , 若输入
的顶点信息即为顶点的编号 , 则时间复
杂度为 O ( n+e ) . 否则要先查找顶点 , 确
定其在图中的位置 , 此时的时间复杂度
为 O ( n* e ) .
四 . 无向图的邻接多重表存储
表示

     邻接表中每一条边 (vi,vj) 有两
个结点 , 分别在第 i 个和第 j 个链表中 .
给在面向边的操作中带来不便 , 因为需
要找到表示同一条边的两个结点 . 因此 ,
这种情况下往往采用邻接多重表来存储
图的信息 .
边的结构    mark ivex   ilink jvex jlink   info


typedef struct Ebox {
   VisitIf    mark; // 访问标记
   int ivex, jvex;
            // 该边依附的两个顶点的位
置
   struct EBox *ilink, *jlink;
      // 分别指向依附这两个顶点的下一
条边
顶点的结构表示         data   firstedge

typedef struct VexBox {
  VertexType data;
  EBox *firstedge; // 指向第一条依附该顶点的边
} VexBox;

 无向图的结构表示
 typedef struct { // 邻接多重表
   VexBox adjmulist[MAX_VERTEX_NUM];
    int vexnum, edgenum;
  } AMLGraph;
0A              B 1
             2C

       3 D            E 4

0 A          0    1         0   3
1 B
2 C          2    1         2   3
3 D
4 E          4    1         2   4

More Related Content

What's hot

What's hot (16)

香港六合彩
香港六合彩香港六合彩
香港六合彩
 
香港六合彩
香港六合彩香港六合彩
香港六合彩
 
2 3平面坐標系
2 3平面坐標系2 3平面坐標系
2 3平面坐標系
 
2 3平面方程式
2 3平面方程式2 3平面方程式
2 3平面方程式
 
香港六合彩
香港六合彩香港六合彩
香港六合彩
 
2 2空間向量
2 2空間向量2 2空間向量
2 2空間向量
 
2 1空間慨念
2 1空間慨念2 1空間慨念
2 1空間慨念
 
麻省教材 --Bstress梁的应力
麻省教材 --Bstress梁的应力麻省教材 --Bstress梁的应力
麻省教材 --Bstress梁的应力
 
2 4三角測量
2 4三角測量2 4三角測量
2 4三角測量
 
2003 amc10
2003 amc102003 amc10
2003 amc10
 
Test(p1~p5)
Test(p1~p5)Test(p1~p5)
Test(p1~p5)
 
Test(p1~p5)
Test(p1~p5)Test(p1~p5)
Test(p1~p5)
 
08
0808
08
 
第2讲 课件
第2讲  课件第2讲  课件
第2讲 课件
 
直线和圆
直线和圆直线和圆
直线和圆
 
Image Stitching Method
Image Stitching MethodImage Stitching Method
Image Stitching Method
 

Viewers also liked

juegos pc parte1/7
juegos pc parte1/7juegos pc parte1/7
juegos pc parte1/7guest44971c
 
Perm upat 2012 - Part 2
Perm upat 2012 - Part 2Perm upat 2012 - Part 2
Perm upat 2012 - Part 2assorel
 
2011 07-11 - dia mundial da população - mónica lopes
2011 07-11 - dia mundial da população - mónica lopes 2011 07-11 - dia mundial da população - mónica lopes
2011 07-11 - dia mundial da população - mónica lopes O Ciclista
 
Newsletter juli dd consulting online assessment rev
Newsletter juli dd consulting online assessment revNewsletter juli dd consulting online assessment rev
Newsletter juli dd consulting online assessment revD&D Consulting
 
Linguagem de especialidade
Linguagem de especialidadeLinguagem de especialidade
Linguagem de especialidadeclaudia murta
 
Getting things done using Lotus Notes
Getting things done using Lotus NotesGetting things done using Lotus Notes
Getting things done using Lotus NotesSasja Beerendonk
 

Viewers also liked (7)

juegos pc parte1/7
juegos pc parte1/7juegos pc parte1/7
juegos pc parte1/7
 
Perm upat 2012 - Part 2
Perm upat 2012 - Part 2Perm upat 2012 - Part 2
Perm upat 2012 - Part 2
 
2011 07-11 - dia mundial da população - mónica lopes
2011 07-11 - dia mundial da população - mónica lopes 2011 07-11 - dia mundial da população - mónica lopes
2011 07-11 - dia mundial da população - mónica lopes
 
Katalogs 09 2012
Katalogs 09 2012Katalogs 09 2012
Katalogs 09 2012
 
Newsletter juli dd consulting online assessment rev
Newsletter juli dd consulting online assessment revNewsletter juli dd consulting online assessment rev
Newsletter juli dd consulting online assessment rev
 
Linguagem de especialidade
Linguagem de especialidadeLinguagem de especialidade
Linguagem de especialidade
 
Getting things done using Lotus Notes
Getting things done using Lotus NotesGetting things done using Lotus Notes
Getting things done using Lotus Notes
 

Similar to 第七章 图[1] (20)

109 p math300dpi
109 p math300dpi109 p math300dpi
109 p math300dpi
 
2005 amc 10
2005 amc 102005 amc 10
2005 amc 10
 
yon298y
yon298yyon298y
yon298y
 
第2讲 课件
第2讲  课件第2讲  课件
第2讲 课件
 
J100-12金門縣國中代理
J100-12金門縣國中代理J100-12金門縣國中代理
J100-12金門縣國中代理
 
香港六合彩
香港六合彩香港六合彩
香港六合彩
 
香港六合彩
香港六合彩香港六合彩
香港六合彩
 
disnaa
disnaadisnaa
disnaa
 
香港六合彩
香港六合彩香港六合彩
香港六合彩
 
J102-05南區聯盟試題
J102-05南區聯盟試題J102-05南區聯盟試題
J102-05南區聯盟試題
 
香港六合彩
香港六合彩香港六合彩
香港六合彩
 
香港六合彩另类
香港六合彩另类香港六合彩另类
香港六合彩另类
 
J101-05南區聯盟試題
J101-05南區聯盟試題J101-05南區聯盟試題
J101-05南區聯盟試題
 
2006 amc10
2006 amc102006 amc10
2006 amc10
 
15.5等腰三角形[听课]
15.5等腰三角形[听课]15.5等腰三角形[听课]
15.5等腰三角形[听课]
 
2 2有理數實數
2 2有理數實數2 2有理數實數
2 2有理數實數
 
104學測數學科考題
104學測數學科考題104學測數學科考題
104學測數學科考題
 
第7章 语法制导翻译和中间代码生成
第7章 语法制导翻译和中间代码生成第7章 语法制导翻译和中间代码生成
第7章 语法制导翻译和中间代码生成
 
108 p math150dpi
108 p math150dpi108 p math150dpi
108 p math150dpi
 
全年筆記F.5
全年筆記F.5全年筆記F.5
全年筆記F.5
 

More from Wang Yizhe

第六章 树和二叉树2
第六章 树和二叉树2第六章 树和二叉树2
第六章 树和二叉树2Wang Yizhe
 
第九章+查找[4]
第九章+查找[4]第九章+查找[4]
第九章+查找[4]Wang Yizhe
 
第九章 查找[3]
第九章 查找[3]第九章 查找[3]
第九章 查找[3]Wang Yizhe
 
第九章 查找[2]
第九章 查找[2]第九章 查找[2]
第九章 查找[2]Wang Yizhe
 
第九章 查找[1]
第九章 查找[1]第九章 查找[1]
第九章 查找[1]Wang Yizhe
 
第三章 栈和队列(新)
第三章 栈和队列(新)第三章 栈和队列(新)
第三章 栈和队列(新)Wang Yizhe
 
第三章 栈和队列
第三章 栈和队列第三章 栈和队列
第三章 栈和队列Wang Yizhe
 
第七章 图[4]1
第七章 图[4]1第七章 图[4]1
第七章 图[4]1Wang Yizhe
 
第七章 图[3]
第七章 图[3]第七章 图[3]
第七章 图[3]Wang Yizhe
 
数据结构 总结与复习
数据结构 总结与复习数据结构 总结与复习
数据结构 总结与复习Wang Yizhe
 
第四章 串操作应用举例
第四章 串操作应用举例第四章 串操作应用举例
第四章 串操作应用举例Wang Yizhe
 
第二章 线性表
第二章 线性表第二章 线性表
第二章 线性表Wang Yizhe
 

More from Wang Yizhe (14)

第四章 串
第四章 串第四章 串
第四章 串
 
第六章 树和二叉树2
第六章 树和二叉树2第六章 树和二叉树2
第六章 树和二叉树2
 
第六章1
第六章1第六章1
第六章1
 
第九章+查找[4]
第九章+查找[4]第九章+查找[4]
第九章+查找[4]
 
第九章 查找[3]
第九章 查找[3]第九章 查找[3]
第九章 查找[3]
 
第九章 查找[2]
第九章 查找[2]第九章 查找[2]
第九章 查找[2]
 
第九章 查找[1]
第九章 查找[1]第九章 查找[1]
第九章 查找[1]
 
第三章 栈和队列(新)
第三章 栈和队列(新)第三章 栈和队列(新)
第三章 栈和队列(新)
 
第三章 栈和队列
第三章 栈和队列第三章 栈和队列
第三章 栈和队列
 
第七章 图[4]1
第七章 图[4]1第七章 图[4]1
第七章 图[4]1
 
第七章 图[3]
第七章 图[3]第七章 图[3]
第七章 图[3]
 
数据结构 总结与复习
数据结构 总结与复习数据结构 总结与复习
数据结构 总结与复习
 
第四章 串操作应用举例
第四章 串操作应用举例第四章 串操作应用举例
第四章 串操作应用举例
 
第二章 线性表
第二章 线性表第二章 线性表
第二章 线性表
 

第七章 图[1]

  • 1. 第七章 图 7.1 抽象数据类型图的定义 7.2 图的存储表示 7.3 图的遍历
  • 2. 图的结构定义 : 图是由一个 顶点集 V(Vertex) 和 一个边 集 R 构成的数据结构。 Graph = (V , R ) 其中, R = {<v,w>| v,w∈ V 且 P(v,w)} <v,w> 表示从 v 到 w 的一条弧 (Arc) ,并称 v 为弧头 (Head) , w 为弧尾 (Tail) 。 V W
  • 3. 这里的弧为“ 有向边 ” 因此对应图为 有向图 (Digraph) 。 例如 : G1 = (V1, E1) 其中 A V1={A, B, C, D, E} B E E1={<A,B>, <A,E>, C D <B,C>, <C,D>, <D,B>, <D,A>, <E,C> }
  • 4. 若 <v, w>∈E, 必有 <w, v>∈E, 则称 (v,w) 为顶点 v 和顶点 w 之间存在一 条边 Edge. 无方向的边构成无向图 (Undigraph). 例如 : G2=(V2,VR2) B C V2={A, B, C, D, E, F} A D VR2={(A,B), (A,E), (B,E), (C,D), (D,F), F E (B,F), (C,F) }
  • 6. 15 A 9 弧或边带权 11 B 7 21 E Weight 的图分别称 3 作有向网或无向网 C 2 F Network 。 B B 设图 G=(V,{VR}) 和 C 图 G′=(V′,{VR′}), A 且 V′⊆V, VR′⊆VR, 则称 G′ 为 G 的 B E 子图。 C F
  • 7. 假设图中有 n 个顶点, e 条边,则 含有 e=n(n-1)/2 条边的无向图称 作完全图; 含有 e=n(n-1) 条弧的有向图称 作 有向完全图 ; 若边或弧的个数 e<nlogn ,则称作稀疏图 Spares Graph ,否则称作稠密图 Dense Graph 。
  • 8. 假若顶点 v 和顶点 w 之间存在一条 边, 边 则称顶点 v 和 w 互为 邻接点 (v,w) 和顶点 v 和 w 相关联。 (Adjacent) , 和顶点 v 关联的边的数目定义为顶点 v 的度 例如 B C : ID(B) = 3 D A ID(A) = 2 F E
  • 9. 对有向图, A 顶点的出度 Outdegree: B E 以顶点 v 为弧尾的弧 C F 的数目; Indegree: 顶点的入度 例如 以顶点 v 为弧头的弧 : OD(B) = 1 的数目。 ID(B) = 2 顶点的度 ( TD) = 出度 ( OD) + 入度 ( ID) TD(B) = 3
  • 10. 设图 G=(V,{VR}) 中的一个顶点序列 { u=vi,0,vi,1, …, vi,m=w} 中, (vi,j-1,vi,j)∈VR 1≤j≤m, 则称从顶点 u 到顶点 w 之间存在一条路径 Path 。 路径上边的数目称作路径长度。 如 : 长度为 3 的路径 {A,B,C,F} 简单路径 : 序列中顶点 不重复出现的路径。 A 简单回路 Cycle: 序列中 B E 第一个顶点和最后一 个顶点相同的路径。 C F
  • 11. B C 若图 G 中任意两个顶 点之间都有路径相通 ,则称此图为连通图 A D ; B C F E 若无向图为非连通图 A D ,则图中各个极大连 通子图称作此图的连 F E 通分量。
  • 12. 对有向图, 若任意两个顶点之间 都存在一条有向路径,则称此有向图为 强连通图。 否则,其各个强连通子图 称作它的强连通分量。 A A B E B E C F C F
  • 13. 假设一个连通图有 n 个顶点和 e 条边 ,其中 n-1 条边和 n 个顶点构成一个极小 连通子图,称该极小连通子图为此连通图 的生成树 Spanning Tree 。 C 对非连通图,则 B 称由各个连通分 量的生成树的集 A D 合为此非连通图 的生成森林。 F E
  • 14. 图的抽象数据结构 ADT Graph{ 数据对象 V: V 是具有相同特性的数据 元素的集合 , 即顶点集 . 数据关系 : R = {VR} VR = {<v,w>|v,w∈V 且 P(v,w) <v,w> 表示从 v 到 w 的弧 ,P(v,w) 定义了 弧 <v,w> 的意义或信息 }
  • 15. 基本操 作 结构的建立和销毁 对顶点的访问操作 插入或删除顶点 插入和删除弧 对邻接点的操作 遍历
  • 16. 结构的建立和销 毁 CreatGraph(&G, V, VR): // 按定义 (V, VR) 构造图 DestroyGraph(&G): // 销毁图
  • 17. 对顶点的访问操作 LocateVex(G, u); // 若 G 中存在顶点 u ,则返回该顶点 在 // 图中 “ 位置 ” ;否则返回其它信息。 GetVex(G, v); // 返回 v 的值。 PutVex(&G, v, value); // 对 v 赋值 value 。
  • 18. 对邻接点的操作 FirstAdjVex(G, v); // 返回 v 的 “ 第一个邻接点” 。若该顶 点 // 在 G 中没有邻接点,则返回 “ 空 ” 。 A 若 v=‘A’ B E 则 C F irstAdjVex(G, v) 返回‘ B’
  • 19. 对邻接点的操作 NextAdjVex(G, v, w); // 返回 v 的(相对于 w 的) “ 下一个 邻接 // 点” 。若 w 是 v 的最后一个邻接点 v ,则 A // 返回 “ 空 ” 。 w B E NextAdjVex(G,v,w ) C F
  • 20. 插入或删除顶点 InsertVex(&G, v); // 在图 G 中增添新顶点 v 。 DeleteVex(&G, v); // 删除 G 中顶点 v 及其相关的弧。
  • 21. 插入和删除弧 InsertArc(&G, v, w); // 在 G 中增添弧 <v,w> ,若 G 是无向 的, // 则还增添对称弧 <w,v> 。 DeleteArc(&G, v, w); // 在 G 中删除弧 <v,w> ,若 G 是无向 的, // 则还删除对称弧 <w,v> 。
  • 22. 历 DFSTraverse(G, v, Visit()); // 从顶点 v 起深度优先遍历图 G ,并对每 // 个顶点调用函数 Visit 一次且仅一次。 BFSTraverse(G, v, Visit()); // 从顶点 v 起广度优先遍历图 G ,并对每 // 个顶点调用函数 Visit 一次且仅一次。
  • 23. 7.2 图的存储表示 一、图的数组 ( 邻接矩阵 ) 存储表示 二、图的邻接表存储表示 三、有向图的十字链表存储表示 四、无向图的邻接多重表存储表示
  • 24. 图的数组 ( 邻接矩阵 ) 存储 表示 图由于结构复杂 , 无法以数据 元素在存储区中的物理位置来表示元素 之间的关系 , 即图没有顺序映像的存储 结构 , 但可借助数组的数据类型表示元 素之间的关系 .
  • 25. 一、邻接矩阵 0 (i,j)∉VR 定义 : 矩阵的元素为 Aij= { 1 (i,j)∈VR A B C D E F B C A 0 1 0 0 1 0 B 1 0 0 0 1 1 C A D 0 0 0 1 0 1 D 0 0 1 0 0 1 E F E 1 1 0 0 0 0 F 0 1 1 1 0 0 无向图的邻接矩阵为对称矩阵
  • 26. A B C D E A A 0 1 0 1 0 B 0 0 1 0 0 B D C 0 0 0 0 1 D C E 0 0 1 0 0 E 1 1 0 0 0 有向图的邻接矩阵为非对称矩阵
  • 27. 邻接矩阵表示法特点 : 1 )无向图邻接矩阵是对称矩阵,同一条 边表示了两次; 2 )顶点 v 的度: 无向图中等于二维数组对应行(或列)中 1 的个数; 有向图中 , 统计第 i 行 1 的个数可得顶 点 i 的出度 ,统计第 j 列 1 的个数可 得顶点 j 的入度。
  • 28. 邻接矩阵表示法特点 : 3 )判断两顶点 v 、 u 是否为邻接点:只需 判二维数组对应分量是否为 1 ; 4 )顶点不变,在图中增加、删除边:只需 对二维数组对应分量赋值 1 或清 0 ; A B C D E A 0 1 0 1 0 A B 0 0 1 0 0 C 0 1 0 0 0 1 B D D 0 0 1 0 0 C E E 1 1 0 0 0
  • 29. 邻接矩阵表示法特点 : 5 )设存储顶点的一维数组大小为 n, 则 G 占用存储空间: n+n2 ; G 占 用存储空间只与它的顶点数有关, 与边数无关;适用于边稠密的图;
  • 30. typedef struct ArcCell { // 弧的定义 VRType adj; // VRType 是顶点关系类 型 // 对无权 图,用 1 或 0 表示相邻否; // 对带权图,则为权值类型。 InfoType *info; // 该弧相关信息的指针 } ArcCell, AdjMatrix[MAX_VERTEX_NUM] [MAX_VERTEX_NUM];
  • 31. typedef struct { // 图的定义 VertexType // 顶点信息 vexs[MAX_VERTEX_NUM]; AdjMatrix arcs; // 弧的信息 int vexnum, arcnum; // 顶点数,弧 数 GraphKind kind; // 图的种类标志
  • 32. 网络的邻接矩阵 W (i , j ), 若i ≠ j且 < i, j >∈ E或(i, j ) ∈ E  A.edge[i ][ j ] = ∞, 若i ≠ j且 < i, j >∉ E或(i, j ) ∉ E 0, 若i == j  0 15 ∞ 9 ∞  15 A 9 ∞ 0 3 ∞ ∞  11   A.edge =∞ ∞ 0 ∞ 2   B 7 21 D   3 ∞ ∞ 21 0 ∞  C E 11 7 ∞ ∞ 0    2
  • 33. 图的链表表示 l 图的复杂结构使我们考虑用多重链表 . 多重链表 由一个数据域和多个指针域组成的结点表示图中 的一个顶点 , 其中数据域存储顶点的信息 , 指针 域指向其邻接结 . 点但图的结点度数的不一致性 , 可能会导致空间浪费或操作不便 . 实际应用中 , 通常是根据具体的图和需要进行操作 , 设计恰 当的结点结构和表结构 . l 常用的有邻接表 Adjacentcy List , 邻接多重表 Adjacency Multilist 和十字链表 Orthogonal List 等 结构表示 .
  • 34. 1 2 二、图的邻接表存储表 B C 示 0 3 A D 0 A 1 4 1 B 0 4 5 E 4 5 F 2 C 3 5 同一个顶点发出的边 3 D 2 5 链接在同一个边链表中 ,每一个链结点代表一 4 E 0 1 条边 ( 边结点 ), 结点中有 5 F 1 2 3 另一顶点的下标 adjvex 和指针 nextedge 。
  • 35. 有向图的邻接 表 A 0 A 1 4∧ B E 1 B 2∧ C D 2 C 3∧ 在有向图的邻接表 3 D 0 1∧ 中 , 不易找到指向 4 E 2∧ 该顶点的弧。
  • 36. A 有向图的逆邻接 B E 表 在有向图的邻接 C D 表中,对每个顶 0 A 3 ∧ 点,链接的是指 3 0 ∧ 1 B 向该顶点的弧。 2 C 4 ∧ 3 D 2 ∧ 4 E 0 ∧
  • 37. 弧的结点结 adjvex nextarc info 构 typedef struct ArcNode { int adjvex; // 该弧所指向的顶点的位置 struct ArcNode *nextarc; // 指向下一条弧的指针 InfoType *info; // 存储和弧相关的信息 , 如权 值 } ArcNode;
  • 38. 顶点的结点结 data firstarc 构 typedef struct VNode { VertexType data; // 顶点信息 ArcNode *firstarc; // 指向第一条依附该顶点的弧 } VNode, AdjList[MAX_VERTEX_NUM];
  • 39. 图的结构定义 typedef struct { AdjList vertices; // 顶点列表 int vexnum, arcnum; // 顶点数和弧数 int kind; // 图的种类标志 } ALGraph;
  • 40. 邻接表表示法特点: 1 )对于无向图 |V|=n,|E|=e. 其邻接表需 要 n 个头结点和 2e 条边 . 2 )顶点 vi 的度:在无向图中等于第 i 个链表中的结点数;在有向图邻接表 中 , 第 i 行的结点数等于顶点 i 的出度 ,在有向图逆邻接表中 , 第 i 行的结 点数等于顶点 i 的入度。
  • 41. 邻接表表示法特点: 3 )在邻接表上容易找到任一顶点的第 一个邻接点和下一个邻接点 . 如要判 定任意两个顶点是否相连 , 需搜寻第 i 个或第 j 个链表 . 4 )设存储顶点的一维数组大小为 n( 顶点数 n), G 占用存储空间: n+e ; G 占用存储空间与它的顶点数 和边数有关;适用于边稀疏的图;
  • 42. 三、有向图的十字链表存储表 示 有向图的十字链表 Orthogonal List 是一种将有向图的邻接表和逆 邻接表结合起来得到的一种链表 . 每条弧对应一个弧结点 , 每个 顶点对应一个顶点结点 .
  • 43. 弧的结点结 构 弧尾顶点位置 弧头顶点位置 弧的 相关信息 指向下一个 指向下一个 有相同弧尾 有相同弧头 的结点 的结点 typedef struct ArcBox { // 弧的结构表示 int tailvex, headvex; InfoType *info; struct ArcBox *hlink, *tlink; } VexNode;
  • 44. 顶点的结点结 构 顶点信息数据 指向该顶点的 指向该顶点的 第一条入弧 第一条出弧 typedef struct VexNode { // 顶点的结构表示 VertexType data; ArcBox *firstin, *firstout; } VexNode;
  • 45. 有向图的结构表示 ( 十字链表 ) typedef struct { VexNode xlist[MAX_VERTEX_NUM]; // 顶点结点 ( 表头向量 ) int vexnum, arcnum; // 有向图的当前顶点数和弧数 } OLGraph;
  • 46. 0 1 A B 2 C D 3 0A 0 1 0 2 1 B 2C 2 0 2 3 3D 3 0 3 1 3 2
  • 47. 建立有向图的十字链表算法 输入 n 个顶点和 e 条弧的信息 , 构 建有向图的十字链表 . Status CreateDG(OLGraph &G) // 采用十字链表 , 构造有向图 G ( G . kind =D G ) { scanf(&G.vexnum,&G.arcnum,&IncInfo); // 读入图的顶点数和边数及相关信息 for(i=0;i<G.vexnum;++i){ // 构造表头信息 scanf(&G.xlist[i].data); // 输入顶点数据 G.xlist[i].firstin = NULL; G.xlist[i].firstout = NULL; // 指针初始化 } ...
  • 48. 建立有向图的十字链表算法 For (k=0; k<G.arcnum;++k) { // 输入各弧构造十字链 表 scanf(&v1,&v2); // 输入一条弧的起点和终点 i = LocateVex(G,v1); j= LocateVex(G,v2) ; // 确定 v1 和 v2 在 G 中的位置 p=(ArcBox*)malloc(sizeof(ArcBox)); *p={i,j,xlist[j].firstin,G.xlist[i].firstout,NULL}; // 对弧点赋值 G.xlist[j].firstin = G.xlist[i].firstout = p; // 完成在如弧和出弧链头的插入 if(IncInfo) Input(*p->infor); // 若弧含有相关信息 , 则 输入 }} //CreateDG
  • 49. 建立有向图的十字链表算法 l 在建立邻接表或逆邻接表时 , 若输入 的顶点信息即为顶点的编号 , 则时间复 杂度为 O ( n+e ) . 否则要先查找顶点 , 确 定其在图中的位置 , 此时的时间复杂度 为 O ( n* e ) .
  • 50. 四 . 无向图的邻接多重表存储 表示 邻接表中每一条边 (vi,vj) 有两 个结点 , 分别在第 i 个和第 j 个链表中 . 给在面向边的操作中带来不便 , 因为需 要找到表示同一条边的两个结点 . 因此 , 这种情况下往往采用邻接多重表来存储 图的信息 .
  • 51. 边的结构 mark ivex ilink jvex jlink info typedef struct Ebox { VisitIf mark; // 访问标记 int ivex, jvex; // 该边依附的两个顶点的位 置 struct EBox *ilink, *jlink; // 分别指向依附这两个顶点的下一 条边
  • 52. 顶点的结构表示 data firstedge typedef struct VexBox { VertexType data; EBox *firstedge; // 指向第一条依附该顶点的边 } VexBox; 无向图的结构表示 typedef struct { // 邻接多重表 VexBox adjmulist[MAX_VERTEX_NUM]; int vexnum, edgenum; } AMLGraph;
  • 53. 0A B 1 2C 3 D E 4 0 A 0 1 0 3 1 B 2 C 2 1 2 3 3 D 4 E 4 1 2 4