力扣完全二叉树的节点个数递归详解


题目


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

说明:

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

示例:

输入:
1
/
2 3
/ \ /
4 5 6

输出: 6


首先明确本题通过递归解题的实质其实就是将每一个节点都当成了根部!!而左右节点只是决定其什么时候停止的标志而已。即其不断的加一就是因为不断的将节点当成根部而已。
而我们只要定义遇到根部就加一,即可完成递归求和。

方法一:

逻辑清晰的递归方法:
即对于一个完全二叉树,首先明白其定义,即:
在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。
所以对于任意给的一个二叉树,求其节点个数即从最上面的第一个开始加上其对应的左边的一个,和右边的一个(当然可能是没有的)。而继续将深度加深一点,所以对他左边这个看,他也需要求他左边的一个节点,和右边的一个节点(同上方也可能是没有的)。所以可知对于一个n层的二叉树,我们需要先将第一层的根部记为一个节点,再把其“庞大的左右根”当成正常的左根节点和右根节点。
即原来为:
力扣完全二叉树的节点个数递归详解_第1张图片

后来为:力扣完全二叉树的节点个数递归详解_第2张图片
所以可知此时第一步计算和原来一样是第一个根部加上左边的根和右边的根。
接下来同理,对其根部对应的左根,把他当成新的“根部”,进而他也会诞生出左右根,右边也同理,所以循环往复,其实就是一个函数的递归问题。
并且注意!!其之所以能够不断的通过递归进行值的叠加直到得到想要的值是因为其将每一个节点都当成根部了。
力扣完全二叉树的节点个数递归详解_第3张图片

如图所示,1为开始的根部,2,3为左右节点。此时有1个根部所以第一次运算是1.第二次对其左右节点当成根部,对2,其一个根部,无左右节点了,所以不会再向下算了,3也同理,所以有2个节点,所以第二次为2,两次相加即为3个节点。

c
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
int countNodes(struct TreeNode* root){
    if(root==NULL)
    {
        return 0;
    }
    int leftnum = 0 ;//定义为左根初始个数
    int rightnum = 0;//定义为右根初始个数
    if(root->left)//即只要左根不是没有时就进行下列的计算
    {
        leftnum=leftnum+countNodes(root->left);//递归求左根的个数,且其个数的叠加其实是不断的
        //将我们新分出来的左根和右根当成新的根部,进而可以对其加一,即左右根自己本身是无存在值来叠加的
    }
    if(root->right)
    {
        rightnum=rightnum+countNodes(root->right);//同理
    }
    int head = 1;//定义根部开始为1,且其的设置使每一个左右根变成新的根部时会加1
    			//即此为递归是和越来越大直到达到我们想要的值的根本给值所在
    return head+leftnum+rightnum;//总数
}

方法二:

与上方同理,只不过是不单独专门分变量存储左右根部的个数,直接一步到位


int countNodes(struct TreeNode* root){
    if(root){
        return 1+countNodes(root->left)+countNodes(root->right);
    }
    return 0;
}

你可能感兴趣的:(Leetcode每日刷题,#,DFS与递归及回溯,二叉树,算法,数据结构,leetcode)