你必须会的DFS的递归实现与堆栈实现

Posted Math_X_CS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了你必须会的DFS的递归实现与堆栈实现相关的知识,希望对你有一定的参考价值。


文章目录

一. 算法原理

相比于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,到源点距离为3
private 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, 3
Map<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]);

//初始化disTo
disTo = 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非递归 DFS 与 BFS,仅在堆栈与队列方面有所不同?

如何仅使用堆栈来实现递归函数?

深度优先搜索DFS

数据结构 有向图的非递归遍历

深度优先(DFS)与广度优先搜索(BFS)递归版与非递归版

python 3中使用堆栈的递归与迭代