北邮22信通:(13)二叉树 书上重要知识点补充 例4.3 统计结点总数 深度和叶子结点数

news2025/1/15 6:43:32

北邮22信通一枚~   

跟随课程进度每周更新数据结构与算法的代码和文章 

持续关注作者  解锁更多邮苑信通专属代码~

上一篇文章:

下一篇文章:

目录

一.统计结点总个数

二.统计二叉树深度

三.统计叶子结点总数

四.完整代码

4.1测试int存储类型:

代码部分:

运行结果: 

4.2测试class储存类型:

代码部分:

运行结果: 


***说明***

书上例4.3的代码和思考题~

对上一篇文章的功能有了新补充~

函数主要思想:递归调用。

***说明完毕***

一.统计结点总个数

思路:二叉树结点总数等于其左子树的节点总数+右子树的结点总数+根结点。

代码部分:

template<class temp>
int bintree<temp>::nodecount(binnode<temp>* r)
{
	if (r == NULL)
		return 0;
	if (r->leftchild == NULL && r->rightchild == NULL)
		return 1;
	else
	{
		int m = nodecount(r->leftchild);
		int n = nodecount(r->rightchild);
		return m + n + 1;
	}
}

二.统计二叉树深度

代码部分:

思路:保存现场截止。

template<class temp>
int bintree<temp>::height(binnode<temp>* r)
{
	if (r == NULL)
		return 0;
	else
	{
		int m = height(r->leftchild);
		int n = height(r->rightchild);
		return m > n ? m + 1 : n + 1;
	}
}

三.统计叶子结点总数

        思路:判断某一处的结点是不是叶子结点,判断条件就是看它左右孩子是否没有。如果都没有,那就是叶子结点。然后调用函数递归来实现整体。

代码部分:

template<class temp>
int bintree<temp>::leafcount(binnode<temp>* r)
{
	if (r == NULL)
		return 0;
	if (r->leftchild == NULL && r->rightchild == NULL)
		return 1;
	else
	{
		int m = leafcount(r->leftchild);
		int n = leafcount(r->rightchild);
		return m + n;
	}
}

四.完整代码

4.1测试int存储类型:

代码部分:

#include<iostream>
#define MAXSIZE 100000
//注意:不能将上面这行宏定义写成
//#define MAXSIZE 1e5
//上面这样写会报错!!
using namespace std;

template<class temp>
struct binnode
{
	temp data;
	binnode<temp>* leftchild;
	binnode<temp>* rightchild;
};

template<class temp>
class bintree
{
private:
	void create(binnode<temp>*& r, temp data[], int i, int n);
	void release(binnode<temp>* r);
public:
	binnode<temp>* root;
	bintree(temp data[], int n);
	void preorder(binnode<temp>* r);
	void inorder(binnode<temp>* r);
	void postorder(binnode<temp>* r);
	void levelorder(binnode<temp>* r);

	int nodecount(binnode<temp>* r);
	int height(binnode<temp>* r);
	int leafcount(binnode<temp>* r);
	~bintree();
};

template<class temp>
void bintree<temp>::create(binnode<temp>*& r, temp data[], int i, int n)
{
	if (i <= n && data[i - 1] != 0)
	{
		r = new binnode<temp>;
		r->data = data[i - 1];
		r->leftchild = r->rightchild = NULL;
		create(r->leftchild, data, 2 * i, n);/*书上代码错误1:向函数传入实参时少传入一个n*/
		create(r->rightchild, data, 2 * i + 1, n);/*书上代码错误同上*/
	}
}

template<class temp>
bintree<temp>::bintree(temp data[], int n)
/*书上代码错误2:构造函数不能有返回值类型,但是书上多加了一个void*/
/*如果构造函数的声明语句写成
void bintree<temp>::bintree(temp data[], int n),
程序会报错:不能在构造函数上指定返回值类型*/
{
	create(this->root, data, 1, n);
}

template<class temp>
void bintree<temp>::preorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		cout << r->data;//访问结点;
		preorder(r->leftchild);//遍历左子树
		preorder(r->rightchild);//遍历右子树
	}
}

template<class temp>
void bintree<temp>::inorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		inorder(r->leftchild);
		cout << r->data;
		inorder(r->rightchild);
	}
}

