今天就着一道比较简单的题目——404. 左叶子之和 复习一下树的基本知识
一、部分基础概念
树的结点:树的结点包括一个数据元素和若干指向其子树的分支。
树的结点的度:树的结点所拥有的子树的数目称为结点的度。没有子树(度为0)的节点称为叶子结点。具有相同父亲的结点称为兄弟结点。度不为0的结点称为分支结点。
树的度:树内各结点的度的最大值
树的深度:树中结点的最大层次数
二、二叉树的一些性质:
1. 二叉树的第 i 层最多有2^(i-1)个结点。
2. 深度为k的二叉树最多有2^k-1个结点。
3. 对任何一棵二叉树,它的叶子结点数 = 2度节点数+1。
4. n个结点的完全二叉树的深度为
⌊
log
2
n
⌋
\lfloor \log_2n\rfloor
⌊log2n⌋ +1
三、二叉树的遍历
先序遍历 根节点—左子树—右子树
void preOrderTraverse(TreeNode* node){
if (node != NULL){
visit(node->data);
preOrderTraverse(node->left);
preOrderTraverse(node->right);
}
else {
return;
}
}
中序遍历与后续遍历类似,只需要修改访问根节点、左子树、右子树的位置即可。
层次遍历:按树的每一层进行遍历。需要使用队列来辅助。大意为:把树从左往右看,第一层入队后,每次出队都要保证刚出队的结点的左子树和右子树入队,这样也就提前确定了下一层的访问顺序,达到了层次遍历的效果。
void LevelTraverse(TreeNode* node){
if (node == NULL){
return;
}
Queue<TreeNode*> queue;
queue.push(node);
while(!queue.empty()){
TreeNode node = queue.front();
visit(node);
queue.pop();
if(node->left!=NULL){
queue.push(node->left);
}
if(node->right!=NULL){
queue.push(node->right);
}
}
}
再来看一看这道题
404. 左叶子之和——计算给定二叉树的所有左叶子之和。
分析:题目给的要求非常明确,就是求左叶子。一个很简单的想法就是根据左叶子的特征(一个结点,如果它的左子树不为空,并且它的左子树的左子树和右子树都为空,那么它的左子树一定是左叶子结点),来遍历这个二叉树即可。
代码及思路: 采用先序遍历和递归来解决。关于递归结果的返回问题:如果树为空,那么一定返回0。如果不为空,那么这个“整体子树”的子问题的解(也就是它的左叶子之和)一定要对这个子树进行先序遍历的递归来求和。
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root){
if (root != NULL){
int res = 0;
res += getNodeNumber(root);
//看看这个根节点是不是有一个左叶子
res += sumOfLeftLeaves(root->left);
//继续,在左子树中查找,并将结果一起加到本次递归的结果中
res += sumOfLeftLeaves(root->right); //右子树中查找
return res;//将这次递归子问题的结果
//返回给上一级更大的子问题,帮助实现递归
}
else{
return 0; //递归终止的条件。
//在这里为了更贴近先序遍历,暂时先用此种方法。
}
}
int getNodeNumber(TreeNode* node){
if (node == NULL){
return 0;
}
if ((node->left != NULL)&&(node->left->left == NULL)&&(node->left->right == NULL)){
return node->left->val;
}
return 0;
}
};
//一种更好的递归方案如下,由于本题中,叶子结点不可能再有左叶子了,
//那么,递归到叶子结点的时候就可以终止了。
//但,也要考虑空树的情况,也需要加上一个判断的条件。
int sumOfLeftLeaves(TreeNode* root) {
if (root==NULL){ //空树
return 0;
}
if((root->right==NULL)&&(root->left==NULL)){ //叶子结点,终止递归
return 0;
}
int res=0;
res += getNodeNumber(root);
res += sumOfLeftLeaves(root->left);
res += sumOfLeftLeaves(root->right);
return res;
}