LeetCode_144_二叉树的前序遍历

题目链接

解题思路

  • 递归法

  • 前序遍历的顺序是根节点--> 左子树-->右子树,简称DLR

  • 注意在访问左子树或者右子树的时候,按照同样的方式遍历,直到遍历完整棵树

  • 大佬的解题思路:Morris遍历

  • Morris遍历的核心思想是利用树的大量空闲指针,实现空间开销的极限缩减,其前序遍历规则总结如下:

    • 新建临时节点,令该节点为root
    • 如果当前节点的左子节点为空格,将当前节点加入答案,并遍历当前节点的右子节点
    • 如果当前节点的左子节点不为空,在当前节点的左子树中找到当前节点在中序遍历下的前驱节点:
      • 如果前驱节点的右子节点为空,将前驱节点的右子节点设置为当前节点。然后将当前节点加入答案,并将前驱节点的右子节点更新为当前节点
      • 如果前驱节点的右子节点为当前节点,将他的右子节点重新设为空。当前节点更新为当前节点的右子节点
    • 重复步骤2和步骤3,直到遍历结束

AC代码

//常规的递归法,时间复杂度O(n),空间复杂度O(n)
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> ans = new ArrayList<Integer>();
        preorder(root, ans);
        return ans;
    }

    public void preorder(TreeNode root, List<Integer> ans) {
        if (root == null) {
            return;
        }
        ans.add(root.val);
        preorder(root.left, ans);
        preorder(root.right, ans);
    }
}
//Morris解法,时间复杂度O(n),空间复杂度O(1)
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        if (root == null) {
            return res;
        }

        TreeNode p1 = root, p2 = null;

        while (p1 != null) {
            p2 = p1.left;
            if (p2 != null) {
                while (p2.right != null && p2.right != p1) {
                    p2 = p2.right;
                }
                if (p2.right == null) {
                    res.add(p1.val);
                    p2.right = p1;
                    p1 = p1.left;
                    continue;
                } else {
                    p2.right = null;
                }
            } else {
                res.add(p1.val);
            }
            p1 = p1.right;
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值