template<class temp>
void bintree<temp>::postorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		postorder(r->leftchild);
		postorder(r->rightchild);
		cout << r->data;
	}
}

template<class temp>
void bintree<temp>::levelorder(binnode<temp>* R)
{
	binnode<temp>* queue[MAXSIZE];
	int f = 0, r = 0;
	if (R != NULL)
		queue[++r] = R;//根节点入队
	while (f != r)
	{
		binnode<temp>* p = queue[++f];//队头元素入队
		cout << p->data;//出队打印
		if (p->leftchild != NULL)
			queue[++r] = p->leftchild;//左孩子入队
		if (p->rightchild != NULL)
			queue[++r] = p->rightchild;//右孩子入队
	}
}

template <class temp>
void bintree<temp>::release(binnode<temp>* r)
{
	if (r != NULL)
	{
		release(r->leftchild);
		release(r->rightchild);
		delete r;
	}
}

/*书上代码错误3:不能在析构函数上指定返回值类型,但是书上代码多了一个void*/
template<class temp>
bintree<temp>::~bintree()
{
	release(this->root);
}

template<class temp>
int bintree<temp>::nodecount(binnode<temp>* r)
{
	if (r == NULL)
		return 0;
	if (r->leftchild == NULL && r->rightchild == NULL)
		return 1;
	else
	{
		int m = nodecount(r->leftchild);
		int n = nodecount(r->rightchild);
		return m + n + 1;
	}
}

template<class temp>
int bintree<temp>::height(binnode<temp>* r)
{
	if (r == NULL)
		return 0;
	else
	{
		int m = height(r->leftchild);
		int n = height(r->rightchild);
		return m > n ? m + 1 : n + 1;
	}
}

template<class temp>
int bintree<temp>::leafcount(binnode<temp>* r)
{
	if (r == NULL)
		return 0;
	if (r->leftchild == NULL && r->rightchild == NULL)
		return 1;
	else
	{
		int m = leafcount(r->leftchild);
		int n = leafcount(r->rightchild);
		return m + n;
	}
}

int main()
{
	system("color 0A");
	int a[5] = { 1,2,3,4,5 };
	bintree<int>bintreee(a, 5);
	cout << "前序遍历:" << endl;
	bintreee.preorder(bintreee.root);
	cout << endl << "中序遍历:" << endl;
	bintreee.inorder(bintreee.root);
	cout << endl << "后序遍历:" << endl;
	bintreee.postorder(bintreee.root);
	cout << endl << "层序遍历:" << endl;
	bintreee.levelorder(bintreee.root);
	cout << endl << "二叉树中的节点总数为:";
	cout << bintreee.nodecount(bintreee.root);
	cout << endl << "二叉树的深度为:";
	cout << bintreee.height(bintreee.root);
	cout << endl << "二叉树的叶子结点数为:";
	cout << bintreee.leafcount(bintreee.root);
	cout << endl;
}

运行结果: 

4.2测试class储存类型:

代码部分:

#include<iostream>
#define MAXSIZE 100000
//注意:不能将上面这行宏定义写成
//#define MAXSIZE 1e5
//上面这样写会报错!!
using namespace std;
class student
{
private:
	int ID;
	string name;
public:
	int existence;
	student()
	{
		this->ID = 0;
		this->name = "unknown name";
		this->existence = 0;
	}
	student(int ID, string name)
	{
		this->ID = ID;
		this->name = name;
		this->existence = 1;
	}
	friend ostream& operator<<(ostream& output, student& s)
	{
		output << s.ID << " " << s.name << endl;
		return output;
	}
};

template<class temp>
struct binnode
{
	temp data;
	binnode<temp>* leftchild;
	binnode<temp>* rightchild;
};

template<class temp>
class bintree
{
private:
	void create(binnode<temp>*& r, temp data[], int i, int n);
	void release(binnode<temp>* r);
public:
	binnode<temp>* root;
	bintree(temp data[], int n);
	void preorder(binnode<temp>* r);
	void inorder(binnode<temp>* r);
	void postorder(binnode<temp>* r);
	void levelorder(binnode<temp>* r);

	int nodecount(binnode<temp>* r);
	int height(binnode<temp>* r);
	int leafcount(binnode<temp>* r);
	~bintree();
};

