104.二叉树的最大深度
二叉树的高度:任意节点到叶子节点的距离(根节点的高度最大,也是二叉树的最大深度);
二叉树的深度:任意节点到根节点的举例;
递归法:从叶子结点开始,计算二叉树的高度。
每次遍历后,分别计算左右孩子的高度,并在其中取最大值,再+1就是父结点的高度,返回给上一层,父结点此时也是作为左或右孩子,再重复。
遍历方式:从叶子结点开始,先遍历左孩子,再遍历右孩子,最后是中,因此是左右中,后序遍历。
递归法:
class Solution {
public:
//递归
int getDepth(TreeNode* root){
if(root ==NULL)return 0;
//确定单层循环逻辑
int leftDepth = getDepth(root->left); //遍历思路:左孩子
int rightDepth =getDepth(root->right); //右孩子
int depth = 1 + max(leftDepth, rightDepth);
return depth;
}
int maxDepth(TreeNode* root) {
return getDepth(root);
}
};
层序遍历:
class Solution {
public:
int maxDepth(TreeNode* root) {
queue<TreeNode*> que;
//root为空的话,最大深度就为0
int result = 0;
if(root != NULL){
que.push(root);
result = 1;
}
while(!que.empty()){
int size = que.size();
while(size--){
TreeNode* node = que.front();
que.pop();
if(node->left)que.push(node->left);
if(node->right)que.push(node->right);
}
//如果在经过while循环以后和pop后,队列不为空,证明某个节点有孩子节点
if(!que.empty())result++;
}
return result;
}
};
111.二叉树的最小深度
最小深度:是根节点到最近的叶子结点最小路径上的节点数。
最小深度不是1,因为它是根节点啊!!!
递归:
class Solution {
public:
//递归 后序遍历(用高度计算深度)
int getDepth(TreeNode* node){
//当节点为空时,该节点的高度为0
if(node == NULL)return 0;
int leftDepth = getDepth(node->left);
int rightDepth = getDepth(node->right);
//如果左子树为空,右子树不为空,那么当前结点的深度就是右子数深度+1
if(node->left == NULL && node->right != NULL){
return 1 + rightDepth;
}
//如果右子树为空,左子树不为空,那么当前结点的深度就是左子数深度+1
if(node->left != NULL && node->right == NULL){
return 1 + leftDepth;
}
//左右子树都存在的情况
int depth = 1 + min(leftDepth,rightDepth);
return depth;
}
int minDepth(TreeNode* root) {
return getDepth(root);
}
};
层序遍历:
lass Solution {
public:
int minDepth(TreeNode* root) {
if(root == NULL)return 0;//先判断根节点是否为空,如果为空,直接返回
int depth = 0;//记录深度
queue<TreeNode*> que;
que.push(root);
while(!que.empty()){
int size = que.size();
depth++;//每循环一次,深度+1
while(size--){
TreeNode* node = que.front();
que.pop();
if(node->left)que.push(node->left);
if(node->right)que.push(node->right);
if(!node->right && !node->left){ //叶节点没有孩子
return depth;
}
}
}
return depth;
}
};
222.完全二叉树的节点个数
递归法:分别求左右孩子节点的个数,再加上其本身(+1)。
class Solution {
public:
int getTreeNum(TreeNode* node){
if(node == NULL)return 0;
//计算左孩子结点个数
int leftNum = getTreeNum(node->left);
//计算有孩子结点个数
int rightNum = getTreeNum(node->right);
//计算当前结点加上其左右孩子结点的总个数
int treeNum = leftNum + rightNum + 1;
return treeNum;
}
int countNodes(TreeNode* root) {
return getTreeNum(root);
}
};
利用满二叉树进行递归:满二叉树节点数就是每层的节点数之和,也是等比数列求和。
class Solution {
public:
//利用满二叉树进行递归
int countNodes(TreeNode* root) {
if(root == NULL)return 0;
//定义左子树
TreeNode* left = root->left;
//定义右子树
TreeNode* right = root->right;
//分别计算左右子树的深度
int leftDepth = 0;
int rightDepth = 0;
//计算左子树的深度
while(left){
left = left->left;
leftDepth++;
}
while(right){
right = right->right;
rightDepth++;
}
//如果左右子树的深度相等,那么就是满二叉树
if(leftDepth == rightDepth){
return (2 << leftDepth)-1; //2<<0将相当于2*2,如果是满二叉树,那么这个满二叉树的节点数就是等比数列求和。
}
//如果不是满二叉树,分别计算左右子树的节点数,最后相加
int leftNum = countNodes(root->left);
int rightNum = countNodes(root->right);
return leftNum + rightNum + 1;
}
};
迭代法(层序遍历):
class Solution {
public:
//层序遍历
int countNodes(TreeNode* root) {
if(root == NULL)return 0;
int treeNum = 0;
queue<TreeNode*>que;
que.push(root);
while(!que.empty()){
int size = que.size();
//每一层的节点数相加
treeNum += size;
while(size--){
TreeNode* node;
node = que.front();
que.pop();
if(node->left)que.push(node->left);
if(node->right)que.push(node->right);
}
}
return treeNum;
}
};