文章目录

  • 一. 算法原理
    • 1.堆栈式实现方法
    • 2.递归式实现方法
  • 二.具体实现
    • 1.实例
    • 2.结果
  • 三.如何输出所有的路径?

一. 算法原理

相比于BFS利用队列实现中心扩散式搜索
DFS就是利用堆栈的思想(先进后出),利用回溯算法,或者使用dfs递归,直观上看是一条路走到黑,如果找到南墙,便回到上个路口,继续一条路走到黑…如此往复,直到到达目标,所以称之为深度优先搜索。

1.堆栈式实现方法

  • 首先将根节点压入堆栈中。
  • 从堆栈中pop一个节点,并检验它是否为目标。
    • 如果找到目标,则结束搜索并回传结果。
    • 否则将它所有尚未检验过的直接子节点加入堆栈中。
  • 若堆栈为空,表示整张图都检查过了——亦即图中没有所搜索的目标。结束搜索并回传“找不到目标”。
  • 重复步骤2。

伪代码

stack.push(root)
while(!stack.isEmpty())node = stack.pop()for each neighbor node的相邻节点if neighbor未被访问stack.push(neightbor)//记录路径stack.parent = node//其余操作...todo...

2.递归式实现方法

  • 给定根节点
  • 遍历根节点所有未被访问的相邻节点
    • 如果找到目标,则结束搜索并传回结果
    • 否则将该相邻节点设置为新的根节点,重复步骤2
    • 若没有未被访问的相邻节点,则结束本分支的搜索并返回
  • 所有分支都遍历完毕,结束搜索并回传“找不到目标”。

伪代码:

DFS()dfsVisit(root)dfsVisit(node)for each neighbor node的相邻节点if neighbor没有访问过//记录路径neighbor.parent = root//其他操作todo..dfs(neighbor)

二.具体实现

选用常见的递归实现

package com.example.DFS;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class DFS {// <1, [2, 3]>表示节点1的父节点是节点2,到源点距离为3private Map<Integer, int[]> disTo;/*** @param edges 一个节点到其他节点的距离*              [[0, 1, 1], [1, 2, 2]] 表示点0到点1的距离为1,点1到点2的距离为2* @param n   所有节点个数  1<= n <= 1000* @param k   源节点   1< k <n*/public Map<Integer, int[]> DFS(int[][] edges, int n, int k){//通过edges数组生成有向图//<0, <{1,2}, {2,3}>>表示节点0有1,2两个相邻节点,距离分别为2, 3Map<Integer, List<int[]>> graph = new HashMap<>();for(int[] edge:edges){if(!graph.containsKey(edge[0]))graph.put(edge[0], new ArrayList<int[]>());graph.get(edge[0]).add(new int[]{edge[1], edge[2]});}//初始化disTodisTo = new HashMap<>();for(int i=0; i<n; i++){if(i==k)disTo.put(i, new int[]{k, 0});else disTo.put(i, new int[]{-1, Integer.MAX_VALUE});}dfsVisit(graph, k);return disTo;}/*** dfs* @param graph* @param k*/private void dfsVisit(Map<Integer, List<int[]>> graph, int k){if(graph.containsKey(k))for(int[] edge:graph.get(k)){int[] temp = disTo.get(edge[0]);//保证该节点未被访问if(temp[0] == -1 && temp[1] == Integer.MAX_VALUE) {//setParent 记录路径temp[0] = k;//setDisTo 记录距离temp[1] = disTo.get(k)[1] + edge[1];//递归实现dfsVisit(graph, edge[0]);}}}/*** 输出结果* @param disTo* @param end*/public void printPath(Map<Integer, int[]> disTo,int pathTo){int distance = disTo.get(pathTo)[1];List<Integer> path = new ArrayList<>();int temp = pathTo;path.add(temp);while (temp!=0 && temp!=-1){temp = disTo.get(temp)[0];path.add(temp);}System.out.print("从初始节点到节点"+end+"的距离为"+distance+"\n"+"路径为:\n"+path.get(0));for(int i=1;i<path.size();i++){System.out.print("<--"+path.get(i));}}
}

1.实例

测试输入
输入:

edges: n: k: pathTo:
{{0, 1, 15},{0, 3, 5}, 6 0 4
{1, 5, 6}, {3, 5, 20},
{1, 2, 15}, {3, 2, 30},
{2, 4, 10}, {5, 4, 9}};

预计输出:距离:30 路径:0–>1–>5–>4

环境:windows10,java11

2.结果

试着输出到节点5的路径和距离

三.如何输出所有的路径?

在一个图没有环的情况下,或者先去环后,允许一个节点可以由多个不同的父节点向下遍历到,这样可以找到图中真正的所有路径


你可能还敢兴趣的图论算法(均附Java实现代码):

  • 算法实验–主函数只有五行的Floyed的算法以及最短路径输出

  • 你必须会的–Dijkstra算法–单源最短路径问题

  • 你了解欧拉回路吗?

  • 你必须会的启发式搜索算法–A*算法

