当前位置: 首页 > news >正文

【数据结构】二叉树运用及相关例题

文章目录

  • 前言
  • 查第K层的节点个数
  • 判断该二叉树是否为完全二叉树
  • 例题一 - Leetcode - 226反转二叉树
  • 例题一 - Leetcode - 110平衡二叉树


前言

在笔者的前几篇篇博客中介绍了二叉树的基本概念及基本实现方法,有兴趣的朋友自己移步看看。

这篇文章主要介绍一下二叉树的其他的几个重要功能实现方法,并对几道例题进行一个分析和解答


查第K层的节点个数

在这里插入图片描述
就比如上图,第一层有1个节点,第二层2个,第三次3个

这个还是比较简单的,我们只需要传进去一个能够证明现在是第几层的变量,然后递归左右节点,为空返回NULL,有值且满足层级要求,返回1,就可以完成了

代码如下

nt TreeLevelKSize(BTNode* root, int k)
{if (root == NULL)return 0;if (k == 1)return 1;// 子问题return TreeLevelKSize(root->left, k - 1)+ TreeLevelKSize(root->right, k - 1);
}

判断该二叉树是否为完全二叉树

首先提一下满二叉树的概念,即

一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是 说,如果一个二叉树的层数为K,且结点总数是2^k-1,则它就是满二叉树。

这里与完全二叉树进行一下区分

完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K 的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。

两者的图例如下

在这里插入图片描述
回到判断环节,我们需要用到之前说过的一个层序遍历即

// 层序遍历
void BinaryTreeLevelOrder(BTNode* root)
{if (root == NULL) {return;}// 使用队列实现层序遍历int front = 0, rear = 0;BTNode** queue = (BTNode**)malloc(sizeof(BTNode*) * 1000); // 假设节点数不超过1000queue[rear++] = root;while (front < rear) {BTNode* current = queue[front++]; // 取出队列前端节点printf("%c ", current->data);if (current->left != NULL) {queue[rear++] = current->left; // 左子节点入队}if (current->right != NULL) {queue[rear++] = current->right; // 右子节点入队}}free(queue); // 释放队列内存
}

而这里我们需要做的就是下面两部

1、层序遍历走,空也进队列
2、遇到第一个空节点时,开始判断,后面全空就是完全二叉树,后面有非空就不是完全二叉树

在这里插入图片描述
比如这个图,我们建立一个队列,不断遍历将左右节点加入到队列中去,而7的位置为空

我们通过循环判断队列是否为空,每次循环出队一个头节点,尾插左右节点,不论是否为空

