图的寻路算法详解:基于深度优先搜索(DFS)的实现
图的寻路算法详解:基于深度优先搜索DFS的实现
🌺The Begin🌺点点关注,收藏不迷路🌺 |
一、寻路算法概述
图的寻路算法是图论中的基础算法之一,用于找到从一个顶点到另一个顶点的路径。深度优先搜索(DFS)是实现寻路算法的一种有效方法,它沿着图的深度方向尽可能远的搜索路径。
DFS寻路示例
0123456
从顶点0到顶点6的DFS路径可能是:0 → 1 → 4 → 6
二、算法核心思想
- 记录路径:使用
from数组记录每个顶点的前驱顶点 - 深度优先遍历:从起点开始递归访问所有未访问的邻接顶点
- 路径回溯:通过
from数组逆向回溯找到完整路径
数据结构设计
Path-Graph G-int s-boolean[] visited-int[] from+dfs(int v)+hasPath(int w)+path(int w)+showPath(int w)
三、算法实现详解
1. 核心数据结构
visited数组:记录顶点是否被访问过from数组:记录路径中每个顶点的前驱顶点s:起始顶点
2. 构造函数初始化
publicPath(Graph graph,int s){G= graph;assert s >=0&& s <G.V(); visited =newboolean[G.V()]; from =newint[G.V()];for(int i =0; i <G.V(); i++){ visited[i]=false; from[i]=-1;}this.s = s;dfs(s);}3. DFS实现
privatevoiddfs(int v){ visited[v]=true;for(int i :G.adj(v)){if(!visited[i]){ from[i]= v;// 记录前驱顶点dfs(i);}}}4. 路径查询方法
booleanhasPath(int w){assert w >=0&& w <G.V();return visited[w];}Vector<Integer>path(int w){asserthasPath(w);Stack<Integer> s =newStack<>();int p = w;while(p !=-1){ s.push(p); p = from[p];}Vector<Integer> res =newVector<>();while(!s.empty()) res.add(s.pop());return res;}四、完整代码实现
importjava.util.Stack;importjava.util.Vector;/** * 基于DFS的寻路算法 */publicclassPath{privateGraphG;// 图的引用privateint s;// 起始点privateboolean[] visited;// 记录访问过的节点privateint[] from;// 记录路径,from[i]表示i的前驱节点// 构造函数,寻路算法publicPath(Graph graph,int s){G= graph;assert s >=0&& s <G.V(); visited =newboolean[G.V()]; from =newint[G.V()];for(int i =0; i <G.V(); i++){ visited[i]=false; from[i]=-1;}this.s = s;// 开始DFS寻路dfs(s);}// 深度优先遍历privatevoiddfs(int v){ visited[v]=true;for(int i :G.adj(v)){if(!visited[i]){ from[i]= v;dfs(i);}}}// 判断是否有路径booleanhasPath(int w){assert w >=0&& w <G.V();return visited[w];}// 获取路径Vector<Integer>path(int w){asserthasPath(w);Stack<Integer> stack =newStack<>();int p = w;while(p !=-1){ stack.push(p); p = from[p];}Vector<Integer> res =newVector<>();while(!stack.empty()) res.add(stack.pop());return res;}// 打印路径voidshowPath(int w){asserthasPath(w);Vector<Integer> vec =path(w);for(int i =0; i < vec.size(); i++){System.out.print(vec.elementAt(i));if(i != vec.size()-1)System.out.print(" -> ");}System.out.println();}}五、算法测试与应用
测试代码
publicclassPathTest{publicstaticvoidmain(String[] args){// 创建一个图Graph g =newSparseGraph(7,false); g.addEdge(0,1); g.addEdge(0,2); g.addEdge(1,3); g.addEdge(1,4); g.addEdge(2,5); g.addEdge(4,6);// 寻路算法测试Path path =newPath(g,0);System.out.println("Path from 0 to 6:"); path.showPath(6);// 输出:0 -> 1 -> 4 -> 6System.out.println("Path from 0 to 5:"); path.showPath(5);// 输出:0 -> 2 -> 5System.out.println("Has path to 3: "+ path.hasPath(3));System.out.println("Has path to 6: "+ path.hasPath(6));}}输出结果
Path from 0 to 6: 0 -> 1 -> 4 -> 6 Path from 0 to 5: 0 -> 2 -> 5 Has path to 3: true Has path to 6: true 六、算法分析与优化
时间复杂度分析
| 操作 | 时间复杂度 |
|---|---|
| 初始化 | O(V) |
| DFS遍历 | O(V + E) |
| 路径查询 | O(L) L为路径长度 |
空间复杂度
- O(V) 用于存储visited和from数组
优化方向
- 广度优先搜索(BFS):可以找到最短路径
- 双向搜索:同时从起点和终点开始搜索
- 启发式搜索:如A*算法,适用于有权图
七、DFS寻路与BFS寻路对比
起点DFS vs BFSDFSBFS使用栈/递归不一定是最短路径使用队列保证最短路径
选择建议:
- 需要找到任意路径时使用DFS
- 需要找到最短路径时使用BFS
- 图非常大时DFS内存消耗更少
八、实际应用场景
- 迷宫求解
- 网络路由
- 社交网络中查找关系链
- 游戏中的AI路径规划
- 依赖关系解析
九、总结
本文详细介绍了基于DFS的图寻路算法,重点讲解了:
- 算法核心思想和数据结构设计
- 完整的Java实现代码
- 算法的时间复杂度和空间复杂度分析
- 与BFS寻路的对比
- 实际应用场景
DFS寻路算法是图算法的基础,虽然不能保证找到最短路径,但实现简单且在某些场景下效率很高。理解这一算法有助于学习更复杂的图算法如Dijkstra、A*等。
🌺The End🌺点点关注,收藏不迷路🌺 |