浅谈DFS(深度优先搜索)与BFS(广度优先搜索)

#DFS是什么,又该怎么实现

      首先,来谈谈什么是dfs(Depth First Search),根据翻译可得知dfs是深度优先搜索;那么作为一个搜索类型的十分常用的工具,“深度”指的是从一个点出发沿着一条线走到头(如下图所示)。

图中“1,2,4”是一段路“1,2,5,7”是另一段路;那么如何走出呢,原理就是到达最底端后,向后退一步然后向其他没走过的方向继续走,一直到将每一条路都走一遍(有时达成题目所给目的也可直接停止);

dfs的优点也可以由此体现,那就是更加完整、全面的将路径推出。

那么该怎么用代码实现这一操作呢,请看下图伪代码;

然后可以进行实践,如下例题:

P1219 [USACO1.5] 八皇后 Checker Challenge

https://www.luogu.com.cn/problem/P1219

首先,分析题目每一列都有且仅有一个皇后,那么就可以从第一列第一行递推到第n列,每到一行若该行的某一列没被标记,并且他将要“占领”的点也未被标记,那么就标记他和他要标记的点再从他开始递推;因为每一次都是从下一行开始推所以最后会大于n,当其大于n时判断是否为前3个;若是输出,然后计数器++,return ;然后代码实现如下:

至此我对dfs的理解综上。 

 #BFS是什么,又该怎么实现

再来讲讲BFS(Breadth First Search),根据翻译“广度优先搜索”,根据名称很容易可以看出其与DFS的区别,如果说dfs是一条路走到底,那么bfs就是同一行的路全走一遍后再走下一行;如下图:

 据图从第一行开始首先是“1”然后下一行走“2,3”,再走“4,5,6”,最后走“7”。

一般bfs条件可能只给到中间某个数据,因此对于dfs,bfs的优点是运算时长会相对短一些。

那么该怎么实现,请看下列伪代码:

 

图中bfs函数有时可以写到main函数里,下面给一道例题。

P1443 马的遍历

P1443 马的遍历 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

 

分析此题从(x,y)点开始到任意一个点的步数,由测试点可知这个马是象棋中走“日”字的马;那么mv数组就可以很快确定下来,然后就从(x,y)点开始遍历就好了,代码如下:

#include<bits/stdc++.h>
using namespace std;
const int M=1;
struct horse{
	int x,y; 
}; 
queue<horse> Q;
int ans[405][405];
int av[8][2] ={{-2,1},{2,1},{-2,-1},{2,-1},
                {1,2},{1,-2},{-1,2},{-1,-2}};
int main(){
	int n,m,sx,sy;
	memset(ans,-1,sizeof ans);
	cin>>n>>m>>sx>>sy;
	horse tmp = {sx,sy};
	Q.push(tmp);
	ans[sx][sy]=0;
	while(!Q.empty()){
		horse u=Q.front();
		int ux=u.x,uy=u.y;
		Q.pop();
		for(int k=0;k<8;k++){
			int x=ux+av[k][0],y=uy+av[k][1];
			int d=ans[ux][uy];
			if(x<1||x>n||y<1||y>m||ans[x][y]!=-1) continue;
			ans[x][y]=d+1;
			horse tmp={x,y};
			Q.push(tmp);
		} 
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cout<<ans[i][j]<<" ";
		}
		cout<<endl;
	}
	return 0;
}

 至此是我对bfs的理解。

感谢鉴赏,留个赞再走吧( ̄▽ ̄)~■□~( ̄▽ ̄)。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值