【图】图的邻接矩阵存储和广度、深度优先遍历

本文介绍了一种使用C语言实现无向图的数据结构,并通过广度优先搜索(BFS)和深度优先搜索(DFS)来遍历图的方法。文章提供了一个具体的例子,包括创建图、进行遍历的过程及其实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

示例:建立如图所示的无向图


由上图知,该图有5个顶点,分别为a,b,c,d,e,有6条边.
示例输入(按照这个格式输入):
5
6
abcde
0 1 1
0 2 1
0 3 1
2 3 1
2 4 1
1 4 1
输入结束(此行不必输入)
注:0 1 1表示该图的第0个顶点和第1个定点有边相连,如上图中的a->b所示
      0 2 1表示该图的第0个顶点和第2个定点有边相连,如上图中的a->c所示
      2 3 1表示该图的第2个顶点和第3个定点有边相连,如上图中的c->d所示


#include <stdio.h>
#define MAX_GRAPH 100
#define MAX_QUEUE 30

typedef struct
{
	char vex[MAX_GRAPH]; /* 顶点 */ 
	int edge[MAX_GRAPH][MAX_GRAPH]; /* 邻接矩阵 */
	int n; /* 当前的顶点数 */
	int e; /* 当前的边数 */
}GRAPH;

void Create(GRAPH *G); /* 图的邻接矩阵表示法 */
void BFS(GRAPH *G,int k); /* 广度优先遍历 */ 
void DFS(GRAPH *G,int k); /*  深度优先遍历 */

int visited[MAX_GRAPH];

int main(int argc, char *argv[])
{
	int i;
	for(i = 0 ; i < MAX_QUEUE ; ++i)
		visited[i] = 0;

	GRAPH G;
	Create(&G);
 
/*	BFS(&G,0);*/
	DFS(&G,0);
		
	return 0;
}

void BFS(GRAPH *G,int k)
{
	int queue[MAX_QUEUE]; /* 队列 */
	int front = -1,rear = -1,amount = 0;
	int visited[MAX_GRAPH]; /* 标记已经访问过的元素 */
	int i,j;
	
	for(i = 0 ; i < MAX_GRAPH ; ++i)
		visited[i] = 0;
		
	printf("访问顶点%c\n",G->vex[k]);
	visited[k] = 1;
	
	rear = (rear + 1) % MAX_QUEUE; /* 入队操作 */
	queue[rear] = k;
	front = rear;
	++amount;
	
	while(amount > 0)
	{
		i = queue[front]; /* 出队操作 */
		front = (front + 1) % MAX_QUEUE;
		--amount;
		
		for(j = 0 ; j < G->n ; ++j)
		{
			if(G->edge[i][j] != 0 && visited[j] == 0)
			{
				printf("访问顶点%c\n",G->vex[j]);
				visited[j] = 1;
				
				rear = (rear + 1) % MAX_QUEUE; /* 入队 */
				queue[rear] = j;
				++amount;
			}
		}
	}
	printf("遍历结束\n");	
}

void DFS(GRAPH *G,int k)
{
	int j;
	printf("访问顶点:%c\n",G->vex[k]);
	visited[k] = 1;
	
	for(j = 0 ; j < G->n ; ++j)
	{
		if(G->edge[k][j] != 0 && visited[j] == 0)
			DFS(G,j);
	}
}

void Create(GRAPH *G)
{
	printf("输入顶点数:\n");
	scanf("%d",&G->n);
	printf("输入边数:\n");
	scanf("%d",&G->e);
	
	getchar();
	
	int i,j,k,w;
	printf("请输入端点(char型):\n");
	for(i = 0 ; i < G->n ; ++i) /* 建立表头 */
		scanf("%c",&G->vex[i]);
		
	for(i = 0 ; i < G->n ; ++i) /* 初始化邻接矩阵 */
		for(j = 0 ; j < G->n ; ++j)
			G->edge[i][j] = 0;
	
	printf("请输入边:\n");	
	for(k = 0 ; k < G->e ; ++k)
	{
		scanf("%d%d%d",&i,&j,&w); /* 输入(vi,vj)上的权w */
		G->edge[i][j] = w;
		G->edge[j][i] = w;
	}
	
}



