描述
深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。属于盲目搜索。 深度优先搜索是图论中的经典算法,利用深度优先搜索算法可以产生目标图的相应拓扑排序表,利用拓扑排序表可以方便的解决很多相关的图论问题,如最大路径问题等等。 因发明“深度优先搜索算法”,约翰·霍普克洛夫特与罗伯特·塔扬在1986年共同获得计算机领域的最高奖:图灵奖。源于:维基百科
应用
迷宫问题
问题描述:有一个m*n的迷宫(m行n列),用1表示可以走,而0表示不可以走;第一行是两个数m,n,接下来的是m行n列由1,0组成的数据,最后两行是起始点和终点;
输出:所有可行的路径,描述一个点时用(x,y)的形式,每个点之间用“->”表示方向;如果无法到达终点则输出-1;
解决代码:
#include <bits/stdc++.h>
using namespace std;
const int maxm = 50, maxn = 50;
int m, n; //m行n列
int vis[maxm][maxn]; //访问数组,代表是否访问过
int f[4][2] = {0, -1, -1, 0, 0, 1, 1, 0}; //指示方向
int map0[maxm][maxn]; //地图
vector<pair<int, int>> q; //vector容器,pair对
int xb, yb, xe, ye; //b代表起始点,e代表终点
bool flag = true; //标志
bool judge(int x, int y) //判断函数,判断x,y是否符合条件
{
return (x >= 1 && x <= m && y >= 1 && y <= n && vis[x][y] == 0 && map0[x][y] == 1);
}
void DFS(int x, int y)
{
if (x == xe && y == ye) //判断结束的标志
{
flag = false;
for (int i = 0; i < q.size(); i++)
{
if (i == 0)
cout << "(" << q[i].first << "," << q[i].second << ")";
else
{
cout << "->"
<< "(" << q[i].first << "," << q[i].second << ")";
}
}
cout << endl;
return;
}
//开始深搜,四个方向
for (int i = 0; i < 4; i++)
{
int x1 = x + f[i][0];
int y1 = y + f[i][1];
if (judge(x1, y1)) //表明本次方向的目的坐标符合条件
{
vis[x1][y1] = 1; //标记已用
pair<int, int> z(x1, y1); //pair数组对
q.push_back(z); //把z加入到q中
DFS(x1, y1); //递归
vis[x1][y1] = 0; //回溯
q.pop_back(); //弹出
}
}
}
int main()
{
memset(map0, 0, sizeof map0);
memset(vis, 0, sizeof vis);
cin >> m >> n;
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
cin >> map0[i][j];
}
}
cin >> xb >> yb >> xe >> ye;
vis[xb][yb] = 1;
pair<int, int> z(xb, yb);
q.push_back(z);
DFS(xb, yb);
if (flag)
{
cout << -1 << endl;
}
return 0;
}
全排列问题
问题描述:对于一个数n,输出从1,…,n的全排列组合;
解决代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 50;
int n;
int vis[maxn];//访问数组
vector<int> q;//可变数组
//传进来的是当前点
void DFS(int x)
{
if (x == n) //结束标志
{
for (int i = 0; i < q.size(); i++)
{
if (i == 0)
cout << q[i];
else
cout << " " << q[i];
}
cout << endl;
return;
}
for (int i = 1; i <= n; i++)
{
if (vis[i] == 0)
{
vis[i] = 1;
q.push_back(i);
DFS(x + 1);
vis[i] = 0;
q.pop_back();
}
}
}
int main()
{
memset(vis, 0, sizeof vis);//初始化数组
cin >> n;
for (int i = 1; i <= n; i++)
{
q.push_back(i);
vis[i] = 1;
DFS(1);
vis[i] = 0;//回溯
q.clear();
}
//DFS(0);
return 0;
}