第六章代码题(四)

news2024/9/29 17:36:51

8.在以孩子兄弟二叉链表存储的树中,求树的叶子结点数。

首先要了解孩子兄弟存储结构,简单来说就是每个结点的左孩子不变,在同一层的结点都依次连在该层的结点的右孩子上。 如图 :

 将上述的左孩子域改为第一个孩子指针,右孩子域改为右兄弟指针。对结构体进行定义:

//孩子兄弟存储结构
typedef struct CSNode {
	ElemType data;
	struct CSNode* FirstChild;
	struct CSNode* NextSibling;
}CSNode,*CSTree;

判断叶子结点的条件应该是当前结点的FirstChild为空。

原因很简单:比如现在有一个结点,它的FirstChild是该结点的孩子,而该结点的NextSibling是它的兄弟;该结点的FirstChild的NextSibling才是该结点的其余孩子,

如果该结点的FirstChild都为空了那其余的都是空谈,结点都为空了肯定不会有兄弟结点,对应的双亲结点也就不会有孩子节点。

其实会做本章的第一道题即求度为2的结点数,这道题也应该会做。只是中间改了一下判定条件。

答案:

int countleafnodes(CSTree cstree) {

	if (cstree==NULL)
	{
		return 0;
	}
	int k = 0;
	//判断为叶子结点时k+1
	if (cstree->FirstChild==NULL)
	{
		k++;
	}

	k += countleafnodes(cstree->NextSibling);
	k += countleafnodes(cstree->FirstChild);

	return k;
}

验证:

写一个创建结点的方法,在main函数里面直接随便构造一个孩子兄弟二叉树。

// 创建新的节点
struct CSNode* createNode(int data) {
	struct CSNode* newNode = (struct CSNode*)malloc(sizeof(struct CSNode));
	newNode->data = data;
	newNode->FirstChild = NULL;
	newNode->NextSibling = NULL;
	return newNode;
}

main函数:

int main() {
// 创建一个孩子兄弟二叉链表的树示例
	struct CSNode* root = createNode(1);
	root->FirstChild = createNode(2);
	root->FirstChild->NextSibling = createNode(3);
	root->FirstChild->NextSibling->FirstChild = createNode(4);
	root->FirstChild->NextSibling->FirstChild->NextSibling = createNode(5);

	int num = countleafnodes(root);

	printf("该孩子兄弟二叉树的叶子结点数为%d", num);
}

执行结果:

 二叉树为:

 很明显,值为2,4,5的结点都为叶子结点。所以叶子结点数为3。

9.孩子兄弟二叉链表存储的树中,求树的高度。

注意孩子兄弟二叉链表存储的树的形状可能已经不是一个标准的二叉树了,那么高度就不能像普通二叉树那样求了。

先看求二叉链表存储的二叉树的高度代码:

树的高度其实就是找离根节点路径最长的结点。既然涉及到了最长那么肯定就要有比较了。直接利用math库里面的fmax函数比较。

// 求二叉树的高度
int treehigh(BITree btree) {
	if (btree==NULL)
	{
		return 0;
	}
	
	return fmax(treehigh(btree->Lchild), treehigh(btree->Rchild)) + 1;
}

接下来看求孩子兄弟二叉链表的二叉树的高度代码:

第一种方法:

孩子兄弟二叉链表的二叉树主要是看结点的FirstChild;而结点的NextSibling和结点在同一层,不影响二叉树的高度。 将孩子兄弟的二叉树仍然按类似普通二叉树的思路进行书写。只是遇到NextSibling返回0,遇到FirstChild返回当前高度加1。

结点为空的时候返回0,为叶子结点时返回参数flag。这种方法主要利用的是递归的回溯,所以可以直接从二叉树的最底层进行解析。随便画一个二叉树:

int dfs(CSTree root, int flag) {


	//结点为空时,返回0
	if (root==NULL)
	{
		return 0;
	}

	//判断是否为叶子结点
	if (root->FirstChild == NULL && root->NextSibling==NULL) {
		return flag;
	}

	//拿到左右域判断的
	return fmax(dfs(root->FirstChild, 1) + 1, dfs(root->NextSibling, 0));
}

