Java中使用队列替代递归造树
定义泛型工具类
1.通过函数式接口实现通用性:
public class TreeUtil {
public static <T, ID> List<T> buildTreeWithQueue(
List<T> nodeList,
Function<T, ID> idGetter, // 获取节点ID的方法
Function<T, ID> parentIdGetter, // 获取父节点ID的方法
ID rootParentId, // 根节点的父ID(如0/null/-1)
BiConsumer<T, List<T>> childrenSetter // 设置子节点集合的方法
) {
// 实现细节见下文
}
}
- 具体实现流程
public static <T, ID> List<T> buildTreeWithQueue(
List<T> nodeList,
Function<T, ID> idGetter,
Function<T, ID> parentIdGetter,
ID rootParentId,
BiConsumer<T, List<T>> childrenSetter
) {
// 1. 构建ID到节点的映射表
Map<ID, T> nodeMap = new HashMap<>();
for (T node : nodeList) {
nodeMap.put(idGetter.apply(node), node);
}
// 2. 初始化队列与结果集
Queue<T> queue = new LinkedList<>();
List<T> roots = new ArrayList<>();
// 3. 遍历所有节点,识别根节点并入队
for (T node : nodeList) {
ID parentId = parentIdGetter.apply(node);
if (Objects.equals(parentId, rootParentId)) {
roots.add(node);
queue.offer(node);
}
}
// 4. 队列处理层级关系
while (!queue.isEmpty()) {
T currentNode = queue.poll();
List<T> children = new ArrayList<>();
// 查找当前节点的所有子节点
for (T node : nodeList) {
if (Objects.equals(parentIdGetter.apply(node), idGetter.apply(currentNode))) {
children.add(node);
queue.offer(node); // 子节点入队,继续处理下一层
}
}
// 设置子节点集合
childrenSetter.accept(currentNode, children);
}
return roots;
}