DFS(深度优先遍历)

DFS的意思为深度优先遍历。
一、DFS的简介:
深度优先遍历(DFS)也叫深度优先搜索。它的定义是:不断地沿着顶点的深度方向遍历。顶点的深度方向是指它的邻接点方向。
二、DFS的实现步骤:
1、从顶点出发。
2、访问顶点,也就是根节点。
3、依次从顶点的未被访问的邻接点出发,进行深度优先遍历;直至和顶点有路径相通的顶点都被访问。
4、若此时尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优遍历,直到所有顶点均被访问过为止。

此次我以《算法竞赛入门经典第2版》6.4.1中的例题6-12《油田》为例

输入一个m行n列的字符矩阵,统计字符“@”组成多少个八连块。如果两个字符所在格子相邻(横竖,对角线)就说他们属于一个八连块

0 0 0  0@

0@@ 0@

0@ 0  0@

@@@0@

@@0  0@

图中就有两个八连块

#include<cstdio>//c++中stdio.h的头文件
#include<cstring>//semset函数头文件
const int maxn=100;//定义一个int类型的常量
char pic[maxn][maxn];//定义一个二维数组用于存储输入的字符
int m, n,idx[maxn][maxn];//idx数组用于给每个字符标记一个数,表示已经访问过(防止多次访问)
void dfs(int r,int c,int id){
  if(r<0||r>=m||c<0||c>=n) return;//格子出界返回;
  if(idx[r][c]>0||pic[r][c]!='@') return;//不是@或者这个@已经被赋值过了;
    for(int dr=-1;dr<=1;dr++){
      for(int dc=-1;dc<=1;dc++)
        if(dr!=0||dc!=0) dfs(r+dr,c+dc,id);//不是本身就进行递归
    }//对数组中某一个元素a[r][c]周围所以数遍历一遍找到有‘@’符号且没有被标记过的元素,再遍历此元素周围的元素。及找到了一条联通的路,其标记的数下标相同
}
int main(){
  scanf("%d%d",m,n);
   for(i=0;i<m;i++) 
   scanf("%s",pic[i]);
  semset(idx,0,sizeof(idx));
  int cnt=0;
   for(i=0;i<m;i++){
     for(j=0;j<n;j++){
       if(id[i][j]==0&&pic[i][j]='@')dfs(i,j,++cnt);}
     }
   printf("%d\n",cnt);
   }
return 0;
}

 memset()函数原型

extern void*memset(void*buffer,int c,int count)

buffer为指针或者数组

c为赋给buffer的值

count为buffer的长度

memset(a,0,sizeof(a))用于清空数组a或者给a数组赋值为0

也可以使用在结构体里

struct Student st{

int a;

char b[10];

int c[10];

}

memset(&st,0,sizeof(struct Student st));

刚分配的内存空间,或者是被你用过的内存空间里面的数据是不固定的为了避免这些无用的数据给自己的程序带来影响,可以用memset把这些内存里面的数据置成某个数值一般情况下是置0,当然,如果你的程序不会受这些无用数据影响,就不用做这个工作了所谓“初始化”,当然是指将你定义的变量或申请的空间赋予你所期望的值,例如语句int i=0;就表明定义了一个变量i,并初始化为0;如果int j=5;就表明定义了一个变量j,并初始化为5。

       但是对于大块儿内存的分配,这种方法当然不行,例如int arr[100];定义了数组arr,包含100个元素,如果你写成int arr[100]=0;想将数组全部内容初始化为0,是不行的,连编译都不能通过。这种情况的初始化,有两种方法,一种是一个一个的初始化,如for(int i=0;i<100;i++)arr[i]=0;就完成了数组的初始化。另一种方法,就是使用memset:一个语句就够了--memset(arr,0,sizeof(int)*100);
各参数解释如下:arr是数组的首地址,0就是要讲这些地址的内容赋值为0,sizeof(int)求出int类型的长度,乘以100就表示arr数组的整个长度。
 

 

 

 

 

 

 

 

 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

需要静养的人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值