完成这步后,等遇到的节点为空时,退出循环,开始判断这个队列是否为空(因为我们在添加时,加入了很多新的空值,所以我们需要遍历队列里面的元素,一旦遇到有元素不为空,就代表空节点后还有元素,就比如上图的7后面还有5,6一样。

代码如下

bool TreeComplete(BTNode* root)
{Queue q;QueueInit(&q);if (root)QueuePush(&q, root);while (!QueueEmpty(&q)){BTNode* front = QueueFront(&q);QueuePop(&q);// 遇到第一个空,就可以开始判断,如果队列中还有非空,就不是完全二叉树if (front == NULL){break;}QueuePush(&q, front->left);QueuePush(&q, front->right);}while (!QueueEmpty(&q)){BTNode* front = QueueFront(&q);QueuePop(&q);// 如果有非空,就不是完全二叉树if (front){QueueDestroy(&q);return false;}}

注意:

  • 因为我们之前创建的队列是通过数组建的,而数组的值往往设定为int,这里如果不是二外创建新的数组就像上面层序遍历那样,就记得使用将队列中数组的元素设为二叉树节点的类型
  • 另外可能有朋友会认为在添入队列时堆对NULL(空节点)进行引用,将空节点的子节点,实则不会,因为我们是通过循环使左右子节点加入,一次仅加入两个,不会因为循环过快导致上述现象

例题一 - Leetcode - 226反转二叉树

Leetcode - 226反转二叉树

在这里插入图片描述
这题的思路没那么复杂,我们抓住他反转的本质,其实就是每个节点的左右节点交换,这样一来就完成了,代码如下

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/typedef struct TreeNode TreeNode;
struct TreeNode* invertTree(struct TreeNode* root) {if(root == NULL)return NULL;TreeNode* left = invertTree(root->left);TreeNode* right = invertTree(root->right);root->left = right;root->right = left;return root;
}

值得一提的是,这里我们不是先进行递归,在对左右节点赋值的吗,因为二叉树的本质还是一种链表,是一种逻辑结构。

所以,即使我们先将左右节点交换再递归下去,是不会影响最终结果的,比如下面这串代码

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/
typedef struct TreeNode TreeNode;
struct TreeNode* invertTree(struct TreeNode* root) {if(root == NULL){return NULL;}TreeNode* left = root->left;TreeNode* right = root->right;root->right = left;root->left = right;left = invertTree(root->left);right = invertTree(root->right);return root;
}

例题一 - Leetcode - 110平衡二叉树

Leetcode - 110平衡二叉树

关于这道题我们需要了解一个概念,即平衡二叉树

在这里插入图片描述
所以我们可以通过方法名来获取一个节点的深度,对左右两个节点进行比较,若插值不大于1即可

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/
#define MAX(a,b) ((a)>(b)?(a):(b))
int height(struct TreeNode* root)
{if(root == NULL)return 0;return MAX(height(root->left),height(root->right))+1;
}
bool isBalanced(struct TreeNode* root) {if(root == NULL)return true;return (fabs(height(root->left) - height(root->right)) <= 1 && isBalanced(root->left) && isBalanced(root->right));
}

于是我们可以按照思路这样写出,但是这个写法存在较大缺陷,就是时间复杂度太高了,由于是自顶向下递归,因此对于同一个节点,函数 height 会被重复调用,导致时间复杂度较高。如果使用自底向上的做法,则对于每个节点,函数 height 只会被调用一次。即

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/
#define MAX(a,b) ((a)>(b)?(a):(b))
int height(struct TreeNode* root)
{if(root == NULL)return 0;int leftHeight = height(root->left);int rightHeight = height(root->right);if(leftHeight == -1 || rightHeight == -1 || fabs(leftHeight - rightHeight) > 1){return -1;}else{return MAX(leftHeight, rightHeight) + 1;}
}
bool isBalanced(str
uct TreeNode* root) {return height(root) != -1;}

相关文章:

【数据结构】二叉树运用及相关例题

文章目录 前言查第K层的节点个数判断该二叉树是否为完全二叉树例题一 - Leetcode - 226反转二叉树例题一 - Leetcode - 110平衡二叉树 前言 在笔者的前几篇篇博客中介绍了二叉树的基本概念及基本实现方法&#xff0c;有兴趣的朋友自己移步看看。 这篇文章主要介绍一下二叉树的…...

Java基础知识点(反射、注解、JDBC、TCP/UDP/URL)

文章目录 反射反射的定义class对象反射的操作 注解注解的定义注解的应用注解的分类基准注解元注解 自定义注解自定义规则自定义demo JDBCTCP/UDP/URLTCPUDPURL 反射 反射的定义 Java Reflection是Java被视为动态语言的基础啊&#xff0c; 反射机制允许程序在执行期间接入Refl…...

postgressql——Tuple学习(2)

Tuple含义 作用 PG并没有像Oracle那样的undo来存放旧数据&#xff0c;而且PG没有真正意义上的delete&#xff0c;而是将旧版本直接存放于relation文件中&#xff0c;也就是成为了dead tuple。我们可以理解成“过期的数据”含义 tuple就相当于一个存储数据的小容器&#xff0c;…...

Linux日志管理

文章目录 一、日志管理概述1.1、日志管理介绍1.2、日志管理的重要性1.3、日志管理的组件1.4、日志管理的流程1.5、日志管理的挑战 二、日志分类介绍2.1、windows日志类别2.1.1、Application Log2.1.2、Security Log2.1.3、System Log2.1.4、Setup Log2.1.5、ForwardedEvents Lo…...

【社区投稿】给 NdArray 装上 CUDA 的轮子

Ndarry是Rust编程语言中的一个高性能多维、多类型数组库。它提供了类似 numpy 的多种多维数组的算子。与 Python 相比 Rust 生态缺乏类似 CuPy, Jax 这样利用CUDA 进行加速的开源项目。虽然 Hugging Face 开源的 candle 可以使用 CUDA backend 但是 candle 项瞄准的是大模型的相…...

Linux|Linux常用命令合集(一)

想记录一下个人会用到的一些linux命令&#xff0c;持续更新中… chmod\chown 之前如果文件权限不足&#xff0c;直接就是 chmod 777 filename/dirname &#xff0c;这并不是一个好习惯。 r&#xff08;读权限&#xff09;&#xff1a;值为4w&#xff08;写权限&#xff09;&a…...

RTPS协议之Behavior Module

目录 交互要求基本要求RTPS Writer 行为RTPS Reader行为 RTPS协议的实现与Reader匹配的Writer的行为涉及到的类型RTPS Writer实现RTPS WriterRTPS StatelessWriterRTPS ReaderLocatorRTPS StatefulWriterRTPS ReaderProxyRTPS ChangeForReader RTPS StatelessWriter BehaviorBe…...

Socket网络通讯入门(一)

提示&#xff1a;能力有限&#xff0c;不足以及错误之处还请指出&#xff01; 文章目录 前言一、 计算机网络 OSI、TCP/IP、五层协议 体系结构1.OSI七层模型每层的作用2.TCP/IP协议分成3.五层协议体系结构 二、Socket服务端和客户端 简单通信1.服务端代码2.客户端 总结 前言 简…...

第十五课,海龟画图:抬笔与落笔函数、画曲线函数

一&#xff0c;turtle.penup()和turtle.pendown()&#xff1a;抬起与落下画笔函数 当使用上节课学习的这个turtle.forward()&#xff1a;画笔前进函数时&#xff0c;画笔会朝着当前方向在画布上留下一条指定&#xff08;像素&#xff09;长度的直线&#xff0c;但你可能发现&a…...

【机器学习】让大模型变得更聪明

文章目录 前言1. 理解大模型的局限性1.1 理解力的挑战1.2 泛化能力的挑战1.3 适应性的挑战 2. 算法创新&#xff1a;提高模型学习和推理能力2.1 自监督学习2.2 强化学习2.3 联邦学习 3. 数据质量与多样性&#xff1a;增强模型的泛化能力3.1 高质量数据的获取3.2 数据多样性的重…...

5.26机器人基础-DH参数 正解

1.建立DH坐标系 1.确定Zi轴&#xff08;关节轴&#xff09; 2.确定基础坐标系 3.确定Xi方向&#xff08;垂直于zi和zi1的平面&#xff09; 4.完全确定各个坐标系 例子&#xff1a; 坐标系的布局是由个人决定的&#xff0c;可以有不同的选择 标准坐标系布局&#xff1a; …...

Vue3项目练习详细步骤(第五部分:用户模块的功能)

顶部导航栏个人信息显示 接口文档 接口请求与绑定 导航栏下拉菜单功能 路由实现 退出登录和路由跳转实现 基本资料修改 页面结构 接口文档 接口请求与绑定 修改头像 页面结构 头像回显 头像上传 接口文档 重置密码 页面结构 接口文档 接口请求与绑定 顶部导航…...

测试onlyoffice在线预览文件功能

HTML示例代码 <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><title>测试onlyoffice在线预览文件功能</title><script type"text/javascript" src"http://onlyoffice服务器ip:端口/…...

Day57 每日温度 + 下一个更大元素Ⅰ

739 每日温度 题目链接&#xff1a;739.每日温度 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;…...

nuxt3 api如何透传(不引第3方库)

背景: nuxt做为一个vue的服务端渲染框架,本身就具备服务端的功能,理论上可以完整做一个系统功能,包括对数据库等等操作,但更合理的做法是nuxt应该定位只做服务端渲染的事情,更偏向ui层面,而非数据curd,业务逻辑,权限等等偏向服务端的逻辑。本身基于vue的服务端渲染已…...

list常用接口模拟实现

文章目录 一、模拟list类的框架二、函数接口实现1、迭代器接口2、常用删除、插入接口3、常用其他的一些函数接口4、默认成员函数 一、模拟list类的框架 1、使用带哨兵的双向链表实现。 2、链表结点&#xff1a; // List的结点类 template<class T> struct ListNode {Li…...

前端工程化工具系列(三) —— Stylelint(v16.6.1):CSS/SCSS 代码质量工具

Stylelint 是 CSS/SCSS 代码的静态分析工具&#xff0c;用于检查代码中的错误和样式违规。 1. 环境要求 v16 以上的 Stylelint&#xff0c;支持 Node.js 的版本为 v18.12.0。 在命令行中输入以下内容来查看当前系统中 node 的版本。 node -vNode.js 推荐使用 v18.20.3 或者 …...

crossover mac好用吗 CrossOver Mac怎么下载 Mac用crossover损害电脑吗

CrossOver 是一款可以让Mac用户能够自由运行和游戏windows游戏软件的虚拟机类应用&#xff0c;虽然能够虚拟windows但是却并不是一款虚拟机&#xff0c;也不需要重启系统或者启动虚拟机&#xff0c;类似于一种能够让mac系统直接运行windows软件的插件。它以其出色的跨平台兼容性…...

PHP模块pdo_sqlite.so: undefined symbol: sqlite3_column_table_name

安装 php-sqlite3 之后&#xff0c;执行php -m 命令有警告&#xff0c;如下 PHP Warning: PHP Startup: Unable to load dynamic library pdo_sqlite (tried: /usr/lib64/php/modules/pdo_sqlite (/usr/lib64/php/modules/pdo_sqlite: cannot open shared object file: No su…...

卷积神经网络-奥特曼识别

数据集 四种奥特曼图片_数据集-飞桨AI Studio星河社区 (baidu.com) 中间的隐藏层 已经使用参数的空间 Conv2D卷积层 ReLU激活层 MaxPool2D最大池化层 AdaptiveAvgPool2D自适应的平均池化 Linear全链接层 Dropout放置过拟合&#xff0c;随机丢弃神经元 -----------------…...

ChatGLM3-6B-128K在客服系统中的应用:智能回复生成

ChatGLM3-6B-128K在客服系统中的应用&#xff1a;智能回复生成 1. 引言 想象一下&#xff0c;一个繁忙的电商客服中心&#xff0c;每天要处理成千上万的客户咨询。传统的人工客服需要不断重复回答相似的问题&#xff0c;不仅效率低下&#xff0c;还容易因为疲劳而出错。现在&…...

Qwen3-ASR-0.6B开发者案例:集成至CRM系统实现通话内容自动归档

Qwen3-ASR-0.6B开发者案例&#xff1a;集成至CRM系统实现通话内容自动归档 1. 项目背景与需求场景 在现代企业客户关系管理&#xff08;CRM&#xff09;系统中&#xff0c;通话录音是宝贵的业务数据资源。销售团队的客户沟通、客服中心的问题解决、业务洽谈的重要细节——所有…...

重庆银行:万亿新贵的高光与隐忧

对于重庆银行而言&#xff0c;2026年3月24日是一个值得载入史册的日子。就在这一天&#xff0c;该行正式发布了2025年年度报告&#xff0c;其资产规模突破以往周期&#xff0c;使其成功跻身“万亿级城商行俱乐部”。其中&#xff0c;该行的营收与净利润时隔五年再次实现了“双十…...

唯品会数据采集API接口||电商API数据采集

唯品会数据采集&#xff0c;优先走合规第三方 API&#xff08;个人 / 企业均可&#xff09;&#xff1b;企业可申请官方开放平台 API&#xff08;仅限合作方&#xff09;。一、合规路径选择&#xff08;必看&#xff09;1. 官方开放平台&#xff08;企业级&#xff09;入口&…...

Java面试高频:阿里真实面试题——Redis分布式锁实现(3分钟速通,不会直接挂)

一、真实面试场景&#xff08;代入感拉满&#xff09; 上周&#xff0c;一个候选人来面试阿里P6。 技术面已经过了两轮&#xff0c;表现都不错。 最后一轮&#xff0c;面试官只问了一个问题&#xff1a; “你们项目里用过Redis分布式锁吗&#xff1f;怎么实现的&#xff1f;…...

bert-base-chinese详细步骤:如何将test.py改造成支持流式文本处理的微服务

bert-base-chinese详细步骤&#xff1a;如何将test.py改造成支持流式文本处理的微服务 1. 项目背景与价值 在实际的工业场景中&#xff0c;我们经常需要处理大量的文本数据流。传统的批处理方式虽然简单&#xff0c;但无法满足实时性要求高的应用场景。比如智能客服系统需要实…...

深求·墨鉴(DeepSeek-OCR-2)完整指南:从卷轴入画到经纬重现

深求墨鉴&#xff08;DeepSeek-OCR-2&#xff09;完整指南&#xff1a;从卷轴入画到经纬重现 1. 引言&#xff1a;当科技遇见水墨美学 在日常工作中&#xff0c;我们经常需要将纸质文档转换为可编辑的电子文本。传统的OCR工具往往界面复杂、操作繁琐&#xff0c;让人望而却步…...

内核热补丁和function trace的兼容性浅析

本文代码基于linux内核4.19.195. 之前的文章简要讲解了内核热补丁的原理&#xff0c;也提到了热补丁是基于ftrace框架实现的。平时我们在用ftrace时&#xff0c;最常用的功能当属function tracer了。这天一个有趣的问题突然浮现在我的脑海里&#xff1a; 如果我对同一个函数&am…...

Pi0大模型环境配置详解:Python 3.11+PyTorch 2.7+lerobot依赖安装

Pi0大模型环境配置详解&#xff1a;Python 3.11PyTorch 2.7lerobot依赖安装 1. 项目概述 Pi0是一个创新的视觉-语言-动作流模型&#xff0c;专门设计用于通用机器人控制任务。这个项目最大的亮点是提供了一个直观的Web演示界面&#xff0c;让用户能够通过简单的操作体验先进的…...

MogFace-large项目GitHub Actions CI/CD流水线构建教程

MogFace-large项目GitHub Actions CI/CD流水线构建教程 最近在折腾一个基于MogFace-large的人脸检测项目&#xff0c;每次手动测试、打包、部署&#xff0c;流程繁琐不说&#xff0c;还容易出错。团队协作时&#xff0c;代码合并后谁去跑测试、谁去更新镜像&#xff0c;也是个…...