104.二叉树的最大深度 (优先掌握递归)
题目链接/文章讲解/视频讲解: 代码随想录
1.分析及思路
用层序遍历请看:117.填充每个节点的下一个右侧节点指针II、104.二叉树的最大深度、111.二叉树的最小深度-CSDN博客
可以知道,根节点的高度就等于根节点的深度,所以转换为求树的高度。
要求根节点的高度,就要求出其孩子结点的高度,要求孩子结点的高度,就要求其孩子的孩子的高度,直到整个树访问完毕。
递归三部曲:
1.确定返回值以及传入参数
返回值,返回其深度,参数要求的结点。
2.终止条件
当传入结果为空时返回,返回值为0
3.确定单层递归的逻辑
拿到一个结点时,求它的左孩子高度,求它的右孩子高度,然后取最大值返回。
2.代码及注释
int maxDepth(struct TreeNode* root) {
if(root == NULL)//递归出口
return 0;//NULL的高度为0
int LeftHigh = maxDepth(root->left);//递归求其左孩子高度
int RightHigh = maxDepth(root->right);//递归求其右孩子高度
//当左孩子高度大于右孩子高度,则向上一层返回1 + LeftHigh,否则返回1 + RightHigh
return (LeftHigh > RightHigh) ? (1 + LeftHigh) : (1 + RightHigh);
}
111.二叉树的最小深度 (优先掌握递归)
题目链接/文章讲解/视频讲解:代码随想录
1.分析及思路
层序遍历请看:117.填充每个节点的下一个右侧节点指针II、104.二叉树的最大深度、111.二叉树的最小深度-CSDN博客
与最大深度类似,都是递归的求出其左孩子高度,右孩子高度取最小值,但还需排除左右孩子结点有一个为空的情况,因为题目要求的是到最近的叶子结点的深度。
递归三部曲:
1.返回值和传入参数
返回值int深度,参数struct TreeNode*即传入的结点
2.递归出口
当结点为空时结束,返回深度为0
3.确定单层递归的逻辑
对每个结点都是求其左右孩子高度,若左孩子结点为空,则取右孩子的高度。若右孩子为空,则取左孩子的高度。做两者都存在,则返回其中小的一方。
2.代码及注释
int minDepth(struct TreeNode* root) {
if(root == NULL)//递归出口
return 0;//空结点深度为0
int LeftHigh = minDepth(root->left);//递归求出其左孩子的深度
int RightHigh = minDepth(root->right);//递归求出其右孩子的高度
if(root->left == NULL)//若左孩子为空,则说明题目要求是到叶子结点的深度,所以选择右孩子的深度
return RightHigh + 1;
if(root->right == NULL)//若右孩子为空,则说明题目要求是到叶子结点的深度,所以选择左孩子的深度
return LeftHigh + 1;
//左右孩子都存在则取最小的深度
return LeftHigh > RightHigh?(1 + RightHigh):(1 + LeftHigh);
}
222.完全二叉树的节点个数(优先掌握递归)
题目链接/文章讲解/视频讲解:代码随想录
遍历求结点数目
1.分析及思路
直接对每一个结点进行统计,即访问每一个结点,进行统计,这里使用后续遍历进行统计。
递归三部曲:
1.传入的参数和返回值
返回值int结点个数,参数要求的结点。
2.递归出口
传入NULL时结束,返回0
3.确定单层递归的逻辑
对每一个结点都是,左子树结点数目加右子树结点数目再加上自身的一个结点数目。
2.代码及注释
后续遍历
int countNodes(struct TreeNode* root) {
if(root == NULL)//递归出口
return 0;//返回0
int LeftNum = countNodes(root->left);//递归的求出其左子树结点数目
int RightNum = countNodes(root->right);//递归的求出其右孩子结点数目
return 1 + LeftNum + RightNum;//加上自身的数目
}
当成满二叉树
1.分析及思路
满二叉树的结点数等于2^h-1。可以把完全二叉树拆分成满二叉树。在运用公式求解。怎么判断它是满二叉树那,就是沿着左孩子一直到空与沿着右孩子一直到空的深度是一样的。
递归三部曲:
1.传入参数以及返回类型
参数还是结点的类型,返回值为int型结点数。
2.终止条件
当结点为空时返回0,当传入结点为满二叉树时,返回公式计算出的结点数目。
3.确定单层递归的逻辑
对每一个结点都是,计算其左子树与右子树结点数+1.
2.代码及注释
int countNodes(struct TreeNode* root) {
if(root == NULL)//递归出口
return 0;
struct TreeNode* left = root->left;
struct TreeNode* right = root->right;
int LeftHigh = 0;
int RightHigh = 0;
while(left){//判断左子树深度
left = left->left;
LeftHigh++;
}
while(right){//判断右子树深度
right = right->right;
RightHigh++;
}
if(RightHigh == LeftHigh)//若相等则为满二叉树,用公式计算
return (2 << RightHigh) - 1;//递归出口
//不相等,则继续递归的求出其左右子树的结点数
int leftNum = countNodes(root->left);
int rightNum = countNodes(root->right);
return leftNum + rightNum + 1;
}