搜索专题(二)

广搜:

广搜和深搜有明显的不同(虽然都是搜索,名字也差不多),不过我觉得最大的不同就是它们的实现方式。深搜是通过栈来实现的,虽然表面上看不到,其实它的递归过程就是一个栈的模拟,因此才能做到“一条道走到黑”。广搜是通过队列来实现的,因此它就可以四面八方地进行扩展,直到搜索到正解。和深搜相比,广搜的效率较快,但是空间较大,容易爆内存。因此两种搜索算法各有所长,在不同的题目应使用有优势的算法。

思想:

以一张图为例:



先将第一个搜索的点(也就是起点)入队,就是把点1入队,并标记。然后进行循环,分别将与它相邻并未标记过的点入队并进行标记。(这里提一点,就是标记可以让搜索的点不重复。)在这里也就是把点2和点3入队。再将点4和点8入队……知道搜索到目的地。

代码如下:

int q[maxn]={}.head=1,tail=0,vis[maxn]={},dis[maxn]={};//q是queue的缩写,表示队列。vis是标记数组,dis是用来保存的。还有这里的队头和队尾一定要初始化,不然会发生一些interesting的事情。假设我已经定义了一个记录当前位置的数组(懒得改),a数组。

q[++tail]=start;//start表示起点,这不操作要在循环之外。

vis[start]=1;//标记

while(head<=tail)

{

    int x=q[head++];

    for(int i=1;i<=n;i++)

        if(a[x][i] && !vis[i])//如果两个点之间有路线且没有标记。

    {

        q[++tail]=i;

        vis[i]=1;

        dis[i]=dis[x]+1;//保存结果。

    }

}

既然是队列,那就用考虑一种情况——溢出。控制溢出的方法就是循环队列(学过队列的同学应该知道),设置循环队列的方法并不难,只要把while的括号中的条件改成:head!=tail即可。

有些题目深搜和广搜都可以使用(看数据量,如果数据量少的话),但有些题规定要用深搜或者广搜。如:N皇后就要用深搜回溯,青铜莲花池什么的就要用广搜,主要还是看情况来。

猜你喜欢

转载自blog.csdn.net/chenkainan1023/article/details/79274850