深度优先搜索两种实现方法java模板 递归和栈以及使用栈的潜在问题

有两种实现 DFS 的方法。

dfs递归模版

第一种方法是进行递归:

boolean DFS(Node cur, Node target, Set<Node> visited) {
    return true if cur is target;
    for (next : each neighbor of cur) {
        if (next is not in visited) {
            add next to visted;
            return true if DFS(next, target, visited) == true;
        }
    }
    return false;
}
12345678910

当我们递归地实现 DFS 时,似乎不需要使用任何栈。但实际上,我们使用的是由系统提供的隐式栈,也称为调用栈(Call Stack)。

dfs显式栈模板

递归解决方案的优点是它更容易实现。 但是,存在一个很大的缺点:如果递归的深度太高,你将遭受堆栈溢出。 在这种情况下,您可能会希望使用 BFS,或使用 显式栈 实现 DFS

boolean DFS(int root, int target) {
    Set<Node> visited;
    Stack<Node> s;
    add root to s;
    while (s is not empty) {
        Node cur = the top element in s;
        return true if cur is target;
        for (Node next : the neighbors of cur) {
            if (next is not in visited) {
                add next to s;
                add next to visited;
            }
        }
        remove cur from s;
    }
    return false;
}

dfs显式栈的问题

当在遍历过程中需要传递一些额外的信息时,会比较麻烦。

比如返回一条深度优先搜索的路径(从根开始直到某个结点):

  • 如果用递归实现,可以每次通过递归函数的参数来传递一些额外的信息,比如list。在递归调用后,可以再调用list.remove()将list的状态回溯。这样在任意深度的地方都可以很方便得到一个属于该层状态的list,比如深度优先搜索的路径。

  • 如果用显示栈实现,那么会面临问题:

    如何在栈中保存状态相关的变量?

    一种思路是可以通过对象包裹后传递给栈,每次从栈中读取相关的信息。但是这样明显带来了额外的对象创建开销,对于比较小的变量尚可接受,对于比较大的对象、或者参数比较多的情况就会显得比较麻烦。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值