图的遍历

219 阅读2分钟

图的深度优先和广度优先遍历

一:深度优先遍历

1.1 : 图的邻接矩阵表示法

邻接矩阵:用一个二维数组来存储一个图,二维数组的第i行第j列表示顶点i到j是否有边,这里用1表示有边,∞表示没有边,将自己到自己设为0.

这是一个图:

他的邻接矩阵为:
(图画的不太好不要在意~)

1.2 :思想

首先以一个未被访问过的顶点作为起始顶点,沿当前顶点的边走到未访问过的顶点,当没有未访问过的顶点时,则回到上一个顶点,继续试探访问别的顶点,直到所有的顶点都被访问过,即深度优先遍历是沿着图的某一条分支遍历直到末端,然后回溯,再沿着另一条进行同样的遍历,直到所有的顶点都被访问过为止.

代码如下:

#include<stdio.h>
int e[101][101],book[101],sum,n;
void dfs(int cur)
{
	printf("%d ",cur);
	sum++;
	if(sum == n)
	{
		return;
	}
	for(int i = 1;i <= n;i++)
	{
		if(e[cur][i] == 1&&book[i] == 0)
		{
			book[i] = 1;
			dfs(i);
		}
	}
	return;
}
int main()
{
	int a,b,m;
	scanf("%d %d",&n,&m);
	for(int i = 1;i <= n;i++)
	{
		for(int j = 1;j <= n;j++)
		{
			if(i == j)
			{
				e[i][j] = 0;
			}
			else
			{
				e[i][j] = 9999999;
			} 
		}
	}
	for(int i = 1;i <= m;i++)
	{
		scanf("%d %d",&a,&b);
		e[a][b] = 1;
		e[b][a] = 1;
	}
	book[1] = 1;
	dfs(1);
	return 0;
}

二 :广度优先遍历

1.1 图示:

1.2 思想:

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

代码如下:

#include<stdio.h>
int main()
{
	int n,m,a,b,cur,book[101] = {0},e[101][101];
	int que[10001],head,tail;
	scanf("%d %d",&n,&m);
	for(int i = 1;i <= n;i++)
	{
		for(int j = 1;j <= n;j++)
		{
			if(i == j)
			{
				e[i][j] = 0;
			}
			else
			{
				e[i][j] = 9999999;
			}
		}
	}
	for(int i = 1;i <= m;i++)
	{
		scanf("%d %d",&a,&b);
		e[a][b] = 1;
		e[b][a] = 1;
	}
	head = 1;
	tail = 1;
	que[tail] = 1;
	tail++;
	book[1] = 1;
	while(head < tail&&tail <= n)
	{
		cur = que[head];
		for(int i = 1;i <= n;i++)
		{
			if(e[cur][i] == 1&&book[i] == 0)
			{
				que[tail] = i;
				tail++;
				book[i] = 1;
			}
			if(tail > n)
			{
				break;
			}
		}
		head++;
	}
	for(int i = 1;i <= n;i++)
	{
		printf("%d ",que[i]);
	}
	return 0;
}