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;
}

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

时间: 2024-10-12 04:07:05

dfs和bfs的简单总结的相关文章

PAT 05-1 List Components (简单DFS与BFS)

刚一拿到这道题把他想的太复杂了 明明是长度最大为十的顺序结构就能解决的问题,竟然优先想到用链表. BFS牵扯到一个队列的操作,在这种小规模数据里面 用顺序结构好很多 题目如下: For a given undirected graph with N vertices and E edges, please list all the connected components by both DFS and BFS. Assume that all the vertices are numbered

lightoj 1111 - Best Picnic Ever(dfs or bfs)

题目链接 http://www.lightoj.com/volume_showproblem.php?problem=1111 题意:给你一个有向图再给你几个人的位置,问所有人可以在哪些点相聚. 简单的搜索题,可以用bfs也可以用dfs,要注意的是存边的时候最好用vector,因为边比较少. 用struct会超时.下面附上dfs和bfs代码. #include <iostream> #include <cstring> #include <queue> #include

关于DFS和BFS的理解 以及坐标的定义

1: 坐标类型搜索 :这种类型的搜索题目通常来说简单的比较简单,复杂的通常在边界的处理和情况的讨论方面会比较复杂,分析这类问题,我们首先要抓住题目的意思,看具体是怎么建立坐标系(特别重要), 然后仔细分析到搜索的每一个阶段是如何通过条件转移到下一个阶段的.确定每一次递归(对于DFS)的回溯和深入条件,对于BFS,要注意每一次入队的条件同时注意判重.要牢牢把握 目标状态是一个什么状态,在什么时候结束搜索.还有,DFS过程的参数如何设定,是带参数还是不带参数,带的话各个参数一定要保证能完全的表示一个

图的DFS与BFS遍历

一.图的基本概念 1.邻接点:对于无向图无v1 与v2之间有一条弧,则称v1与v2互为邻接点:对于有向图而言<v1,v2>代表有一条从v1到v2的弧,则称v2为v1的邻接点. 2.度:就是与该顶点相互关联的弧的个数. 3.连通图:无向图的每个顶点之间都有可达路径,则称该无向图为连通图.有向图每个顶点之间都有<v1,v2>和<v2,v1>,则称此有向图为强连通图. 二.存储结构 1.邻接矩阵存储(Adjacency Matrix) 对无权图,顶点之间有弧标1,无弧标0:

图的 DFS 与 BFS 复杂度分析

DFS的复杂度分析: 对于邻接表的存储方式:因为邻接表中每条链表上的从第2个结点到表尾结点一定是表头结点的邻接点,所以遍历表头结点的邻接的过程中只需要遍历这些顶点即可,无需遍历其他的顶点,所以遍历某个顶点的所有邻接点的复杂度为O(ei), ei为每个顶点的邻接点个数,也就是每条链表的边数.所以邻接表版的 dfs 遍历所有邻接点的时间复杂度为 O(e1 + e2 + e3 + .... + en) ,因为所有边数之和为 E , 所以时间复杂度为 O(E) , 又因为访问每个顶点都必须被访问一次,

学习笔记:图的DFS和BFS的两种搜索办法

  在学习图结构的过程中,DFS和BFS是两种不同的遍历方式,其寻找元素具有不同的优点和缺陷. BFS被称作广度优先算法, 在遍历整个图的过程中,BFS将采用入队的方式进行,值得一提的是,这和树结构中的层序遍历有很大的相似之处. 在层序遍历中,将父亲节点入队后,在父亲节点出队后,将其儿子节点入队. 同理在图的BFS遍历中,先让BFS的首元素入队,在收元素入队后将他的儿子节点入队,放能够实现BFS搜索,他们的整体思想是一样的. 1 void TraversalGraph_BFS(LGraph Gr

递归,回溯,DFS,BFS的理解和模板【摘】

递归:就是出现这种情况的代码: (或者说是用到了栈) 解答树角度:在dfs遍历一棵解答树 优点:结构简洁缺点:效率低,可能栈溢出 递归的一般结构: 1 void f() { 2 if(符合边界条件) { 3 /////// 4 return; 5 } 6 7 //某种形式的调用 8 f(); 9 } 回溯:递归的一种,或者说是通过递归这种代码结构来实现回溯这个目的.回溯法可以被认为是一个有过剪枝的DFS过程.解答树角度:带回溯的dfs遍历一棵解答树回溯的一般结构: 1 void dfs(int

搜索分析(DFS、BFS、递归、记忆化搜索)

搜索分析(DFS.BFS.递归.记忆化搜索) 1.线性查找 在数组a[]={0,1,2,3,4,5,6,7,8,9,10}中查找1这个元素. (1)普通搜索方法,一个循环从0到10搜索,这里略. (2)递归(从中间向两边) 1 //递归一定要写成记忆化递归 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool vis[11]; 5 int count1=0; 6 7 void search(int n){ 8 count1++; 9

数据结构(11) -- 邻接表存储图的DFS和BFS

/////////////////////////////////////////////////////////////// //图的邻接表表示法以及DFS和BFS /////////////////////////////////////////////////////////////// #include <iostream> #include <stdlib.h> #include <queue> using namespace std; //图的邻接表表示法