代码
//深度优先遍历
void DFS(int u)
{
flag[u]=true;
cout<<u<<" ";
for(int i=0; i<n; i++)
{
if(flag[i]==false&&G[u][i]==1)
{
DFS(i);
}
}
}
//广度优先遍历
void BFS(int u)
{
//开始的点标明访问过
flag[u]=true;
queue<int> q;
q.push(u);
//只要队列不空,就出队,出队之前检查这个点有没有连通别的点且那个点没被访问过
while(!q.empty())
{
for(int i=0; i<n; i++)
{
if(G[q.front()][i]==1&&flag[i]==false)
{
q.push(i);
flag[i]=true;
}
}
cout<<q.front()<<" ";
q.pop();
}
}
深度搜索
- 深度搜索(邻接矩阵方式)
- 深度搜索(邻接表结构)
广度优先遍历
- 广度优先遍历(邻接矩阵方式)
- 广度优先遍历(邻接表方式)
例题
- 问题一:广度优先遍历,深度优先遍历与回溯算法的关系,尤其是深度优先与回溯关系。参考题目:搜索回溯题目
- 问题二:地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?
思路:
深度优先遍历
void DFS(int row, int column, int k)
{
if((!map[row][column]))
{
map[row][column] = 1;
number++;
// cout << "row" << row << "column" << column << endl;
for(int i = 0; i < 4; i++)
{
int new_row = row + direction[i][0];
int new_column = column + direction[i][1];
if(JudgeIfRight(new_row,new_column, k))//judge表示元素在范围内且满足题目要求
DFS(new_row,new_column,k);
}
}
}
一个简短写法:
class Solution {
public:
int movingCount(int m, int n, int k) {
vector<vector<bool>> visit(m, vector<bool>(n, 0));
visit[0][0] == 1;
return dfs(0, 0, m, n, k, visit);
}
int dfs(int i, int j, int m, int n, int k, vector<vector<bool>>& visit) {
if (i<0 || i==m || j<0 || j==n || visit[i][j] || i%10+i/10+j%10+j/10>k)
return 0;
visit[i][j] = true;
return dfs(i+1, j, m, n, k, visit) +
dfs(i-1, j, m, n, k, visit) +
dfs(i, j+1, m, n, k, visit) +
dfs(i, j-1, m, n, k, visit) + 1;
}
};
广度优先遍历:
int BFS(int k)
{
queue<vector<int>> q;
q.push({0,0});
map[0][0] = 1;
int number = 0;
while(!q.empty())
{
for(int i = 0; i < 4; i++)
{
int new_row = (q.front())[0] + direction[i][0];
int new_column = (q.front())[1] + direction[i][1];
if(JudgeIfRight(new_row,new_column,k)&& !map[new_row][new_column])
{
q.push({new_row,new_column});
map[new_row][new_column] = 1;
}
}
q.pop();
number++;
}
return number;
}