Loading

力扣 - 144. 二叉树的前序遍历

题目

144. 二叉树的前序遍历

思路1(递归)

  • 前序先遍历根节点,然后左孩子,然后右孩子
  • 使用递归解题

代码

class Solution {
    List<Integer> res = new LinkedList<>();

    public List<Integer> preorderTraversal(TreeNode root) {
        preOrder(root);
        return res;
    }

    public void preOrder(TreeNode root) {
        if (root == null) {
            return;
        }

        res.add(root.val);
        preOrder(root.left);
        preOrder(root.right);
    }
}

复杂度分析

  • 时间复杂度:\(O(N)\),其中 N 为二叉树的结点数
  • 空间复杂度:\(O(N)\)

思路2(迭代)

  • 用栈来遍历
  • 和层序遍历有些类似,不过不用队列,而是用栈

代码

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new LinkedList<>();
        if (root == null) {
            return res;
        }
        Deque<TreeNode> stack = new LinkedList<>();

        while (!stack.isEmpty() || root != null) {
            while (root != null) {
                res.add(root.val);
                // 入栈
                stack.push(root);
                root = root.left;
            }
            root = stack.pop().right;
        }
        return res;
    }
}

复杂度分析

  • 时间复杂度:\(O(N)\),其中 N 为二叉树的结点数
  • 空间复杂度:\(O(N)\)

思路3(Morris遍历)

  • 如果左孩子不为空
    • 找到左子树的最右端的节点
      • 如果该节点的right是null,那么将其right指向当前节点,并且将当前节点加入res
      • 否则将其right置为null
  • 如果左孩子为空
    • 直接将当前节点加入res
  • 每次循环结束都将指针指向当前节点的右孩子right

代码

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new LinkedList<>();
        TreeNode p1 = root;
        TreeNode 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;
    }
}

复杂度分析

  • 时间复杂度:\(O(N)\),其中 N 为二叉树的结点数
  • 空间复杂度:\(O(1)\)
posted @ 2020-12-07 00:18  linzeliang  阅读(78)  评论(0)    收藏  举报