翻转二叉树

题目描述

力扣链接🔗

翻转二叉树 - 图1

题目分析

大概思路为每次遍历道一个节点交换2个左右孩子节点。具体代码中详细注释。

代码

以下所有方法交换左右孩子节点的方法都为

  1. /**
  2. * 用于交换两个节点
  3. *
  4. * @param root
  5. */
  6. public void wrapNode(TreeNode root) {
  7. TreeNode tempNode = root.left;
  8. root.left = root.right;
  9. root.right = tempNode;
  10. }

以下代码就不详细写了。

递归法

翻转二叉树 - 图2

前后序递归

  1. /**
  2. * 前序和后序的递归遍历
  3. *
  4. * @param root
  5. * @return
  6. */
  7. public TreeNode invertTree(TreeNode root) {
  8. if (root == null) {
  9. return null;
  10. }
  11. wrapNode(root);
  12. // 递归遍历(前序和后序都可以) 后序交换顺序即可
  13. invertTree(root.left);
  14. invertTree(root.right);
  15. return root;
  16. }

中序递归法

不是严格的中序遍历,因为此处没有取值,所以普通递归而可以使用。

  1. /**
  2. * 中序递归法(不完全是中序)
  3. *
  4. * @param root
  5. * @return
  6. */
  7. public TreeNode invertTree(TreeNode root) {
  8. if (root == null) {
  9. return null;
  10. }
  11. invertTree(root.left); // 左
  12. wrapNode(root); // 中
  13. invertTree(root.left); // 左,此时已经翻转,相当于现在左边是右孩子
  14. return root;
  15. }

统一迭代遍历

中序的迭代遍历

  1. /**
  2. * 统一迭代的中序遍历
  3. *
  4. * @param root
  5. * @return
  6. */
  7. public TreeNode invertTree(TreeNode root) {
  8. Stack<TreeNode> stack = new Stack<>();
  9. if (root == null) {
  10. return null;
  11. }
  12. stack.push(root);
  13. while (!stack.isEmpty()) {
  14. TreeNode node = stack.peek();
  15. if (node != null) {
  16. stack.pop(); // 先出栈,防止重复
  17. if (node.right != null) stack.push(node.right);
  18. stack.push(node);
  19. stack.push(null);
  20. if (node.left != null) stack.push(node.left);
  21. } else {
  22. stack.pop(); // 将null出栈
  23. node = stack.peek();
  24. stack.pop();
  25. wrapNode(node);
  26. }
  27. }
  28. return root;
  29. }

层序遍历

层序遍历也是每层遍历到一个节点就进行翻转。

  1. /**
  2. * 层序遍历
  3. *
  4. * @param root
  5. * @return
  6. */
  7. public TreeNode invertTree(TreeNode root) {
  8. Queue<TreeNode> queue = new LinkedList<>();
  9. if (root == null) {
  10. return null;
  11. }
  12. queue.offer(root);
  13. while (!queue.isEmpty()) {
  14. int len = queue.size();
  15. while (len > 0) {
  16. TreeNode node = queue.poll();
  17. wrapNode(node); // 直接交换孩子节点即可
  18. if (node.left != null) queue.offer(node.left);
  19. if (node.right != null) queue.offer(node.right);
  20. len--;
  21. }
  22. }
  23. return root;
  24. }