二叉树---翻转二叉树

🔥个人主页: Milestone-里程碑

❄️个人专栏: <<力扣hot100>> <<C++>><<Linux>>

<<Git>><<MySQL>>

🌟心向往之行必能至

先看题目:

给定一棵二叉树,翻转这棵二叉树,并返回其根节点。所谓翻转,就是把每个节点的左子树和右子树互换,一层一层递归完成即可。

一、题目分析

翻转二叉树的核心逻辑只有两步:

  1. 终止条件 :如果当前节点是空节点(nullptr),直接返回,不用处理。
  2. 递归处理:先交换当前节点的左右孩子,再递归翻转左子树、递归翻转右子树。

举个直观例子:

plaintext

复制代码
原树:
     4
   /   \
  2     7
 / \   / \
1   3 6   9

翻转后:
     4
   /   \
  7     2
 / \   / \
9   6 3   1

每个节点的左右子树都完成了互换,完美符合要求。

二、完整 C++ 代码(递归版)

这是最简洁、最容易理解的递归实现,也是面试首选写法:

cpp

运行

复制代码
/**
 * 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 == nullptr) return nullptr;
        
        // 交换当前节点的左右孩子
        TreeNode* temp = root->left;
        root->left = root->right;
        root->right = temp;
        
        // 递归翻转左子树
        invertTree(root->left);
        // 递归翻转右子树
        invertTree(root->right);
        
        // 返回翻转后的根节点
        return root;
    }
};

三、代码逐行解析

我把代码拆解开,一步步讲清楚每一行的作用:

1. 递归终止条件

cpp

运行

复制代码
if(root == nullptr) return nullptr;
  • 如果当前节点是空节点,没有左右孩子可以交换,直接返回,避免空指针报错。
  • 这是递归的出口,所有递归题都必须有明确的终止条件。

2. 交换当前节点的左右孩子

cpp

运行

复制代码
TreeNode* temp = root->left;
root->left = root->right;
root->right = temp;
  • 用一个临时指针temp暂存左孩子。
  • 把右孩子赋值给左指针,左孩子赋值给右指针,完成当前节点的左右翻转。

3. 递归处理子树

cpp

运行

复制代码
invertTree(root->left);
invertTree(root->right);
  • 交换完当前节点后,它的左、右子树还没翻转,所以递归调用函数处理左、右子树。
  • 递归会一直深入到叶子节点,再逐层返回处理,最终整棵树完成翻转。

4. 返回根节点

cpp

运行

复制代码
return root;
  • 最终返回翻转后的二叉树根节点,符合题目要求。

四、复杂度分析

  1. 时间复杂度:O(n)二叉树的每个节点都会被访问一次,所以时间复杂度和节点数成正比。

  2. 空间复杂度:O(h)h 是二叉树的高度,递归调用栈的深度等于树的高度。

    • 最坏情况(斜树):h=n,空间复杂度 O(n)
    • 最好情况(平衡二叉树):h=logn,空间复杂度 O(logn)

五、递归思想总结

这道题完美体现了递归三要素:

  1. 确定递归函数的功能:翻转以 root 为根的二叉树。
  2. 确定递归终止条件:节点为空时返回。
  3. 确定递归递推公式:交换当前节点左右孩子 + 递归翻转左右子树。

只要掌握这个思路,二叉树的绝大多数递归题都能轻松搞定~

六、小拓展:迭代版(广度优先)

如果面试要求不用递归,可以用队列 + BFS实现,思路是层序遍历每个节点,逐个交换左右孩子:

cpp

运行

复制代码
TreeNode* invertTree(TreeNode* root) {
    if(!root) return nullptr;
    queue<TreeNode*> q;
    q.push(root);
    while(!q.empty()){
        TreeNode* node = q.front();
        q.pop();
        // 交换当前节点左右孩子
        swap(node->left, node->right);
        if(node->left) q.push(node->left);
        if(node->right) q.push(node->right);
    }
    return root;
}

总结

  1. 翻转二叉树核心:交换当前节点左右孩子 + 递归翻转子树。
  2. 递归代码极简,面试首选,时间复杂度 O(n)。
  3. 掌握递归三要素,二叉树递归题一通百通。
相关推荐
看浪的路人3 分钟前
第5讲:Prompt 管理与版本追踪
大数据·数据库·elasticsearch
Eloudy6 分钟前
全文 - version.A - AMBA CHI Chip-to-Chip(C2C)
java·开发语言·数据库·gpu·chiplet
秋名RG13 分钟前
Java历代LTS版本新特性详解(代码增强版)
java·开发语言·python
李少兄13 分钟前
深度剖析 Hutool ObjectUtil
java·开发语言
牢姐与蒯14 分钟前
位运算及其oj题
c++·算法
魏码不凡14 分钟前
Go 编译报错:undefined: webp.Encode 问题排查与解决
开发语言·后端·golang
276695829215 分钟前
youdao/有道翻译APP 算法协议分析
开发语言·前端·python·sign·youdao·有道翻译app算法·有道app协议请求
渡我白衣17 分钟前
深入理解 Transformer:Decoder与Masked_Attention
linux·服务器·网络·c++·人工智能·深度学习·transformer
励志不掉头发的内向程序员23 分钟前
【从零写一个CAD 04】中键拖动平移:抓住一个点,让它一直待在鼠标底下
开发语言·c++·qt·学习·系统架构·计算机外设
UIU11424 分钟前
同一个变量在两个 .c 文件里类型不一致,程序会怎样?
c++·学习·c#