给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
翻转前:

  1. 4
  2. / \
  3. 2 7
  4. / \ / \
  5. 1 3 6 9

翻转后:

  1. 4
  2. / \
  3. 7 2
  4. / \ / \
  5. 9 6 3 1

参考前序遍历二叉树的实现

  1. public TreeNode invertTree(TreeNode node) {
  2. // 递归的结束条件
  3. if (node == null) {
  4. // 终止时处理办法
  5. return null;
  6. }
  7. // 当前节点需要做的事情
  8. nodeNeedTodo(node);
  9. // 让当前节点的左子节点重复当前节点
  10. invertTree(node.left);
  11. // 让当前节点的右子节点重复当前节点
  12. invertTree(node.right);
  13. return node;
  14. }
  15. /**
  16. * 实现左子节点和右子节点对换
  17. */
  18. private void nodeNeedTodo(TreeNode node) {
  19. TreeNode temp = node.left;
  20. node.left = node.right;
  21. node.right = temp;
  22. }
  1. public static void main(String[] args) {
  2. Integer[] arr = {4,2,7,1,3,6,9};
  3. TreeNode root = BinaryTreeUtil.arrToTree(arr);
  4. root = invertTree(root);
  5. BinaryTreePrintUtil.print(root);
  6. }
  1. 4
  2. / \
  3. 7 2
  4. / \ / \
  5. 9 6 3 1

运行结果,符合期望

参考中序遍历二叉树的实现

  1. public TreeNode invertTree(TreeNode node) {
  2. // 递归的结束条件
  3. if (node == null) {
  4. // 终止时处理办法
  5. return null;
  6. }
  7. // 让当前节点的左子节点重复当前节点
  8. invertTree(node.left);
  9. // 当前节点需要做的事情
  10. nodeNeedTodo(node);
  11. // 让当前节点的右子节点重复当前节点
  12. invertTree(node.right);
  13. return node;
  14. }
  15. /**
  16. * 实现左子节点和右子节点对换
  17. */
  18. private void nodeNeedTodo(TreeNode node) {
  19. TreeNode temp = node.left;
  20. node.left = node.right;
  21. node.right = temp;
  22. }
  1. public static void main(String[] args) {
  2. Integer[] arr = {4,2,7,1,3,6,9};
  3. TreeNode root = BinaryTreeUtil.arrToTree(arr);
  4. root = invertTree(root);
  5. BinaryTreeUtil.levelOrderPrint(root);
  6. }
  1. 4
  2. / \
  3. 7 2
  4. / \ / \
  5. 6 9 1 3

运行结果,不符合期望

参考后序遍历二叉树的实现

  1. public TreeNode invertTree(TreeNode node) {
  2. // 递归的结束条件
  3. if (node == null) {
  4. // 终止时处理办法
  5. return null;
  6. }
  7. // 让当前节点的左子节点重复当前节点
  8. invertTree(node.left);
  9. // 让当前节点的右子节点重复当前节点
  10. invertTree(node.right);
  11. // 当前节点需要做的事情
  12. nodeNeedTodo(node);
  13. return node;
  14. }
  15. /**
  16. * 实现左子节点和右子节点对换
  17. */
  18. private void nodeNeedTodo(TreeNode node) {
  19. TreeNode temp = node.left;
  20. node.left = node.right;
  21. node.right = temp;
  22. }
  1. public static void main(String[] args) {
  2. Integer[] arr = {4,2,7,1,3,6,9};
  3. TreeNode root = BinaryTreeUtil.arrToTree(arr);
  4. root = invertTree(root);
  5. BinaryTreeUtil.levelOrderPrint(root);
  6. }
  1. 4
  2. / \
  3. 7 2
  4. / \ / \
  5. 9 6 3 1

运行结果,符合期望

思考

为什么参考中序遍历二叉树的实现不符合期望而参考前序和后序遍历二叉树的实现符合期望?

前序遍历:先操作根节点,然后操作根节点的左子树,最后操作根节点的右子树
先操作根节点,把左子树和右子树对换了一下;然后操作左子树(即最初的右子树)。完成左子树的翻转;最后操作右子树(即最初的左子树),完成右子树的翻转。

后序遍历:先操作根节点的左子树,然后操作根节点的右子树,最后操作根节点
先操作左子树,完成左子树的翻转;然后操作右子树,完成右子树的翻转;最后操作根节点,对换左子树和右子树。

中序遍历:先操作根节点的左子树,然后操作根节点,最后操作根节点的右子树
先操作左子树,完成左子树的翻转;然后操作根节点,对换左子树和右子树;最后操作右子树(实际是翻转后的初始左子树),翻转右子树,实际上变成了初始的左子树
所以最终结果是仅完成了根节点的左子树和右子树对换,左子树和右子树内部并没有完成翻转

树节点对象

  1. public class TreeNode {
  2. int val;
  3. TreeNode left;
  4. TreeNode right;
  5. TreeNode(){}
  6. TreeNode(int val) {this.val = val;}
  7. TreeNode(int val, TreeNode left, TreeNode right) {
  8. this.val = val;
  9. this.left = left;
  10. this.right = right;
  11. }
  12. }