LeetCode 每日一题 144.二叉树的前序遍历

10.27

LeetCode 每日一题 144.二叉树的前序遍历
image-20201027161452151

本题其实很简单,就是考察二叉树的前序遍历。

什么是前序遍历: 前序遍历(VLR), 是二叉树遍历的一种,也叫做先根遍历、先序遍历、前序周游,可记做根左右。前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。

方法一:递归

class Solution {
    List<Integer> res = new ArrayList<Integer>();
    public List<Integer> preorderTraversal(TreeNode root) {
        VLR(root);
        return res;
    }
    void VLR(TreeNode root){
        if(root == null)
            return;
        res.add(root.val);
        VLR(root.left);
        VLR(root.right);
    }
}

方法二:栈迭代

public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        if(root == null)
            return res;
        Stack<TreeNode> stack = new Stack<TreeNode>();
        stack.push(root);  // 根节点入栈
        while(!stack.isEmpty()){   // 当栈为空的时候,则已经遍历完全部节点
            TreeNode cur = stack.pop();  //先遍历根节点
            res.add(cur.val);    // 加入返回的结果集中
            
            // 因为栈是先进后出的,前序遍历是  根->左->右  遍历
            // 所以应该将右结点先入栈,左结点后入栈
            if(cur.right != null)   //当前结点的右结点不为空时,则入栈
                stack.push(cur.right);
            if(cur.left != null)  //当前结点的左结点不为空时,则入栈
                stack.push(cur.left);
        }
        return res;
    }

方法三:Morris算法

前两种算法的空间复杂度都是O(n),而这种算法将空间复杂度降低到了O(1)。

morris遍历的实现原则

记作当前节点为cur

  1. 如果cur无左孩子,cur向右移动(cur=cur.right)

  2. 如果cur有左孩子,找到cur左子树上最右的节点,记为mostright

    1. 如果mostright的right指针指向空,让其指向cur,cur向左移动(cur=cur.left)
    2. 如果mostright的right指针指向cur,让其指向空,cur向右移动(cur=cur.right)

实现以上的原则,即实现了morris遍历。

知乎传送门 https://zhuanlan.zhihu.com/p/101321696

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        if(root == null)
            return res;
        TreeNode cur = root;
        while(cur != null){
            if(cur.left == null){
                res.add(cur.val);
                cur = cur.right;
            }else{
                TreeNode temp = cur.left;
                while(temp.right != null && temp.right != cur){
                    temp = temp.right;
                }
                if(temp.right == null){
                    res.add(cur.val);
                    temp.right = cur;
                    cur = cur.left;
                }else{
                    temp.right = null;
                    cur = cur.right;
                }
            }
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值