计算完全二叉树的节点数(算法优化)

完全二叉树

我们先来回顾一下什么是完全二叉树?

一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。 ————来自维基百科

从定义里面,我们就知道完全二叉树其对应的结点编号和对应的满二叉树是一致的。进而我们知道它的子树必然包含一颗满二叉树子树。

计算完全二叉树的节点数(算法和优化复杂度)

1、使用普通的二叉树节点数计算

int countNode(TreeNode root){
	if(root==null) return 0;
	return 1+countNode(root.left)+countNode(root.right);
}

时间复杂度上看,计算了所有的结点,所以复杂度为O(n)

2、计算完美二叉树(满二叉树)的节点数

因为完美二叉树它的节点数是有规律的,每一层和下一层是成比例增加的,所以我们只需要知道其深度,即可利用等比数列的求和公式返回它的节点数。

int countNode(TreeNode root){
	if(root==null) return 0;
	//计算树高
	int h=0;
	while(root!=null){
		root = root.left;
		h++;
	}
	
	return (int)Math.pow(2,h)-1;
}

从时间复杂度上看,计算树高,为O(logN)

2.3、结合以上两类(完全二叉树含满二叉子树)

void countNode(TreeNode root){
	if(root==null) return 0;
	//计算左右子树的高度
	int hl=0,hr=0;
	TreeNode left = root,right=root;
	while(left !=null){
		left = left .left;
		hl++;
	}
	while(right!=null){
		right= right.left;
		hr++;
	}
	if(hr==hl){//满二叉树
		return (int)Math.pow(2,hl)-1;
	}
	//否则不是满二叉树,则按照普通的方法计算
	return 1+countNode(root.left)+countNode(root.right);
	
}

复杂度分析上看,首先根据完全二叉树必然含有一个满二叉树,要么是左子树,要么是右子树。那么

return 1 + countNodes(root.left) + countNodes(root.right);

这两个递归只有一个会真的递归下去,另一个一定会触发hl == hr而立即返回,不会递归下去。
综上,算法的递归深度就是树的高度 O(logN),每次递归所花费的时间就是 while 循环,需要 O(logN),所以总体的时间复杂度是 O(logN*logN)。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雨夜※繁华

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值