0

0

c++中如何计算二叉树的深度_c++求二叉树高度

尼克

尼克

发布时间:2026-01-07 15:28:02

|

770人浏览过

|

来源于php中文网

原创

二叉树高度按节点数定义,递归解法为:空节点返回0,否则返回左右子树最大高度加1;非递归用BFS按层计数;注意避免重复计算、段错误及定义混淆。

c++中如何计算二叉树的深度_c++求二叉树高度

用递归求二叉树高度,核心就是左右子树最大深度加1

二叉树的高度(深度)定义为从根节点到最远叶子节点的最长路径上的边数或节点数,C++ 中通常按「节点数」算(即空树高度为 0,单节点树高度为 1)。递归是最自然的解法:当前节点高度 = max(左子树高度, 右子树高度) + 1

关键点在于边界处理:遇到空指针 nullptr 就返回 0。不要写成返回 -1 或 1,否则结果会偏移。

  • 如果按「边数」定义(LeetCode 一些题),空树为 0,单节点为 0,那递归式仍是 max(left, right) + 1,但初始调用后要减 1 —— 更推荐统一用「节点数」定义,避免混淆
  • 函数签名建议用 int getHeight(TreeNode* root),明确语义;别用 depth 当函数名,容易和「当前递归深度」参数混淆
  • 不推荐在递归中传入引用计数器或全局变量,既难调试又破坏纯函数性
int getHeight(TreeNode* root) {
    if (!root) return 0;
    return std::max(getHeight(root->left), getHeight(root->right)) + 1;
}

非递归写法:用 BFS 层序遍历统计层数

想避免递归溢出(比如极不平衡的链状树),就用队列做层序遍历。每处理完一层,高度加 1。比 DFS 递归略慢但空间可控——最坏空间复杂度是 O(w),其中 w 是最大层宽,而非树高。

注意别把「每 pop 一个节点就 height++」,那是错的;必须按层隔离,用内层循环或记录当前层节点数。

立即学习C++免费学习笔记(深入)”;

Beautiful.ai
Beautiful.ai

AI在线创建幻灯片

下载
  • 初始化队列后,先检查 if (!root) return 0
  • 每次外层 while 循环开始前,height++;内层 for 循环负责清空当前层所有节点
  • C++ 中推荐用 queue,别存整数值或智能指针,除非有特殊生命周期管理需求
int getHeightBFS(TreeNode* root) {
    if (!root) return 0;
    std::queue q;
    q.push(root);
    int height = 0;
    while (!q.empty()) {
        height++;
        int levelSize = q.size();
        for (int i = 0; i < levelSize; ++i) {
            TreeNode* node = q.front(); q.pop();
            if (node->left) q.push(node->left);
            if (node->right) q.push(node->right);
        }
    }
    return height;
}

常见错误:把深度和直径、平衡判断混在一起

看到「深度」就下意识套用上面任一函数,但实际场景常有隐藏要求。比如:

  • isBalanced() 需要同时获取左右子树高度并比较差值,若重复调用 getHeight() 会退化成 O(n²);应改用后序遍历一次返回高度+是否平衡
  • 求「二叉树直径」本质是找某节点左右子树深度之和的最大值,不能只算根节点的左右高度
  • 某些 OJ 题(如 LeetCode 104)输入可能为空指针,而你的 TreeNode 定义没给默认构造,直接访问 root->left 会段错误

模板类或泛型树时,高度计算逻辑不变但类型要适配

如果你用的是自定义模板节点(如 template struct TreeNode),只要成员名一致(left/right),上面两个函数几乎不用改。但要注意:

  • 模板函数需声明为 template int getHeight(TreeNode* root),不能漏掉 typename T
  • 若节点存储智能指针(如 std::unique_ptr>),则判空用 !root 仍有效,但访问子节点要写 root->left.get() 或直接用 -> 操作符(unique_ptr 重载了它)
  • 静态断言可加: static_assert(std::is_pointer_vleft)>, "left must be pointer");,提前暴露接口不匹配问题

真正容易被忽略的是:很多初学者在调试时打印中间高度值,却忘了递归中同一函数被多次调用,输出顺序和直觉不符;与其加一堆 cout,不如用 IDE 单步或写个带 depth 参数的辅助函数来跟踪。

相关专题

更多
if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

720

2023.08.22

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

83

2023.09.25

全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

73

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

96

2025.09.18

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

314

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

529

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

49

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

193

2025.08.29

java学习网站推荐汇总
java学习网站推荐汇总

本专题整合了java学习网站相关内容,阅读专题下面的文章了解更多详细内容。

3

2026.01.08

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
HTML5/CSS3/JavaScript/ES6入门课程
HTML5/CSS3/JavaScript/ES6入门课程

共102课时 | 6.6万人学习

前端基础到实战(HTML5+CSS3+ES6+NPM)
前端基础到实战(HTML5+CSS3+ES6+NPM)

共162课时 | 18.6万人学习

第二十二期_前端开发
第二十二期_前端开发

共119课时 | 12.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号