递归与回溯,DFS及BFS的算法

转载自:https://blog.csdn.net/qq_21158525/article/details/79459378

递归:就是出现这种情况的代码: (或者说是用到了栈)

解答树角度:在dfs遍历一棵解答树

优点:结构简洁

缺点:效率低,可能栈溢出

递归的一般结构:

void f()  
{  
     if(符合边界条件)  
    {  
       ///////  
        return;  
    }  

     //某种形式的调用  
     f();  
} 

回溯:递归的一种,或者说是通过递归这种代码结构来实现回溯这个目的。回溯法可以被认为是一个有过剪枝的DFS过程。

解答树角度:带回溯的dfs遍历一棵解答树

回溯的一般结构:

void dfs(int 当前状态)  
    {  
          if(当前状态为边界状态)  
          {  
            记录或输出  
            return;  
          }  
          for(i=0;i<n;i++)       //横向遍历解答树所有子节点  
         {  
               //扩展出一个子状态。  
               修改了全局变量  
               if(子状态满足约束条件)  
                {  
                  dfs(子状态)  
               }  
                恢复全局变量//回溯部分  
            }  
    }

经典例题,比如解数独问题。

BFS与 DFS

BFS的占用的是队列的空间,DFS 占用的是栈的空间(因为递归)。BFS和DFS的空间复杂度恰好相反。对链状图,BFS最好(队列中最多只有1个元素),DFS最差(所有节点都在根节点的递归内)。对起点与其他所有点相邻的图,DFS最好(递归深度为1),BFS最差(队列中放满了所有与起点相邻的图)。
BFS一般结构:

queue<type> q;

q.push(初始状态);



 while (!q.empty())

{

  type t = q.front() ;

  q.pop();

  遍历 t 的各个Next状态  next

  { 

    if (next is legal)

      q.push(next); 计数或维护等; 

  } 

}

但是BFS的状态数一多,需要的空间就会较大。
DFS 一般结构与回溯相似

DFS(顶点) 

{

  处理当前顶点,记录为已访问

  遍历与当前顶点相邻的所有未访问顶点

  {

      标记更改;

      DFS( 下一子状态);

      恢复更改;

  }

}

猜你喜欢

转载自blog.csdn.net/u013182960/article/details/80869663