LeetCode刷题小记——二叉树的中序遍历

本文详细介绍了二叉树中序遍历的递归和非递归方法,包括模仿系统栈和手工辅助栈技巧。通过实例代码演示,展示了如何利用栈数据结构实现中序遍历,适合初学者理解算法原理。
摘要由CSDN通过智能技术生成

二叉树的中序遍历

没事就练练

image-20201130095505161

方法:两大类

  • 递归
  • 非递归
    • 模仿系统栈(模仿递归的过程)
    • 手工辅助栈(利用栈的特点)

递归写法

代码奉上

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        
        List<Integer> res = new ArrayList<>();
        inorder(root,res);
        return res;
    }

    public void inorder(TreeNode root,List<Integer> res){
            if(root == null) return;
            inorder(root.left,res);
            res.add(root.val);
            inorder(root.right,res);

    }
}

没啥说的,看非递归

模仿系统栈

思想:模拟递归的过程,自己构造一个栈来模拟系统栈。

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        //初始化
        List<Integer> res = new ArrayList<>();//存放结果
        Stack<TreeNode> stack = new Stack<>();//手工栈
        TreeNode node;//工具人
        //先判空
        if(root == null) return res;
        node = root;
        while(!stack.isEmpty() || node!=null){
            //一直找左子树,压栈
            while(node!=null){
                stack.push(node);
                node = node.left;
            }
            //出栈访问(放入集合)
            node = stack.pop();
            res.add(node.val);
            //看右子树
            node = node.right;
        }
        return res;
    }
}

手工辅助栈

思想:利用栈的特点,把节点按照逆序放进去,如中序遍历,放入节点顺序为(右,中,左)。

以当前子树为单位,放入栈。

这里借鉴了大佬的颜色标记法。本文用节点类型代替颜色标识。

在放入当前子树根节点的时候,放的是值,不是节点。以此来代替颜色标记(树节点代表未访问,值代表已访问)。

实际上,是不断的把子树替换掉根,最终形成一个序列。

此代码思想适用于先序遍历与后序遍历,强烈推荐!!!

代码:

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        //初始化
        List<Integer> res = new ArrayList<>();//存放结果
        Stack stack = new Stack<>();//手工栈
        TreeNode node;//工具人
        //先判空
        if(root == null) return res;
        node = root;
        stack.push(node);
        while(!stack.isEmpty()){
            Object o = stack.pop();
            if(o instanceof TreeNode){//如果是个未访问子树,压栈
                node = (TreeNode)o;
                //三个节点压栈,按照后进先出的原则,注意根节点放的是值,不是节点。
                if(node.right != null)
                    stack.push(node.right);
                stack.push(node.val);	//放的是值,以此来判断当前子树是否已被压栈。
                if(node.left != null)
                    stack.push(node.left);
                
            }else{					//如果是个已访问子树,直接放结果。
                res.add((Integer)o);
            }
        }
        return res;
    }
}

不得不惊叹,大佬的颜色标记法确实牛!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值