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

一,深度优先搜索

基本思路:

深度优先遍历图的方法是,从图中某顶点v出发:

(1)访问顶点v;
(2)依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问;
(3)若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。

举例:

给出如图3-1所示的图,求图中的V0出发,是否存在一条路径长度为4的搜索路径。


 

3-1

显然,我们知道是有这样一个解的:V0->V3->V5->V6。

处理过程

 

深度优先搜索用一个数组存放产生的所有状态。
(1) 把初始状态放入数组中,设为当前状态;
(2) 扩展当前的状态,产生一个新的状态放入数组中,同时把新产生的状态设为当前状态;
(3) 判断当前状态是否和前面的重复,如果重复则回到上一个状态,产生它的另一状态;
(4) 判断当前状态是否为目标状态,如果是目标,则找到一个解答,结束算法。
(5) 如果数组为空,说明无解。

void dfs(int x)
{
    visited[x]=true;
    //标记x被访问
    for(int i=0;i<g[x].size();i++)
        if(!visited[i])
            dfs(i);
    遍历x的相邻结点,若没被访问则从这个结点开始深搜遍历
}


int main()
{
    for(int i=1;i<=MAXN;i++)
        g[i].clear();
    memset(visited,0,sizeof(visited));
    //初始化清空g和visited数组
    for(int i=1;i<=MAXN;i++)
        if(!visited[i])
            dfs(i);
    //多个图深搜遍历
}


二,广度优先搜索

其别名又叫BFS,属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。

算法首先搜索和s距离为k的所有顶点,然后再去搜索和S距离为k+l的其他顶点。

基本思路:

广度优先搜索使用队列(queue)来实现,整个过程也可以看做一个倒立的树形:
1、把根节点放到队列的末尾。
2、每次从队列的头部取出一个元素,查看这个元素所有的下一级元素,把它们放到队列的末尾。并把这个元素记为它下一级元素的前驱。
3、找到所要找的元素时结束程序。
4、如果遍历整个树还没有找到,结束程序。

实际的应用:

BFS在求解最短路径或者最短步数上有很多的应用。
应用最多的是在走迷宫上

具体的举例:

我们采用示例图来说明这个过程,在搜索的过程中,初始所有节点是白色(代表了所有点都还没开始搜索),把起点V0标志成灰色(表示即将辐射V0),下一步搜索的时候,我们把所有的灰色节点访问一次,然后将其变成黑色(表示已经被辐射过了),进而再将他们所能到达的节点标志成灰色(因为那些节点是下一步搜索的目标点了),但是这里有个判断,就像刚刚的例子,当访问到V1节点的时候,它的下一个节点应该是V0和V4,但是V0已经在前面被染成黑色了,所以不会将它染灰色。这样持续下去,直到目标节点V6被染灰色,说明了下一步就到终点了,没必要再搜索(染色)其他节点了,此时可以结束搜索了,整个搜索就结束了。然后根据搜索过程,反过来把最短路径找出来,图3-1中把最终路径上的节点标志成绿色。

整个过程的实例图如图3-1所示。

初始全部都是白色(未访问

即将搜索起点V0(灰色)

已搜索V0,即将搜索V1、V2V3

……终点V6被染灰色,终止

找到最短路径

3-1 寻找V0V6的过程

3.2.广度优先搜索流程图

 


3-2 广度优先搜索的流程图


void bfs()
{
    visited[1]=1;//初始结点1进入队列
    q.push(1);
    while(!q.empty())//队列为空时结束遍历
    {
        int t=q.front();
        q.pop();
    //寻找队头元素的相邻结点并弹出对头元素
        for(int i=0;i<g[t].size();i++)
            if(!visited[i])
            {
                q.push(i);
                visited[i]=1;
            //访问相邻结点并使之入队
            }
    }
}





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值