你必须会的DFS的递归实现与堆栈实现相关推荐

  1. C语言过河问题主函数,c,c++_C语言踩石头过河问题,用DFS搜索递归了17万次但是没报错,请问是什么原因?,c,c++,算法 - phpStudy...

    C语言踩石头过河问题,用DFS搜索递归了17万次但是没报错,请问是什么原因? 这是原题目,后面附上我的代码,刚刚接触DFS,不是很熟练,求教育--谢谢!!!TUT 这是题目,我大概概括一下 用'※'和 ...

  2. 汉诺塔的非递归实现(借助堆栈模拟递归)

    汉诺塔的非递归实现 借助堆栈以非递归(循环)方式求解汉诺塔的问题(n,a,b,c).即将n个盘子从起始柱(标记为"a")通过借助柱(标记为"b")移动到目标杜( ...

  3. Javascript中递归造成的堆栈溢出及解决方案

    Javascript中递归造成的堆栈溢出及解决方案 参考文章: (1)Javascript中递归造成的堆栈溢出及解决方案 (2)https://www.cnblogs.com/cuew1987/p/4 ...

  4. 图的dfs非递归_如何理解恶心的递归

    力扣​leetcode-cn.com 递归恶心主要恶心在无论是做题还是解析都比较抽象,这里记录一下递归小白的理解过程: # Definition for a binary tree node. 以上图 ...

  5. POJ - 2083 Fractal(dfs,递归画图)

    题目链接:点击查看 题目大意:给出一个n,要求递归画图 题目分析:重点就是设计递归啦,也没什么好说的,因为题目保证了n小于等于7,然后矩阵的大小为3^(n-1)*3^(n-1)所以矩阵最大不超过729 ...

  6. DFS迷宫递归所有路径 新手入门

    这篇文章写给自己以后复习和个个入门朋友:提示同学们一定耐心看完解释 哪怕看得很难受,我是新手我懂大家的心烦.看完后慢慢体会代码 我们假设迷宫为如下状况:         {0,0,1,0}       ...

  7. 【PAT - 甲级1004】Counting Leaves (30分) (dfs,递归)

    题干: A family hierarchy is usually presented by a pedigree tree. Your job is to count those family me ...

  8. 迷宫探索DFS(递归记录来回路径)

    Problem Description 有一个地下迷宫,它的通道都是直的,而通道所有交叉点(包括通道的端点)上都有一盏灯和一个开关:请问如何从某个起点开始在迷宫中点亮所有的灯并回到起点? Input ...

  9. 水管工游戏:dfs(递归)

    添柴网这题好想不能评测,所以不确保代码的正确性 题目描述: 这小节有点难,看不太懂可以跳过哦. 最近小哼又迷上一个叫做水管工的游戏.游戏的大致规则是这样的.一块矩形土地被分为N * M的单位正方形,现 ...

最新文章

  1. 物体的三维识别与6D位姿估计:PPF系列论文介绍(一)
  2. vs2008编译中文变量名的lua解释器环境
  3. 运算符重载 返回类型说明符后加_Java学习:运算符的使用与注意事项
  4. Poj(1459),最大流,EK算法
  5. mysql下拉框记忆,Mysql alter语句记忆分析
  6. Hibernate的数据过滤查询
  7. python任务调度平台 界面_分布式任务调度平台XXL-JOB
  8. CF980D Perfect Groups
  9. P5299-[PKUWC2018]Slay the Spire【dp】
  10. 数据结构与算法————九九乘法表
  11. (85)FPGA显示激励(monitor)
  12. Android开发学习之ImageView手势拖拽、缩放、旋转
  13. startlogging中设置setstdout=false来禁用这个功能。_无线路由器的安全功能,你知道多少?...
  14. 多标签分类任务大赛50万奖金等你来
  15. 6. ubuntu 下 mysql 数据库迁移
  16. 【POJ 3279】【开关问题】Fliptile【暑期 No.5】
  17. 虚拟机在教学实验中的应用
  18. 系分 02 软件工程
  19. ARMv8-A编程指导之Caches(1)
  20. PMP备考之路 - 汪博士第六章(项目进度管理)

热门文章

  1. TCP/IP协议族(一) HTTP简介、请求方法与响应状态码
  2. 用vs2008打开vs2012项目
  3. Java字符串的子串
  4. DeepEarth中的拖放行为(DragBehavior)
  5. Oracle常用系统表
  6. 神经网络与机器学习 笔记—改善反向传播的性能试探法
  7. 【数字信号处理】基本序列傅里叶变换总结 ( 单位脉冲序列 δ(n) | {1} 序列 | e^jωn 序列 | cosωn 序列 | sinωn 序列 | a^nu(n) | 矩形窗函数 ) ★★★
  8. 【C 语言】二级指针案例 ( 字符串切割 | 返回 自定义二级指针 作为结果 )
  9. 【错误记录】Java 中 ArrayList 排序 ( 使用 Comparator 接口时注意 compare 返回值是 -1 和 +1 )
  10. 【C 语言】文件操作 ( 读文本文件 | 文本加密解密 | fgets 函数 | fputs 函数 )