数据结构——图基础

一、图概述

对图的描述有两个参数:点个数(vertex)与边数(edge)。若两节点间有边将二者相连,则称两点邻接(adjacency),点与该边成为关联(incidence)。
图又分为有向图和无向图,若一张图中每条边都具有方向,则该图为有向图 ,否则是无向图。
在这里插入图片描述

二、路径

1.简单路径

将每个节点均遍历一次的路径为简单路径:
在这里插入图片描述

2.简单环路

依次遍历每个节点并最终回到初始位置的路径为简单回路
在这里插入图片描述

3.欧拉环路

可经过每条边各一次的回路

4.汉密尔顿回路

可经过每个节点各一次的回路

三、图的表示方法

1.邻接矩阵

以矩阵形式表示各个顶点的连接关系。
若该图有n个节点,则生成n行n列矩阵,i行j列用0/1表示节点i与j是否有邻接关系。
在这里插入图片描述

2.关联矩阵

一个有n个节点与e条边组成的图可由n行e列矩阵表示。若一个节点与一条边有关联关系,则该隔填入1,否则为0。不难得出,关联矩阵中,没列有且仅有两个1。
在这里插入图片描述

三、实现方法

1.相邻矩阵的表示

n个n维向量组成邻接矩阵,用上述方法表示完整的图。
在这里插入图片描述

2.相邻顶点查找

查找相邻顶点时,只需搜索该顶点所在行中下一个‘1’所在的位置即可。

int nextNbr(int i, int j)
{
	while ((-1 < j) && !exists(i, --j));  //寻找下一个相邻节点
	return j;  //返回该节点
}

3.边查找

判断边(i, j)是否存在

bool exists(int i, int j)
{
	return (0 <= i) && (i < n) && (0 <= j) && (j < n) && E[i][j] != NULL;
}

4.边插入

在点 i, j间插入边 w

void insert(Te const & edge, int i, int j)
{
	if(exists(i, j)  //判断是否存在
		return;
	E[i][j] = new Edge<Te>(edge, w);  //插入边
	//更新图中原有信息
	e++;  //更新边数
	v[i].outDegree++;
	v[j].inDegree++;
}

3.边删除

该操作与边插入相似

4.顶点添加

在图中添加顶点较为麻烦,需为每个行向量增添一列,并在结尾处增加一个行向量。延长所有向量后,令新增所有边为空。

int insert(Tv const & vertex)
{
	for(int j = 0; j < n; j++)
		E[j].insert(NULL);
	n++;
	E.insert(Vector<Edge<Te>* >(n, n, NULL) );
	return V.insert(Vertex<Tv>(vertex) );
}

5.顶点删除

顶点删除与新增顶点互为逆过程,代码也较为相似。需注意的是处理顶点时需注意边的关系。

四、图的遍历

最基础的图遍历方式有两种,及深度优先遍历与广度优先遍历。具体遍历方法详见博文:图的搜索

发布了35 篇原创文章 · 获赞 18 · 访问量 6803

猜你喜欢

转载自blog.csdn.net/acslsr/article/details/104822838