力扣226-翻转二叉树(C++,层序遍历,前序递归,前序迭代)

这篇博客讨论了如何翻转二叉树,强调了翻转节点而非节点值的重要性。提供了三种方法实现:层序遍历、前序递归和前序迭代。每种方法都通过交换节点的左右子节点来完成翻转。层序遍历使用队列,前序递归和迭代则利用栈或递归思路。
摘要由CSDN通过智能技术生成

 

思路:

这个题我觉得最重要的地方在于思路的开始是“翻转节点”还是“翻转节点里面的值”。这两种思路看上去相差不多,其实相差很多。如果仅仅对值做反转,则遇到

                A                                 A
 
               / \                              /   \

              B   C                            C     B

             /                                         \                         

            D                                            D

的D节点就会束手无策,因为如果是只交换值的话,是不可能把D节点从左子节点换为右子节点的。所以想到这一层就知道是要交换节点,而不能仅仅交换值。

明白了之后就要采用遍历的方式,我采用层序遍历,因为不涉及到递归,比较简单。在层序遍历模板的基础上,对当前节点进行一个交换左右子节点的操作即可,其他改变不用做。

层序遍历代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if(!root){
            return nullptr;
        }
        queue<TreeNode*> q;
        q.push(root);
        while(!q.empty())
        {
            int sz=q.size();
            while(sz--)
            {
                TreeNode* cur=q.front();
                q.pop();
                if(cur->left||cur->right){
                    swap(cur->left,cur->right);
                }
                if(cur->left){
                    q.push(cur->left);
                }
                if(cur->right){
                    q.push(cur->right);
                }
            }
        }
        return root;
    }
};

前序递归

代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    void Traverse(TreeNode* root)
    {
        if(!root){
            return ;
        }
        swap(root->left,root->right);
        Traverse(root->left);
        Traverse(root->right);
    }
    TreeNode* invertTree(TreeNode* root) {
        if(!root){
            return nullptr;
        }
        Traverse(root);
        return root;
    }
};

递归的思路:只看当前节点,而不去管递归的过程。什么意思呢?就是说我看当前节点的时候,就认为当前节点的左右节点下面的所有节点都交换好了,只需要交换对于当前节点来说的左右节点即可。

前序迭代:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:

    TreeNode* invertTree(TreeNode* root) {
        if(!root){
            return nullptr;
        }
        stack<TreeNode*> stk;
        stk.push(root);
        while(!stk.empty())
        {
            TreeNode* cur=stk.top();
            stk.pop();
            swap(cur->left, cur->right);
            if(cur->right){
                stk.push(cur->right);
            }
            if(cur->left){
                stk.push(cur->left);
            }
        }
        return root;
    }
};

用栈模拟前序遍历的过程,代码结构很像层序遍历。前序遍历是DLR,但是栈是先进后出,所以入栈的时候是先右节点进再左节点进,其他处理手法与层序遍历无异。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值