返回

LeetCode二叉树的三种遍历

闲谈

递归遍历

class Solution {
  // 先序遍历
  public List<Integer> preorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    preorder(root, result);
    return result;
  }

  private void preorder(TreeNode root, List<Integer> result) {
    if (root == null) {
      return;
    }
    result.add(root.val);
    preorder(root.left, result);
    preorder(root.right, result);
  }

  // 中序遍历
  public List<Integer> inorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    inorder(root, result);
    return result;
  }

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

  // 后序遍历
  public List<Integer> postorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    postorder(root, result);
    return result;
  }

  private void postorder(TreeNode root, List<Integer> result) {
    if (root == null) {
      return;
    }
    postorder(root.left, result);
    postorder(root.right, result);
    result.add(root.val);
  }
}

迭代遍历

class Solution {
  // 先序遍历
  public List<Integer> preorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    Stack<TreeNode> stack = new Stack<>();
    while (root != null || !stack.isEmpty()) {
      while (root != null) {
        result.add(root.val);
        stack.push(root);
        root = root.left;
      }
      root = stack.pop();
      root = root.right;
    }
    return result;
  }

  // 中序遍历
  public List<Integer> inorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    Stack<TreeNode> stack = new Stack<>();
    while (root != null || !stack.isEmpty()) {
      while (root != null) {
        stack.push(root);
        root = root.left;
      }
      root = stack.pop();
      result.add(root.val);
      root = root.right;
    }
    return result;
  }

  // 后序遍历
  public List<Integer> postorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    Stack<TreeNode> stack = new Stack<>();
    TreeNode prev = null;
    while (root != null || !stack.isEmpty()) {
      while (root != null) {
        stack.push(root);
        root = root.left;
      }
      root = stack.peek();
      if (root.right == null || root.right == prev) {
        result.add(root.val);
        prev = root;
        stack.pop();
        root = null;
      } else {
        root = root.right;
      }
    }
    return result;
  }
}

Morris遍历

class Solution {
  // 先序遍历
  public List<Integer> preorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    TreeNode cur = root;
    while (cur != null) {
      if (cur.left == null) {
        result.add(cur.val);
        cur = cur.right;
      } else {
        TreeNode predecessor = cur.left;
        while (predecessor.right != null && predecessor.right != cur) {
          predecessor = predecessor.right;
        }
        if (predecessor.right == null) {
          predecessor.right = cur;
          result.add(cur.val);
          cur = cur.left;
        } else {
          predecessor.right = null;
          cur = cur.right;
        }
      }
    }
    return result;
  }

  // 中序遍历
  public List<Integer> inorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    TreeNode cur = root;
    while (cur != null) {
      if (cur.left == null) {
        result.add(cur.val);
        cur = cur.right;
      } else {
        TreeNode predecessor = cur.left;
        while (predecessor.right != null && predecessor.right != cur) {
          predecessor = predecessor.right;
        }
        if (predecessor.right == null) {
          predecessor.right = cur;
          cur = cur.left;
        } else {
          predecessor.right = null;
          result.add(cur.val);
          cur = cur.right;
        }
      }
    }
    return result;
  }

  // 后序遍历
  public List<Integer> postorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    TreeNode cur = root;
    TreeNode prev = null;
    while (cur != null) {
      if (cur.left == null) {
        cur = cur.right;
      } else {
        TreeNode predecessor = cur.left;
        while (predecessor.right != null && predecessor.right != cur) {
          predecessor = predecessor.right;
        }
        if (predecessor.right == null) {
          predecessor.right = cur;
          cur = cur.left;
        } else {
          predecessor.right = null;
          result.addAll(postorderTraversal(cur.left));
          result.add(cur.val);
          cur = cur.right;
        }
      }
    }
    return result;
  }
}

总结

在这篇博客中,我们详细介绍了二叉树的三种遍历方法:递归、迭代和Morris遍历。每种方法都有其自身的优点和缺点,适合不同的场景。对于初学者来说,递归遍历可能是最容易理解的,但是迭代遍历和Morris遍历在某些情况下可能更有效率。我们希望这篇文章能够帮助您更好地理解二叉树遍历算法,并将其应用到您的编程项目中。