深度优先搜索算法是一种用于遍历或搜索树或图的算法,其过程简要来说是对于每一个可能的分支路径穷尽所有可能,而且每个分支只能走一遍。对于深度优先搜索算法来说,其关键在于“回溯”,每当道路的可能性被穷尽时,算法就会发动“回溯”能力将事件回溯到做出决定的那一刻,去创造另一种可能。与其空口白谈,不如做出行动,让我们借助题目来理解什么是“回溯”吧。
按照字典序输出自然数 1 到 n 所有不重复的排列,即 n 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。
输入格式
一个整数 n。
输出格式
由 1∼n 组成的所有不重复的数字序列,每行一个序列。
每个数字保留 5个场宽。
输入
3
输出
1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1
直接从代码分析
#include<stdio.h>
int c[10],n;//用c数组来记录数字的使用情况,使用记为1,否则记为0
int d[10];//表示输出结果
int a[10];//记录填入矩阵数字
void dfs(int x)
{
if(x==n)//当一行赋值完成时输出结果
{
for(int v=0;v<n;v++)
{
printf("%d ",d[v]);
}
printf("\n");
}
else
{
for(int i=0;i<n;i++)
{
if(c[i]==0)
{
d[x]=a[i];
c[i]=1;
dfs(x+1);//是一个递归调用,自己调用自己
c[i]=0;
}
}
}
return ;//返回到调用函数,执行c[i]=0的操作
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
c[i]=0;//开始时初始化为0
for(int i=0;i<n;i++)
a[i]=i+1;
dfs(0);
}
从这道题目分析“回溯”的关键在于函数的递归调用,通过对return的使用将结果返回到上一步,使结果产生另一种可能,去得到自己想要的结果。
总的来说深度优先算法是由固定公式的,下面代码就是他的套路
void dfs(int dep,其它参数表)
{ 自定义参数;
if(当前目标状态)
{
输出解或者计数、评价处理;
else
for(int i=1;i<=状态的拓展可能性;i++)
{ if(第i种状态拓展可行)
{ 维护自定义参数;
dfs(dep+1,其它参数表);
}
}
}
}
因此当我们遇到求结果过程中会产生多种可能性的题目时就可以采用深度优先算法,去一步步推导每一步的所有可能,再采用“回溯”去将过程的可能性向自己想要的结果靠近,从而得到答案,