02_01_深度优先搜索(Depth-First Search,DFS)

news/2024/10/20 11:47:41/

深度优先搜索(Depth-First Search,DFS)

深度优先搜索(Depth-First Search,DFS)介绍:

深度优先搜索(Depth-First Search,DFS)是一种图算法,用于遍历或搜索图的节点。它从起始节点开始,沿着一条路径尽可能深入地探索图,直到到达末端节点或无法继续前进,然后回溯到上一个节点,继续探索其他路径。

深度优先搜索(Depth-First Search,DFS)原理:

  1. 选择一个起始节点,并将其标记为已访问。
  2. 检查起始节点的邻居节点,选择一个未被访问的邻居节点。
  3. 将选中的邻居节点标记为已访问,并将其加入遍历路径中。
  4. 递归地应用步骤2和步骤3,直到当前节点没有未访问的邻居节点。
  5. 回溯到上一个节点,并继续检查其他未访问的邻居节点。
  6. 重复步骤2到步骤5,直到遍历完整个图或找到目标节点。

Java 代码实现:

DFS使用栈或递归来实现。使用栈时,可以将待访问的节点依次入栈,并在遍历过程中不断出栈节点进行处理。使用递归时,递归函数会自动处理节点的遍历顺序和回溯。

package com.algorithm.graph;import java.util.ArrayList;
import java.util.List;
import java.util.Stack;public class DFS {/*** 测试方法** @param args*/public static void main(String[] args) {/*** 构建一个二叉树,调用 DFS 算法*/Graph graph = new Graph(6);graph.addEdge(0, 1);graph.addEdge(0, 2);graph.addEdge(1, 3);graph.addEdge(2, 4);graph.addEdge(2, 5);System.out.println("Depth-First Traversal (starting from vertex 0):");graph.DFS(0);}
}/*** 图数据结构*/
class Graph {/*** 节点数量*/private int numVertices;/*** 邻接表*/private List<List<Integer>> adjacencyList;/*** 构造方法** @param numVertices 节点数量*/public Graph(int numVertices) {this.numVertices = numVertices;this.adjacencyList = new ArrayList<>(numVertices);for (int i = 0; i < numVertices; i++) {adjacencyList.add(new ArrayList<>());}}/*** 添加边到邻接表** @param source      起点* @param destination 终点*/public void addEdge(int source, int destination) {adjacencyList.get(source).add(destination);}/*** 深度优先搜索算法实现** @param startVertex 进行 DFS 的顶点*/public void DFS(int startVertex) {/*** 标记节点是否已被访问*/boolean[] visited = new boolean[numVertices];/*** 存储待访问的节点*/Stack<Integer> stack = new Stack<>();/*** 将第一个节点(头节点)标记为已访问*/visited[startVertex] = true;/*** 将第一个节点入栈*/stack.push(startVertex);/*** 遍历整个栈*/while (!stack.isEmpty()) {/*** 获取当前栈顶元素(节点)*/int currentVertex = stack.pop();/*** 打印当前节点*/System.out.print(currentVertex + " ");List<Integer> neighbors = adjacencyList.get(currentVertex);/*** 遍历所有邻接点,如果节点没有访问过,则访问并入栈*/for (int neighbor : neighbors) {if (!visited[neighbor]) {visited[neighbor] = true;stack.push(neighbor);}}}}
}

代码简单解释:

该代码中,首先定义了一个Graph类表示图数据结构,其中包括节点数量numVertices和邻接表adjacencyList。addEdge方法用于添加边到邻接表。

在DFS方法中,使用一个布尔数组visited来标记节点是否已被访问。创建一个栈stack用于存储待访问的节点。首先将起始节点标记为已访问并入栈。接下来,从栈中取出节点,打印该节点,并将其未访问的邻居节点标记为已访问并入栈。重复这个过程直到栈为空。

在主函数中,创建一个Graph对象,并通过addEdge方法添加边。然后调用DFS方法以深度优先的方式遍历图,从起始节点0开始。

程序执行结果:

Depth-First Traversal (starting from vertex 0):
0 2 5 4 1 3 
Process finished with exit code 0

DFS的应用:

  1. 图的遍历:DFS可以用于遍历图中的所有节点,以便获取图的结构信息或执行特定操作。
  2. 连通性检测:DFS可以用于检测图中的连通分量,即查找图中的所有连通子图。
  3. 拓扑排序:DFS可以进行拓扑排序,即对有向无环图进行排序,使得任何有向边的起始节点都排在终止节点的前面。
  4. 寻找路径:DFS可以用于寻找两个节点之间的路径,如迷宫问题、远程路径规划等。
  5. 回溯算法:DFS的回溯特性使其成为解决组合优化问题、生成排列和组合等问题的有效方法。