验证:

 仍然利用第8题的二叉树进行验证。调用上面的函数即可。

执行结果:

二叉树为:

 由图可见二叉树高度为3。

第二种方法:

如果树的根节点为空,那么就返回0,maxHeight记录数的最大高度,while循环遍历根结点的所有子结点,循环中对每个子结点递归调用treeHeight函数,进行比较后返回最大高度+1,加1是因为要算上根节点。

// 计算孩子兄弟树的高度
int treeHeight( CSNode* root) {

	if (root == NULL) {
		return 0;
	}

	int maxHeight = 0;

	struct CSNode* child = root->FirstChild;

	while (child != NULL) {
		int height = treeHeight(child);
		if (height > maxHeight) {
			maxHeight = height;
		}
		child = child->NextSibling;
	}

	return maxHeight + 1;
}

本方法和第一种方法验证一样,这里不再进行验证。

其实对比标准二叉树和孩子兄弟二叉树可以看到,不论是求叶子结点的个数还是求高度大体思路都是一样的,毕竟不论用哪种存储结构数据结构仍然是二叉树。只是在一些细节方面有略微的区别。

10.实现对顺序存储在一维数组的完全二叉树的先序遍历

按照二叉树节点连续编号的次序,将各结点数据存放到一组连续的存储单元即数组中。为了方便,不使用数组的0号单元,所以数组对应的第i号元素就存储的是二叉树第i个结点。

根据二叉树的性质就有,下标为i的结点的左孩子下标为2i,右孩子下标为2i+1。

(如果要从0开始存储,那么数组中下标为i的元素对应的就是二叉树第i+1个结点。相应地,下标为j的结点左孩子下标为2j+1,右孩子下标为2j+2。)

结构体:

//顺序存储结构
typedef struct {
	//0号单元不用
	ElemType SqbiTree[MaxSize+1];
	int nodemax;
}Bitree;

代码:

有索引就好说了,根据上面的性质,以及先序遍历的特点,先输出当前结点的值,然后进行递归,左子树为2*i,右子树为2*i+1。这里要注意,静态数组有容量上限,所以进行递归前要进行判定,没有超出容量上限才能进行递归。

void BeforeTraversal_Sq(Bitree* btree,int i) {
	printf("%d", btree->SqbiTree[i]);
	if (2*i<MaxSize+1)
	{
		BeforeTraversal_Sq(btree, 2 * i);
	}
	if (2*i+1<MaxSize+1)
	{
		BeforeTraversal_Sq(btree, 2 * i+1);
	}
}

这上面有个细节:为什么两个判定条件是<而不是<=呢?

当MaxSize为奇数时,数组的最后一个下标就是MaxSize为奇数(因为最大容量为MaxSize+1),那么2*i就不能取<=,因为2*i是偶数,如果取<=,在2*i=MaxSize+1时刚好可以进行递归,这样就会发生数组越界。

同理,当MaxSize为偶数时,2*i+1就不能取<=。

所以综合以上情况,两个判定条件都取<即可。

如果非要取<=,那么在输出前也加个判定条件也可以避免上述情况,代码如下:

void BeforeTraversal_Sq(Bitree* btree,int i) {
	if (i<MaxSize+1)
	{
		printf("%d", btree->SqbiTree[i]);
	}
	
	if (2*i<=MaxSize+1)
	{
		BeforeTraversal_Sq(btree, 2 * i);
	}
	if (2*i+1<=MaxSize+1)
	{
		BeforeTraversal_Sq(btree, 2 * i+1);
	}
}

还要注意一点,在C语言中,数组下标越界不会引发编译器错误或运行时错误。当你输出一个超出数组范围的下标时,C语言会尝试将该下标转换为对应的内存地址,并将该地址的内容作为输出。这可能是数组之后的内存空间,或者可能是其他全局或局部变量的地址。

