发布时间:2025-06-24 19:52:41  作者:北方职教升学中心  阅读量:151


在图的遍历中,DFS 从一个起始节点开始,标记该节点为已访问,然后遍历该节点的所有邻居。

总之,DFS 在不同的数据结构中有着广泛的应用,可以帮助我们解决各种复杂的问题。

🏳️‍🌈四、右)是否可行。通过这种方式,我们可以确保图中的每个节点都被访问到。例如,给定一个 N * N 的矩阵 M,表示班级中学生之间的朋友关系。迭代实现使用显式栈来模拟递归的过程,每次从栈中取出一个节点,访问其邻居,并将未访问的邻居压入栈。
例如,对于一个有向无环图,DFS 可以用于拓扑排序,确定节点的线性排序。可以使用 DFS 遍历所有可能的放置方案,找到满足条件的解。在这个过程中,每次尝试在一个位置放置皇后,如果放置后不满足条件,则回溯到上一步重新尝试。具体实现可以通过递归或者迭代的方式进行。


👥总结


本篇博文对 深度优先搜索(DFS)做了一个较为详细的介绍,不知道对你有没有帮助呢

觉得博主写得还不错的三连支持下吧!会继续努力的~

请添加图片描述

以下是使用 DFS 解决最大岛屿面积问题的 C++ 代码示例:

publicintmaxAreaOfIsland(int[][]grid){intmax =0;for(inti =0;i <grid.length;i++){for(intj =0;j <grid[0].length;j++){if(grid[i][j]==1){max =Math.max(dfs(i,j,grid),max);}}}returnmax;}publicintdfs(inti,intj,int[][]grid){if(i<0||i>=grid.length||j<0||j>=grid[0].length||grid[i][j]==0){return0;}grid[i][j]=0;intcount=1;count+=dfs(i+1,j,grid);count+=dfs(i-1,j,grid);count+=dfs(i,j+1,grid);count+=dfs(i,j-1,grid);returncount;}

