今天是释然发题解的第十二天,以后每一天都会和大家分享学习路上的心得,希望和大家一起进步,一起享受coding的乐趣。
本文约1600字,预计阅读5分钟
昨天我们学习了深度优先搜索,忘记的小伙伴们可以看一下哦:
今天我们来聊一聊的宽度优先搜索和深度优先搜索的区别,明天和大家分享分治和贪心的相关知识:
定义
宽度优先搜索( BFS,Breadth-First Search )也是搜索的手段之一。它与深度优先搜索类似,从某个状态出发探索所有可以到达的状态。
与深度优先搜索的不同之处在于搜索的顺序,宽度优先搜索总是先搜索距离初始状态近的状态。
也就是说,它是按照开始状态→只需1次转移就可以到达的所有状态→只需2次转移就可以到达的所有状态 …这样的顺序进行搜索。对于同一个状态,宽度优先搜索只经过一一次,因此复杂度为0(状态数x转移的方式)。
深入理解
深度优先搜索(隐式地)利用了栈进行计算,而宽度优先搜索则利用了队列。搜索时首先将初始状态添加到队列里,此后从队列的最前端不断取出状态,把从该状态可以转移到的状态中尚未访问过的部分加入队列,如此往复,直至队列被取空或找到了问题的解。通过观察这个队列,我们可以就知道所有的状态都是按照距初始状态由近及远的顺序被遍历的。
比较:优势和缺点
敲重点:那么他们的优缺点在哪呢?
对于深度优先搜索来说,它会一直不停地沿着可以走的方向走下去,一旦数据过大,那这个复杂度也会按照指数级增长,当然我们还有一种搜索方式叫:迭代加深深度优先搜索(IDDFS)一种类似于BFS的状态转移顺序,(害,我也没弄懂这个,当我弄懂了一定也好好总结一下。)
不过它也有好处就是:不需要使用队列来存储状态,因此会比BFS占用更少的内存空间
对于宽度优先搜索它会优先遍历所有最接近的状态,并把状态保存在队列当中,那么一旦找到了最短的路径,那么一定是最优的解答,因此非常适用最短的方案的搜索。当然BFS也可以搜索全图,相比于BFS来说,需要记录很多的数据
总结
因此,一般情况下,适用问题为:
BFS:最短路径
DFS:解的个数
模板
DFS:
void dfs(int , int )
{
map[x][y] = '';//标记
if(符合搜索条件)
{
//处理
return ;
}
else
{//不同方向搜索
for (int dx = -1; dx <= 1; dx++)
{
for (int dy = -1; dy <= 1; dy++)
{
x += dx, y += dy;
if (x >= 1 && x <= M && y >= 1 && y <= N && map[x][y]=='')
dfs(x,y);
}
}
}
return ;
}
BFS:
dx={1,0,-1,0};
dy={0,1,0,-1};
void BFS(node current_exception)
{
queue<node> q;
node now, next;
current_exception.step = 0; //步数清零;
q.push(current_exception); //入队;
map[current_exception.x][current_exception.y] = 1; //访问标记
while (!q.empty())
{
now = q.front(); //取队首元素进行拓展
q.pop(); //队首元素出队;
if (now == 所需要的状态) //出现需要的状态,此时的step为最小值,做做相关处理后退出即可;
{
……;
return;
}
//如果没有到目标解:
else
{
for (int i = 0; i < 4; i++)
{
next.x = now.x + dx[i]; //按照规则生成下一个状态
next.y = now.y + dy[i];
if(next.x== 可行解 &&next.y== 可行解)//如果状态满足条件则入队
{
next.step = now.step + 1;
q.push(next);
}
}
}
return;
}
}
好了,今天的有关深度优先搜索和宽度优先搜索的区别就到这里
释然每天发布一点自己学习的知识,希望2年后我们也能在ACM的赛场上见面,一起去追寻自己的程序猿之路吧!
后期也会和大家一起分享学习心得和学习经验呢,明天我们不见不散哦!
下期预告:
分治和贪心
如果大家有什么建议或者要求请后台留言,释然也想和大家一起进步呀!
联系方式:shirandexiaowo@foxmail.com