力扣算法二叉树篇:完全二叉树的结点个数

完全二叉树的结点个数

    • 层序遍历求结点个数
    • 递归:后序遍历
    • 递归:利用完全二叉树性质

力扣算法二叉树篇:完全二叉树的结点个数_第1张图片
题解:

层序遍历求结点个数

常规思路:层序遍历求得结点个数

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int countNodes(TreeNode* root) {
        //遍历树求得结点个数 层序遍历
        //根节点为空时,返回0
        if(root == NULL){
            return 0;
        }
        //队列
        queue<TreeNode*> que;
        //根节点入队
        que.push(root);
        //完全二叉树的结点个数
        int countnodes = 0;
        //遍历二叉树
        while(!que.empty()){
            //处理该层结点
            int size = que.size();
            countnodes+=size;
            for(int i = 0;i<size;i++){
                //取出该层结点
                TreeNode * node = que.front();
                //出队
                que.pop();
                //将该结点的左右孩子结点加入队列
                if(node->left){
                    que.push(node->left);
                }
                if(node->right){
                    que.push(node->right);
                }
            }
        }
        return countnodes;
    }
};

递归:后序遍历

递归三部曲:
1、确定递归函数的参数和返回值
参数为二叉树的根节点,返回值为该树的结点个数
2、确定终止条件
当结点为空时返回0
3、确定单层递归逻辑
左子树结点数加上右子树结点数加1,得二叉树结点数

class Solution {
public:
    int getCount(TreeNode* node){
        if (node == NULL){
            return 0;
        }
        //左子树结点数
        int leftCounts = getCount(node->left);
        //右子树结点数
        int rightCounts = getCount(node->right);
        //总结点数
        return (leftCounts+rightCounts+1);
    }
    int countNodes(TreeNode* root) {
       //递归
       return getCount(root);
    }
};

递归:利用完全二叉树性质

满二叉树的结点个数为2^深度-1(根节点深度为1)
一个完全二叉树由若干满二叉树构成,利用递归求其结点数
递归三部曲:
1、确定递归函数的参数和返回值
参数为二叉树的根节点,返回值为该树的结点个数
2、确定终止条件
当结点为空时返回0
3、确定单层递归逻辑
判断该树的是否是满二叉树,是的话直接按照公式计算结点个数(需要计算深度),不是的话递归求左右子树结点个数(同样先判断是否为满完全二叉树)

class Solution {
public:
    int countNodes(TreeNode* root) {
       //递归
       if(root == NULL){
           return 0;
       }
       //左子树根节点和右子树根节点
       TreeNode *leftnode = root->left;
       TreeNode *rightnode = root->right;
       //左右子树的深度
       int leftHight = 0;
       int rightHight = 0;
       //计算左子树深度(最小深度) 左孩子结点到底
       while(leftnode){
           leftnode=leftnode->left;
           leftHight++;
       }
       //计算右子树深度(最小深度),右孩子结点到底 
       while(rightnode){
           rightnode = rightnode->right;
           rightHight++;
       }
       //如果相等 说明是满二叉树
       if(leftHight==rightHight){
           //移位运算 2<<1 将数字2左移1位 相当于2*2 即2^2 则2^(leftHight+1) 使用移位运算表达 2<
           return (2<<leftHight)-1;
       }
       //否则 递归
       return 1+countNodes(root->left)+countNodes(root->right);
    }
};

你可能感兴趣的:(力扣算法篇,二叉树,算法)