【Day-28慢就是快】代码随想录-二叉树-完全二叉树的节点个数

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

【Day-28慢就是快】代码随想录-二叉树-完全二叉树的节点个数_第1张图片

——————————————————————————————————————

1. 普通二叉树的求法

递归法与求深度类似,但是深度是depth++,而此题是计算nodeNum。

迭代法使用层序遍历,记录遍历的节点个数即可。

递归法

【Day-28慢就是快】代码随想录-二叉树-完全二叉树的节点个数_第2张图片

迭代法

【Day-28慢就是快】代码随想录-二叉树-完全二叉树的节点个数_第3张图片

层序遍历的模板是通用的,不一定只适用完全二叉树。

2. 完全二叉树的求法

完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。

对于情况一,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。

对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。

【Day-28慢就是快】代码随想录-二叉树-完全二叉树的节点个数_第4张图片

可以看出如果整个树不是满二叉树,就递归其左右孩子,直到遇到满二叉树为止,用公式计算这个子树(满二叉树)的节点数量。

这里关键在于如何去判断一个左子树或者右子树是不是满二叉树呢?

在完全二叉树中,如果递归向左遍历的深度等于递归向右遍历的深度,那说明就是满二叉树。如图:

【Day-28慢就是快】代码随想录-二叉树-完全二叉树的节点个数_第5张图片

在递归逻辑中,第二步的终止条件为:判断左右子树的深度是否相等来判断是否为满二叉树。

if (root == nullptr) return 0; 
// 开始根据左深度和右深度是否相同来判断该子树是不是满二叉树
TreeNode* left = root->left;
TreeNode* right = root->right;
int leftDepth = 0, rightDepth = 0; // 这里初始为0是有目的的,为了下面求指数方便
while (left) {  // 求左子树深度
    left = left->left;
    leftDepth++;
}
while (right) { // 求右子树深度
    right = right->right;
    rightDepth++;
}
if (leftDepth == rightDepth) {
    return (2 << leftDepth) - 1; // 注意(2<<1) 相当于2^2,返回满足满二叉树的子树节点数量
}

单层递归的逻辑则是后序遍历,求节点数。

return countNodes(root->left) + countNodes(root->right) + 1; 

整体的迭代法:

【Day-28慢就是快】代码随想录-二叉树-完全二叉树的节点个数_第6张图片

你可能感兴趣的:(代码随想录,c++,算法,数据结构)