数据结构---图


一、图的定义和基本术语

图的基本定义

图(Graph)是由顶点的有穷非空集合和顶点之间的边组成,通常表示为:G(V,E),其中,G 表示一个图,V 是图 G 中顶点的集合,E 是图 G 中边的集合。

1.线性表中将数据元素叫元素,树中将数据元素叫结点,在图中数据元素称之为顶点(Vertex)。
2.顶点集合 V 有穷非空。
3.图中,任意两个顶点之间都可能有关系,顶点之间的逻辑关系用边来表示,边集可以是空的。

图的基本术语

无向边: 若顶点 vi 到 vj 之间的边没有方向,则称这条边为无向边(Edge),用无序偶对(vi,vj)来表示。 如果图中任意两个顶点之间的边都是无向边,则称该图为无向图。
在这里插入图片描述
无向完全图:在无向图中,如果任意两个顶点之间都存在边,则称该图为无向完全图。
在这里插入图片描述
有向边:若顶点 vi 到 vj 之间的边有方向,则称这条边为有向边,也称为弧(Arc),用有序偶对 <vi,vj> 来表示。
在这里插入图片描述
有向完全图:在有向图中,如果任意两个顶点之间都存在方向互为相反的两条弧,则称该图为有向完全图。
在这里插入图片描述

简单图:在图中,若不存在顶点到此结点自身的边,且同一条边不重复出现,则称这样的图为简单图。
稀疏图和稠密图:有很少条边的图称为稀疏图,反之称为稠密图。这里的稀疏和稠密是模糊的概念,都是相对而言的。
权和网:有些图的边或弧具有与它相关的数字,这种与图的边或弧相关的数叫做权(Weight)。这些权可以表示从一个顶点到另一个顶点的距离或耗费。这种带权的图通常称为网(Network)。
回路和环:第一个顶点和最后一个顶点相同的路径称为回路或环
连通,连通图和连通分量:在无向图 G 中,如果顶点 v 到顶点 v’ 有路径,则称 v 和 v’ 是连通的。如果对于图中任意两个顶点 vi、vj ∈ V,vi 和 vj 都是连通的,则称 G 是连通图(Connected Graph)。无向图中的极大连通子图称为连通分量。
注意连通分量的概念,他强调:
1、要是无向图的子图;
2、子图要是连通的;
3、连通子图含有极大顶点数;
4、具有极大顶点数的连通子图包含依附于这些顶点的所有边。
例如,下图(1)不是连通图,而图(2)和(3)是图(1)的两个连通分量。
在这里插入图片描述

强连通图和强连通分量:在有向图 G 中,如果对于每一对 vi、vj ∈ V,vi ≠ vj ,从 vi 到 vj 和从 vj 到 vi 都存在路径,则称 G 是强连通图有向图中的极大强连通子图称为强连通分量

例如,下图(a)并不是强连通图,因为顶点 b 到顶点 a 路径不存在。图(b)和单独一个b顶点就是是图(a)的强连通分量。

在这里插入图片描述

连通图的生成树:连通图的生成树是一个极小的连通子图,它含有图中全部的 n 个顶点,但只有足以构成一棵树的 n-1 条边。
如下图2就是图1的生成树
在这里插入图片描述
有向树和生成森林:如果一个有向图恰有一个顶点的入度为 0,其余顶点的入度均为 1,则是一颗有向树。一个有向图的生成森林由若干颗有向树组成,含有图中全部顶点,但只有足以构成若干颗不相交的有向树的弧。

二、图的存储结构

邻接矩阵

图的邻接矩阵(Adjacency Matrix)存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组(称为邻接矩阵)存储图中的边或弧的信息。
在这里插入图片描述
类型定义

#define maxint 32767//表示最大值,即无穷
#define maxsize 100//表示最大顶点数
typedef struct {
   
	char vexs[maxsize];//顶点数据类型为字符型
	int arcs[maxsize][maxsize];//边的权值类型为整型
	int vexnum, arcnum;//图的顶点数和边数
}AMGraph;

采用邻接矩阵法构建无向图(存在伪代码)

void createUND(AMGraph& g) {
   
	cin >> g.vexnum >> g.arcnum;
	for (int i = 0; i < g.vexnum; i++)//输入顶点信息
		cin >> g.vexs[i];
	for (int i = 0; i < g.vexnum; i++)//边初始化
		for (int j = 0; j < g.vexnum; j++)
			g.arcs[i][j] = maxint;
	for (int k = 0; k < g.arcnum; k++) {
   
		cin >> v1 >> v2 >> w;//输入两个顶点和边的权值
		i = locatevex(g, v1), j = locatevex(g, v2);//找出两个顶点在g中的位置
		g.arcs[i][j] =g.arcs[j][i]= w;
	}
}

时间复杂度为O(n^2)
若要构建有向图,只需初始化邻接矩阵时,将边的权值均初始化为0,稍加修改即可

邻接矩阵的优缺点
优点:
1.便于判断两个顶点之间是否有边,根据arcs[i][j]来判断即可
2.便于计算各个顶点的度。对于无向图,邻接矩阵第i行元素之和就是顶点i的度;对于有向图,第i行就是该元素的出度,第i列就是该元素的入度。
缺点:
1.不便于增加和删除顶点
2.不便于统计边的数目。需要扫描邻接矩阵所有元素才能统计完毕,时间复杂度为O(n^2)
3.空间复杂度高

邻接表

邻接表(Adjacency List)是图的一种链式存储方法;在邻接表中对于图 G 中的每个顶点 vi 建立一个单链表,把与vi相邻的顶点放在这个链表中。邻接表中每个单链表的第一个结点存放有关顶点的信息,把这一结点看成链表的表头,其余结点存放有关边的信息,这样邻接表就由两部分组成:表头结点表和边表。
表头结点表:由所有表头结点以顺序结构形式存储,以便可以随机访问任何一个顶点的边链表。表头结点包括数据域和链域两部分。
边表:边链表包括邻接点域(adjvex)和数据域和链域三个部分;邻接点域存储与顶点vi邻接的点在图中的位置;数据域存储和边相关的信息,如权值等;链域存储与顶点vi邻接的下一个结点;
在这里插入图片描述
在这里插入图片描述
类型定义

#define maxsize 100//表示最大顶点数
typedef struct ArcNode {
   
	int adjvex;//该边所指的顶点位置
	struct ArcNode* nextarc;//指向下一条边的指针
	int info;//和边相关的信息
};
typedef struct VNode{
   
	char data;//顶点信息
	ArcNode* firstarc;//指向第一条依附该顶点的边的指针
}VNode,AdjList[maxsize];
typedef struct {
   
	AdjList vertices;
	int vexnum, arcnum;//图的顶点数和边数
}ALGraph;

采用邻接表创建无向图

void createUDG(ALGraph& g
  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值