### 回答1: 建立无向邻接矩阵存储,可以使用一个二维数组来表示。其中,数组的行列分别表示中的节点,而数组中的元素则表示节点之间的连通关系。如果节点i节点j之间有连通关系,则邻接矩阵中第i行第j列的元素为1;否则为。 深度优先遍历是一种递归的遍历方式,它从中的某个节点开始,沿着一条路径一直走到底,直到不能再走为止,然后回溯到上一个节点,再选择另外一条路径继续遍历,直到遍历完整个广度优先遍历则是一种迭代的遍历方式,它从中的某个节点开始,先访问该节点,然后依次访问该节点的所有邻居节点,再依次访问邻居节点的邻居节点,直到遍历完整个。在广度优先遍历中,需要使用一个队列来存储待访问的节点,以便按照先进先出的顺序进行遍历。 ### 回答2: 建立无向邻接矩阵指的是将顶点按一定方式编号,然后将边转化为矩阵中的元素。如果两个顶点之间存在一条边,则在对应矩阵元素的位置上标记为1;否则标记为0。建立好邻接矩阵后,我们可以进行深度优先遍历广度优先遍历。 深度优先遍历:从任一顶点开始,按照某种规则(例如编号增序)依次访问相邻的顶点,并继续向下遍历直到无法继续为止,然后返回上一个顶点继续遍历,直至所有顶点都被访问过为止。在用邻接矩阵存储的无向上,深度优先遍历的过程可以通过递归实现,具体步骤如下: 1. 从某个顶点v开始访问,我们先将v标记为已访问; 2. 根据邻接矩阵中v所在的行,遍历所有边相连的顶点; 3. 对于每个相邻的顶点,如果它没有被访问过,则递归访问它; 4. 重复步骤2-3,直到所有与v相邻的顶点都被访问过。 广度优先遍历:从任一顶点开始,按照某种规则(例如编号增序)依次访问相邻的顶点,然后再依次访问这些相邻顶点相邻的顶点,直至所有顶点都被访问过为止。在用邻接矩阵存储的无向上,广度优先遍历的过程可以通过队列实现,具体步骤如下: 1. 从某个顶点v开始访问,我们先将v标记为已访问,并将v入队; 2. 当队列不为空时,取出队头元素u,根据邻接矩阵中u所在的行,遍历所有边相连的顶点; 3. 对于每个相邻的顶点,如果它没有被访问过,则标记为已访问并入队; 4. 重复步骤2-3,直到队列为空。 在实际编码中,我们可以将邻接矩阵存储成一个二维数组(如array[i][j]表示顶点i顶点j之间是否存在边),然后编写深度优先遍历广度优先遍历的函数。需要注意的是,在状态判断中,我们需要记录每个顶点是否已被遍历过。 ### 回答3: 无向邻接矩阵存储是一种常见的存储结构。它将每个顶点作为矩阵的一行一列,矩阵中的值表示两个顶点之间的边。对于无向邻接矩阵是对称的,因为每个边都有相反的方向。如果顶点ij之间有一条边,则矩阵中的第i行第j列第j行第i列的值将被设置为1。如果两个顶点之间没有边,则矩阵中的值将为0。 邻接矩阵是用于实现深度优先遍历广度优先遍历的非常方便的数据结构。在深度优先遍历(DFS)中,我们从任意起始点开始遍历,不断深入直到不能再深入为止。我们通过维护一个栈标记每个节点被访问的状态来实现该算法。在使用邻接矩阵实现时,我们在矩阵中搜索与当前顶点相邻的顶点,将它们加入栈中,然后重复该过程,直到没有更多未访问的节点。 在广度优先遍历(BFS)中,我们从任意起始点开始遍历,逐层遍历直到所有可达节点都被访问。我们通过维护一个队列标记每个节点被访问的状态来实现该算法。在使用邻接矩阵实现时,我们在矩阵中搜索与当前顶点相邻的顶点,将它们加入队列中,然后处理队列中的下一个节点,重复该过程直到队列为空。 综上所述,使用邻接矩阵实现深度优先遍历广度优先遍历是一种方便且有效的方法,特别是对于小型无向。但是,在大型无向中,邻接矩阵可能会占用大量内存,导致效率降低。因此,在这种情况下,邻接表或其他更高级的数据结构可能更适合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值