初阶数据结构学习记录——열 二叉树(3)链式

news2025/7/22 6:53:52

链式二叉树是由指针形成的二叉树,之前写的二叉树是由数组组成的,链式由链表来做。链式二叉树每个节点有两个指针,指向两边。以往二叉树,栈,队列等等都需要增删查改,但链式二叉树则不是这样,是因为由于链表结构,它没办法很好地增删查改。所以这里要写的并不是和数组二叉树一样的结构,而是一颗搜索树,左子树比根节点小,右子树比根节点大。这样插入一个数值就可以安放的位置,想要搜索某个数也可以选择一颗来往下查找,这样查找的效率也就是树的高度次。搜索二叉树也就有了增删查改的意义,以及也可以进行遍历了。像之前写的二叉树并不能用来遍历,或者说也没有任何意义,而搜索二叉树则可以展示两个子树各自的情况。

我们先来看搜索二叉树的四种遍历方法

前中后序(根)以及层序遍历

搜索二叉树一个思路就是一个根节点只管自己的两个子节点,其他一概不管。

关于前序,顺序为根,左子树,右子树:1 2 3 NULL NULL NULL 4 5 NULL NULL 6 NULL NULL。

分析一下这个前序,从根走起,然后再走左子树,也就是1 2 ,之后走到3,3的左子树是NULL,那么再看3的右子树,也是NULL,那么3这里就结束了,出现了两个NULL,回到2,3是2的左子树,那么再看2的右子树,是NULL,回到1,所有出现了1 2 3 NULL NULL NULL。那么再访问1的右子树,4,访问左子树5,5的左右子树都是NULL,所以有 4 5 NULL NULL,再看6,6后面也是两个NULL,所以最后整个顺序就出来了。

关于中序,顺序为左子树,根,右子树:NULL 3 NULL 2 NULL 1 NULL 5 NULL 4 NULL 6 NULL

关于后序,顺序为左子树,右子树,根:NULL NULL 3 NULL 2  NULL NULL 5 NULL NULL 6 4 1

关于层序,从第一层开始,每层从左到右,一层层访问:1 2 4 3 5 6

现在我们从代码角度理解这种二叉树。

这个二叉树由链表构成,所以

typedef int BTDataType;
typedef struct BinaryTreeNode
{
    BTDataType data;
    struct BinaryTreeNode* left;
    struct BinaryTreeNode* right;
}BTNode;

int main()
{
    BTNode* root;
}

搜索二叉树的实现会用到递归。遍历时,整个数的根节点和它的子节点遍历完后,再以子节点为根节点,继续向下遍历,所以整体用递归更适合。

我们先写前序遍历。如果root本身就为空,那么就把直接返回空;不为空的情况下,由于顺序为根,左子树,右子树,那么我们需要先打印一下根节点元素,然后左下走,如果左面走完了再走右面,然后我们还得回来再走整个数的右子树。代码如下:

void PrevOrder(BTNode* root)
{
    if (root == NULL)
    {
        printf("NULL");
        return;
    }
    printf("%d ", root->data);
    PrevOrder(root->left);
    PrevOrder(root->right);
}

尽量画图理解递归过程,这里就不写了。呈现出来有点麻烦。

我们先测试一下,写个创建结构体函数。

BTNode* BuyBTNode(BTDataType x)
{
    BTNode* node = (BTNode*)malloc(sizeof(BTNode));
    if (node == NULL)
    {
        perror("malloc fail");
        exit(-1);
    }
    node->data = x;
    node->left = node->right = NULL;
    return node;
}
然后测试,我们手动写出关系

结果如下

 所以接下来中序,后序也都好写了。

现在解决一些难题

1、求二叉树节点个数 

能够很快想到的办法就是遍历一遍,数出节点个数,不是NULL就size++一次。但是我们不能直接这样

 每一次递归,都会开一块栈帧,每一块空间size都为0,所以最后根本不是我们要的结果。那如果static一下如何?static int size,size在静态区,确实不会受递归影响,但是同样也不受我们控制了,当多次调用后,size会一直加下去,也不是我们要的数字。不过size可以定义成全局变量,每次调用前都设为0,不过这个办法也有点麻烦。

关于计算节点个数,同样也可以用之前的思路,一个根节点管两个子节点,为空就0,不为空就传回来数字

