深度优先及广度优先算法
程序员文章站
2022-05-21 16:17:24
...
深度优先搜索算法DFS
广度优先搜索算法BFS
在猪呢个算法知识点中占比非常大,应用最多的地方是对图进行遍历(树以为是图的一种)
深度优先搜索算法DFS
DFS解决的 是连通性的问题,及给定两个起始点(或某种起始状态)和一个终点(某种最终状态),判断是否有一条路径能从起点连接到终点。
很多情况下,联通的路径很多条,只需要找出一条即可,DFS只关心路径存在与否,不在乎其长短。
算法的思想:从起点出发,选择一个可选方向不断向前,直到无法继续为止。
然后尝试另外一种方向,直到最后走到终点。
boolean dfs(int maze[][],int x,int y)
{
if(x == B[0] && y == B[1])//判断是否抵达了目的地B,是则立即返回。
{
return true;
}
maze[x][y] == -1; //标记当前已经被访问过的点(一般标记是否被访问过,直接修改访问过的数据,利用一个额外的数据结构来记录)
for(int d =0;d<4;d++) 在规定的4个方向上进行尝试
{
int i =x+dx[d];
int j =y+dy[d];
if(isSafe(maze,i,j)&& dfs(maze,i,j)) 对于每个要尝试的方向,检查是否越界。以及新的点是否已经被访问过了。
{
return true; 如果有一条路径被找到了,则返回true
}
}
return false; 尝试了所有可能还没找到B,则返回false
}
DFS递归实现
利用递归去实现DFS可以让代码看上去很简洁
递归的时候需要讲话当前程序中的变量及及状态压入到系统的栈里面
压入和弹出都需要较多的时间,如果需要压入很深的栈,会造成运行效率低下。
DFS非递归实现:
栈的数据结构也支持压入和弹出操作。
bool dfs(int maze[][],int x,int y)
{
stack<int[]>stack =new stack<>();//创建一个stack,用来将要访问的点压入及弹出
maze[x][y] = -1; //将起始点压入栈,并标记为被访问过。
while(!stack.empty())//只要stack不为空,就不断地循环,处理每一个点
{
int pos[] =stack.pop();
x =pos[0]; //从堆栈取出当前要处理的点
y =pos[1];
if(x==B[0]&&y ==B[1]) //判断是否抵达了目的地B,否则返回ture
{
return true;
}
}
for(int d =0;d<4;d++) //如果不是就从4个方向上去尝试
{
int i=x+dx[d];
int j =y+dy[d];
if(issafe(maze,i,j))
{
stack.push(new int[]{i,j}); //将各个方向上的点压入堆栈,并把标记为访问过
maze[i][j] =-1;
}
}
return false;//尝试了所有可能还没有找到B,返回false
}