1、DFS深度优先搜索
每次将一个节点一直搜到底,边回溯边查看是否可以接着向另一边向下搜素
数据结构是栈 空间O(h)
2、BFS宽度优先搜索
每次将树的一层搜索, 当每层搜索完成后在接着搜索下一层
数据结构是队列 空间O()
/*
深度优先搜索是将一个分支走到头在返回一个节点走另一个分支,知道走完所有分支
递归过程提供了一个栈的结构,而回复向下走之前的状态,才能往另一个分支前行
*/
#include <iostream>
using namespace std;
const int N = 8;
int path[N], n; // path[N]存放答案的路径
bool st[N]; // 存放没个数是否被用过
void dfs (int k)
{
if (k == n) // 已经找到了一个答案
{
for (int i = 0; i < n; i ++) printf("%d ", path[i]);
puts("");
return;
}
for (int i = 1; i <= n; i ++)
{
if (!st[i])
{
path[k] = i;
st[i] = true;// 向下走的过程中状态的改变回来要复原
dfs(k + 1); // 递归时是递归下一层体现出深度(向下走的过程),递归结束就是往回走
st[i] = false;// 出来的时候清空现场是深度优先的特点,这样就需要把所有的分支都走完
}
}
}
int main()
{
cin >> n;
dfs (0);
return 0;
}
/*
bfs思路是定义一个队列, 队列中存放的是可行的路径
初始化队列中的元素
每次向下进行时将队列中这个元素弹出,如果找到就将下一个元素添加到队列,当队列为空,即找到接着往下找
*/
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
const int N = 110;
queue<PII> q;// 判断用的队列
int g[N][N], d[N][N];// g用来存图,d用来存距离
//PII pre[N][N]; // 存储这条路径前面一个点
int n, m;
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};// 定义向量, 来枚举每个方向的图中元素
int bfs ()
{
memset (d, -1, sizeof d);
d[0][0] = 0;// 初始化第一个元素必须在memset的后面 不然白初始化
q.push({0, 0});// 队列初始化
// pre[0][0] = {-1, -1}; // 路径第一个点初始化
while (q.size())
{
PII t = q.front();
q.pop();
for (int i = 0; i < 4; i ++)// 每次向四个方向查找,在对应的数组中记录distance
{
int x = t.first + dx[i], y = t.second + dy[i];// 下一个元素的坐标
if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1)// 坐标满足不越界,有路且未被走过
{
//pre[x][y] = t;// 记录这个点的上一个点
d[x][y] = d[t.first][t.second] + 1;//在上一个元素的距离加一
q.push({x, y});// 可行就加到队列中
}
}
}
/*
输出路径
int i = n - 1, j = m - 1;
while (~i || ~j)
{
printf("(%d, %d)\n", i, j);
auto t = pre[i][j];
i = t.first, j = t.second;
}
*/
return d[n - 1][m - 1];// 终点的距离
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i ++)
for (int j = 0; j < m; j ++)
scanf("%d", &g[i][j]);
printf("%d", bfs());
return 0;
}