template<class temp>
void bintree<temp>::create(binnode<temp>*& r, temp data[], int i, int n)
{
	/*书上代码的一个问题:data[i-1]!=0会报错,这是因为data的数据类型是temp,没法实现!=的运算*/
	//书上原代码
	//if (i <= n && data[i - 1] != 0)
	if (i <= n && data[i - 1].existence != 0)
	{
		r = new binnode<temp>;
		r->data = data[i - 1];
		r->leftchild = r->rightchild = NULL;
		create(r->leftchild, data, 2 * i, n);/*书上代码错误1:向函数传入实参时少传入一个n*/
		create(r->rightchild, data, 2 * i + 1, n);/*书上代码错误同上*/
	}
}

template<class temp>
bintree<temp>::bintree(temp data[], int n)
/*书上代码错误2:构造函数不能有返回值类型,但是书上多加了一个void*/
/*如果构造函数的声明语句写成
void bintree<temp>::bintree(temp data[], int n),
程序会报错:不能在构造函数上指定返回值类型*/
{
	create(this->root, data, 1, n);
}

template<class temp>
void bintree<temp>::preorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		cout << r->data;//访问结点;
		preorder(r->leftchild);//遍历左子树
		preorder(r->rightchild);//遍历右子树
	}
}

template<class temp>
void bintree<temp>::inorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		inorder(r->leftchild);
		cout << r->data;
		inorder(r->rightchild);
	}
}

template<class temp>
void bintree<temp>::postorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		postorder(r->leftchild);
		postorder(r->rightchild);
		cout << r->data;
	}
}

template<class temp>
void bintree<temp>::levelorder(binnode<temp>* R)
{
	binnode<temp>* queue[MAXSIZE];
	int f = 0, r = 0;
	if (R != NULL)
		queue[++r] = R;//根节点入队
	while (f != r)
	{
		binnode<temp>* p = queue[++f];//队头元素入队
		cout << p->data;//出队打印
		if (p->leftchild != NULL)
			queue[++r] = p->leftchild;//左孩子入队
		if (p->rightchild != NULL)
			queue[++r] = p->rightchild;//右孩子入队
	}
}

template <class temp>
void bintree<temp>::release(binnode<temp>* r)
{
	if (r != NULL)
	{
		release(r->leftchild);
		release(r->rightchild);
		delete r;
	}
}

/*书上代码错误3:不能在析构函数上指定返回值类型,但是书上代码多了一个void*/
template<class temp>
bintree<temp>::~bintree()
{
	release(this->root);
}

template<class temp>
int bintree<temp>::nodecount(binnode<temp>* r)
{
	if (r == NULL)
		return 0;
	if (r->leftchild == NULL && r->rightchild == NULL)
		return 1;
	else
	{
		int m = nodecount(r->leftchild);
		int n = nodecount(r->rightchild);
		return m + n + 1;
	}
}

template<class temp>
int bintree<temp>::height(binnode<temp>* r)
{
	if (r == NULL)
		return 0;
	else
	{
		int m = height(r->leftchild);
		int n = height(r->rightchild);
		return m > n ? m + 1 : n + 1;
	}
}

template<class temp>
int bintree<temp>::leafcount(binnode<temp>* r)
{
	if (r == NULL)
		return 0;
	if (r->leftchild == NULL && r->rightchild == NULL)
		return 1;
	else
	{
		int m = leafcount(r->leftchild);
		int n = leafcount(r->rightchild);
		return m + n;
	}
}

int main()
{
	system("color 0A");
	student stu[5] = { {1,"zhang"},{2,"wang"},{3,"li"},{4,"zhao"},{5,"liu"} };
	bintree<student>bintreee(stu, 5);
	cout << "前序遍历:" << endl;
	bintreee.preorder(bintreee.root);
	/*说明:这里体现了将根节点定义为public类型的好处,
	不然需要通过一个成员函数来实现这个功能,
	从数据保密性来看,这样做也是可以的:
	外部如果不通过调用成员函数,就只能访问根节点一个节点内的数据,
	但是其他任意节点内的数据都无法访问,安全性也相对较高。
	*/
	cout << endl << "中序遍历:" << endl;
	bintreee.inorder(bintreee.root);
	cout << endl << "后序遍历:" << endl;
	bintreee.postorder(bintreee.root);
	cout << endl << "层序遍历:" << endl;
	bintreee.levelorder(bintreee.root);
	cout << endl << "二叉树中的节点总数为:";
	cout << bintreee.nodecount(bintreee.root);
	cout << endl << "二叉树的深度为:";
	cout << bintreee.height(bintreee.root);
	cout << endl << "二叉树的叶子结点数为:";
	cout << bintreee.leafcount(bintreee.root);
	cout << endl;
	return 0;
}

