图的寻路算法详解:基于深度优先搜索(DFS)的实现

图的寻路算法详解:基于深度优先搜索(DFS)的实现

图的寻路算法详解:基于深度优先搜索DFS的实现

🌺The Begin🌺点点关注,收藏不迷路🌺

一、寻路算法概述

图的寻路算法是图论中的基础算法之一,用于找到从一个顶点到另一个顶点的路径。深度优先搜索(DFS)是实现寻路算法的一种有效方法,它沿着图的深度方向尽可能远的搜索路径。

DFS寻路示例

0123456

从顶点0到顶点6的DFS路径可能是:0 → 1 → 4 → 6

二、算法核心思想

  1. 记录路径:使用from数组记录每个顶点的前驱顶点
  2. 深度优先遍历:从起点开始递归访问所有未访问的邻接顶点
  3. 路径回溯:通过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数组

优化方向

  1. 广度优先搜索(BFS):可以找到最短路径
  2. 双向搜索:同时从起点和终点开始搜索
  3. 启发式搜索:如A*算法,适用于有权图

七、DFS寻路与BFS寻路对比

起点DFS vs BFSDFSBFS使用栈/递归不一定是最短路径使用队列保证最短路径

选择建议

  • 需要找到任意路径时使用DFS
  • 需要找到最短路径时使用BFS
  • 图非常大时DFS内存消耗更少

八、实际应用场景

  1. 迷宫求解
  2. 网络路由
  3. 社交网络中查找关系链
  4. 游戏中的AI路径规划
  5. 依赖关系解析

九、总结

本文详细介绍了基于DFS的图寻路算法,重点讲解了:

  1. 算法核心思想和数据结构设计
  2. 完整的Java实现代码
  3. 算法的时间复杂度和空间复杂度分析
  4. 与BFS寻路的对比
  5. 实际应用场景

DFS寻路算法是图算法的基础,虽然不能保证找到最短路径,但实现简单且在某些场景下效率很高。理解这一算法有助于学习更复杂的图算法如Dijkstra、A*等。

在这里插入图片描述

🌺The End🌺点点关注,收藏不迷路🌺

Read more

《算法题讲解指南:优选算法-二分查找》--19.x的平方根,20.搜索插入位置

《算法题讲解指南:优选算法-二分查找》--19.x的平方根,20.搜索插入位置

🔥小叶-duck:个人主页 ❄️个人专栏:《Data-Structure-Learning》 《C++入门到进阶&自我学习过程记录》《算法题讲解指南》--从优选到贪心 ✨未择之路,不须回头 已择之路,纵是荆棘遍野,亦作花海遨游 目录 19. x的平方根 题目链接: 题目描述: 题目示例: 解法(二分查找算法): 算法思路: C++算法代码: 算法总结及流程解析: 20. 搜索插入位置 题目链接: 题目描述: 题目示例: 解法(二分查找算法): 算法思路: C++算法代码: 算法总结及流程解析: 结束语 19. x的平方根 题目链接: 69. x 的平方根 - 力扣(LeetCode) 题目描述: 题目示例:

By Ne0inhk
【数据结构手札】空间复杂度详解:概念 | 习题

【数据结构手札】空间复杂度详解:概念 | 习题

🌈个人主页:聆风吟 🔥系列专栏:数据结构手札 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 * 📚专栏订阅推荐 * 📋往期回顾:复杂度概念 * 📋往期回顾:大O的渐进表示法 * 一. ⛳️算法的空间复杂度 * 二. ⛳️常见空间复杂度计算举例 * 1️⃣实例一 * 2️⃣实例二 * 3️⃣实例三 * 4️⃣实例四 * 📝全文总结 📚专栏订阅推荐 专栏名称专栏简介C++藏宝阁本专栏聚焦学习阶段核心知识点,深耕基础与实战,干货笔记持续更新,和大家共学共进,夯实编程功底。数据结构手札本专栏主要是我的数据结构入门学习手札,记录个人从基础到进阶的学习总结。数据结构手札・刷题篇本专栏是《数据结构手札》配套习题讲解,通过练习相关题目加深对算法理解。 📋往期回顾:复杂度概念 算法在编写成可执行程序后,运行时需要耗费时间资源和空间(内存)资源 。因此衡量一个算法的好坏,一般是从时间和空间两个维度来衡量的,即时间复杂度和空间复杂度。 时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法运行所需要的额

By Ne0inhk
【数据结构】树、森林与二叉树的转换(含详细图解)

【数据结构】树、森林与二叉树的转换(含详细图解)

亲爱的读者朋友们😃,此文开启知识盛宴与思想碰撞🎉。 快来参与讨论💬,点赞👍、收藏⭐、分享📤,共创活力社区。 😖如果你对二叉树的概念还存在疑惑,欢迎观看我之前的作品: 🔥🔥🔥【数据结构】剖析二叉树(Binary Tree) 目录 💯前言 💯树转换为二叉树  ⭐转换步骤详解 (一)连接兄弟节点 (二)给除长子以外的孩子去线 (三)层次调整 💯森林转换为二叉树   ⭐转换步骤详解 (一)将森林里的每一棵树转换为二叉树 (二)将所有二叉树转换为一棵二叉树 💯二叉树转换成树   ⭐转换步骤详解 (一)加线 (二)去线 (三)层次调整 💯将二叉树转换成森林    ⭐转换步骤详解 (一)寻找右孩子去线 (二)将分离的二叉树转换成树 💯总结 💯前言 👀在数据结构的世界里,树、森林和二叉树是重要的概念,它们之间存在着巧妙的转换关系,这种转换不仅具有理论意义,

By Ne0inhk