论深搜(dfs)以及广搜(bfs)的区别及C++代码实现

发布于:2022-10-17 ⋅ 阅读:(540) ⋅ 点赞:(0)

本蒟蒻第一次发文章,如有写的不详细或不正确的的请在评论区指出及纠正

那就直接开始正题吧

DFS全称Depth First Search,中文名为“深度优先搜索”,是基于递归的实现的

深搜本质思想先随意选择某种情况执行,在过程中,一旦发现方案不可用,就马上退回一步重新选择另一种情况,如此重复进行,直到找到解

两个基本框架:

第一种

int fx(int k){
	for(int i=1;i<=算符总数;i++){
		if(满足条件){ 
			保存结果;
			if(到目的地){
				输出解; 
			}
			else fx(k+1);
		}
		恢复:保存结果之前的状态; 
}

第二种

int fx(int k){
	if(到目的地){
		输出解; 
	}
	else{
		for(int i=1;i<=算符总数;i++){	
			if(满足条件){ 
				保存结果;
				fx(k+1);
				恢复:保存结果之前的状态(回溯一步); 
			}
		}	
	}
}

接下来,让我们了解下广搜bfs

BFS全称Breadth First Search,中文名为“广度优先搜索”

广搜本质思想:从初始节点开始,生成第二层节点,检查目标节点是否存在于这一层节点中,如果是,直接输出解,不然就继续生成节点,继续检查是否存在于这一层中......如此反复循环,直到找到解

例如下面这张图......

 

本画画废柴亲自手绘,不喜勿喷

像上面那张图一样

先生成A2,A3点,检查目标节点是否在里面,如果没有,继续生成A4,A5,A6,A7四个点,继续检查,如果有就输出,没有继续生成...

深搜的优点:代码量少,容易理解,能找出所有解决方案

缺点:非常容易超时!!!!!!!!!

广搜优点:解决最短路等问题特别好用

缺点:内存消耗大

“总之,一般情况下,深度优先搜索法占内存少但速度较慢,广度优先搜索算法占内存多但速度较快,在距离和深度成正比的情况下能较快地求出最优解。因此在选择用哪种算法时,要综合考虑。决定取舍。”摘自査佬@haohao_____

看道例题

1255:迷宫问题


时间限制: 1000 ms         内存限制: 65536 KB
提交数: 12406     通过数: 5777

【题目描述】

定义一个二维数组:

int maze[5][5] = {
0,1,0,0,0,
0,1,0,1,0,
0,0,0,0,0,
0,1,1,1,0,
0,0,0,1,0,
};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

【输入】

一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。

【输出】

左上角到右下角的最短路径,格式如样例所示。

【输入样例】

0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

【输出样例】

(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)

 

题目传送门 

这道题用深搜和广搜都可以做,不过深搜最多只能A 9个点,广搜才能AC 

深搜代码

思路:把所有路线枚举出来,选择最短的

#include<bits/stdc++.h>
#define inf 1<<30
using namespace std;
int a[6][6];
int xxx[160][160][6];
int pyx[6]={0,0,1,-1},
	pyy[6]={1,-1,0,0};
int ans[160];
int tot;
void dfs(int x,int y,int step)
{
	int xx,yy;
	if(x==4&&y==4){
		ans[tot]=step;
		tot++;
		return;
	}
	for(int i=0;i<4;i++)
	{
		xx=pyx[i]+x;
		yy=pyy[i]+y;
		if(xx<=4&&yy<=4&&xx>=0&&yy>=0&&a[xx][yy]!=1){
			a[xx][yy]=1;
			xxx[tot][step][0]=xx;
			xxx[tot][step][1]=yy;
			dfs(xx,yy,step+1);
			a[xx][yy]=0;
		}
	}
}
int main()
{
	for(int i=0;i<=4;i++){
		for(int j=0;j<=4;j++){
			cin>>a[i][j];
		}
	}
	dfs(0,0,0);
	int min=inf,index;
	for(int i=0;i<tot;i++){
		if(ans[i]<=min) min=ans[i],index=i;
	}
	cout<<"(0, 0)"<<endl;
	for(int i=0;i<min;i++){
		cout<<"("<<xxx[index][i][0]<<", "<<xxx[index][i][1]<<")"<<endl;
	}
}

广搜代码


#include<bits/stdc++.h>
using namespace std;
int a[6][6];
int pyx[6]={0,0,1,-1},
	pyy[6]={1,-1,0,0};//偏移量
struct node{
	int x,y,pre;//pre前驱
}p[10001];
void print(int len)//这里运用递归方法,一直递归直到到了最顶层节点
{
	if(p[len].pre!=0) print(p[len].pre);
	cout<<"("<<p[len].x<<", "<<p[len].y<<")"<<endl;
}
int main()
{
	for(int i=0;i<=4;i++){
		for(int j=0;j<=4;j++){
			cin>>a[i][j];
		}
	}
	int head,tail,xx,yy;
	head=0;tail=1;//头指针及尾指针
	p[tail].x=0;
	p[tail].y=0;
	p[tail].pre=0;
	while(head<tail){
		head++;
		for(int i=0;i<4;i++){
			xx=p[head].x+pyx[i];
			yy=p[head].y+pyy[i];
			if(xx>=0&&yy>=0&&xx<=4&&yy<=4&&a[xx][yy]!=1)//判断条件
            {
				a[xx][yy]=1;//不能走回头路
				tail++;
				p[tail].x=xx;
				p[tail].y=yy;
				p[tail].pre=head;
				if(xx==4&&yy==4)//输出结果
                {
					print(tail);
					break;
				}
			}
		}
	}
}

最后安利一下洛谷账号(逃)doge

哈哈嗨

GOODBYE!


网站公告

今日签到

点亮在社区的每一天
去签到