dfs和bfs的简单总结

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dfs和bfs的简单总结相关的知识,希望对你有一定的参考价值。

首先是dfs,又名深度优先搜索。看名字就知道,它的核心思想就是一直搜索,先在一条路上面一路撸到底,如果到底没有办法前进了,那么判断是否到达终点,如果没有到达,那么就回溯到之前的点再撸。

dfs的要点:

1、考虑当下应该怎么做,在你现在的点上面你应该怎么做,可以怎么做。可以向上吗?可以向下吗?

2、后面的和前面一样的做。递归的思想。

3、要考虑边界,终点等题目给出的条件检测。过滤掉那些不需要的解。

4、利用适当的数据结构,保存当前点是否走过,保存走过的路线等。

 

模版:

void dfs(int step)

{

     判断你的所有条件,如果不行直接return;

   for(循环每一个方向)

  {

      dfs(step+1)

   return;

}

 

map【】【】记录走过的地方,走过的记为1

可以尝试利用堆栈来存放记录

 

#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<iostream>

using namespace std;

int result[10];
int book[10];
int r=0;
/*求九个不同的个位数组合满足,3位+3位=3位的题目,主要是记录一下dfs的模版*/
void dfs(int step)
{
    if(step == 7)/*简单的优化一下*/
    {
        int sum = result[1]*100 + result[4]*100 + result[2]*10 + result[5]*10 + result[3] + result[6];

        if(book[sum%10] == 1)
            return;

        sum/=10;

        if(book[sum%10] == 1)
            return;

        sum/=10;
        if(book[sum%10] == 1)
            return;
    }

    if(step == 10)
    {
        if(result[1]*100 + result[4]*100 + result[2]*10 + result[5]*10 + result[3] + result[6] == result[7]*100 + result[8]*10 + result[9])
        {
            printf("%d%d%d + %d%d%d = %d%d%d\n",result[1],result[2],result[3],result[4],result[5],result[6],result[7],result[8],result[9]);
            r++;
        }
        return;
    }

    int i;
    for (i = 1; i <= 9; i++)
    {
        if(book[i] == 0)
        {
            result[step] = i;
            book[i] = 1;
            dfs(step+1);
            book[i] = 0;
        }
    }

    return;
}

int main()
{
    clock_t start,finish;
    double duration;
    start = clock();

        dfs(1);
    cout<<"-------------------"<<r<<endl;

    finish = clock();
    duration = double(finish - start)/CLOCKS_PER_SEC;
    printf("time used:%f ms\n\n",1000*duration);
        return 0;
}

 

接下来是bfs,又名广度优先搜索,他是一个老实人,一步步走的很踏实,只有把n步的能走的地方走遍,才会走第n+1步,慢慢的拓展

要点:

1、用队列保存每一步走的结果,用一个字段去表示走的步数;

2、没有递归,利用while循环到最终结果;

3、时刻注意队列的首尾指针的位置;

 

模版:

while(head<tail)

{

     for(循环所有方向)

    {

            把坐标进行改变,改成now的坐标,意思就是走一步

            判断所有不可能的情况,不可能就continue

            标记走过了

            在队列中加入这个走过的点和步数

            *****tail++*****

    }

     *****head++*****

}

 

 

#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<iostream>

using namespace std;

/*首先定义方向数组*/


/*     
       X/Y

       0/-1
-1/0   0/0     1/0
       0/1
右下左上*/

int way[4][2] = {
                {1,0},//
                {0,1},//
                {-1,0},//
                {0,-1}//
                };
int map[50][50];
int book[50][50];
int n,m;
int head=0;
int tail=0;
int flag=0;

struct que
{
    int x;
    int y;
    int stpe;
};

struct que q[2500];

int main()
{

    int x,y;
    cin>>n>>m;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            cin>>map[i][j];
        }
    }
    
    head = 1;
    tail = 1;

    q[tail].x = 1;
    q[tail].y = 1;
    q[tail].stpe = 0;
    tail++;

    book[1][1] = 1;
    flag = 0;

    while (head<tail)
    {
        for (int i = 0; i < 3; i++)
        {
            x = q[head].x + way[i][0];
            y = q[head].y + way[i][1];
            
            if(x<1 || y < 1 || x > n || y > m)
                continue;
            if(map[x][y] == 0 && book[x][y] == 0)
            {
                q[tail].x = x;
                q[tail].y = y;
                q[tail].stpe = q[head].stpe + 1;
                tail++;
                book[x][y] = 1;

                
                
            }

            if(x == 4 && y == 3)
                {
                    printf("--------------------%d\n",q[tail-1].stpe);
                    return 0;
                }
        }
        head++;
    }

    return 0;
}

 

 

主要是记录一下两钟搜索的模版,具体两种搜索的使用还要在实际中进行检验,对于迷宫的题目只是现在肯定不会迷茫了,之后对于图的遍历还有别的,对于两种搜索的比较取舍,之后再写吧。

以上是关于dfs和bfs的简单总结的主要内容,如果未能解决你的问题,请参考以下文章

通过迷宫问题简单学习DFS和BFS算法

通过迷宫问题简单学习DFS和BFS算法

通过迷宫问题简单学习DFS和BFS算法

DFS和BFS的思想探究

DFS和BFS的思想探究

熬夜怒肝,图解算法!BFS和DFS的直观解释