在这段代码中,maxAreaOfIsland函数遍历二维矩阵,找到所有的陆地格子,并调用dfs函数计算每个岛屿的面积。通过对图进行 DFS,并在回溯时将节点加入到排序结果中,可以得到一个满足拓扑顺序的序列。DFS 的应用场景

    • ❤️(一)路径发现
    • 🧡(二)拓扑排序
    • 💛(三)解决谜题和游戏
    • 💚(四)连通性检测
    • 💙(五)生成迷宫
  • 🏳️‍🌈四、以图的遍历为例,递归函数接受当前节点、

    然而,在遍历大图时,递归实现可能会导致栈溢出问题。

    💛(三)解决谜题和游戏

    在一些谜题和游戏中,DFS 也有广泛的应用。例如,在处理非常深的树或者大规模的图时,递归实现可能会因为栈溢出而失败。下、dfs函数使用递归的方式遍历与当前格子相邻的陆地格子,并将其标记为已访问,最后返回岛屿的面积

    另外,我们还可以使用方向数组的方式来实现 DFS,代码如下:

    int[][]dirs =newint[][]{{-1,0},{1,0},{0,-1},{0,1}};voiddfs(int[][]grid,inti,intj,boolean[]visited){intm =grid.length,n =grid[0].length;if(i <0||j <0||i >=m ||j >=n){return;}if(visited[i][j]){return;}visited[i][j]=true;for(int[]d :dirs){intnext_i =i +d[0];intnext_j =j +d[1];dfs(grid,next_i,next_j,visited);}}

    这种写法使用方向数组来处理上下左右的遍历,更加简洁和方便。这是因为递归调用会在栈上分配空间,当递归深度过大时,栈空间可能会耗尽。拓扑排序的目标是将图中的节点按照依赖关系进行排序,使得对于任意一条有向边 (u, v),节点 u 在排序后的序列中出现在节点 v 之前。然后,在循环中,不断从栈中取出节点进行访问。例如,在任务调度问题中,每个任务可能依赖于其他任务的完成,使用拓扑排序可以确定任务的执行顺序,确保所有任务能够按照正确的顺序完成。

    以下是使用 DFS 解决朋友圈问题的 C++ 代码示例:

    classSolution{public:intfindCircleNum(vector<vector<int>>&M){intn=M.size(),cnt=0;vector<bool>vis(n,false);for(inti=0;i<n;i++){if(!vis[i]){dfs(M,vis,i);++cnt;}}returncnt;}voiddfs(vector<vector<int>>&M,vector<bool>&vis,intu){vis[u]=true;intm=M[u].size();for(inti=0;i<m;i++){if(M[u][i]==1&&!vis[i])dfs(M,vis,i);}}};

    在这段代码中,findCircleNum函数遍历所有学生,如果当前学生未被访问,则调用dfs函数进行深度优先搜索,将与当前学生互为朋友的学生标记为已访问,并增加朋友圈数量。具体实现可以通过递归或者迭代的方式进行。

    在二叉树的遍历中,DFS 可以用于前序、例如,在网络拓扑结构中,我们可以使用 DFS 来检测网络中的节点是否都能够相互通信。例如,在处理复杂的图结构时,我们可以根据需要对栈的操作进行优化,以提高遍历的效率。从起点开始,使用 DFS 不断尝试向四个方向移动,直到找到终点或者遍历完所有可能的路径。这种方式可以确保图中的每个节点都被访问到,并且可以用于检测图的连通性、例如,在一个二维迷宫中,我们可以将迷宫看作一个图,每个格子是一个节点,相邻的格子之间有边连接。如果可行,则继续向该方向进行深度优先搜索,直到找到终点或者无法继续前进。中序、DFS(i,c -1,matrix,toAt,Integer.MIN_VALUE);//遍历最后一列}for(inti =0;i <c;i++){DFS(0,i,matrix,toPa,Integer.MIN_VALUE);//遍历第一行DFS(r -1,i,matrix,toAt,Integer.MIN_VALUE);//遍历最后一行}for(inti =0;i <r;i++){for(intj =0;j <c;j++){if(toPa[i][j]&&toAt[i][j]){List<Integer>cur =newArrayList<>();cur.add(i);cur.add(j);res.add(cur);}}}returnres;}int[][]directions =newint[][]{{0,1},{0,-1},{-1,0},{1,0}};publicvoidDFS(intr,intc,int[][]matrix,boolean[][]toSea,intheight){if(r <0||r >=matrix.length ||c <0||c >=matrix[0].length ||toSea[r][c]||matrix[r][c]<height){return;}toSea[r][c]=true;for(int[]dir :directions){DFS(r +dir[0],c +dir[1],matrix,toSea,matrix[r][c]);}}};

    在这段代码中,pacificAtlantic函数首先初始化两个布尔数组toPa和toAt,分别表示能够流到太平洋和大西洋的格子。比如八皇后问题,要求在一个 8x8 的棋盘上放置 8 个皇后,使得它们不能相互攻击。如果邻居未被访问,则继续对该邻居进行深度优先搜索。DFS函数使用递归的方式遍历与当前格子相邻的格子,并将能够流到相应海洋的格子标记为true。它可以处理大规模的图,并且可以更好地控制遍历的过程。这种方式使得代码逻辑直观,对于小型图或者树的遍历非常高效。具体来说,我们从太平洋和大西洋的边界开始,使用 DFS 遍历与其相邻的格子,如果格子的高度不小于当前格子的高度,则可以流向该格子。以下是使用递归方式实现二叉树的前序、

    💚(四)连通性检测

    对于一个图,DFS 可以用于检测其连通性。inOrderRecur函数和postOrderRecur函数分别用于实现二叉树的前序、这些函数使用递归的方式遍历二叉树中的节点,并输出节点的值。DFS 的应用场景

    ❤️(一)路径发现

    在迷宫问题中,DFS 可以用于寻找从起点到终点的路径。然后,我们继续遍历其他未被访问过的陆地格子,找到最大的岛屿面积。在这个过程中,我们可以记录下路径上的节点,以便在找到终点后回溯得到完整的路径。在这个过程中,我们可以记录下路径,从而生成一个迷宫。DFS 的具体应用示例

    • ❤️(一)迷宫问题
    • 🧡(二)岛屿问题
    • 💛(三)朋友圈问题
    • 💚(四)大洋流水问题
    • 💙(五)图的遍历
  • 👥总结