运行结果: 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/435789.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络原理基础(认识IP地址、子网掩码、端口号、协议、五元组)

文章目录 前言一、网络通信基础1、IP地址2、子网掩码3、端口号4、协议5、五元组 二、协议基础知识1.协议分层2.OSI七层模型3、TCP/IP五层(或四层)模型4、网络设备所在分层5、封装和分用 总结 前言 网络互连的目的是进行网络通信&#xff0c;也即是网络数据传输&#xff0c;更具…

Mac/Linux系统idea启动springboot项目慢;Oracle数据库连接:ORA-21561: OID generation failed

Mac/Linux系统idea启动springboot项目慢;Oracle数据库连接:ORA-21561: OID generation failed 解决方案&#xff1a; 1、终点输入localhost查看&#xff1b;发现我这里是local 2、终点输入cat /etc/hosts查看配置&#xff1b; hosts文件中127.0.0.1的映射是&#xff1a;127…

react 之 useState

参考&#xff1a;https://blog.csdn.net/Ljwen_/article/details/125319191 一、基本使用 useState是 react 提供的一个定义响应式变量的 hook 函数&#xff0c;基本语法如下&#xff1a; const [count, setCount] useState(initialCount)它返回一个状态和一个修改状态的方…

R语言ggplot2 | 绘制随机森林重要性+相关性热图

&#x1f4cb;文章目录 原图复现准备数据集及数据处理构建不同分类随机森林模型的并行计算绘制随机森林变量重要性柱状图计算数据集的相关性热图可视化合并随机森林重要性和热图 附上所有代码 在文献中&#xff0c;我们经常遇到随机森林和相关性热图的组合图片(下图)&#xff0…

LeetCode热题HOT100:76. 最小覆盖子串,84.柱状图中最大的矩形、96. 不同的二叉搜索树

LeetCode 热题 HOT 100 76. 最小覆盖子串 题目&#xff1a;给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串&#xff0c;则返回空字符串 “” 。 注意&#xff1a; 对于 t 中重复字符&#xff0c;我们寻找的子字…

Ubuntu18.04获取root权限并用root用户登录

写在前面&#xff1a;以下步骤中需要在终端输入命令&#xff0c;电脑端查看博客的朋友可以直接复制粘贴到终端&#xff0c;手机端查看的朋友请注意命令里面的空格是必须的&#xff0c;否则运行会出错。 1.为root设置初始密码 &#xff08;1&#xff09;登录系统&#xff0c;打…

【unity实战】随机地下城生成1

先看看最终效果 导入素材 导入房间图片素材,配置图片信息信息 点击sprite Editor,开始切割图片 随机创建基本房间 已一个白底图片模拟房间预设体 思路:建立一个空的 GameObject 用来做创建房间的点,设置坐标(0,0,0)。每创建1个房间之后,随机在上、下、右判断是否有…

python以及PyCharm工具的环境安装与配置

这里以Windows为例 Python的安装 当然是到Python官网下载咯&#xff0c;https://www.python.org/downloads/点我直达&#xff0c;如图&#xff1a; 可以下载最新版本&#xff0c;可以下拉找到之前特定的版本安装&#xff0c;如图&#xff1a; 这里先择的是最新版的进行安装…

leetcode每日一题:链表专题篇第一期(1/2)

&#x1f61a;一个不甘平凡的普通人&#xff0c;日更算法学习和打卡&#xff0c;期待您的关注和认可&#xff0c;陪您一起学习打卡&#xff01;&#xff01;&#xff01;&#x1f618;&#x1f618;&#x1f618; &#x1f917;专栏&#xff1a;每日算法学习 &#x1f4ac;个人…

现在备考2023年5月软考网络工程师时间够吗?

距离2023年5月软考还有1个多月的时间&#xff0c;备考网络工程师的时间是够的&#xff0c;以下是一些备考方法&#xff1a; 1.了解考试内容 在你开始学习考试之前&#xff0c;了解考试的形式和内容是很重要的。这将帮助你把注意力集中在最有可能被测试的领域。你应该复习考试…