BTDataType TreeSize(BTNode* root)
{
    return root == NULL ? 0 : 1 + TreeSize(root->left) + TreeSize(root->right);
}

 画图就能理解这个代码

增加一下难度,求叶子节点的个数

虽然这个问题的思路和之前异曲同工,但是不能这样写

程序最终会停在那里,然后直接退出。这是为什么?我们就着这个图再看

 1的两个子节点都不是空,找到2,2同样也不是叶节点,找到3,3是叶节点,返回1,再回到2,访问2的右子节点,这时候就出问题了,本身这个节点就是NULL,然后程序还在判断它的左右子节点为不为空,程序就崩了。

所以我们必须要在判断左右前先判空

    if (root == NULL)
        return 0;

这样整个代码就对了。 我放上一整段测试代码

 

2、求树的深度(高度)

默认根从1开始。

先把原先的图增加一层

左右子树并不一定同样高度,我们就需要算出两个高度,然后比较一下即可。

 测试代码

3、求第k层的节点个数 k >= 1

其实也是要分左右子树啊,但是和层序没有关系啊,这个题不需要层序。这里提供一个想法,第k层是相对于第1层的第k层,那对于第2层来说,那就是第k-1层,第k层的节点个数就等于左子树的第k-1层节点个数 +  右子树的第k-1层节点个数。遇到NULL就返回0。如果k为1,一个是本身就统计的祖先层,一个是相对来说是第一层,意思就程序已经来到第k层,那么这时候就相对来说是第1层,返回1.

 测试代码

 我们还是用上面那个白图。

最终结果就是3.

4、查找值为x的节点

当然,还是递归。不过经历上面的问题,可以发现,关于具体数值的问题,我们就不能直接递归,需要在递归过程中用一个变量存储值才行。这个问题同样如此。

根据以上问题,慢慢理解二叉树的结构。

结束。 

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

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

相关文章

深入理解java虚拟机:虚拟机字节码执行引擎(1)

文章目录1. 概述2. 运行时栈帧结构2.1 局部变量表2.2 操作数栈2.3 动态连接2.4 方法返回地址2.5 附加信息1. 概述 代码编译的结果是从 本地机器码 转变为 字节码 ,是存储格式发展的一小步,却是编程语言发展的一大步。 执行引擎 是Java虚拟机最核心的组…

pmp是什么意思啊?

PMP是一个证书,项目管理类的专业认证考试,从国外引进大陆已经很多年了,反响也不错。 以前,大陆每年报考PMP的人很少,那时的思维观念,更多的认为有了这个PMP证书,代表着你很上进,学习…

Terraform 初始化慢~配置本地离线源

解决Terraform初始化慢~配置本地离线源 - 知乎 这里不再介绍Terraform是啥了,可以参考最近上线的课程。直奔主题,配置一个离线的源。需要手动或者terraform init一次下载, 然后缓存。后续直接使用缓存。 本次实践使用的是Linux/Mac 系统&am…

【App自动化测试】(十二)App异常弹框处理

目录1. app弹框异常处理——递归方式1.1 黑名单弹框异常处理逻辑1.2 实现代码1.3 方法缺点2. app弹框异常处理——装饰器版本2.1 装饰器的优势2.2 实现代码前言: 本文为在霍格沃兹测试开发学社中学习到的一些技术写出来分享给大家,希望有志同道合的小伙伴…

计算机毕业设计之java+ssm交通信息网上查询系统

项目介绍 随着交通交通管理需求和在线交通管理渗透率的提升,中国交通管理在线市场将释放巨大潜力,交通管理系统的建设和发展成为业界广泛关注的重点,本文将对此进行分析,以期为我国交通管理电子商务的发展提供参考。交通管理业对…

石化能源行业工业互联网智能工厂解决方案

随着时代的发展,中国的工业企业逐渐进入了一个“新常态”:生产效率提升,非计划停运或检修造成的生产损失更为昂贵;高盈利的要求,需要更加关注能源使用效率;法律法规对于人员安全及环保合规要求更为严格&…

基于ffmpeg开发的多音频文件音量均衡程序

前言 audio_balance ✨ 基于ffmpeg开发的多音频文件音量均衡程序 ✨ 项目地址 GitHub:https://github.com/Ikaros-521/audio_balance gitee:https://gitee.com/ikaros-521/audio_balance 使用说明 Python:3.9 程序依赖 ffmpeg实现。请先安…

