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

Java初学者求助:无参二叉树前序遍历转ArrayList实现问题

帮你修正二叉树前序遍历的实现问题

嘿,作为Java初学者,能尝试自己实现遍历逻辑已经很棒啦!不过你的代码确实存在几个关键问题,我来帮你拆解并给出正确的实现~

先说说你现有代码的问题

  • list.set()的致命错误:刚创建的ArrayList是空的(初始大小为0),直接调用set(index, value)会抛出IndexOutOfBoundsException——因为这个索引位置根本不存在元素。你应该用list.add()来向列表中追加元素。
  • 遍历逻辑完全不符合前序规则:你的循环只是反复访问根节点的左/右节点,没有真正深入子树。比如第一个while循环会无限执行(因为root始终指向根节点,它的左节点不会凭空消失),而且就算能退出,也只是重复添加根节点左孩子的值,完全没遍历左子树的其他节点;右子树的处理也犯了同样的错误。
  • 没理解前序遍历的核心:前序遍历的顺序是根节点 → 左子树前序遍历 → 右子树前序遍历,这是一个递归的过程,要么用递归实现,要么用栈模拟递归的调用过程。

正确的实现方式

方式1:递归实现(最易理解,适合初学者)

我们可以写一个辅助递归方法,让它负责遍历节点并把值加入列表,主方法只需要初始化列表并触发递归:

public ArrayList<T> toPreOrderList() {
    ArrayList<T> list = new ArrayList<>();
    // 调用辅助方法开始遍历
    preOrderHelper(root, list);
    return list;
}

// 私有辅助方法,负责递归遍历节点
private void preOrderHelper(Node<T> currentNode, ArrayList<T> resultList) {
    // 递归终止条件:遇到空节点直接返回
    if (currentNode == null) {
        return;
    }
    // 1. 先添加当前节点的值(前序的"根")
    resultList.add(currentNode.getData());
    // 2. 递归遍历左子树(前序的"左")
    preOrderHelper(currentNode.getLeft(), resultList);
    // 3. 递归遍历右子树(前序的"右")
    preOrderHelper(currentNode.getRight(), resultList);
}

方式2:迭代实现(用栈模拟递归,适合理解底层逻辑)

如果不想用递归,可以用栈来手动管理遍历的节点,模拟递归的调用栈过程:

import java.util.Stack;

public ArrayList<T> toPreOrderList() {
    ArrayList<T> list = new ArrayList<>();
    // 空树直接返回空列表
    if (root == null) {
        return list;
    }
    
    Stack<Node<T>> nodeStack = new Stack<>();
    nodeStack.push(root);
    
    while (!nodeStack.isEmpty()) {
        Node<T> current = nodeStack.pop();
        // 先处理当前节点(根)
        list.add(current.getData());
        
        // 注意:栈是后进先出,所以先压右子节点,再压左子节点
        // 这样弹出的时候会先处理左子节点,符合前序"根→左→右"的顺序
        if (current.getRight() != null) {
            nodeStack.push(current.getRight());
        }
        if (current.getLeft() != null) {
            nodeStack.push(current.getLeft());
        }
    }
    return list;
}

几个关键提醒

  • 永远不要忽略空节点的处理,否则很容易抛出NullPointerException
  • 向空的ArrayList添加元素一定要用add(),set()只能修改已存在索引位置的元素
  • 前序遍历的核心顺序是根→左→右,不管用哪种实现方式,都要严格遵循这个顺序

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:39:27