验证:

写一个创建顺序存储结构的二叉树的函数:

void createSqBitree(Bitree* btree) {
	int a;
	for (int  i = 1; i <MaxSize+1; i++)
	{
		printf("请输入数值");
		scanf_s("%d", &a);
		btree->SqbiTree[i] = a;
	}
}

 main函数如下:

int main() {
//第十题
	Bitree* btree = (Bitree*) malloc (sizeof(Bitree));
	createSqBitree(btree);
	BeforeTraversal_Sq(btree, 1);
}

执行结果:

 二叉树如下:

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

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

相关文章

安卓开发问题记录:需要常量表达式

问题原因 写代码过程中爆出这个错误&#xff1a;需要常量表达式&#xff0c;定位到switch。 解决方法&#xff1a;把switch case&#xff0c;改成if else 错误源代码&#xff1a; public void onClick(View view) {switch (view.getId()) {case R.id.iv_code:RxCaptcha.build(…

三、web核心防御机制(下)

文章目录 核心防御机制2.3处理攻击者2.3.1 处理错误2.3.2 维护审计日志2.3.3 向管理员发出警报2.3.4 应对攻击 2.4 管理应用程序 核心防御机制 2.3处理攻击者 任何设计安全应用程序的开发人员必须基于这样一个假设&#xff1a;应用程序将成为蓄意破坏且经验丰富的攻击者的直接…

RISC-V公测平台发布 · UnixBench完整测试

简介 UnixBench是一个开源的GPLv2许可的工具&#xff0c;它提供了对类Unix系统性能的基本指标。 通过运行UnixBench&#xff0c;可以获得有关系统性能的基本指标&#xff0c;用于与其他系统进行比较&#xff0c;也可以作为改进系统性能的参考。但UnixBench并不是一个综合性能…

Python数据分析实战-格式化字符串的两种方法(附源码和实现效果)

实现功能 格式化字符串的两种方法 实现代码 # 方法一&#xff1a;format方法 query SELECT customer_id, COUNT(*) as num_ordersFROM ordersWHERE date > {start_date} AND date < {end_date} GROUP BY customer_idHAVING num_orders > {min_orders} start_da…

springboot:统一参数校验(JSR303校验)

业务需求&#xff1a;在controller中对必填参数和参数类型做合法性校验 1、在项目父工程添加spring-boot-starter-validation的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifa…

xml布局不显示的编写代码方法

新建项目在新项目用dp编写布局复制粘贴去掉所有dp在复制dimen/dp_

element-plus的日期选择器限定选择范围

目录 前言一、最近30天总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; element-plus的日期选择器限定选择范围&#xff0c;由于数据的获取范围限定&#xff0c;需要前端处理一下日期的选择范围 提示&#xff1a;以下是本篇文章正文内容&#xff0c…

golang学习随记

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 go学习快捷键及快速生成代码片段go基础循环流程控制关键字切片&#xff0c;拷贝函数闭包 defer语句格式化输出go语言随机数rand.seed() 包管理并发编程goroutinecha…

LangChain源码逐行解密之LLMs(一)

LangChain源码逐行解密之LLMs(一) 18.1 LangChain应用程序演示 本节会以一个简单的应用程序为切入点,进入到LangChain的源码部分,带领大家贯通整个LangChain最核心的框架源码,我们的应用程序不会太复杂,只是分析LangChain源码的切入点或者入口点。 如图18-1所示,是应用程…

【洋码头关键词获取商品列表技术解析】

洋码头关键词获取商品列表功能简介 洋码头的关键词获取商品列表功能是为了满足用户的个性化需求&#xff0c;提供更精准、更有针对性的商品推荐。用户可以输入关键词搜索&#xff0c;系统会根据关键词从海量的商品库中筛选出相关的商品列表&#xff0c;从而使用户更容易找到所需…

【目标检测系列】YOLOV1解读

