剑指Offer27.二叉树的镜像

  • 剑指Offer27.二叉树的镜像

  • 题目:
    给定一个二叉树,返回它的镜像二叉树;

  • 思路:
    将一颗二叉树镜像,相当于交换它的所有节点的左右孩子;
    因此本题等价于在遍历二叉树时交换每个结点的左右孩子;
    可选的遍历方式:前,中,后,层序均可,只要可以遍历二叉树即可,下面分别列出递归和迭代写法:

1.递归:O(n):遍历一次树的所有节点,O(n):递归n次所占的栈空间

注意点:
①其实代码中的return没什么用,作用只是返回当前节点,如果删掉这一句也能完成镜像操作,只是没法返回最终的头节点(其实就是本来的头节点);
②递归操作时,并不需要返回值做什么事,因此不用去接住下一层的返回值;
③注意遍历顺序:swap操作放在前面或后面均可,但放在中间会出错,因为中的操作本就是交换左右孩子,因此要么先交换再递归的处理左右孩子,要么先递归到最底层再交换左右孩子均可,但如果swap放在中间,会导致swap前后的两个递归操作所基于的“左右”发生了改变;

//写法1:先序遍历
class Solution {
public:
	//交换树的每个节点的左右孩子
    TreeNode* mirrorTree(TreeNode* root) {

        swap(root->left, root->right);//中
        mirrorTree(root->left);//
        mirrorTree(root->right);
        
        return root;//这里return的作用本就是返回当前节点
    }
};

//写法2:中序遍历
class Solution {
public:
    TreeNode* mirrorTree(TreeNode* root) {
        if (!root) return nullptr;

        mirrorTree(root->left);//递归操作root的左孩子
        swap(root->left, root->right);//交换root的左右孩子
        mirrorTree(root->left);//因为交换了root的左右孩子,所以现在的root->left就是原来的root->right
        
        return root;
    }
};


//写法3:后序遍历
class Solution {
public:
    TreeNode* mirrorTree(TreeNode* root) {
        if (!root) return nullptr;

        mirrorTree(root->left);//左
        mirrorTree(root->left);//右
        swap(root->left, root->right);//中
        
        return root;
    }
};

2.迭代写法(借助栈或队列):O(n):遍历一遍树的所有节点,O(n):需要一个大小为n的额外空间
原理相同,只是借助的数据结构不用;

//写法1:栈(下面以前序遍历为例,中序和后序同理)
class Solution {
public:
    TreeNode* mirrorTree(TreeNode* root) {
        if (!root) return nullptr;

        stack<TreeNode*> stk;
        stk.push(root);//空结点不入栈
        while (!stk.empty()) {
            TreeNode* tmp = stk.top();
            stk.pop();
            swap(tmp->left, tmp->right);
            if (tmp->left) stk.push(tmp->left);
            if (tmp->right) stk.push(tmp->right);
        }
        return root;
    }
};


//写法2:队列(层序遍历)
class Solution {
public:
    TreeNode* mirrorTree(TreeNode* root) {
        if (!root) return nullptr;

        queue<TreeNode*> que;
        que.push(root);//空结点不入队
        while (!que.empty()) {
            TreeNode* tmp = que.front();
            que.pop();
            swap(tmp->left, tmp->right);
            if (tmp->left) que.push(tmp->left);
            if (tmp->right) que.push(tmp->right);
        }
        return root;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值