深度与广度 总结

 深度与广度 总结

1.深度优先搜索(回溯法)

[算法思路]

    深度优先搜索(DFS,Depth-First Search)是搜索的手段之一.它从某个状态开始,不断地转移状态直到无法转移,然后回退到前一步状态,继续转移到其他状态,如此不断重复,直到找到最终的解.根据深度优先搜索的特点,采用递归函数(隐式地利用了栈进行计算)实现比较简单.

[算法描述]
void dfs(int step)
{
	判断边界
	尝试每一种可能for(i=1;i<=n;i++)
	{
		继续下一步 dfs(step+1);
	}
	返回
}

[算法效率]

     深度优先搜索从最开始的状态出发,遍历所有可以到达的状态.由此可以对所有的状态进行操作,或列举出所有的状态.作为搜索算法的一种,DFS对于寻找一个解的NP(包括NPC)问题作用很大.

    但是,搜索算法毕竟是时间复杂度是 O(n!) 的阶乘级算法,它的效率比较低,在数据规模变大时,这种算法就显得力不从心了. 关于深度优先搜索的效率问题,有多种解决方法.最具有通用性的是剪枝(prunning),也就是去除没有用的搜索分支. 可行性剪枝和最优性剪枝两种.此外,对于很多问题,可以把搜索与动态规划(DP,dynamic programming)、完备匹配(匈牙利算法)等高效算法结合.

2.宽度优先搜索(分支限界法)
[算法思路]
    宽度优先搜索(BFS,Breadth-First Search)也是搜索的手段之一.他与深度优先搜索类似, 从某个状态出发搜索所有可以到达的状态. 根据宽度优先搜索的特点,采用队列实现比较简单.

[算法描述] 

/*遍历连通图*/

void BFS(Graph G,int v)
{    
    /*按广度优先非递归遍历连通图G*/
    cout<<v;vistited[v]=true;      /*访问第v个顶点,并置访问标志数组相应分量值为true*/
     InitQueue(Q);                  /*辅助队列Q初始化,置空*/
    EnQueue(Q,v);                  /*v入队*/
    while(!QueueEmpty(Q))          /*队列非空*/
    {
      DeQueue(Q,u);              /*队头元素出队并置为u*/
      for(w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,w))
       {  /*依次检查u的所有邻接点w,FirstAdjVex(G,u)表示u的第一个邻接点*/
          /*NextAdjVex(G,u,w)表示u相对于w的下一个邻接点,w>=0表示存在邻接点*/
          if(!vistited[w])        /*w为u的尚未访问的邻接顶点*/
            {
             cout<<w; vistited[w]=true; /*访问w,并置访问标志数组相应分量值为true*/
             EnQueue(Q,w);       /*w进队*/
             }
        }
    }
}
[算法效率]

     与深度优先不同之处在与搜索的顺序,宽度优先搜索总是先搜索距离初始状态近的状态.也就是说,它是按照开始状态->只需1次转移就可以到达的所有状态->只需2次转移就可以到达的所有状态->.....这样的顺序进行搜索.对于同一个状态,宽度优先搜索只经过一次,因此复杂度为

O(状态数*转移的方式).很容易地用来求最短路径、最少操作之类问题的答案.

广度搜索的判断重复如果直接判断十分耗时,我们一般借助哈希表来优化时间复杂度.

3.Death-Breadth总结

    宽度优先搜索与深度优先搜索一样,都会生成所有能够遍历到的状态,因此需要对所有状态进行处理时使用宽度优先也是可以的.但是递归函数可以很简短地编写,而且状态的管理也更简单,所以大多数情况下还是用深度优先搜索实现.反之,在求取最短路时深度优先搜索需要反复经过同样的状态,所以还是使用宽度优先搜索比较好.

    宽度优先搜索会把状态逐个加入队列,因此通常需要与状态数成正比的内存空间.反之,深度优先搜索是与最大的递归深度成正比的.一般与状态数相比,递归的深度并不会太大,所以可以认为深度优先搜索更加节省内存.





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值