文章目录
前言——什么是搜索与回溯算法
搜索与回溯算法的原理
搜索与回溯是计算机解题中常用的算法,很多问题无法根据某种确定的计算法则来求解,可以利用搜索与回溯的技术求解。回溯是搜索算法中的一种控制策略。它的基本思想是:为了求得问题的解,先选择某一种可能情况向前探索,在探索过程中,一旦发现原来的选择是错误的,就返回一重新选择,继续向前探索,如此反复进行,直至得到解或证明无解。
如迷宫问题:进人迷宫后,先随意选择一个前进方向,一步步向前试探前进,如果碰到死胡同,说明前进方向已无路可走,这时,首先看其他方向是否还有路可走,如果有路可走,则沿该方向再向前试探;如果已无路可走,则返回一步,再看其他方向是否还有路可走;如果有路可走,则沿该方向再向前试探。按此原则不断搜索回溯再搜索,直到找到新的出路或从原路返回入口处无解为止。
搜索与回溯算法由于其自身特性需要先探索再判断是否回溯,通常是由递归实现的,也存在通过循环和队列实现BFS(宽度优先搜索算法)。
现在主流的搜索回溯算法是两种,分别是深度优先搜索回溯算法(DFS)和宽度优先搜索回溯算法(BFS)。接下来我们会一一介绍这两种算法。
下面是通过递归实现的两个深度优先搜索回溯算法框架
递归回溯法算法框架[一]
int search(int k)
{
for(i=1;i<=算符种数;i++)
{
if(满足条件)
{
保存结果
if(到目的地) 输出解;
else search(k+1);
恢复:保存结果之前的状态{
回溯一步}
}
}
}
递归回溯法算法框架[二]
int search(int k)
{
if(到目的地)输出解;
else
for(i=1;i<=算符种数;i++)
{
if(满足条件)
{
保存结果
search(k+1);
恢复:保存结果之前的状态{
回溯一步}
}
}
}
一维DFS
全排列问题
题目描述
按照字典序输出自然数 1 1 1 到 n n n 所有不重复的排列,即 n n n 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。
输入格式
一个整数 n n n。
输出格式
由 1 ∼ n 1 \sim n 1∼n 组成的所有不重复的数字序列,每行一个序列。
每个数字保留 5 5 5 个场宽。
样例 #1
样例输入 #1
3
样例输出 #1
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
提示
1 ≤ n ≤ 9 1 \leq n \leq 9 1≤n≤9。
题目分析
这道题目考察的是运用一定的技巧来寻找1~n的全排列,并且按照字典序从小到大输出,就是我们经常听到的DFS(深度优先搜索回溯算法),DFS算法就是通过标记已经访问过的节点,从还未标记的节点中挑选来合适的节点进行下一次搜索,当把n个数字都排列好了,就可以输出了,这就是我们常说的搜索目的地,即达到符合题目要求的一种状态。为了避免搜索出现重复的部分,我们需要一个标记数组,进行标记数字是否已经使用过,如果已经使用的数字,不能重复使用,达到排列的要求和搜索的剪枝。我们通常把这个标记数组命名为st[N],因为st是stay的缩写,我们经常在CSDN和洛谷上看到许多同学如此命名。接下来就是DFS代码实现。
代码实现
#include<stdio.h>
int a[10],st[10];
void dfs(int x,int n)
{
if(x>n)
{
for(int i=1;i<=n;i++)
printf(" %d",a[i]);
printf