DFS深度优先遍历

一,
1.深度优先遍历的递归定义 
  假设给定图G的初态是所有顶点均未曾访问过。在G中任选一顶点v为初始出发点(源点),
则深度优先遍历可定义如下:首先访问出发点v,并将其标记为已访问过;然后依次从v出发
搜索v的每个邻接点w。若w未曾访问过,则以w为新的出发点继续进行深度优先遍历,直至图
中所有和源点v有路径相通的顶点(亦称为从源点可达的顶点)均已被访问为止。若此时图中
仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有
顶点均已被访问为止。
  图的深度优先遍历类似于树的前序遍历。采用的搜索方法的特点是尽可能先对纵深方向
进行搜索。这种搜索方法称为深度优先搜索(Depth-First Search)。相应地,用此方法遍历
图就很自然地称之为图的深度优先遍历


2.基本实现思想:


(1)访问顶点v;
(2)从v的未被访问的邻接点中选取一个顶点w,从w出发进行深度优先遍历;
(3)重复上述两步,直至图中所有和v有路径相通的顶点都被访问到。


3.伪代码
递归实现
/*
DFS:
int offset[4][2]={-1,0,0,1,1,0,0,-1};
bool bVisited[M][N]={false,};


int DFS(int i,int j,int Matrix[M][N])
{
bVissted[i][j]=true;


for(k=0;k<4;k++)
{
if(i+offset[k][0]>=0 && i+offset[k][0]<M &&
j+offset[k][1]>=0 && j+offset[k][1]<N &&
bvisited[i+offset[k][0]][offset[k][1]]==false)
{
DFS(i+offset[k][0],j+offset[k][1],Matric);
}
}
}
*/
(1)访问顶点v;visited[v]=1;//算法执行前visited[n]=0


(2)w=顶点v的第一个邻接点;


(3)while(w存在)  


           if(w未被访问)


                   从顶点w出发递归执行该算法; 
           w=顶点v的下一个邻接点;


 
二,非递归实现

 (1)栈S初始化;visited[n]=0;

 (2)访问顶点v;visited[v]=1;顶点v入栈S

 (3)while(栈S非空)
            x=栈S的顶元素(不出栈);
            if(存在并找到未被访问的x的邻接点w)
                    访问w;visited[w]=1;
                    w进栈;
            else
                     x出栈;
三,
例题:
(1)题目星图 :
在给出的二维数组中,1代表星星,0代表空,找出有多少个星团(上下左右相连的算在一个星团内,45度角相连不算),并且最大的星团内有多少个星星数


[Input]
There can be more than one test case in the input. 
The first line has T, the number of test cases. 
Then the totally T test cases are provided in the following lines (T<=10)
In each test case, the first line has an integer N(5 ≤ N ≤ 25), the size of map. 
The map is a square, and is represented as N x N matrix.
For next N lines, each contains each raw of the matrix
[Output]
For each test case, you should print the number of constellation and the number of starts in the greatest constellation separated by blank.
[I/O Example] 
Input
2
7
0 1 1 0 0 0 0
0 1 1 0 1 0 0
1 1 1 0 1 0 1
0 0 0 0 1 1 1
1 0 0 0 0 0 0
0 1 1 1 1 1 0
0 1 0 1 1 0 0
5
0 1 0 0 0
0 1 0 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 0 0


Output 
4 8
1 3


(2)解答:

//DFS
#include <stdio.h>
#include <iostream>


using namespace std;


int N;
int data[26][26];
int vis[26][26];
int move[4][2]={-1,0,0,1,1,0,0,-1};
int tempC;
int numS;//星团个数
int numC;//最大星团星星个数


int DFS(int x,int y)
{
	int i,j;
	int tmpx,tmpy;
	vis[x][y]=1;
	data[x][y]=0;
	tempC++;
	for(i=0;i<4;i++)
	{
		tmpx=x+move[i][0];
		tmpy=y+move[i][1];
		if(tmpx>0 && tmpx<=N &&
			tmpy>0 && tmpy<=N &&
			vis[tmpx][tmpy]==0 &&
			data[tmpx][tmpy]==1)
			DFS(tmpx,tmpy);
	}
	return 0;
}


int main(void)
{
	int test_case;
	int T;
	//freopen("input.txt", "r", stdin);


	setbuf(stdout, NULL);


	scanf("%d", &T);
	for(test_case = 0; test_case < T; test_case++)
	{
		int i,j;


		scanf("%d", &N);
		
		for(i=1; i<=N; i++) {
			for(j=1; j<=N; j++) {
				scanf("%d", &data[i][j]);
			}
		}
		numS=0;
		numC=0;
		memset(vis,0,sizeof(vis));
		for(i=1;i<=N;i++)
		{
			for(j=1;j<=N;j++)
			{
				if(data[i][j]==1)
				{
					tempC=0;
					DFS(i,j);
					numS++;
					if(numC<tempC)
						numC=tempC;
				}
			}
		}
		printf("%d %d\n", numS, numC);
		
	}


	return 0;//Your program should return 0 on normal termination.
}



猜你喜欢

转载自blog.csdn.net/u011938614/article/details/44953803
今日推荐