深度优先搜索和广度优先搜索

前言

一个程序员一生中可能会邂逅各种各样的算法,不过搜索永远是其中最基础也是最重要的一种算法,下面我们就来分深度优先搜索和广度优先搜索来看一下吧。

深搜

深搜又叫深度优先搜索,dfs。顾名思义就是深度优先搜索,以深度第一,每一道搜索题其实都可以画出一棵搜索树。我们来举一个例子: 以这个求 1,2,3 的全排列为例,先枚举第一个数 1,再往下枚举出 1,2,3,但是明显 1 肯定不对,直接回溯,这就是剪枝,剪枝可以大大减少做题时的时间复杂度,再从 2 往下枚举 1,2,3再把 1,2排除,得到 3,输出后回到 2再回到 1,这就是回溯,回溯就代表着这条路径已经完结,要返回到上一个路口再一次进行选择,以此类推,就可以得到

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

然后我们来贴出一个最基本的全排列的算法,顺便让大家更好的理解深搜。

#include<bits/stdc++.h>
using namespace std;
int b[1000], a[1000], n;//b是标记,a是路径
void dfs(int x)
{
	if(x==n+1)//结束条件
	{//输出要求
		cout<<"    ";
		for(int i=1;i<=n;i++)
		{
			cout<<a[i]<<"    ";
			if(i==n)
			{
				cout<<endl;
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		if(b[i]==0)//没有走过
		{
			a[x]=i;//统计路径
			b[i]=1;//做好标记
			dfs(x+1);//继续搜索
			b[i]=0;//回溯标记
		}
	}
}
int main()
{
	cin>>n;
	dfs(1);
	return 0;
}

宽搜

宽搜又叫广度优先搜索或宽度优先搜索,bfs。宽搜需要使用队列queue来完成。那我们先来看一下宽搜的基本框架

while (队列不为空) {
    读取头结点,头结点出队
    扩展新结点 {                        // 状态转移
        if (新结点可以入队) {
            如果是目标结点,就地结束    // 若没有目标结点,则不判断
            新结点入队
            标记新结点已入队
        }
    }
}
  • 状态表示:状态一般指对结点信息的描述,通常用T表示。一般用T0表示初始状态,Tn表示目标状态。
  • 状态转移:根据产生式规则和约束条件控制从当前状态转移到下一个状态。
  • 状态判重:大多数情况下,如果出现重复状态会造成死循环。这是宽度优先搜索不同于深度优先搜索的方面。

然后我们以一到走迷宫来详细解说一下宽搜。

 

农夫知道一头牛的位置,想要抓住它。农夫和牛都位于数轴上,农夫起始位于点N(0≤N≤100000)N(0≤N≤100000),牛位于点K(0≤K≤100000)K(0≤K≤100000)。农夫有两种移动方式:(这里要注意的是N可以到100000,所以数组要开到200000以上,(2*X))

1、从XX移动到X−1或X+1,每次移动花费一分钟

2、从X移动到2×X

,每次移动花费一分钟

假设牛没有意识到农夫的行动,站在原地不动。农夫最少要花多少时间才能抓住牛?

以下就是代码了。 

 

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
int a[1000000];
int n,k;
struct node
{
	int x,step;//结构体定义
};
node now,ne,start;
void bfs()
{
	queue<node>que;
	que.push(start);//入队
	while(que.size())
	{
		now=que.front();
		que.pop();
		if(now.x==k)//抓住了
		{
			cout<<now.step;
			return ;
		}
		for(int i=0; i<3; i++)//四个方向
		{
			if(i==0)//方向0
				ne.x=now.x+1;
			else if(i==1)//方向1
				ne.x=now.x-1;
			else if(i==2)//方向2
				ne.x=now.x*2;
			ne.step=now.step+1;
			if(a[ne.x]==0&&ne.x>=0&&ne.x<100005)//是否越界
			{
				que.push(ne);
				a[ne.x]=1;
			}
		}
	}
}
int main()
{
	cin>>n>>k;
	memset(a,0,sizeof a);
	a[n]=1;
	start.x=n;
	start.step=0;
	bfs();
	return 0;
}

结尾 

那么到这里本篇对于搜索的介绍就到这里了,如果认为对你有帮助的,麻烦点一个赞吧。也请大家多多指教。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值