完全二叉树的节点个数

完全二叉树的节点个数

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2 h 2^h 2h个节点。

思路

完全二叉树的左右子树必有一个满二叉树。对该满二叉子树,只需计算高度即可

### 如何计算二叉中的节点数量 对于二叉节点计数问题,可以采用多种方法来实现。以下是详细的说明以及相应的代码示例。 #### 方法一:递归遍历整棵 通过递归的方式访问每一个节点并统计总数。这种方法适用于任意类型的二叉(包括完全二叉树)。 核心逻辑如下: - 如果当前节点为空,则返回0。 - 否则分别递归计算左子和右子节点数,并加上当前节点本身。 ```java public int countNodes(TreeNode root) { if (root == null) { return 0; } int leftCount = countNodes(root.left); // 左子节点数 int rightCount = countNodes(root.right); // 右子节点数 return leftCount + rightCount + 1; // 当前节点计入总和 } ``` 此方法的时间复杂度为 \(O(n)\),其中 \(n\) 是节点的数量[^1]。 --- #### 方法二:利用完全二叉树特性优化 当题目明确指出这是一棵 **完全二叉树** 时,可以通过更高效的方法减少不必要的递归操作。具体思路如下: 1. 判断当前子是否为满二叉(即左右子的高度相等)。 2. 若是满二叉,则可以直接用公式 \(2^h - 1\) 计算该子节点数(\(h\) 表示高度)。 3. 若不是满二叉,则继续递归处理其左右子。 时间复杂度接近于 \(O(\log n \cdot \log n)\)[^2]。 ##### 实现代码 ```java public int countNodes(TreeNode root) { if (root == null) { return 0; } TreeNode left = root.left; TreeNode right = root.right; int leftDepth = 0, rightDepth = 0; while (left != null) { // 获取左子深度 left = left.left; leftDepth++; } while (right != null) { // 获取右子深度 right = right.right; rightDepth++; } if (leftDepth == rightDepth) { // 满二叉情况 return (2 << leftDepth) - 1; // 使用位运算代替幂次方 } else { // 非满二叉情况 return countNodes(root.left) + countNodes(root.right) + 1; } } ``` 上述代码充分利用了完全二叉树的特点,在某些情况下能够显著提升性能[^2]。 --- #### 方法三:基于节点高度的迭代法 另一种方式是从根节点出发逐层遍历,记录每一层的节点数直至最后一层完成。这种方式通常用于广度优先搜索(BFS),适合较大的二叉结构。 ```java import java.util.LinkedList; import java.util.Queue; public int countNodes(TreeNode root) { if (root == null) { return 0; } Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); int count = 0; while (!queue.isEmpty()) { TreeNode node = queue.poll(); count++; // 统计当前节点 if (node.left != null) { queue.offer(node.left); } if (node.right != null) { queue.offer(node.right); } } return count; } ``` 这种做法虽然简单直观,但由于需要额外的空间存储队列,因此空间复杂度较高,达到 \(O(w)\),其中 \(w\) 是最宽的一层宽度[^3]。 --- ### 节点高度与节点数量的关系 在实际应用中,有时还需要结合节点高度来进行分析。例如,给定一棵二叉的一个特定节点,可通过递归来获取它的高度: ```java public int getHeight(TreeNode node) { if (node == null) { return 0; } return Math.max(getHeight(node.left), getHeight(node.right)) + 1; } ``` 这里需要注意的是,叶节点的高度定义为其父节点到它自身的路径长度减去1。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值