二叉树(三)

news2024/11/15 11:11:36

我们之前对树和二叉树有了基本的了解,然后我们进一步对二叉树的性质进行分类。小伙伴们如果有疑问或者感兴趣的可以看一下我之前写的两篇博客。

二叉树(一):二叉树(一)_染柒_GRQ的博客-CSDN博客

二叉树(二):二叉树(二)_染柒_GRQ的博客-CSDN博客

为了巩固之前学的内容,我们先来写两道题目加深映像。

题目

1.在具有 2n 个结点的完全二叉树中,叶子结点个数为( )

A n

B n+1

C n-1

D n/2

解析:选A

解析

这里再强调一次,叶子节点就是没有子树的节点,也就是度为0的节点;然后完全二叉树的概念要搞清楚,详见二叉树(二)_染柒_GRQ的博客-CSDN博客

2.一棵完全二叉树的节点数位为531个,那么这棵树的高度为( )

A 11

B 10

C 8

D 12

解析:选B

解析

二叉树的链式存储

其实在二叉树(一)_染柒_GRQ的博客-CSDN博客中我们对链式存储有了初步了解,但是了解得比较浅显,本章内容会跟大家深度了解二叉树中的链式存储。

其实我们之前学的的链表就是链式储存——五分钟入门链表(一)_染柒_GRQ的博客-CSDN博客,我们先来了解一下来自百度的定义,

链式存储:

二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的

方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩

子和右孩子所在的链结点的存储地址 。链式结构又分为二叉链和三叉链,当前我们学习中一般都

是二叉链,后面课程学到高阶数据结构如红黑树等会用到三叉链。

还是老套路,我们先试着把结构图画出来。

法一:

法一

这种方式就是我们在二叉树(一)_染柒_GRQ的博客-CSDN博客中的套路,优点是相当方便,缺点就是不能返回双亲,但是我们要和学单链表与双链表一样,有什么需求就用什么结构,复杂的结构可以应对更加复杂的场景,简单的结构写起来更加方便。

参考文献:五分钟入门链表(一)_染柒_GRQ的博客-CSDN博客

快速入门双链表(上)_染柒_GRQ的博客-CSDN博客

法二:

法二

这个结构有了指向双亲的指针可以返回指向双亲,这样便于查找双亲,但是这种结构一般要在平衡树或者红黑树中使用,普通结构一般不用。

那我们就用法一实现代码吧。还是和之前一样。

typedef char BTDataType;
typedef struct BinaryTreeNode
{
    struct BinaryTreeNode* left;
    struct BinaryTreeNode* right;
    BTDataType data;

}BTDNode;

前序

那么前序实现也差不多。原理:根节点,左子树和右子树。

//前序
void PrevOrder(BTDNode* root) 
{
    if (root == NULL) {
        printf("NULL ");
        return;
    }

    printf("%c ", root->data);
    PrevOrder(root->left);
    PrevOrder(root->right);
}

中序

那么顺便也写一下中序吧。原理:左子树,根节点和右子树。

//中序
void InOrder(BTDNode* root)
{
    if (root == NULL) {
        printf("NULL ");
        return;
    }

    InOrder(root->left);
    printf("%c ", root->data);
    InOrder(root->right);
}

后序

我们再来试着实现一下后序。原理:左子树,右子树和根节点。

//后序
void PostOrder(BTDNode* root)
{
    if (root == NULL) {
        printf("NULL ");
        return;
    }

    PostOrder(root->left);
    PostOrder(root->right);
    printf("%c ", root->data);
}

计数

我们再试着实现一下计数。

我们可以用递归原理进行。

法一

//法一:
int size = 0;
void TreeSize(BTDNode* root)
{
    //为空
    if (root == NULL)
    {
        return;
    }
    //非空
    else
    {
        ++size;
    }

    TreeSize(root->left);
    TreeSize(root->right);
}

原理图:

原理图

但是这种全局变量有缺点,我们试想一下,如果是在操作系统中或者多线程任务中,全局变量就很不安全了。

我们试着改一下。

法二

我们是不是可以用指针操作呢?试一下:

//法二:
void TreeSize(BTDNode* root, int* psize)
{
    if (root == NULL)
    {
        return;
    }
    else
    {
        ++(*psize);
    }

    TreeSize(root->left, psize);
    TreeSize(root->right, psize);
}

其实我们还能够更加简便。

法三

我们思考一下,我们计数无非是左边的加上右边的再加上根节点。

原理图;

原理图一

可能这样看不是很清楚,再来修改一下。

原理图二

我们可以发现这就是三个圈相加。

那么写成代码就是这样:

