完全二叉树节点问题

完全二叉树节点问题

一. 简介

首先,明确一下完全二叉树和满二叉树的区别。

下图是一颗完全二叉树,它的每一层都是紧凑靠左排列的:
在这里插入图片描述
满二叉树则是一种特殊的完全二叉树,每层都是满的:
在这里插入图片描述

计算一颗完全二叉树的节点个数,算法的时间复杂度应该为(logN*logN)。

二.如何求一颗完全二叉树节点个数

// 输入一棵完全二叉树,返回节点总数
int countNodes(TreeNode root);

普通的二叉树的话,很简单:

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

如果是一颗满二叉树,节点总数和树的高度呈指数关系,时间复杂度为O(logN):

public int countNodes(TreeNode root){
	int h=0;
	while(root!=null){
		root = root.left;
		h++;
	}
	return (int)Math.pow(2,h)-1; //这里需要转换是因为Math.pow方法得到的是double类型。
}

完全二叉树是普通二叉树和满二叉树的结合:

public int countNodes(TreeNode root){
	TreeNode l=root,r=root;
	int hl=0,hr=0;
	while(l!=null){
		l=l.left;
		hl++;
	}
	while(r!=null){
		r=r.left;
		hr++;
	}
	//左右子树高度一样,按满二叉树计算
	if(hl==hr) return (int)Math.pow(2,hl)-1;
	else return 1+countNodes(root.left)+countNodes(root.right);
}

三.复杂度分析

这个算法的时间复杂度是O(logNlogN);但很容易认为算法的复杂度是O(NlogN),因为之前的while需要logN的时间,最后要O(N)的时间向左右子树递归:return 1+countNodes(root.left)+countNodes(root.right)

然而,关键点在于,这两个递归实际上只有一个会真的递归下去,另一个一定会触发hl=hr而立刻返回。

因为一颗完全二叉树的两棵子树,至少有一棵是满二叉树。

「完全二叉树」这个概念还是有它存在的原因的,不仅适用于数组实现二叉堆,而且连计算节点总数这种看起来简单的操作都有高效的算法实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值