前言 从R-CNN到Fast-RCNN&#xff0c;之前的目标检测工作都是分成两阶段&#xff0c;先提供位置信息在进行目标分类&#xff0c;精度很高但无法满足实时检测的要求。 而YoLo将目标检测看作回归问题&#xff0c;输入为一张图片&#xff0c;输出为S*S*(5*BC)的三维向量。该向量…

PyTorch 微调终极指南:第 2 部分 — 提高模型准确性

一、说明 如今&#xff0c;在训练深度学习模型时&#xff0c;通过在自己的数据上微调预训练模型来迁移学习已成为首选方法。通过微调这些模型&#xff0c;我们可以利用他们的专业知识并使其适应我们的特定任务&#xff0c;从而节省宝贵的时间和计算资源。本文分为四个部分&…

AI文档识别技术之表格识别 (一)

AI文档识别技术之表格识别(一) 文章目录 文章目录 AI文档识别技术之表格识别(一)1. 表格识别原理介绍1.1 表格类型分类1.2 识别原理 2. 整体识别流程2.1 流程图2.2 图像处理部分大致流程 3. 将表格转换为html与json格式输出3.1 html格式3.2 json格式3.3 表格识别实例 前言 此文…

可靠传输概述——停止-等待协议

基本概念&#xff1a; 使用差错检测技术&#xff08;例如循环冗余校验CRC&#xff09;&#xff0c;接收方的数据链路层就可检测出帧在传输过程中是否出现了误码。 此时有&#xff1a; 不可靠传输服务&#xff1a;仅仅丢弃有误码的帧&#xff0c;其他什么也不做 可靠传输服务&a…

Weblogic未授权远程代码执行漏洞 (CVE-2023-21839)

前言&#xff1a; Weblogic 允许远程用户在未经授权的情况下通过IIOP/T3进行JNDI lookup 操作&#xff0c;当JDK版本过低或本地存在javaSerializedData时&#xff0c;这可能会导致RCE漏洞。 0x00 环境设置 此次实验&#xff0c;我们使用P神的vulhub。启动环境&#xff1a; cd…

Android Studio实现图形验证码

源代码 源代码MainActivity 效果图32行需要修改,不修改会报错:需要常量表达式,我的代码已修改 点击后 MainActivity import static com.example.graphicverificationcode.RxCaptcha.TYPE.NUMBER;import android.annotation.SuppressLint; import android.os.Bundle; impo…

【Terraform学习】保护敏感变量(Terraform配置语言学习)

实验步骤 创建 EC2 IAM 角色 导航到IAM 在左侧菜单中&#xff0c;单击角色 。单击创建角色该按钮以创建新的 IAM 角色。 在创建角色部分&#xff0c;为角色选择可信实体类型&#xff1a; AWS 服务 使用案例:EC2 单击下一步 添加权限&#xff1a;现在&#xff0c;您可以看到…

Sentieon | 每周文献-Multi-omics(多组学)-第九期

多组学系列文章-1 标题&#xff08;英文&#xff09;&#xff1a; Prediction of axillary lymph node metastasis in triple-negative breast cancer by multi-omics analysis and an integrated model标题&#xff08;中文&#xff09;&#xff1a; 基于多组学分析和综合模型…

Java使用String来开发验证码

Java使用String来开发验证码 需求分析代码实现小结Time 需求分析 使用String来开发验证码。 实现随机产生验证码&#xff0c;验证码的每位可能是数字、大写字母、小写字母 根据需求分析&#xff0c;步骤如下&#xff1a; 1.首先&#xff0c;设计一个方法&#xff0c;该方法接收…

细胞——求细胞数量 C++详解

细胞——求细胞数量 C详解 求细胞数量题目描述输入格式输出格式样例样例输入样例输出 提示数据规模与约定 解法代码 求细胞数量 题目描述 一矩形阵列由数字 0 0 0 到 9 9 9 组成&#xff0c;数字 1 1 1 到 9 9 9 代表细胞&#xff0c;细胞的定义为沿细胞数字上下左右若还…