图的遍历

深度优先遍历的思想:

首先以一个未被访问过的顶点作为起始顶点,沿当前顶点的边走到未访问的顶点:
当没有未访问过的顶点时,则回到上一个顶点,继续试探别的顶点,直到所有的顶点都被访问过。

深度优先遍历时沿着图的某一条分支遍历直到末端,然后回溯,再沿着另一条进行同样的遍历,直到所有的点都被遍历过为止

这是遍历,而不是走一个通路
需要把所有的点都进行访问

#include<stdio.h>

int book[101];	//book用于记录顶点i是否被访问过
int sum, n;
int e[101][101];	//图的存储

void dfs(int cur)
{
	int i;
	printf("%d ", cur);		//访问了这个顶点cur
	sum++;	//每访问一个顶点,sum就+1
	if (sum == n)	//如果已经遍历完所有点,直接退出
		return;
	for (i = 1; i <= n; i++)
	{
		//判断从点cur到i是否有路,且i没有被访问过
		if (e[cur][i] == 1 && book[i] == 0)	
		{
			book[i] = 1;	//标记i点,表示已被访问
			dfs(i);	//访问i点
		}
	}
	return;
}

int main()
{
	int i, j, m, a, b;
	scanf("%d%d", &n, &m);	//n表示有多少个点,m表示有多少条边

	for (i = 1; i <= n; i++)
	{
		for (j = 1; j <= n; j++)
		{
			if (i == j)
				e[i][j] = 0;	//自己到自己
			else
				e[i][j] = 10000000;	//无穷表示没有边
		}
	}

	for (i = 1; i <= m; i++)	//输入边
	{
		scanf("%d%d", &a, &b);	//表示a,b点有边
		e[a][b] = 1;	//在e中存储a,b两点之间有边
		e[b][a] = 1;	//因为是无向图,因此在a,b和b,a都存储一次
	}

	book[1] = 1;	//从1顶点开始遍历
	dfs(1);
	return 0;
}

广度优先遍历的思想:

首先以一个未被访问过的顶点作为起始顶点,访问其所有相邻的顶点,然后对每个相邻的顶点,再访问它们相邻的未被访问过的顶点,直到所有顶点都被访问过,遍历结束。

广度优先遍历的根本在于队列

#include<stdio.h>
int book[101] = { 0 };	//存储该点是否已经被访问
int e[101][101];	//存储图
int que[10000];	//表示表示一个队列
int head, tail;	//队首与队尾
int main()
{
	int i, j, n, m, a, b, cur;
	scanf("%d%d", &n, &m);

	for (i = 1; i <= n; i++)	//初始化
	{
		for (j = 1; j <= n; j++)
		{
			if (i == j)
				e[i][j] = 0;	//自身与自身无边
			else
				e[i][j] = 10000000;
		}
	}

	for (i = 1; i <= m; i++)	//输入边
	{
		scanf("%d%d", &a, &b);	
		e[a][b] = 1;	//无向,存两次
		e[b][a] = 1;
	}
	
	//队列初始化
	head = 1;
	tail = 1;

	//从1号顶点出发
	que[tail] = 1;	//将1号顶点加入队列中
	tail++;	//队尾标志后移,队尾标志指向队尾元素的后一个位置
	book[1] = 1;	//标记1号顶点已经被访问

	while (head < tail)
	{
		cur = que[head];
		for (i = 1; i <= n; i++)	
		{	
			//遍历每一个点,看当前点与下一个点是否有通路且下一个点还没有被访问过
			if (e[cur][i] == 1 && book[i] == 0)
			{
				que[tail] = i;	//加入队列
				tail++;
				book[i] = 1;
			}
			if (tail > n)	//总共n个点,已经访问了n个了,自然退出
			{
				break;
			}
		}
		head++;	//队列队首++
	}
	for (i = 1; i < tail; i++)	//按照访问顺序输出
	{
		printf("%d ", que[i]);
	}
	return 0;
}

图的存储

图的邻接矩阵存储法
使用一个二维数组e来存储
<i, j> == 1,表示顶点i到顶点j之间有边
<i, j> == ∞,表示顶点i到顶点j之间无边
<i, i> == 0,表示自己到自己为0

无向图,使用图的邻接矩阵法,矩阵是沿对角线对称的

for (i = 1; i <= m; i++)	//输入边
	{
		scanf("%d%d", &a, &b);	//表示a,b点有边
		e[a][b] = 1;	//在e中存储a,b两点之间有边
		e[b][a] = 1;	//因为是无向图,因此在a,b和b,a都存储一次
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值