完全二叉树的结点个数

本文详细介绍了计算完全二叉树节点数量的三种方法:递归法、迭代法和利用完全二叉树的性质。递归法中,当节点为空时返回0,否则计算左右子树节点数并加1。迭代法的时间复杂度和空间复杂度均为O(n)。利用性质的方法主要针对满二叉树和非满二叉树的情况,通过递归计算节点数量,时间复杂度为O(logn * logn)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

递归法

1、确定递归函数的参数和返回值:参数就是传⼊树的根节点,返回就返回以该节点为根节点⼆叉树的节点数量,所以返回值为int类型。

int countNodes(TreeNoed* root)

2、确定终⽌条件:如果为空节点的话,就返回0,表示节点数为0。代码如下:

if(node==nullptr) return 0;

3、确定单层递归的逻辑:先求它的左⼦树的节点数量,再求的右⼦树的节点数量,最后取总和再加⼀(加1是因为算上当前中间节点)就是⽬前节点为根节点的节点数量。

 int leftnodes=getnodes(node->left); //左
 int rightnodes=getnodes(node->right);//右
 int sum=leftnodes+rightnodes;//中
 return sum+1;

完整递归代码:

class Solution {
public:
    int getnodes(TreeNode* node)
    {
      if(node==nullptr) return 0;
      int leftnodes=getnodes(node->left); //左
      int rightnodes=getnodes(node->right);//右
      int sum=leftnodes+rightnodes;//中
      return sum+1;
    }
    
    int countNodes(TreeNode* root) {
        return getnodes(root);
    }
};

时间复杂度:O(n)
空间复杂度:O(logn),算上了递归系统栈占⽤的空间

迭代法

class Solution{
public:
    int countNodes(TreeNode* root){
       if(root==nullptr) return 0;
       queue<TreeNode*> que;
       que.push(root);
       int sum=0;
       
       while(!que.empty()){
         int size=que.size();
         for(int ii=0;ii<size;ii++){
           sum++;
           TreeNode* node=que.front();
           que.pop();
           if(node->left) que.push(node->left);
           if(node->right) que.push(node->right);
         }
       }
       return sum;
    }
};

时间复杂度:O(n)空间复杂度:O(n)

利用完全二叉树的性质

完全二叉树只有两种情况:
1、满二叉树----->高度为h的满二叉树有 2^h-1 个结点。
2、最后⼀层叶⼦节点没有满。---->也就是说如果整个树不是满二叉树就分别递归其左右孩子,递归到一定深度一定会有左孩子或右孩子为满二叉树,然后可以按照满二叉树来计算节点个数。

class Solution{
public:
    int countNodes(TreeNode* root){
        if(root==nullptr) return 0;
        
        TreeNode* left=root->left;
        TreeNode* right=root->right;
        
        int leftHeight=0,rightHight=0;
        while(left){ //求左子树的高度
          left=left->left; leftHeight++;
        }
        while(right){ //求右子树的高度
          right=right->right; rightHeight++;
        }
        
        if(leftHeight==rightHeight){
          return (2<<leftHeight)-1; //2<<相当于2^2 ,所以高度初始化为0 
        }

        //如果整棵树不是满二叉树,就递归其左右孩子
        return countNodes(root->left)+countNodes(root->right)+1}
};

时间复杂度:O(logn * logn)
空间复杂度:O(logn)

### 如何计算二叉树中的节点数量 对于二叉树的节点计数问题,可以采用多种方法来实现。以下是详细的说明以及相应的代码示例。 #### 方法一:递归遍历整棵树 通过递归的方式访问每一个节点并统计总数。这种方法适用于任意类型的二叉树(包括完全二叉树)。 核心逻辑如下: - 如果当前节点为空,则返回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。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值