BM24-二叉树的中序遍历

本文介绍了一种实现二叉树中序遍历的方法,包括递归和迭代两种方式,并给出了具体的Java代码实现。

题目

给定一个二叉树的根节点root,返回它的中序遍历结果。

数据范围:树上节点数满足0≤n≤1000,树上每个节点的值满足 −1000≤val≤1000。
进阶:空间复杂度O(n),时间复杂度O(n)。

示例1

输入:{1,2,#,#,3}

返回值:[2,3,1]

说明:

示例2

输入:{}

返回值:[]

示例3

输入:{1,2}

返回值:[2,1]

说明:

示例4

输入:{1,#,2}

返回值:[1,2]

说明:

备注:树中节点数目在范围 [0, 100] 内;树中的节点的值在[-100,100]以内


思路1:递归(左根右)


代码1

import java.util.*;

public class Solution {
    public int[] inorderTraversal (TreeNode root) {
        //添加遍历结果的数组
        List<Integer> list = new ArrayList(); 
        //递归中序遍历
        inorder(list, root); 
        //返回的结果
        int[] res = new int[list.size()]; 
        for(int i = 0; i < list.size(); i++){
            res[i] = list.get(i);
        }
        return res;
    }

    public void inorder(List<Integer> list, TreeNode root){
        //遇到空节点则返回
        if(root == null){ 
            return;
        }
        //左
        inorder(list, root.left); 
        //根
        list.add(root.val); 
        //右
        inorder(list, root.right); 
    }
}

思路2:迭代,栈

第二次访问根节点(走完左树),根节点才能真正遍历输出。


代码2

import java.util.*;

public class Solution {
    public int[] inorderTraversal (TreeNode root) {
        //添加遍历结果的数组
        List<Integer> list = new ArrayList(); 
        Stack<TreeNode> s = new Stack<TreeNode>();

        //空树返回空数组
        if(root == null){
            return new int[0];
        }

        //当树节点不为空或栈中有节点时
        while(root != null || !s.isEmpty()){ 
            //一路向左走一直走到最左侧的最后一个节点
            while(root != null){ 
                s.push(root);
                root = root.left;
            }
            //当前左树已经全部入栈,访问该节点
            TreeNode node = s.pop(); 
            //此时访问根节点
            list.add(node.val); 
            //继续访问右子树
            root = node.right; 
        }

        //返回的结果
        int[] res = new int[list.size()]; 
        for(int i = 0; i < list.size(); i++){
            res[i] = list.get(i);
        }
        return res;
    }
}

<think>好的,我需要帮助用户解决C++代码中主函数遍历节点时出现的逻辑错误,导致遍历不完全的问题。用户提到需要检查并修复while循环中的条件和指针操作。首先,我需要回忆常见的遍历错误,尤其是在树或图的遍历中常见的陷阱。 根据用户提供的引用,特别是引用[4]中的层序遍历代码,正确的做法是使用队列,每次取出队首节点,处理后再将其子节点入队。如果用户的代码是层序遍历的问题,可能问题出在循环条件或子节点入队的逻辑上。比如,可能在循环中没有正确处理空指针,或者在入队时漏掉了左右子节点。 另外,用户提到“遍历不完全”,可能是在循环结束条件设置不当,比如提前退出循环,或者没有正确处理队列中的节点。例如,可能在队列尚未为空时就终止了循环,或者在处理当前节点后没有正确地将子节点加入队列。 还需要考虑指针操作的问题,比如在出队时是否正确获取了节点,或者在访问子节点时是否进行了空指针检查。如果用户的代码没有检查子节点是否存在就直接入队,可能会导致访问非法内存,进而引发错误。 根据引用[3],构建二叉树时依赖后序和中序遍历,如果构建过程中有错误,也可能导致遍历时的结构问题。但用户的问题集中在主函数的遍历逻辑,所以可能构建过程没有问题,而是遍历代码本身有误。 可能的错误点包括: 1. while循环的条件错误,比如使用了错误的终止条件。 2. 队列操作不当,比如在弹出节点后没有及时处理子节点。 3. 指针未正确检查是否为null,导致某些节点未被访问。 4. 队列的push操作遗漏了左或右子节点。 需要用户提供具体的代码片段才能更准确地诊断,但根据常见错误,我可以假设一个示例代码,并指出其中的问题。例如,假设用户可能在循环中漏掉了子节点的入队,或者在处理节点时错误地跳过了某些情况。 修复步骤可能包括: 1. 确保循环条件正确,例如while循环应持续直到队列为空。 2. 在每次处理节点时,检查左右子节点是否存在,若存在则入队。 3. 确保队列的pop操作在正确的位置,避免提前终止循环。 例如,参考引用[4]的正确代码,用户的代码可能缺少对子节点的入队操作,或者在处理节点时没有正确输出,导致遍历不完整。需要检查while循环内部的所有步骤是否符合标准层序遍历的实现。</think>根据代码逻辑错误特征和层序遍历的常见问题,以下是分步排查和修复建议: --- ### **1. 检查队列操作完整性** 层序遍历核心代码框架应为: ```cpp std::queue<TreeNode*> q; q.push(root); while (!q.empty()) { //正确循环条件 TreeNode* current = q.front(); q.pop(); //及时移除已处理节点 //处理节点代码 if (current->left) q.push(current->left); //左子节点入队 if (current->right) q.push(current->right); //右子节点入队 } ``` **常见错误:** - **错误条件**:错误使用`q.size()>0`替代`!q.empty()`(功能相同但易错) - **遗漏子节点**:忘记检查或入队左/右子节点 - **错误顺序**:先处理右子节点导致遍历顺序错误(若需要从左到右应优先左子节点) --- ### **2. 验证指针有效性** 必须添加空指针检查防止访问异常: ```cpp //错误示例:直接访问未检查的指针 q.push(current->left); //若current->left为空,队列会存入nullptr //正确做法: if (current->left != nullptr) { //显式检查[^4] q.push(current->left); } ``` --- ### **3. 调试循环逻辑** **问题示例:** ```cpp while (current != nullptr) { //错误!会导致死循环或提前终止 q.push(current->left); q.push(current->right); current = q.front(); } ``` **修复方向:** - 必须使用`while (!q.empty())`确保处理所有已入队节点 - 每次循环都要执行`q.pop()`移除已处理节点 --- ### **4. 完整修复代码示例** ```cpp #include <queue> using namespace std; void levelOrderTraversal(TreeNode* root) { if (!root) return; //空树直接返回 queue<TreeNode*> q; q.push(root); while (!q.empty()) { //正确循环条件 TreeNode* current = q.front(); q.pop(); //关键!移除队首元素 cout << current->val << " "; //处理当前节点 //严格检查子节点并入队[^4] if (current->left) q.push(current->left); if (current->right) q.push(current->right); } } ``` --- ### **5. 关键错误点总结** | 错误类型 | 错误示例 | 正确写法 | |---------|---------|---------| | 循环条件错误 | `while (root != NULL)` | `while (!q.empty())` | | 遗漏节点移除 | 未调用`q.pop()` | 每次循环必须执行`q.pop()` | | 指针未检查 | `q.push(current->left)` | `if (current->left) q.push(...)` | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值