c++中如何判断二叉树是否是对称的_c++镜像二叉树判断算法
发布时间 - 2025-12-31 00:00:00 点击率:次判断二叉树是否对称需递归或迭代检查左右子树是否镜像相等:即左子树左孩子与右子树右孩子、左子树右孩子与右子树左孩子分别相等且值相同;常见错误是误判子树各自对称或忽略空指针和节点值校验。
用递归比较左右子树是否互为镜像
判断二叉树是否对称,本质是检查左子树是否与右子树“镜像相等”:即左子树的左孩子等于右子树的右孩子,左子树的右孩子等于右子树的左孩子。不能只比结构,必须同步比较节点值。
关键点在于设计一个辅助函数 isMirror(TreeNode* left, TreeNode* right),它接收两个子树根节点,返回它们是否互为镜像:
- 都为空 → 对称(
return true) - 仅一个为空 → 不对称(
return false) - 都不为空但值不等 → 不对称(
return false) - 都不为空且值相等 → 递归检查
left->left与right->right,以及left->right与right->left
bool isSymmetric(TreeNode* root) {
if (!root) return true;
return isMirror(root->left, root->right);
}
bool isMirror(TreeNode left, TreeNode right) {
if (!left && !right) return true;
if (!left || !right) return false;
if (left->val != right->val) return false;
return isMirror(left->left, right->right) &&
isMirror(left->right, right->left);
}
迭代写法:用栈模拟递归配对检查
递归直观但有栈溢出风险;迭代更可控,核心是把“待比较的节点对”压入栈中,每次弹出一对做值比较,再把下一层的镜像组合推入栈。
初始压入 root->left 和 root->right;每次取两个节点 l 和 r:
立即学习“C++免费学习笔记(深入)”;
- 都为空 → 继续下一轮
- 仅一个为空 → 返回
false - 值不等 → 返回
false - 值相等 → 将
l->left与r->right、l->right与r->left成对压栈
bool isSymmetric(TreeNode* root) {
if (!root) return true;
stack stk;
stk.push(root->left);
stk.push(root->right);
while (!stk.empty()) {
TreeNode* r = stk.top(); stk.pop();
TreeNode* l = stk.top(); stk.pop();
if (!l && !r) continue;
if (!l || !r) return false;
if (l->val != r->val) return false;
stk.push(l->left); stk.push(r->right);
stk.push(l->right); stk.push(r->left);
}
return true;
}
常见错误:误用“左右子树各自对称”逻辑
新手常写成:isSymmetric(root->left) && isSymmetric(root->right) —— 这是在检查“左子树自身对称”且“右子树自身对称”,完全偏离题意。对称性是跨左右子树的镜像关系,不是子树内部性质。
另一个典型错误是只比结构忽略值:比如用 nullptr 占位但没校验 val,导致 [1,2,2,null,3,null,3] 被误判为对称(实际不是,因为两个 3 不在镜像位置)。
测试时务必覆盖这些用例:
-
[1,2,2,3,4,4,3]→ true -
[1,2,2,null,3,null,3]→ false(注意 null 的位置) -
[1]→ true -
[]→ true
时间与空间复杂度差异明显
递归和迭代都是 O(n) 时间复杂度,每个节点访问一次。但空间表现不同:
- 递归:最坏深度
O(n)(退化为链表),平均O(h)(h 为树高) - 迭代:栈中最多存
O(w)个节点(w 为最大宽度),对于满二叉树,宽度远小于深度,此时迭代更省内存
如果题目明确要求“避免递归”或输入可能极深,优先选迭代;否则递归更易写对、不易漏边界。
真正容易被忽略的是空指针解引用——无论递归还是迭代,必须在取 ->val 或访问子指针前,先判断指针非空。漏掉这一层检查,本地能过但线上 runtime error 是高频翻车点。
# node
# 栈
# c++
# NULL
# Error
# 递归
# 指针
# 空指针
# 算法
# 子树
# 镜像
# 迭代
# 为空
# 都不
# 二叉树
# 不对称
# 的是
# 只比
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何在云服务器上快速搭建个人网站?
实例解析Array和String方法
Android自定义控件实现温度旋转按钮效果
Laravel怎么设置路由分组Prefix_Laravel多级路由嵌套与命名空间隔离【步骤】
Laravel如何实现API版本控制_Laravel版本化API设计方案
高性能网站服务器配置指南:安全稳定与高效建站核心方案
中山网站制作网页,中山新生登记系统登记流程?
javascript读取文本节点方法小结
Bootstrap整体框架之JavaScript插件架构
javascript中的数组方法有哪些_如何利用数组方法简化数据处理
Laravel如何保护应用免受CSRF攻击?(原理和示例)
Laravel怎么清理缓存_Laravel optimize clear命令详解
php打包exe后无法访问网络共享_共享权限设置方法【教程】
Windows10怎样连接蓝牙设备_Windows10蓝牙连接步骤【教程】
javascript基本数据类型及类型检测常用方法小结
Laravel中Service Container是做什么的_Laravel服务容器与依赖注入核心概念解析
简历在线制作网站免费版,如何创建个人简历?
美食网站链接制作教程视频,哪个教做美食的网站比较专业点?
如何在Ubuntu系统下快速搭建WordPress个人网站?
深圳网站制作培训,深圳哪些招聘网站比较好?
购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?
Zeus浏览器网页版官网入口 宙斯浏览器官网在线通道
node.js报错:Cannot find module 'ejs'的解决办法
phpredis提高消息队列的实时性方法(推荐)
香港网站服务器数量如何影响SEO优化效果?
如何选择PHP开源工具快速搭建网站?
Laravel的契約(Contracts)是什么_深入理解Laravel Contracts与依赖倒置
Android使用GridView实现日历的简单功能
如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?
laravel怎么用DB facade执行原生SQL查询_laravel DB facade原生SQL执行方法
DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解
Laravel Eloquent关联是什么_Laravel模型一对一与一对多关系精讲
头像制作网站在线观看,除了站酷,还有哪些比较好的设计网站?
哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?
网站制作软件免费下载安装,有哪些免费下载的软件网站?
Laravel中间件如何使用_Laravel自定义中间件实现权限控制
北京专业网站制作设计师招聘,北京白云观官方网站?
详解MySQL数据库的安装与密码配置
Laravel如何配置.env文件管理环境变量_Laravel环境变量使用与安全管理
javascript中闭包概念与用法深入理解
如何用美橙互联一键搭建多站合一网站?
Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】
Laravel怎么创建控制器Controller_Laravel路由绑定与控制器逻辑编写【指南】
Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南
Python数据仓库与ETL构建实战_Airflow调度流程详解
Laravel Livewire是什么_使用Laravel Livewire构建动态前端界面
Bootstrap整体框架之CSS12栅格系统
详解Android图表 MPAndroidChart折线图
如何获取PHP WAP自助建站系统源码?
如何快速搭建高效简练网站?
上一篇: ,石家庄四十八中学官网?
下一篇:建站之星上传入口如何快速找到?
上一篇: ,石家庄四十八中学官网?
下一篇:建站之星上传入口如何快速找到?


