DFS求矩阵中的连通块数
上一次为了解决矩阵中的连通块的个数,我模仿了算法笔记中的代码,通过BFS(广度优先搜索算法)解决问题。
实际上这个问题(问题链接)也可以通过DFS(深度优先搜索遍历)解决。
解决思路:这个DFS的“岔道口”其实有四个(因为有四个方向)。这里为了防止走回头路,所以我们必须设立一个数组
记录该位置元素是否被访问过。其实这个数组的信息就产生了一个“死胡同条件”。另一方面,根据题目要求,我们只关注
元素为1的位置,即遇到0的就是一种“死胡同情况”。所以继续往深处递归的条件就是:
1、不越界
2、不回头
3、元素为1
这样,我们就可以写出来代码了。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <math.h> 4 #include <string.h> 5 #include <ctype.h> 6 7 #define maxn 100 8 #define MAX_SIZE 5 //最大队列长度+1 9 10 11 struct postion{ 12 int x; 13 int y; 14 }pos; 15 16 17 18 19 int n,m; //矩阵大小n*m 20 int martix[maxn][maxn] = {0}; //01矩阵 21 int vis[maxn][maxn] = {0}; //记录位置x,y是否已经入队 22 23 int X[] = {0,0,1,-1}; 24 int Y[] = {1,-1,0,0}; 25 26 void DFS(int x,int y); 27 28 int judge(int x,int y); 29 30 int main(){ 31 32 scanf("%d%d",&n,&m); //输入矩阵大小 33 34 for(int x=0;x<n;x++){ 35 for(int y=0;y<m;y++){ 36 scanf("%d",&martix[x][y]); 37 } 38 } 39 40 41 42 int ans = 0;//统计块数 43 44 for(int x=0;x<n;x++){ 45 for(int y=0;y<m;y++){ 46 if(judge(x,y)==1){ //满足访问的要求 47 DFS(x,y); 48 ans++; 49 } 50 51 } 52 } 53 54 printf("%d\n",ans); 55 return 0; 56 } 57 58 59 void DFS(int x,int y){ 60 61 pos.x = x; 62 pos.y = y; 63 vis[x][y] = 1;//记录其已经入队 64 65 for(int i=0;i<4;i++){ 66 int newX = x+X[i]; 67 int newY = y+Y[i]; 68 69 if(judge(newX,newY)==1){ 70 DFS(newX,newY); 71 72 } 73 } 74 75 } 76 77 78 79 int judge(int x,int y){ //判断坐标x,y是否需要访问处理 80 //如果出界,返回0,不需要进一步访问 81 if(x>=n||x<0||y>=m||y<0){ 82 return 0; 83 } 84 //或者已经入队或者元素为0 85 if(martix[x][y] == 0||vis[x][y] == 1){ 86 return 0; 87 } 88 89 return 1; 90 }