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

Java自定义树实现BFS遍历返回重复节点的解决方法咨询

问题描述

我正在Java中实现树结构的BFS遍历,项目包含两种实现策略:一种使用Java Collections,另一种使用自定义节点与引用。我的自定义实现进行BFS遍历时有时会返回重复节点,当结构中存在意外的重复引用时,同一节点会多次出现在遍历结果中。以下是我当前的BFS方法:

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public List<String> bfs(Node root) {
    Queue<Node> queue = new LinkedList<>();
    List<String> result = new ArrayList<>();

    queue.add(root);

    while (!queue.isEmpty()) {
        Node current = queue.poll();

        result.add(current.getName());

        for (Node child : current.getChildren()) {
            queue.add(child);
        }
    }

    return result;
}

请问避免BFS遍历中重复访问节点的正确方法是什么?即使结构理论上应为树,是否仍需使用Set跟踪已访问节点?


解决方案

核心方法:用Set跟踪已访问节点

当结构中存在意外的重复引用时,你的"树"实际上已经变成了有环图,这时候必须通过记录已访问节点来避免重复遍历和潜在的死循环。

修改后的BFS实现

添加一个Set<Node>存储已处理的节点,在将节点加入结果前先检查是否已访问;更高效的方式是在将子节点加入队列前就检查并标记,避免队列中存入重复节点:

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.HashSet;
import java.util.Set;

public List<String> bfs(Node root) {
    Queue<Node> queue = new LinkedList<>();
    List<String> result = new ArrayList<>();
    Set<Node> visited = new HashSet<>();

    if (root == null) {
        return result;
    }

    queue.add(root);
    visited.add(root);

    while (!queue.isEmpty()) {
        Node current = queue.poll();
        result.add(current.getName());

        for (Node child : current.getChildren()) {
            if (!visited.contains(child)) {
                visited.add(child);
                queue.add(child);
            }
        }
    }

    return result;
}

关于"理论上是树是否需要Set"的问题

如果能100%保证结构是严格的树(无环、每个节点仅有一个父节点、无重复引用),理论上不需要Set。但实际工程中建议始终加上:

  • 意外的引用错误(比如代码逻辑失误导致节点被重复添加为子节点)很难完全避免;
  • 额外的Set开销对于大多数场景可以忽略,却能大幅提升代码鲁棒性,避免出现难以排查的重复结果或死循环。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 05:23:09