You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于DFS代码实现合规性及不同版本遍历输出差异的疑问

Graph image
你提供的DFS实现代码:

public void dfs(){
    ArrayList<Node> exploredList = new ArrayList<>();
    Stack s=new Stack();
    s.push(this.rootNode);
    while(!s.isEmpty()){
        Node n = (Node)s.pop();
        exploredList.add(n);
        printNode(n);
        ArrayList<Node> childList = getChildNodes(n);
        for (Node child : childList){
            if (!exploredList.contains(child) && !s.contains(child)) {
                s.push(child);
            }
        }
    }
}

运行输出:

A D C F B E 

参考实现输出:

A B E F C D 

解答

1. 该代码属于合法的DFS实现

DFS的核心逻辑是优先沿当前节点的分支深入到最末端,再回溯处理其他分支,只要符合这个规则的实现都属于合法DFS,你提供的迭代版本完全满足该逻辑。

2. 和常规DFS实现的核心差异

  • 子节点入栈逻辑不同:该实现会一次性将当前节点所有未访问的子节点全部压入栈;而常见的递归DFS、另一种迭代DFS实现,是每次仅处理当前节点的第一个未访问子节点,剩余子节点留待回溯时再处理。
  • 子节点遍历顺序相反:由于栈是后进先出结构,若getChildNodes返回的子节点顺序固定,该实现会优先处理子节点列表的最后一个元素,常规实现会优先处理子节点列表的第一个元素。

3. 两次输出不同的原因

输出差异完全由子节点的入栈顺序导致,和DFS本身的合法性无关:
假设示例图中getChildNodes返回的子节点顺序为:A的子节点是[B, C, D],B的子节点是[E, F],C的子节点是[F]:

  • 该实现将B、C、D依次压栈,弹出顺序为D→C→B,所以优先走D分支,再走C、B分支,最终输出A D C F B E
  • 参考实现优先处理第一个子节点B,再深入B的第一个子节点E,回溯后处理F,再回溯处理C、D分支,最终输出A B E F C D

两种输出都是合法的DFS遍历结果,仅和子节点的处理顺序有关,没有对错之分。


内容的提问来源于stack exchange,提问作者Hisham Syed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 08:36:05