镜像翻转是原地交换每个节点的left和right指针,不新建节点;需先递归翻转子树再swap,用std::swap并检查空指针,函数应为void类型。

什么是镜像翻转?它不是复制而是原地交换
镜像翻转的本质是把每个节点的 left 和 right 指针互换,而不是新建节点或重建整棵树。关键在于“原地”——所有操作都在原有内存地址上完成,空间复杂度 O(h),h 是树高(递归栈深度),不额外分配节点。
容易误以为要深拷贝再反转,结果写出冗余代码、内存泄漏或指针悬空。实际只需一次递归遍历,每到一个节点就立刻 swap 它的左右子树指针。
swap 要用对:别直接赋值,也别漏掉空指针检查
常见错误是写成:node->left = node->right; node->right = node->left; —— 这会导致左子树被覆盖后丢失,最终两棵子树都变成原右子树的副本。
正确做法是用标准库 std::swap 或手动临时变量。同时必须处理空指针:如果当前节点为 nullptr,直接返回,否则访问 left/right 会崩溃。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 推荐用
std::swap(node->left, node->right),简洁且安全 - 递归调用必须放在
swap之后:先翻转子树,再交换当前节点的指针,才能保证子树内部已翻转完毕 - 顺序不能颠倒:若先 swap 再递归,会把未翻转的子树传给下一层,结果不对
递归函数怎么写?边界和返回值要明确
镜像翻转本身不需要返回值(void 函数即可),因为修改的是原树结构。但很多人习惯写成返回 TreeNode*,这容易引发混淆:你返回的是当前节点指针,但调用者通常并不需要它。
典型实现就是一个无返回值的 void 递归函数:
void mirrorTree(TreeNode* root) {
if (!root) return;
mirrorTree(root->left);
mirrorTree(root->right);
std::swap(root->left, root->right);
}注意:这里递归顺序是“先下后换”,即先递归到底部叶子节点,再逐层向上 swap。也可以先 swap 再递归(先换后下),但此时递归调用要用交换后的指针,逻辑稍绕,不推荐。
测试时最容易忽略的边界:单边子树和空树
写完函数别急着交,立刻验证这几个 case:
- 输入
nullptr→ 不崩溃,静默返回 - 只有根节点(
left和right都为nullptr)→ 根不变,没问题 - 只有左子树(
right == nullptr)→ 翻转后应变成只有右子树 - 链状树(如全左斜树)→ 应变成全右斜树
真正难调试的是指针没清空导致的野指针问题:比如 swap 后忘了某处仍持有旧 left 的引用,后续访问就段错误。所以翻转后建议加简单中序/层序验证结构是否符合预期。

