Centernet 生成高斯热图

写在前面的话 最近学校阳了,宿舍给封了,宿舍网络不好远程跑不了实验,随缘写一下对CenterNet源码的一个解读,之前写论文的那段时间留下来的工作,respect! 这个文章主要是对CenterNet中生成高斯核的部分代码…

皕杰报表之语义层

1 语义层定义 语义层——是处于数据源与报表之间的一个概念,是用户和数据库之间的一个代码翻译层,通俗的讲是将数据库中的比较凌乱、复杂的数据对象(例如:存储在table中的各个字段的记录)按预先定义好的规则&#xff…

权限管理框架Shiro renren-security权限管理结构

权限管理框架Shiro: 一直在做项目,由于是二次开发的项目,今天才发现自己连权限控制都没有搞懂。二次开发的是基于renren开源的一个项目。 链接:https://gitee.com/renrenio/renren-security 这个项目主要使用shiro权限管理框架来…

31、Java高级特性——Math类、Random类、String类、StringBuffer类、StringBuilder类

目录 一、Math类 1、Math类中的方法 1.1 圆周率:PI 1.2 绝对值:abs() 1.3 返回最小近似值:ceil() 1.4 返回最大近似值 1.5 四舍五入:round() 1.6 最大值和最小值:max()/min() 1.7 求指定次幂 :po…

Java面向对象16:接口的定义与实现

普通类:只有具体的实现 抽象类:具体的实现和规范(抽象方法)都有 接口:只有规范!自己无法写方法,专业的约束,约束和实现分离:面向接口编写(大佬把接口定义好…

vue3 响应式 API 之 ref

ref 是最常用的一个响应式 API,它可以用来定义所有类型的数据,包括 Node 节点和组件。 没错,在 Vue 2 常用的 this.$refs.xxx 来取代 document.querySelector(‘.xxx’) 获取 Node 节点的方式,也是使用这个 API 来取代。 类型声明…

[附源码]计算机毕业设计JAVA乒乓球俱乐部管理系统

[附源码]计算机毕业设计JAVA乒乓球俱乐部管理系统 项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM my…

我为什么将机器学习主力语言从Python转到Rust

我为什么将机器学习主力语言从Python转到Rust 文章目录写在前面Python的痛点猴子补丁(Monkey Patch)缺乏参数类型校验允许跨作用域访问运行缓慢太多隐含规则Rust之剑猴子补丁参数类型作用域运行速度隐含规则结论写在前面 首先要声明一下:Python依然是我最喜欢的编程…

S5PV210的启动过程

一、内存 SRAM 静态内存 特点就是容量小、价格高,优点是不需要软件初始化直接上电就能用。DRAM 动态内存 特点就是容量大、价格低,缺点就是上电后不能直接使用,需要软件初始化后才可以使用。 单片机中:内存需求量小,而…

SpringBoot SpringBoot 开发实用篇 6 监控 6.7 自定义端点

SpringBoot 【黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)】 SpringBoot 开发实用篇 文章目录SpringBootSpringBoot 开发实用篇6 监控6.7 自定义端点6.7.1 问题引入6.7.2 自定义端点6.7.3 小结6.7.…

20221125使用PR2023自动识别obs-studio录屏生成的MKV视频的字幕

20221125使用PR2023自动识别obs-studio录屏生成的MKV视频的字幕 2022/11/25 19:07 01 obs.png obs studio (64bit) 02 obs 设置.png 03 obs 输出.png 04 obs默认为MKV.png 05 obs改mkv为MP4.png 警告:如果文件无法完成(例如&…

供应Alkyne-PEG-Biotin,Alk-PEG-Biotin,炔烃-聚乙二醇-生物素

炔烃-聚乙二醇-生物素是一种化学PEG试剂其英文名为Alkyne-PEG-Biotin(Alk-PEG-Biotin),它所属分类为Alkyne PEG Biotin PEG。 peg试剂的分子量均可定制,有:生物素-聚乙二醇5-炔烃、生物素-PEG 20-炔烃 、Biotin-PEG 2…

【kafka】九、kafka消费者分区分配策略

消费者分区分配策略 分区分配策略 一个consumer group中有个多个topic,一个topic有多个partition,所以必然会涉及到partition的分配问题,即确定哪个partition由哪个消费者进行消费。 kafka有两种分配策略,RoundRobin和Range Ro…