【数据结构】 二叉树 | 翻转二叉树-递归+迭代

93 阅读1分钟

题目226. 翻转二叉树 - 力扣(LeetCode)

递归法

image.png

思路

从最下面的子树开始处理,再回溯,明显是一个递归的做法,需要思考一下几个问题

  • 递归函数的终止条件(遇到空节点)
  • 递归参数(node)
  • 递归函数内容(先处理左子树,再处理右子树,最后翻转当前节点的左右指针)

代码

  • 第一版代码:自己写的
  • 问题:根节点的处理好像可以统一到迭代函数里
class Solution {
    public TreeNode invertTree(TreeNode root) {
        // 递归法处理
        if(root == null) return null;
        invert(root);
        return root;
    }
    public void invert(TreeNode node) {
        if(node.left == null && node.right == null) return;
        if(node.left != null) invert(node.left);
        if(node.right != null) invert(node.right);
        TreeNode tmp = node.left;
        node.left = node.right;
        node.right = tmp;
    }
}

改进后:

class Solution {
    public TreeNode invertTree(TreeNode root) {
        // 递归法处理
        if(root == null) return null;
        invertTree(root.left);
        invertTree(root.right);
        TreeNode tmp = root.left;
        root.left = root.right;
        root.right = tmp;
        return root;
    }
}

迭代法:后序遍历

  • 访问过的节点用null标记
  • 遇到null时处理该节点逻辑

代码

class Solution {
    public TreeNode invertTree(TreeNode root) {
        // 迭代法模拟后序遍历
        if(root == null) return root;
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while(!stack.isEmpty()) {
            TreeNode node = stack.pop();
            if(node == null) {
                node = stack.pop();
                swap(node);
                continue;
            }
            stack.push(node);
            stack.push(null);
            if(node.left != null) stack.push(node.left);
            if(node.right != null) stack.push(node.right);
        }
        return root;
    }
    public void swap(TreeNode node) {
        TreeNode tmp = node.left;
        node.left = node.right;
        node.right = tmp;
    }
}

迭代法:层序遍历

两层循环,队列实现

  • 外循环遍历队列中所有节点
  • 在内循环处理每个节点,翻转当前层所有节点的左右指针

代码

class Solution {
    public TreeNode invertTree(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        if(root == null) {
            return root;
        }
        int size = 1;
        // BFS
        queue.offer(root);
        while(!queue.isEmpty()) {
            // TreeNode node = stack.pop();
            size = queue.size();
            for(int i = 0;i<size;i++) {
                TreeNode node = queue.poll();
                swap(node);
                if(node.left != null) queue.offer(node.left);
                if(node.right != null) queue.offer(node.right);
            }

        }
        return root;
    }
    public void swap(TreeNode node) {
        TreeNode tmp = node.left;
        node.left = node.right;
        node.right = tmp;
    }
}

总结

  1. 递归方法代码最简洁,如果正确理解了递归的思路,大有妙处~
  2. 迭代法可以用栈模拟递归的实现,加深对递归思路的理解

学习时长:1h30min