需要注意的是,DFS没有保证找到最优解,它只能保证找到可行解。对于某些问题,如最短路径问题,通常需要使用其他算法(如Dijkstra算法)来获得最优解。

用图画的方式描述 DFS 算法:

当我们使用图来描述DFS算法时,可以通过节点和边的连接关系来表示图的结构。下面是一个使用节点和边的图示例,描述DFS算法的执行过程:

假设我们有以下图结构:

     0/ \1   2/   / \3   4   5

开始时,选择起始节点0进行深度优先搜索。我们从节点0开始,然后沿着一条路径尽可能深入地探索。
首先,我们选择节点1作为下一个要探索的节点,然后再选择节点3。
由于节点3没有未访问的邻居节点,我们回溯到节点1。
接下来,我们选择节点2作为下一个要探索的节点,然后再选择节点4。
再次回溯到节点2,我们发现节点2还有一个未访问的邻居节点5。
因此,我们选择节点5进行探索。

DFS算法执行的过程描述:

  1. 选择起始节点0,并将其标记为已访问。
     0*/ \1   2/   / \3   4   5
  1. 选择节点0的邻居节点1,并将其标记为已访问。
     0*/ \1*  2/   / \3   4   5
  1. 选择节点1的邻居节点3,并将其标记为已访问。
     0*/ \1*  2/   / \3*  4   5
  1. 回溯到节点1,因为节点1没有其他未访问的邻居节点。

  2. 选择节点2的邻居节点4,并将其标记为已访问。

     0*/ \1   2*/   / \3   4*  5
  1. 回溯到节点2。

  2. 选择节点2的邻居节点5,并将其标记为已访问。

     0*/ \1   2*/   / \3   4   5*
  1. 回溯到节点2,因为节点2没有其他未访问的邻居节点。

  2. 回溯到节点0。

最终,DFS算法的遍历路径为0-1-3-2-4-5。

通过图的可视化,可以更直观地理解DFS算法的执行过程,以及节点的访问顺序和回溯操作。


http://www.ppmy.cn/news/470112.html

相关文章

演唱会 (15 分)

持续时间是该音乐会中所有歌曲的持续时间之和。 请帮助xrf&#xff0c;找出演唱会持续时间之间可能的最小差异&#xff08;分钟&#xff09;。 输入格式: 第一行包含一个整数t&#xff08;1≤t≤1000&#xff09;–测试案例的数量。 每个测试案例由一行包含三个整数a,b,c&am…

演唱会售票网站

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a;

演唱会买门票问题

转载思路&#xff1a; https://blog.csdn.net/ssl_lzx/article/details/61206679

如何抢演唱会门票,AI给你一套超强攻略

有的歌手的演唱会门票不会放在一个平台&#xff0c;以应该提前做好攻略&#xff0c;那么对于我这种新手小白该如何抢到票呢&#xff0c;其实我们可以通过AI去找到解决办法 1、打开多御浏览器、找到ChatGPT进入页面 二、提前准备好你想去看谁谁的演唱会&#xff0c;他会给你分析…

音乐节、livehouse、演唱会的区别

说唱表演的角度——Max马俊 Livehouse&#xff1a;最大的特点是互动性强&#xff0c;因为和观众的距离最近&#xff0c;所以可以有很多跟观众互动的方式&#xff0c;演唱曲目也会有针对性的制作现场演出的版本&#xff0c;跟DJ的配合也尤为重要 音乐节&#xff1a;最大的特点…

门票的问题

题目的链接 https://www.dotcpp.com/oj/contest4318_problem0.html 题目描述 有M个小孩到公园玩&#xff0c;门票是1元。其中N个小孩带的钱为1元&#xff0c;K个小孩带的钱为2元。售票员没有零钱&#xff0c;问这些小孩共有多少种排队方法&#xff0c;使得售票员总能找得开零…

刘德华重庆演唱会场外

昨晚刘德华重庆演唱会&#xff0c;我和一同事报着开场后去混个低价票进去看看的心态&#xff0c;下班吃了饭就忙到坐车往奥体赶。结果里奥体还很远就开始严重堵车&#xff0c;车外看到很多人在步行往奥体走&#xff0c;我们也是在离奥体多远就下车步行了&#xff0c;果然比车快…

香港--北京演唱会------罗大佑

香港--北京演唱会------罗大佑 http://sh.joyo.com/product/music.asp?prodidbkmu501187&uidu77upnmy6e0pwj8yisggms75a&ref%2FProdSearch%2Fprodsearch%2Easp 上周刚买了这套2DVD2CD套装&#xff0c;引进版的&#xff0c;不贵。但&#xff0c;如同引进版历来的作风&a…