【树】-Lc94-二叉树的中序遍历(递归 + 非递归,栈)

本文介绍了如何在Java中实现二叉树的中序遍历,包括递归和非递归两种方法,通过实例代码展示了具体步骤和栈在非递归方法中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写在前面

  最近想复习一下数据结构与算法相关的内容,找一些题来做一做。如有更好思路,欢迎指正。



一、场景描述

  给定一个二叉树,返回它的中序遍历。

示例:
输入: [1,null,2,3]
   1
    \
     2
    /
   3

输出: [1, 3, 2]

二、具体步骤

1.环境说明

名称说明
IntelliJ IDEA2019.2

2.代码

以下为Java版本实现:

public class Lc94_inOrderTraversal {

    public static void main(String[] args) {
        TreeNode n3 = new TreeNode(3);
        TreeNode n2 = new TreeNode(2);
        n2.left = n3;
        TreeNode root = new TreeNode(1);
        root.right = n2;

        // 递归方式
        System.out.println(inOrderTraversal0(root));
        // 非递归方式
        System.out.println(inOrderTraversal(root));
        System.out.println(inOrderTraversal(null));
    }

    /**
     * 非递归方式,借助于栈
     *
     * 思路:
     * 返回值是List
     * 中序遍历,顺序是 左子树-》根-》右子树
     * 中序遍历首先访问的是左,所以首先找到最左的节结点。然后出栈,处理右子树(右子树不为空同样的逻辑要找最左结点)
     *
     * 定义一个 stack:Stack, result:List
     * 定义一个指针,从根开始,curr = root,一直找到最左结点
     *
     * while外层循环(出栈和右子树入栈),!s.isEmpty() || curr!= null
     * while内层循环,左子树结点依次入栈, 直到左子树为空,while(curr != null) curr = curr.left
     *
     * s.pop出栈, 添加到result中
     *
     * 然后处理右子树 curr = curr.right(可以简化成 根-》左子树)
     * 说明:没有右子树,curr=null,栈只要不为空继续出栈
     *
     * @param root
     * @return
     */
    private static List<Integer> inOrderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();

        // 防止 root为 null,导致stack不为空,node.val为空报错
        if (root == null) {
            return result;
        }

        Stack<TreeNode> stack = new Stack<>();
        TreeNode curr = root;

        while (!stack.isEmpty() || curr != null) {
            // 一直找到最左结点
            while (curr != null) {
                stack.push(curr);
                curr = curr.left;
            }

            TreeNode node = stack.pop();
            result.add(node.val);

            // 处理右子树
            curr = node.right;
        }

        return result;
    }

    /**
     * 递归方式
     *
     * 思路:
     * 返回值是List
     * 中序遍历,顺序是左子树-》根-》右子树
     *
     * @param root
     * @return
     */
    private static List<Integer> inOrderTraversal0(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        inOrder(root, result);
        return result;
    }

    private static void inOrder(TreeNode root, List<Integer> result) {
        // 结束条件
        if (root == null) {
            return;
        }

        inOrder(root.left, result);
        result.add(root.val);
        inOrder(root.right, result);
    }

    static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        public TreeNode(int val) {
            this.val = val;
        }
    }
}


写在后面

  如果本文内容对您有价值或者有启发的话,欢迎点赞、关注、评论和转发。您的反馈和陪伴将促进我们共同进步和成长。

对于链式存储的二叉树,先序、中序、后序遍历递归遍历可以按照以下方法进行: 1. 先序遍历(PreOrder):先访问根节点,然后递归地遍历左子,最后递归地遍历右子。具体代码如下: ```cpp void PreOrder(BiTree &root) // 递归序遍历 { if(root == NULL) return; cout << root->data << " "; // 访问根节点 PreOrder(root->lc); // 遍历左子 PreOrder(root->rc); // 遍历右子 } ``` 2. 中序遍历(MidOrder):先递归地遍历左子,然后访问根节点,最后递归地遍历右子。具体代码如下: ```cpp void MidOrder(BiTree &root) // 中序遍历 递归 { if(root == NULL) return; MidOrder(root->lc); // 遍历左子 cout << root->data << " "; // 访问根节点 MidOrder(root->rc); // 遍历右子 } ``` 3. 后序遍历(PostOrder):先递归地遍历左子,然后递归地遍历右子,最后访问根节点。具体代码如下: ```cpp void PostOrder(BiTree &root) // 后序遍历 { if(root == NULL) return; PostOrder(root->lc); // 遍历左子 PostOrder(root->rc); // 遍历右子 cout << root->data << " "; // 访问根节点 } ``` 以上是链式存储二叉树递归遍历方法,根据需要选择先序、中序或后序对二叉树进行遍历。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [链式二叉树 先序、中序、后序 遍历(递归非递归)](https://blog.youkuaiyun.com/hpu2022/article/details/84564252)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值