参考 总结 DFS、BFS、回溯、递归 模板。

23 篇文章 0 订阅
22 篇文章 0 订阅

目前在学习 DFS BFS 回溯 递归 及剪枝 ----> 等算法,观看了好多博主的博客 自己总结一下:

递归::简单来说就是自己调用自己,循环下去知道 条件满足,返回条件的数据。
优点: 结构简单
缺点: 效率不高 ,可能会栈溢出

一般形式::

void dfs()
{
       if(符合边界条件)
        {
            ******
               return *; 
          }
        ***
        dfs();
 } 

回溯:是递归的一种,是通过用递归来实现的回溯目的,回溯也可以认为是剪枝的DFS过程。
从树的角度:带回溯的DFS遍历一棵解答树

代码结构::

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

** BFS和DFS相似**
BFS (显示用队列)
DFS (隐试用队列 ->递归)

BFS:::

将(起始)首节点加入队列:
 q.push(head);     
  标记首节点已经被访问:
isvisited[head]=true;                   
 以下自动反应:
 while(!q.empty())                                                                                         
         {                                                                       
               int temp=q.front();                       
               q.pop();                                      
              访问temp,并标记temp已被访问过,
               将temp的子相关节点加入列                                                                              
                    q.push(temp相关节点);         
       }

**

DFS --------DFS 区别

**
BFS : 一层一层的遍历 ——用来求 最短路径
DFS :一条路走到黑 ——运用递归进行回溯遍历

BFS常用语找最短路径(路径没有权重,如果有权重的话 可以用Dijkstra 、bellman等)

BFS简单理解就是 一成一成的往下遍历,如果找到目标节点就是最短路,因为其他的路径最少起码再往下走一层或更多层才有可能到达,无疑比当前这条路径长如下fig1,从开始出发后,先在第一层中找,即1,2,3没有找到结束标记,接着从第二层中找4,5,6,7,8,9没有结束标记,接着从第三层找即10,11,12,end 哇!找到了,这时就可以结束了即最短路径就是start-2-6-end,为什么呢?因为尽管接着继续往下一层走还有可能有到达终点的路径类如(start-1-4-11-14-16-end),但层数增多了,路径增多了,我们要的是最短路径所以不给予考虑。注意,有可能同一层下有多条路径,这时候就最短路径有可能就是多条,类如fig2其实最短路径除了start-2-6-end还有start-3-8-end,但是如果要求只是找到一条最短路径,那么其实一旦找到一条就可以停止了,但如果是找到所有最短路径,务必把当前层遍历完才可结束。
如图所示:
在这里插入图片描述

在这里插入图片描述

大致步骤:(就是找到一条路就可以了)
1.首先将开始节点加入队列
2.取出首节点,判断当前节点是否为结束节点,是则结束while 返回需要信息,如果不不是进行操作3.
3.然后将当前对首节点相邻的(一步到达)所有节点依次放入队列中,放入时记录路径信息。(步数,该节点的父节点等等)。同时标记该节点为一访问过。

BFS 找最短路径模板::

void bfs(begin,end,list)
{
     #1 将开始节点放入队列
     queue=[(begin,1)]
     listtemp=list
   while queue:
        temp,lens=queue.pop(0);
        if( temp==end)
           return list;
       else
          for newnode in tempNeighbourNodes;
             #记录路径信息:最后遍历到一个就加入到队列里 
               queue。append(new node,lens+1)
              listtemp.remove(newnode)
 return 0; 
}

二 来源于其他博主

DFS====
在这里插入图片描述BFS
在这里插入图片描述
两者代码模板

BFS:
#include<cstdio>#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=100;
bool vst[maxn][maxn]; // 访问标记
int dir[4][2]={0,1,0,-1,1,0,-1,0}; // 方向向量
struct State // BFS 队列中的状态数据结构
{
     int x,y; // 坐标位置
     int Step_Counter; // 搜索步数统计器
};
  State a[maxn];
bool CheckState(State s) // 约束条件检验
{
    if(!vst[s.x][s.y] && ...) // 满足条件
       return 1;
    else // 约束条件冲突
    return 0;
}
void bfs(State st)
{
    queue <State> q; // BFS 队列
    State now,next; // 定义2 个状态,当前和下一个
    st.Step_Counter=0; // 计数器清零
    q.push(st); // 入队
    vst[st.x][st.y]=1; // 访问标记
    while(!q.empty())
    {
       now=q.front(); // 取队首元素进行扩展
       if(now==G) // 出现目标态,此时为Step_Counter 的最小值,可以退出即可
       {
             ...... // 做相关处理
        return;
         }
       for(int i=0;i<4;i++)
       {
          next.x=now.x+dir[i][0]; // 按照规则生成下一个状态
          next.y=now.y+dir[i][1];
          next.Step_Counter=now.Step_Counter+1; // 计数器加1
          if(CheckState(next)) // 如果状态满足约束条件则入队
          {
             q.push(next);
             vst[next.x][next.y]=1; //访问标记
            }
       }
       q.pop(); // 队首元素出队
    }
 return;
}



DFS
/*
该DFS 框架以2D 坐标范围为例,来体现DFS 算法的实现思想。
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
const int maxn=100;
bool vst[maxn][maxn]; // 访问标记
int map[maxn][maxn]; // 坐标范围
int dir[4][2]={0,1,0,-1,1,0,-1,0}; // 方向向量,(x,y)周围的四个方向
bool CheckEdge(int x,int y) // 边界条件和约束条件的判断
{
     if(!vst[x][y] && ...) // 满足条件
         return 1;
     else // 与约束条件冲突
     return 0;
}
void dfs(int x,int y)
{
     vst[x][y]=1; // 标记该节点被访问过
     if(map[x][y]==G) // 出现目标态G
     {
       ...... // 做相应处理
       return;
      }
     for(int i=0;i<4;i++)
     {
        if(CheckEdge(x+dir[i][0],y+dir[i][1])) // 按照规则生成下一个节点
           dfs(x+dir[i][0],y+dir[i][1]);
       }
      return; // 没有下层搜索节点,回溯
 }
int main()
{
         .....
      return 0;
}
***



  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值