图的深度、广度优先搜索遍历

存储方式:
邻接矩阵:表示顶点之间相邻关系的矩阵,是顺序存储结构。
采用两个数组分别来存储图的顶点和边的信息。其中,用一个一维数组来存储顶点信息,一个二维数组来存储边的信息。

深度优先搜索遍历(DFS):
类似于树的先序遍历,尽可能先对纵深方向进行搜索。
基本思想:

  1. 从图中某个顶点 i 出发,访问此顶点
  2. 依次从 i 的各个未被访问的邻接点出发深度优先遍历图
  3. 直至图中所有和 i 路径相通的顶点都被访问到

广度优先搜索遍历(BFS):
类似于树的按层次遍历。
其本思想:

  1. 从图中的某个顶点 i 出发
  2. 在访问此顶点之后依次访问 i 的所有未被访问的邻接点
  3. 按这些邻接点被访问的先后顺序依次访问它们的邻接点
  4. 直至图中所有和 i 有路径相通的顶点都被访问到

利用邻接矩阵存储图,分别采用图的深度优先搜索和广度优先搜索遍历该图,并输出遍历结果

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define MAXVEX 20 //最大顶点个数
#define INFINITY 65535//表示极大值无穷

int visited[MAXVEX] = { 0 };//访问标记数组初始化(DFS,BFS)

typedef struct
{
	char vexs[MAXVEX];//顶点信息
	int arc[MAXVEX][MAXVEX];//边信息
	int vexnum, arcnum;//图中当前的顶点数目,边数目
}AdjMatrix;//邻接矩阵

//用邻接矩阵创建图
void Creat(AdjMatrix* g)
{
	int i, j, k, w,t;
	//t为1~4,分别表示无向图、有向图、带权无向图、带权有向图
	printf("请输入顶点数,边数和t(中间用空格):");
	scanf("%d %d %d", &(g->vexnum), &(g->arcnum), &t);
	printf("\n");
	for (i = 1; i <= g->vexnum; i++)
	{
		getchar();
		printf("请输入第%d个顶点信息vexs[%d]=", i, i);
		scanf("%c", &(g->vexs[i]));
	}
	printf("\n");
	for (i = 1; i <= g->vexnum; i++)//给图初始化
	{
		for (j = 1; j <= g->vexnum; j++)
			if (t > 2)//为带权图
				g->arc[i][j] = INFINITY;
			else//不带权
				g->arc[i][j] = 0;
	}
	for (k = 1; k <= g->arcnum; k++)
	{
		printf("请输入边信息i j(中间用空格):");
		scanf("%d %d", &i, &j);
		if (i > g->vexnum || j > g->vexnum)
			exit(0);
		if (t > 2)//为带权图
		{
			printf("请输入权值w:");
			scanf("%d", &w);
			g->arc[i][j] = w;
			if (t == 3)//为带权无向图
				g->arc[j][i] = w;
		}
		else//为不带权图
		{
			g->arc[i][j] = 1;
			if (t == 1)//为无向图
				g->arc[j][i] = 1;
		}
	}
	printf("\n");
	printf("输出邻接矩阵:\n");
	for (i = 1; i <= g->vexnum; i++)
	{
		for (j = 1; j <= g->vexnum; j++)
		{
			printf("%8d", g->arc[i][j]);
			if (t > 2 && g->arc[i][j] == 65535)//带权图权值为无穷
				g->arc[i][j] = 0;//没关系
			else if (t > 2 && g->arc[i][j] != 65535)
				g->arc[i][j] = 1;//有关系
		}
		printf("\n");
	}
}

//深度优先搜索遍历连通子图(递归)
void DFS(AdjMatrix g, int i)
{
	//从i出发
	int j;
	printf("%d->", i);//输出访问顶点
	visited[i] = 1;//全局数组访问标志置1表示已经访问
	for (j = 1; j <= g.vexnum; j++)
		if ((g.arc[i][j] == 1) && (!visited[j]))//边有关系且没有被访问
			DFS(g, j);
}
//广度优先搜索遍历连通子图(队列保存已访问过顶点)
void BFS(AdjMatrix g, int i)
{
	int visited[MAXVEX] = { 0 };
	//int q[g.vexnum+1];
	int q[MAXVEX+1];
	int f, r, j;
	f = r = 0;
	printf("%d->", i);
	visited[i] = 1;
	r++;
	q[r] = i;
	while (f < r)
	{
		f++;
		i = q[f];
		for(j=1;j<=g.vexnum;j++)
			if ((g.arc[i][j] == 1) && (!visited[j]))
			{
				printf("%d->", j); 
				visited[j] = 1;
				r++;
				q[r] = j;
			}
	}

}
int main()
{
	AdjMatrix g;
	int i;
	printf("t为1~4,分别表示无向图、有向图、带权无向图、带权有向图\n");
	Creat(&g);
	printf("\n请输入出发点i:");
	scanf("%d", &i);
	printf("\n深度优先搜索遍历:");
	DFS(g, i);
	printf("NULL\n");
	printf("广度优先搜索遍历:");
	BFS(g, i);
	printf("NULL\n");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值