学习笔记—完全二叉树节点个数_完全二叉树的节点个数特征-程序员宅基地

技术标签: 牛客算法  

题目:统计完全二叉树节点个数。

观察完全二叉树的结构发现主要有如下几种:规律就是要么根节点的左子树为满二叉树,要么根节点的右子树为满二叉树。

思路: 首先,如果当前节点的右子树最左边那个节点和二叉树的层数(深度)一样则说明该节点的左子树为满二叉树,如上图左边所示,的确根节点的右子树的最左边那个节点所在层数和二叉树的层数是一样的,那么整颗二叉树的节点个数就是左边满二叉树的节点+当前节点(根节点)+递归右子树节点个数。反之,当前节点的右子树最左边那个节点没有到达二叉树的层数(深度),则就是上图右边的情况:该节点的右子树为一颗满二叉树。那么整颗二叉树的节点个数就是右边满二叉树的节点+当前节点(根节点)+递归左子树节点个数。

 实现代码:

//接受两个参数,节点指针和节点所在层数,最后返回最左侧节点所在层数
int mostLeftLevel(TreeNode* node, int level) {
	while (node != NULL) {
		level++;
		node = node->left;
	}
	return level - 1;
}
int nodeNum(TreeNode* root) {
	if (root == NULL)
		return 0;
	return bs(root, 1, mostLeftLevel(root, 1));//root为头结点,1位当前节点所在层数,mostLeftLevel求得是当前节点左侧的深度
}
int bs(TreeNode* node, int level, int h) {
	if (level == h)//如果当前层数等于总层数h则返回1表示只有一个节点
		return 1;
	if (mostLeftLevel(node->right, level + 1) == h) {//如果当前节点的右子树的最左边那个节点到达了最后一层位置,该节点的左子树必为一个满二叉树:
		//那么应该返回该节点的满二叉树即左子树的节点个数+当前节点+右子树递归
		return (1 << (h - level)) + bs(node->right, level + 1, h);
	}
	else {//如果当前节点的右子树的最左边那个节点还没有到达最后一层位置,那么该右子树必为满二叉树:
		//应该返回该满二叉树即右子树的节点个数+当前节点+左子树递归
		return(1 << h - level - 1) + bs(node->left,level + 1, h);

	}
}

测试二叉树为上图四种情况,测试代码如下:

#include<iostream>
#include<stack>
#include<queue>
using namespace std;

class TreeNode{
public:
	int val;
	TreeNode* left;
	TreeNode* right;
	TreeNode(int val){
		this->val = val;
		left = NULL;
		right = NULL;
	}
};
TreeNode* creatTreeNode()
{
	TreeNode *p;
	int data;
	cin >> data;
	if (data == -1)
		p = NULL;
	else
	{
		p = new TreeNode(data);
		p->left = creatTreeNode();
		p->right = creatTreeNode();
	}
	return p;
}
//接受两个参数,节点指针和节点所在层数,最后返回最左侧节点所在层数
int mostLeftLevel(TreeNode* node, int level) {
	while (node != NULL) {
		level++;
		node = node->left;
	}
	return level - 1;
}
int bs(TreeNode* node, int level, int h) {
	if (level == h)//如果当前层数等于总层数h则返回1表示只有一个节点
		return 1;
	if (mostLeftLevel(node->right, level + 1) == h) {//如果当前节点的右子树的最左边那个节点到达了最后一层位置,该节点的左子树必为一个满二叉树:
		//那么应该返回该节点的满二叉树即左子树的节点个数+当前节点+右子树递归
		return (1 << (h - level)) + bs(node->right, level + 1, h);
	}
	else {//如果当前节点的右子树的最左边那个节点还没有到达最后一层位置,那么该右子树必为满二叉树:
		//应该返回该满二叉树即右子树的节点个数+当前节点+左子树递归
		return(1 << (h - level - 1)) + bs(node->left, level + 1, h);

	}
}
int nodeNum(TreeNode* root) {
	if (root == NULL)
		return 0;
 	return bs(root, 1, mostLeftLevel(root, 1));//root为头结点,1位当前节点所在层数,mostLeftLevel求得是当前节点左侧的深度
}
int main(){
	while (cin) {
		TreeNode* p = creatTreeNode();
		int number = nodeNum(p);
		cout << number << endl;
	}
}

 测试结果:

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Li_haiyu/article/details/94588071

智能推荐

Windows 设置护眼色的两种方法_word窗口怎么设置护眼模式-程序员宅基地

文章浏览阅读5.8k次。1. winxp/7/8 可以直接通过右键来修改,且修改后立刻生效。2. win10 需要通过注册表(regedit)来修改,简单的方式,可以将下列的内容保存为 change_background_color.reg,直接修改即可 REGEDIT4[HKEY_CURRENT_USER\Control Panel\Colors]"Window"="202 234 206"_word窗口怎么设置护眼模式

win11系统电脑打开桌面便签小工具的操作方法_win11 桌面便签插件-程序员宅基地

