一,
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
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.
}