Gartner Magic Quadrant for SD-WAN 2022 (Gartner 魔力象限:软件定义广域网 2022)

Gartner 魔力象限&#xff1a;SD-WAN 2022 请访问原文链接&#xff1a;https://sysin.org/blog/gartner-magic-quadrant-sd-wan-2022/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Gartner 魔力象限&#xff1a;SD-WAN 2022…

ChatGPT最强竞争对手,无需魔法,直接使用

无需科学上网&#xff0c;无需加入Waitlist&#xff0c;免费使用&#xff0c;没有高峰限制&#xff0c;而且效果媲美ChatGPT&#xff01; ChatGPT 的最强竞争对手Claude!!! Claude 是由Anthropic这家人工智能公司开发出来的&#xff0c;其联合创始人Dario Amodei曾经担任OpenAI…

K8S使用持久化卷存储到NFS(NAS盘)

参考文章&#xff1a;K8S-v1.20中使用PVC持久卷 - 知乎 Persistent Volumes&#xff1a;PV是持久化卷&#xff0c;系统管理员设置的存储&#xff0c;它是群集的一部分&#xff0c;是一种资源&#xff0c;所以它有独立于Pod的生命周期 Persistent Volume Claim&#xff1a;PVC…

抽象同步队列AbstractQueuedSynchronizer(AQS)简要理解

抽象同步队列AbstractQueuedSynchronizer AQS 简要理解 1 什么是AQS2 AQS结构2.1 同步状态2.2 CLH队列2.3 Node 3 AQS流程 https://zhuanlan.zhihu.com/p/370501087 1 什么是AQS AQS&#xff08;AbstractQueuedSynchronizer&#xff09;是 Java 中实现锁和同步器的基础设施&am…

el-input-number中添加单位(css版)

优点: 通过css添加,非常便捷和简单 例如此处,需要添加一个分钟单位 <el-input-number class"input-number" v-model"value" :step"5" :min"30" ></el-input-number> //css <style lang"scss"> .input-nu…

node项目(一) koa脚手架的搭建

一、koa 安装 // 安装koa npm install -g koa-generator // 创建项目 koa2 项目名称 当出现这个框的时候安装完毕 之后就是进入目录文件&#xff0c;根据package.json执行即可 二、出现问题 汇总 问题一&#xff1a;koa-generator安装失败 没有出现koa-generator安装成功 …

分类预测 | MATLAB实现BO-CNN-GRU贝叶斯优化卷积门控循环单元多输入分类预测

分类预测 | MATLAB实现BO-CNN-GRU贝叶斯优化卷积门控循环单元多输入分类预测 目录 分类预测 | MATLAB实现BO-CNN-GRU贝叶斯优化卷积门控循环单元多输入分类预测效果一览基本介绍模型描述程序设计参考资料 效果一览 基本介绍 基于贝叶斯(bayes)优化卷积神经网络-门控循环单元(CN…

4月第2周榜单丨飞瓜数据B站UP主排行榜(哔哩哔哩平台)发布!

飞瓜轻数发布2023年4月10日-4月16日飞瓜数据UP主排行榜&#xff08;B站平台&#xff09;&#xff0c;通过充电数、涨粉数、成长指数三个维度来体现UP主账号成长的情况&#xff0c;为用户提供B站号综合价值的数据参考&#xff0c;根据UP主成长情况用户能够快速找到运营能力强的B…

Linux进程概念——其一

目录 冯诺依曼体系结构 操作系统(Operator System) 概念 设计OS的目的 定位 如何理解 "管理" 总结 系统调用和库函数概念 进程 基本概念 描述进程-PCB task_struct-PCB的一种 task_ struct内容分类 组织进程 查看进程 通过系统调用获取进程标示符 通…

Docker Desktop 占用过多C盘存储空间的一种解决办法——在其他磁盘分区添加访问路径

一、问题背景 Docker Desktop默认是安装到C盘中的。但随着Docker的使用&#xff0c;其占用的空间也越来越大&#xff0c;Docker占用C盘空间过大成了个令人头疼的问题。恰好最近腾出了一个空的磁盘分区&#xff0c;因此可以使用“在其他磁盘分区添加访问路径”的方式&#xff0c…