文章浏览阅读1.7k次。俗话说好脑子不如烂笔头,面对日益繁杂的事务,找一个好用的便签进行记录、梳理以及提醒。那么有没有在win11桌面上有没有好用的便签小工具呢?当然是有的。小编找到之后,一用之下颇为满意,不敢独吞,奉上共享!Win11是刚出不久的电脑系统,据说Win11系统运行程序的速度会比Win10要快,而且更安全。能适应win11系统的便签,推荐敬业签。敬业签是办公型便签,可以在win7/win8/win10/win11/xp/Mac以及web、Android、harmony、ios里使用。多端登录同一个敬业签账号的话,多_win11 桌面便签插件

376.1-2013通信报文解析(数据单元标识的计算)-程序员宅基地

文章浏览阅读3.8k次,点赞4次,收藏3次。1.什么是376.1-2013协议?2.什么是数据单元标识?3.什么是信息点DA?4.什么是信息类DT?5.什么是数据单元?6.数据单元标识的计算

生成器-程序员宅基地

文章浏览阅读90次。#生成器一共两种创建方式# 1.(x*2 for x in range(5))# 2.yields = (x*2 for x in range(2))print(s)print(next(s)) #等价于print(s.__next__()) in py2: s.next()print(next(s))print(next(s))print(next(s))print(ne..._s._next——for i in s print i

Apereo CAS 4.1反序列化RCE漏洞_apereo-cas 4.1-rce-程序员宅基地

文章浏览阅读740次。漏洞简介Apereo CAS 是一款Apereo发布的集中认证服务平台,常被用于企业内部单点登录系统。其4.1.7版本之前存在一处默认密钥的问题,利用这个默认密钥我们可以构造恶意信息触发目标反序列化漏洞(硬编码导致的漏洞),进而执行任意命令。版本: Apereo CAS <= 4.1.7环境搭建拉docker环境之后访问web界面http://127.0.0.1:8080/cas/login下载安装相关工具1、安装 jdk 1.8 ,配置好系统环境变量2、安装 maven _apereo-cas 4.1-rce

vue运行报错Extra space after key template-程序员宅基地

文章浏览阅读5.4k次,点赞4次,收藏2次。刚开始学习vue,跟着教程一步一步的自己敲代码,发现了如下错误:Extra space after key ‘template’其实错误中已经给出提示key-spacing,一开始并未注意,经多番尝试,发现template后面多了一个空格本人初学菜鸟,不知道为何校验如此沿革,冒号前不能有空格,冒号后必须有空格,待日后深入研究!..._extra space after key

随便推点

PuTTY用户手册(十四)_remote side sent disconnect message-程序员宅基地

文章浏览阅读8.6k次,点赞3次,收藏5次。第10章:常见错误消息本章列出了PuTTY及其相关工具可以生成的一些常见错误消息,并更详细地解释了它们的含义。我们不打算在这里列出所有错误消息:有许多错误消息不应该出现,有些错误消息应该是不言自明的。如果您收到本章未列出且您不理解的错误消息,请将其作为错误报告给我们(参见附录B),我们将为其添加文档。10.1"服务器的主机密钥没有缓存在注册表中"(The server’s host key..._remote side sent disconnect message

myeclipse 导入项目后报错 An error has occurred:_myeclipse svn an error occurred while accessing th-程序员宅基地

文章浏览阅读910次。今早遇到这样的问题了,一直弹出这种提示,查看了log显示如下刚开始以为是插件版本不符的问题导致不能调用结果一直尝试都不能解决后来查了下国外网友遇到的问题和我相似所以参考了他的做法:第一步:需要清空你工作空间org.eclipse.core.resources\.projects中之前的删除项目预留下来的项目;它可能导致空指针异常调用失败的原因。所以我的做法是直接删除D:\workspaces\.m..._myeclipse svn an error occurred while accessing the repository entry

Android studio笔记:工程介绍和控件(Toolbar)_androidx.appcompat.widget.toolbar-程序员宅基地

文章浏览阅读418次。app:navigationIcon是用来设置图标,我们一般是弄一个返回箭头。DarkActionBar我们一般修改为NoActionBar,自己设置。android:gravity="center"这个是设置不了的,要用。为什么我们要用toolbar就是因为我们可以能灵活的使用。也可以通过java的方式设置。_androidx.appcompat.widget.toolbar

python猜随机数游戏-程序员宅基地

文章浏览阅读3.8k次,点赞2次,收藏3次。利用python写的猜随机数游戏_python猜随机数

office打开文件提示“启用编辑”_word打开每次都要点启用编辑-程序员宅基地

文章浏览阅读8.2k次。不想word、excel一打开网络文件、不安全位置的文件、Outlook附件就提示“启用编辑”,只需将如下位置的勾选去掉即可!_word打开每次都要点启用编辑

mysql写入代码_MYSQL批量插入数据的实现代码第1/3页-程序员宅基地

文章浏览阅读86次。@echo offclsset CLASSPATH=..\api\jogre.jarset CLASSPATH=%CLASSPATH%;.set CLASSPATH=%CLASSPATH%;classesset CLASSPATH=%CLASSPATH%;lib\dom4j.jarjava org.jogre.server.JogreServer建表create database con_test..._mysql批量写入记录的代码

推荐文章

热门文章

相关标签