404. 左叶子之和

今天就着一道比较简单的题目——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;
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值