版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shineboyxxb/article/details/52200236
深度优先搜索适合解决必须走到最深处(例如对于树,须走到它的叶子节点)才能得到一个解的问题。通常利用递归实现,所以每次递归开始的时候要判断是否达到收敛条件,若达到了则得到一个可行解,若没达到,则对当前状态进行扩展(扩展的时候通常会根据实际情况过滤掉一些非法的状态,这个过程叫剪枝,适当的剪枝有时能极大地提高搜索的速度),如果要求输出具体解,则此时应该保存该状态,当扩展结束后,需要释放这个保存的状态。下面是一个深度优先搜索的编程模板:
/**
* dfs 模板.
* @param[in] input 输入数据指针
* @param[inout] cur or gap 标记当前位置或距离目标的距离
* @param[out] path 当前路径,也是中间结果
* @param[out] result 存放最终结果
* @return 路径长度,如果是求路径本身,则不需要返回长度
*/
void dfs(type *input, type *path, int cur or gap, type *result) {
if (数据非法) return 0; // 终止条件
if (cur == input.size( or gap == 0)) { // 收敛条件
将 path 放入 result
}
if (可以剪枝) return;
for(...) { // 执行所有可能的扩展动作
执行动作,修改 path
dfs(input, step + 1 or gap--, result);
恢复 path
}
}
下面用Leecode上一个具体的问题来说明深度优先搜索算法:
实现的程序如下:
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Solution {
public:
vector<vector<string> > solveNQueens(int n) {
column=vector<int>(n,0);
principle_diagonals=vector<int>(2*n,0);
counter_diagonals=vector<int>(2*n,0);
vector<int> C(n,0); //C[i]的值表示第i行皇后所在的列
vector<vector<string>> result;
DFS(result,C,0);
return result;
}
private:
vector<int> column; //column[i]表示第i行皇后所在的列
vector<int> principle_diagonals; //表示主该主对角线是否已经有皇后
vector<int> counter_diagonals; //表示副对角线是否已经有皇后
void DFS(vector<vector<string> >& result,vector<int>&C ,int row)
{
int n=C.size();
if(row==n) //收敛条件
{
string tmpStr(n,'.');
vector<string>tmpResult(n,tmpStr);
for(int i=0;i<n;++i)
{
tmpResult[i][C[i]]='Q';
}
result.push_back(tmpResult);
return;
}
for(int i=0;i<n;++i)
{
bool ok=column[i]==0&&principle_diagonals[row+i]==0 && counter_diagonals[n-row+i]==0;
if(ok) //用于剪枝,只扩展合法的状态
{
//执行扩展
column[i]=principle_diagonals[row+i]=counter_diagonals[n-row+i]=1;
C[row]=i;
DFS(result,C,row+1);
//撤销扩展
column[i]=principle_diagonals[row+i]=counter_diagonals[n-row+i]=0;
C[row]=0;
}
}
}
};
int _tmain(int argc, _TCHAR* argv[])
{
vector<vector<string>> result;
Solution sln;
result=sln.solveNQueens(4);
for (int i=0;i<result.size();++i)
{
for (int j=0;j<result[0].size();++j)
{
cout<<result[i][j]<<endl;
}
cout<<endl;
cout<<endl;
}
return 0;
}
对于4皇后,上述程序输出结果如下: