代码随想录|二叉树|06翻转二叉树

leetcode:226. 翻转二叉树 - 力扣(LeetCode)

题目

翻转一棵二叉树。

代码随想录|二叉树|06翻转二叉树_第1张图片

思路

整棵树以root节点所处的中轴线为轴进行翻转,我们需要做的就是翻转每一个节点的左右孩子。

我们在遍历的过程中进行翻转,那么递归和迭代都是可以做的。

递归法

递归三部曲

(1)确定递归函数的参数和返回值

参数就是根节点root,返回的也是根节点,所以是TreeNode型。

(2)确定终止条件

当前节点为空的时候就返回。

(3)递归逻辑

因为是前序遍历,所以先交换左右孩子,然后反转左子树,再反转右子树。

基于递归三部曲,代码如下:

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if (root == NULL) return root;
        swap(root->left, root->right);  // 中
        invertTree(root->left);         // 左
        invertTree(root->right);        // 右
        return root;
    }
};

迭代法

整体的思想跟上面一样,遍历的过程我们保持不变,只是在每一个node位置需要交换它的左右孩子,代码如下:

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if (root == NULL) return root;
        stack st;
        st.push(root);
        while(!st.empty()) {
            TreeNode* node = st.top();              // 中
            st.pop();
            swap(node->left, node->right);
            if(node->right) st.push(node->right);   // 右
            if(node->left) st.push(node->left);     // 左
        }
        return root;
    }
};

层序遍历

我们前面的层序遍历是一层一层的,那我们现在每一层指向左右之前也交换左右孩子。

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        queue que;
        if (root != NULL) que.push(root);
        while (!que.empty()) {
            int size = que.size();
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                swap(node->left, node->right); // 节点处理
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
        }
        return root;
    }
};

总结

本文的递归法和迭代法都是前序遍历做的,使用后序的话其实也是一样的道理,但是中序的处理就比较麻烦了,因为中序遍历会把某些节点的左右孩子翻转两次!

我目前觉得理解好前序的两种方法以及层序遍历就可以了。

参考资料

代码随想录 

听说一位巨佬面Google被拒了,因为没写出翻转二叉树 | LeetCode:226.翻转二叉树_哔哩哔哩_bilibili 

你可能感兴趣的:(算法,数据结构,c++,leetcode)