深度优先搜索---一个懵逼的东东

Posted re-tle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度优先搜索---一个懵逼的东东相关的知识,希望对你有一定的参考价值。

深度优先搜索属于图算法的一种,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.(来自百度百科)

先解释以下深度:

深度指在搜索的过程中沿着一条路一直向下进行,直到这条路没有下一个节点停止,然后返回到上一步接着进行上述操作

所以深度优先搜索的整体结构就是:

1.递归2.剪枝

可能这样说有点不清楚,举个例子

打印1-4的全排列开头为1和2的所有序列;

1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
1 4 2 3
1 4 3 2
2 1 3 4
2 1 4 3
2 3 1 4
2 3 4 1
2 4 1 3
2 4 3 1

上述是由编译器进行深搜算法打印的1-4的全排列开头为1和2的所有序列

下面是运行的代码

#include<bits/stdc++.h>
using namespace std;
int n,pd[100],used[100];//pd是判断是否用过这个数
void print()//输出函数

    int i;
    for(i=1;i<=n;i++)
    printf("%5d",used[i]);//保留五位常宽
    cout<<endl;

void dfs(int k)//深搜函数,当前是第k格

    int i;
    if(k==n) //填满了的时候
    
        print();//输出当前解
        return;
    
    for(i=1;i<=n;i++)//1-n循环填数
    
        if(!pd[i])//如果当前数没有用过
        
            pd[i]=1;//标记一下
            used[k+1]=i;//把这个数填入数组
            dfs(k+1);//填下一个
            pd[i]=0;//回溯
        
    

int main()

    cin>>n;
    dfs(0);//注意,这里是从第0格开始的!
    return 0;

我们通过上述举例以及举例所用代码来进行分析:

比如我们发现输出的第一行是1 2 3 4,第二行是1 2 4 3

为什么一行会输出四个数字?是因为剪枝,即在递归函数中下一个判定条件,也就是深搜搜索到这一步已经没有路能走了

上边解释剪枝可能有点笼统,简单的说就是走到这,不能往下走了

为什么要有剪枝呢?很显然根据剪枝的定义,就是避免遍历的时候越界,或者去掉影响结果的因素

第二个问题,为什么第一行是1 2 3 4,而第二行是1 2 4 3?

因为在其中进行递归操作,在这先说一个标记数组,这个数组作用是,对所已经便利过的数进行标记,下来我们看下标记数组的记录过程

我们开始运行程序输入4:

进入dfs(0),dfs()中系数表示已经确定几个数的输出,下来遍历1-4发现pd[1]=0,标记1,即pd[1]=1,used[1]=1

下来进行dfs(1)遍历1-4发现used[1]=1,跳过,下一个pd[2]=0,标记2,即pd[2]=1,used[2]=2

依次一直到dfs(4)遍历时发现,满足剪枝条件,输出第一行1 2 3 4

下来进行递归的回溯操作,即在dfs(3)的时候我们标记pd[4]=1;现在回溯pd[4]=0,这样在dfs(3)中的for遍历结束

下来到了dfs(2)是for遍历到i=3的时候进行的上面的dfs(3)的递归结束,所以回溯pd[3]=0,此时dfs(2)中的i=3结束,进行i=4遍历的pd[i]=0,所以used[2+1]=4,即pd[4]=1;

下来进行dfs(2)是i=4的dfs(3)递归,当i=3时pd[i]=0,所以used[3+1]=3,pd[3]=1,下来进行dfs(4)递归

此时达到剪枝边界,进行输出,得到1 2 4 3

然后下来进行..........

算了不写了,太累了,剩下递归,剪枝,回溯按照上面的步骤进行即可

简单的说就是

dfs(k)

        if(k==n)剪枝
for()遍历所有,和上面if没关系 如果未标记 标记 dfs(k+1)递归 回溯

如果遍历的是图,那么就是遍历相同深度未标记的子节点,具体题目中如何使用看下https://www.cnblogs.com/RE-TLE/category/1531861.html里面的题目以及题解

以上来自一个练习时间长达一年的蒟蒻Acmer,有事您Q我,我一直在de

 

以上是关于深度优先搜索---一个懵逼的东东的主要内容,如果未能解决你的问题,请参考以下文章

有关搜索和深度优先搜索的浅陋见解

岛屿的数量(深度优先搜索算法)

数据结构与算法图遍历算法 ( 深度优先搜索 DFS | 深度优先搜索和广度优先搜索 | 深度优先搜索基本思想 | 深度优先搜索算法步骤 | 深度优先搜索理论示例 )

基本算法——深度优先搜索(DFS)和广度优先搜索(BFS)

简述深度优先搜索遍历的方法。

Python算法-深度优先搜索&广度优先搜索(DFS&BFS)