//法三:
int TreeSize(BTDNode* root)
{
    return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

叶子节点计数

小伙伴们可以自己尝试写一下叶子节点计数。

叶子节点就是度为0或者说没有子树的节点。

转换为代码就是这样:

//变形——叶子节点个数
int TreeLeafSize(BTDNode* root)
{
    if (root == NULL)
    {
        return 0;
    }
    if (root->left == NULL
        && root->right == NULL)
    {
        return 1;
    }
    return TreeLeafSize(root->left)
        + TreeLeafSize(root->right);
}

测试

我们用之前的方法来做一个静态的链表。

参考文献:二叉树(一)_染柒_GRQ的博客-CSDN博客

int main()
{
    BTDNode* A = (BTDNode*)malloc(sizeof(BTDNode));
    A->data = 'A';
    A->left = NULL;
    A->right = NULL;

    BTDNode* B = (BTDNode*)malloc(sizeof(BTDNode));
    B->data = 'B';
    B->left = NULL;
    B->right = NULL;

    BTDNode* C = (BTDNode*)malloc(sizeof(BTDNode));
    C->data = 'C';
    C->left = NULL;
    C->right = NULL;

    BTDNode* D = (BTDNode*)malloc(sizeof(BTDNode));
    D->data = 'D';
    D->left = NULL;
    D->right = NULL;

    BTDNode* E = (BTDNode*)malloc(sizeof(BTDNode));
    E->data = 'E';
    E->left = NULL;
    E->right = NULL;

    A->left = B;
    A->right = C;

    B->left = D;
    B->right = E;
    return 0;
}

我们简单测试一下前序。

再试一下中序。

最后再来试一下后序。

这样三种排序就测试完成了。

我们再来看一下技数的三种方式。

先来看法一:

这里要注意如果要检测别的节点,size要制成0

不制成0就会累加。

法二:注意要传指针

法三:

最后再来测试一下叶子节点计数:

这样我们就测试完所以代码了,当然大家如果不熟悉的话也可以写一个测试一个,这样也方便我们更好的写代码,增加自信。

总结

本节复习了前两章的内容,重点是用C语言完善了二叉树的链式储存结构,并对代码进行了测试。

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

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

相关文章

一文读懂卫星导航测量天线

1957年10月4日,前苏联发射了第一颗人造地球卫星,第二年,美国便启动了第一代卫星导航系统——子午仪卫星导航系统的研制。经过几十年的发展,全球各类航天器发射活动日益增多,全球卫星导航卫星系统(GNSS&…

【go语言udp分析】

go语言udp分析serverclientudp相等于tcp来说是不可靠的协议,当然优点就是速度快,相对于包的首部来说比较小。然后接下来看一下对应的实现server package mainimport ("fmt""net" )// UDP服务端配置 func main() {//1:启动监听liste…

2023年中高级前端养成指南-需要关注和学习的13大类80余个前端技术栈与前端趋势-看这篇就够了系列

今天是兔年开工的第一个星期一,我们又要投入到忙碌的工作了。 以下是imqdcn研究整理的2023年中高级前端养成指南,收藏起来,从开工第一天起,立下全新的计划和目标,愿你在兔年大展宏兔,扬眉兔气。 文章目录一…

【SpringCloud】Sentinel的基础概念及使用

一、雪崩问题1.问题描述微服务中,服务间调用关系错综复杂,一个微服务往往依赖于多个其它微服务。如果服务提供者I发生了故障,当前的应用的部分业务因为依赖于服务I,因此也会被阻塞。此时,其它不依赖于服务I的业务似乎不…

SAP 实施新的金融工具 IFRS17规则解析

在实施新的金融工具 IFRS 规则的过程中,保险公司现在看到了保险负债的新标准。经过多年的长期讨论,IASB 于 2016 年 11 月承诺在 2021 年 1 月 1 日生效,并明确表示不会考虑进一步推迟法规的通过日期。由于有必要将 2020 年作为比较期&#x…

[思考进阶]05 人与人之间的差距,在于“自律”

除了要提升自己的技术能力,思维的学习和成长也非常非常重要,特推出此[思考进阶]系列,进行刻意练习,从而提升自己的认知。 我认识两个成功的长者。 其中有一个人,每天记录当天的重要事项,比如今天和谁签了什…

英语学习 1

1 词汇积累 1、evolution 进化、发展 2、work efficiency 工作效率 3、material 物质的、非精神上的 4、mental 精神的 5、concern 担忧 6、physical contact 身体接触 7、imply 暗示 8、interpersonal relationships 人际关系 9、indifference 漠不关心 10、depression 抑郁 …

【八大数据排序法】冒泡排序法的图形理解和案例实现 | C++

第十四章 冒泡排序法 目录 第十四章 冒泡排序法 ●前言 ●认识排序 ●一、冒泡排序是什么? 1.简要介绍 2.具体情况 3.算法分析 ●二、案例实现 1.案例一 2.案例二 ●总结 前言 排序算法是我们在程序设计中经常见到和使用的一种算法,它…

在线支付系列【10】微信支付接入前准备

有道无术,术尚可求,有术无道,止于术。 文章目录前言1. 获取基本参数商户号(mchid)应用ID(appid)绑定商户号和应用ID2. 配置API v3密钥3. 下载并配置商户API证书3.1 简介3.2 生成证书串3.3 获得商…

卷积神经网络CNN :1.基础知识

​卷积神经网络是一种深度学习概念,专为处理图像而构建。机器学习是计算机从过去的经验中学习的概念。深度学习是机器学习的高级部分。CNN 旨在寻找视觉模式。 当我们人类看到图像时,我们看到物体、颜色等。我们在成长过程中学习这些东西,但计…

CRPS:贝叶斯机器学习模型的评分函数

连续分级概率评分(Continuous Ranked Probability Score, CRPS)或“连续概率排位分数”是一个函数或统计量,可以将分布预测与真实值进行比较。 机器学习工作流程的一个重要部分是模型评估。这个过程本身可以被认为是常识:将数据分…

【CLYZ集训】变量取值【网络流】

思路: 容易把答案转化为∑siwi∑ti(wx−wy)\sum{s_iw_i}\sum{t_i(w_x-w_y)}∑si​wi​∑ti​(wx​−wy​),然后我们设初始代价为−∑∣si∣wi-\sum{|s_i|w_i}−∑∣si​∣wi​,然后考虑建模。 如果Si大于0,则源点向i连一条流量为2…

【Java AWT 图形界面编程】FileDialog 对话框 ( 打开文件 | 保存文件 | 构造函数 | 获取文件路径 | 获取文件名称 | 代码示例 )

文章目录一、FileDialog 对话框1、构造函数2、获取文件路径3、获取文件名称二、FileDialog 对话框代码示例一、FileDialog 对话框 在开发时 , 经常遇到文件相关操作 , 如 : 选择文件 , 保存文件 等 , 在 AWT 中使用 FileDialog 文件对话框 实现上述功能 ; 1、构造函数 FileDial…

量子计算初创公司Oxford Ionics完成3000万英镑A轮融资

(图片来源:网络)未来,量子计算机会解决世界上最大的超级计算机无法解决的问题。然而,大规模制造量子计算机仍然是一个巨大的挑战。英国量子计算初创公司Oxford IonicsA轮融资获得的3000万英镑(约合人民币2.…

Java集合(六)Set接口和常用方法

Set接口基本介绍: (1)无序(添加和取出的顺序不一致),没有索引 (2)不允许重复元素,所以最多包含一个null (3)JDK API中Set接口的实现类有: 其中set接口的已…

2023年,最新最权威的上海Java培训机构排行榜出炉!

2022也许你的很多学习和工作计划都被打乱,但是过去的2022不管多艰难,多难熬。都已经成为过去式。2023悄然而至,新的一年,你我都该有新气象新动力,学习什么时候开始都不晚,想跨行从事软件开发、IT行业的小伙…

跳槽至今0 offer的大冤种,问题到底出在哪儿?

众所周知,2022年市场很难!看着企业们纷纷裁员,甚至连内推这个后门都走不通!哪怕有面试,都是屡屡碰壁,你想清楚问题出在哪了吗?😭“求职不得,夜不能寐;三更半夜…

C++基础——C++ 指针

C基础——C 指针C 指针什么是指针?C 中使用指针C 指针详解C Null 指针C 指针的算术运算递增一个指针递减一个指针指针的比较C 指针 vs 数组C 指向指针的指针(多级间接寻址)C 传递指针给函数C 指针 学习 C 的指针既简单又有趣。通过指针&…

Python语言基础学习之Python基础之列表介绍和循环遍历

今天给大家分享一些Python基础 (列表基础和循环遍历介绍),一起来看看吧~ 一、列表介绍 想一想: 字符串可以用来存储一串信息,那么想一想,怎样存储所有同学的名字呢?定义100个变量,每个变量存放一个学生的姓名可行吗…

LinkedList VS ArrayList~

ArrayList VS LinkedList: One: ArrayList:基于数组,需要连续内存LinkedList:基于双向链表,无需连续内存Two: ArrayList:随机访问快(指根据下标访问)LinkedList:随机访问慢(要沿着链表遍历)点击ArrayList的源码: 点击LinkedList的源码: Ar…