二叉树 Ⅳ —— 二叉树基本操作

1、求总结点个数

很明确,就是求该二叉树总共有多少节点数。那么,一棵二叉树节点之和就等于根节点+左子树节点数+右子树节点数。而左/右子树又可以看成一棵新的二叉树,节点数依然等于左右子树的根节点+其左右子树的节点数,依次类推。

题解关键:整体问题拆分成小问题------》每一个子树的节点等于左子树节点数+右子树节点数+根节点

对于上面节点总数的求法,我们不难看出可以采用递归的求法。

代码:

public int getNodeNumber( BTNode root)
{
	if(root==null)
	{
		return 0;
	}
	return getNodeNumber(root.left)+getNodeNumber(root.right)+1;
}

2、求叶子结点个数

叶子节点:左右节点都为空的节点叫做叶子节点。

因此,我们只需要遍历每个节点,当其左右孩子都为null时,数值+1,即可得到叶子节点总数。我们采用前序遍历来遍历该树。

public int getLeafNodeCount( BTNode root)
{
	if(root==null)
	{
		return 0;
	}
	if(root.left==null && root.right==null)
	{
		return 1;
	}
	return getLeafNodeCount(root.left)+getLeafNodeCount(root.right);
}

3、求第 k 层结点个数

获取第k层的节点个数==》相当于求k-1层,即这棵树的k-1层节点的左右孩子个数之和
在这里插入图片描述
如上图所示,假如我们要求第三层的节点书,就相当于求第二层(k-1)的左右孩子总数。

代码:

public int getKLevelNodeCount(BTNode root,int k)
{
	if(root==null || k<=0)
	{
		return 0;
	}
	if(k==1)
	{
		return 1;
	}
	
	return getKLevelNodeCount(root.left,k-1)+getKLevelNodeCount(root.right,k-1);
}

4、获取二叉树的高度

一棵二叉树的高度其实就是左右子树的最大高度。

递归代码很简单,但是理解其中的递归细节还是有点难度,我们先来看看代码:

 public  int getHeight(BTNode root)
{
    if(root==null)
    {
    	return 0;
    }
    int leftCount=getHeight(root.left);
    int rightCount=getHeight(root.right);
    return leftCount>rightCount?leftCount+1:rightCount+1;
 }

我们以根节点的左子树为例,来看看这个递归的过程:
在这里插入图片描述

  • 我们从根节点(A)出发,root不为空,调用 int leftCount=getHeight(root.left);参数root.left也就是节点B
  • B不为空,继续调用 int leftCount=getHeight(root.left); ,参数root.left是节点D
  • D不为空,继续调用 int leftCount=getHeight(root.left); ,参数root.left是null;此时就将0返回给leftCount。即leftCount=1;
  • 代码向下执行,也就是执行int rightCount=getHeight(root.right);此时的root=D,root.left=null,所以此时返回0给rightCount,,即:rightCount=0;
  • 此时D节点的左子树高度为0,右子树高度为0 ,代码继续向下执行: return leftCount>rightCount?leftCount+1:rightCount+1;也就是返回给D节点的左右子树最大高度就为0;
  • 然后继续向上返回到节点B,由于节点B的左子树已经遍历,此时就应该执行: int rightCount=getHeight(root.right);,此处的root=B,root.right=E;
  • 和上面过程类似,向下递归,后续具体过程见上图。

5、判断这个节点是否在树中

思路:只需要遍历这棵树,对比该节点的值域是否一致,一直则返回该节点,否则返回null

代码:

public BTNode find(BTNode root,int val)
{
	if(root==null)
	{
		return null;
	}
	if(root.val==val)
	{
		return root;
	}else{
		BTNode ret1=find(root.left,int val);
		BTNode ret2=find(root.right,int val);
		return ret1!=null?ret1:ret2;		
	}	
}

上面代码实现了判断这个节点是否在树中,它相对于后面这种方法在递归时间上还是比较长的,来看看:

改进版:

public BTNode find(BTNode root,int val)
    {
        if(root==null)
        {
            return null;
        }
        if(root.val==val)
        {
            return  root;
        }
        BTNode ret=null;
        if(( ret=find(root.left,val)) != null || null != ( ret=find(root.right,val)))
        {
            return ret;
        }
        return null;
    }

这种方法的奥妙就在于if里边的条件,巧妙地运用了或运算符。

微妙之处:

  • 如果递归左子树的结果不为空(也就是在左子树中找到了这个节点),那么就不需要进行或运算符的右边了,直接将左子树的递归结果返回;
  • 只有在左子树中没有找到该节点才会递归右子树。大大节省了时间效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值