【数据结构与算法】数据结构初阶:详解二叉树(一)

🔥个人主页:胡萝卜3.0

🎬作者简介:C++研发方向学习者

📖个人专栏:  《C语言》《数据结构》 《C++干货分享》

⭐️人生格言:不试试怎么知道自己行不行

正片开始之前,我们来了解一下我们即将要来介绍、学习的这个数据结构——二叉树。

二叉树的作用:

(1)快速查找
二叉树(尤其是二叉排序树)可以用于高效的数据查找,其查找的时间复杂度为 O(log⁡n),最坏情况下为O(n)。这种特性使得二叉树特别适合需要频繁查找、插入和删除操作的场景。

(2)动态数据管理
由于二叉树支持动态查询,并且可以通过调整树的结构来优化性能(例如 AVL 树、红黑树),它被广泛应用于需要动态管理数据的场景,如数据库索引和内存管理。

(3)有序序列生成
中序遍历一棵二叉排序树可以得到一个关键字的有序序列,这使得二叉树成为一种有效的排序工具。构造二叉排序树的过程本质上就是对无序序列进行排序的过程。

(4)树状结构表示
许多现实世界的问题可以用树状结构来建模,例如网站目录结构、文件系统等。虽然这些结构可能不是严格的二叉树,但通过适当的转换,它们可以使用二叉树的相关算法来处理。

应用场景:

(1)网页爬虫中的遍历
在互联网工程中,当需要下载某个网站的所有网页时,可以利用二叉树的遍历算法来模拟这一过程。这种算法能够确保所有页面都被访问到,并且按照一定的顺序进行处理。

(2)二叉树的展开
在某些特定的应用中,比如将二叉树转换为链表形式,可以通过递归的方式实现。例如,在先序遍历的顺序下,左子树会被移到右指针位置,而左子树的最后一个节点会指向原来的右子树。

(3)平衡二叉树的应用
平衡二叉树(如 AVL 树、红黑树)通过保持树的高度平衡来确保查找、插入和删除操作的时间复杂度始终为O(logn)。这类树结构广泛应用于需要高性能数据检索的场景,例如数据库索引和操作系统调度器。

(4)表达式树
表达式树是一种特殊的二叉树,其中叶子节点表示操作数,内部节点表示运算符。这种结构可以用于解析和求值数学表达式,并且在编译器设计中具有重要应用。

(5)哈夫曼编码
哈夫曼树是一种带权路径长度最短的二叉树,常用于数据压缩领域。通过构建哈夫曼树,可以生成最优前缀编码,从而减少存储空间或传输成本。

(6)决策树
在机器学习和人工智能领域,二叉树可以用来表示决策过程。每个节点代表一个特征判断,每个分支代表一个可能的结果,最终的叶子节点则代表最终的决策结果。

二叉树这个部分学起来不会容易,但是会让你觉得很有收获,你慢慢会觉得学二叉树很爽!


目录

正文 

一、树

1.1 树的概念与结构

1.2 非树形结构

1.3 树的相关术语

1.4 树的表示方法--孩子兄弟表示法

1.5 属性结构实际运用场景

二、二叉树

2.1 二叉树的概念与结构

2.2 特殊的二叉树

2.2.1 满二叉树

2.2.2 完全二叉树

三、二叉树的存储结构

3.1 顺序结构

3.2 链式结构


正文 

一、树

树是什么?数据结构中的树和自然界中的树有什么联系吗?有。

树的根在地下,故曰“向阳而生”;树形结构的根在上面——

1.1 树的概念与结构

树是一种非线性的数据结构,它是由n(n>=0)有限结点组成一个具有层次结构的集合。我们把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。

  • 有一个特殊的结点,称为根节点,根节点没有前驱结点。(根节点称为父节点/双亲结点)
  • 除根节点外,其余结点被分成M(M>0)个互不相交的集合(T1、T2、……、Tm),其中每一个集合Ti(1<=i<=m)又是一棵结构与树类似的子树。每棵树的根节点有且只有一个前驱,可以有0个或者多个后继。因此,树是递归定义的。
1.2 非树形结构

在树形结构中,子树之间不能有交集,否则就不是树形结构!!!如果子树之间有交集,那就是非树形结构

上图中的三个都是非树形结构,红方框内的子树有交集

注意:

  • 子树是不相交的(如果存在相交就是图了,图以后得课程会有讲解)
  • 除了根结点外,每个结点有且仅有一个父节点
  • ⼀棵N个结点的树有N-1条边(记忆方式:2个结点有一条边)
1.3 树的相关术语

下图就是一个树形结构——

父结点/双亲结点若一个结点含有子结点,则这个结点称为其子结点的父结点,如上图:A是B的父结点。

子结点/孩子结点一个结点含有的子树的根结点称为该结点的子结点,如上图:B是A的孩子结点。

结点的度一个结点有几个孩子,他的度就是多少,比如A的度为6,F的度为2,K的度为0。

树的度一棵树中,最大的结点的度称为树的度,如上图:树的度为6。

叶子结点/终端结点度为0的结点称为叶结点,如上图: B、C、H、I . . .等结点为叶结点。

分支结点/非终端结点度不为0的结点,如上图: D、E、F、G... 等结点为分支结点。

兄弟结点具有相同父结点的结点互称为兄弟结点(必须是亲兄弟),如上图: B、C 是兄弟结点。

结点的层次从根开始定义起,根为第 1 层,根的子结点为第 2 层,以此类推

树的高度或深度树中结点的最大层次,如上图:树的高度为4。

结点的祖先从根到该结点所经分支上的所有结点,如上图: A 是所有结点的祖先。

路径:一条从树中任意节点出发,沿父结点 - 子节点连接,达到任意节点的序列,比如A到Q的路径为: A-E-J-Q、H到Q的路径H-D-A-E-J-Q。

子孙以某结点为根的子树中任一结点都称为该结点的子孙,如上图:所有结点都是A的子孙。

森林由m(m>0)棵互不相交的树的集合称为森林
 

1.4 树的表示方法--孩子兄弟表示法

树结构相对线性表就比较复杂了,要存储表示起来就比较麻烦了,既要保存值域,也要保存结点和结点之间的关系,实际中树有很多种表示方式如:双亲表示法,孩子表示法、孩子双亲表示法以及孩子兄弟表示法等。我们这里就简单的了解其中最常用的孩子兄弟表示法:

struct TreeNode
{struct Node* child; // 左边开始的第⼀个孩⼦结点struct Node* brother; // 指向其右边的下⼀个兄弟结点int data; // 结点中的数据域
}

比如说下面这幅图中的树结构:

我们用孩子兄弟表示法可以这样表示——

1.5 属性结构实际运用场景

文件系统是计算机存储和管理文件的一种方式,它利用树形结构来组织和管理文件和文件夹。在文件系统中,树结构被广泛应用,它通过父结点和子结点之间的关系来表示不停层级的文件和文件夹之间的关联。

二、二叉树

2.1 二叉树的概念与结构

在树形结构中,我们最常用的就是二叉树,一棵二叉树是结点的一个有限集合,该集合由一个根节点加上两棵分别称为左子树和右子树的二叉树组成或者二叉树为空。

结构:

从上图可以看出:

  1. 二叉树不存在度大于2的结点(0,1,2)
  2. 二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树

注意:对于任意的⼆叉树都是由以下几种情况复合而成的:

因此二叉树不是很好驾驭,于是我们定义了特殊的二叉树,比如满二叉树、完全二叉树等。

2.2 特殊的二叉树

树->二叉树->特殊的二叉树->满二叉树

2.2.1 满二叉树

满二叉树(度为2,即最大结点个数为2),每一层结点数都最大,层数为K,结点总数为2^(k-1),这就是满二叉树。

满二叉树的结点总数是怎么求出来的呢?

2.2.2 完全二叉树

完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。

简单来说

完全二叉树就是:除了最后一层,其他每层结点个数都达到最大,最后一层结点个数不一定达到最大,满二叉树就是完全二叉树的一种,并且完全二叉树的结点从左向右依次排列。

完全二叉树就是:除了最后一层,其他每层结点个数都达到最大,最后一层结点个数不一定达到最大,满二叉树就是完全二叉树的一种,并且完全二叉树的结点从左向右依次排列。

完全二叉树的每层结点的个数达到最大就是满二叉树;除了最后一层,其他每层结点个数都达到最大就是完全二叉树

完全二叉树的结点是从左往右依次排列的——

这是非常重要的一个知识点,观察下图,是不是一个完全二叉树——

缺一个左孩子,这样一来不是从左到右依次排列了,就不是完全二叉树

二叉树的性质:

三、二叉树的存储结构

二叉树一般可以使用二中存储结构,一种顺序结构,一种链式结构

3.1 顺序结构

顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树因为不是完全二叉树会有空间的浪费,完全二叉树更适合使用顺序结构存储。

我们通常把堆(一种二叉树)使用顺序结构的数组来存储,需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段

链表结构

3.2 链式结构

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

通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址。

链式结构又分为二叉链和三叉链,当前我们学习中⼀般都是二叉链。后面的学习中会学到高阶数据结构如红黑树等会用到三叉链。

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

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

相关文章

工具测试 - marker (Convert PDF to markdown + JSON quickly with high accuracy)

参考链接如下&#xff1a;&#xff1a; 参考链接&#xff1a;https://github.com/datalab-to/marker?tabreadme-ov-file#llm-services 底层的OCR模型&#xff1a;https://github.com/datalab-to/surya 作用&#xff1a;开源免费&#x1f193;&#xff0c;多 GPU 推理、生成效…

STM32HAL 快速入门(七):GPIO 输入之光敏传感器控制蜂鸣器

STM32HAL 快速入门&#xff08;七&#xff09;&#xff1a;GPIO 输入之光敏传感器控制蜂鸣器 前言 大家好&#xff0c;这里是 Hello_Embed。上一篇我们用 GPIO 输入模式实现了按键控制 LED&#xff0c;本篇将进阶到 “光敏传感器控制蜂鸣器”—— 通过读取光敏传感器的信号&…

windows环境,安装kafka

步骤 1: 准备工作 确保已安装 Java&#xff1a;Kafka 需要 Java 运行时环境 (JRE) 或 Java 开发工具包 (JDK) 来运行。请确认您的系统上已安装了 Java&#xff0c;并且 JAVA_HOME 环境变量正确配置。 解压 Kafka&#xff1a;将下载的 Kafka 压缩包解压到一个目录&#xff0c;比…

机器翻译60天修炼专栏介绍和目录

文章目录 第一章:机器翻译基础认知与语言学铺垫 第二章:经典机器翻译模型(统计机器翻译) 第三章:神经网络基础与词向量技术 第四章:神经机器翻译(NMT)基础架构 第五章:NMT模型进阶与训练实践 第六章:预训练模型与机器翻译应用 第七章:研究前沿与综合项目 导论:学习…

openwrt增加自定义网页

一. 简介 本文介绍在OpenWRT中使用Luci框架定制设备配置页面的方法,包括添加静态页面和参数配置页面的过程,以及如何利用lua脚本实现界面与功能的结合。 二. Luci介绍 UCI 是 Openwrt 中为实现所有系统配置的一个统一接口,英文名 Unified Configuration Interface,即统一…

微服务的编程测评系统11-jmeter-redis-竞赛列表

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言1. 退出登录1.1 后端1.2 前端2. 获取当前用户信息3. C端用户竞赛列表功能3.1 后端3.2 Jmeter-基本操作3.3 数据版本性能测试-压力测试3.4 redis版本-缓存结构设计…

海滨浴场应急广播:守护碧海蓝天的安全防线

海滨浴场应急广播&#xff1a;守护碧海蓝天的安全防线&#xff01;海滨浴场&#xff0c;是人们休闲娱乐、亲近自然的理想场所。然而&#xff0c;变幻莫测的海洋环境也潜藏着诸多安全隐患&#xff0c;如溺水、离岸流、海蜇蜇伤、极端天气等。为了有效应对突发事件&#xff0c;保…

华曦达港股IPO观察丨以创新研发为笔,构建AI Home智慧生活新蓝图

深圳市华曦达科技股份有限公司自创立伊始&#xff0c;便将敏锐的市场洞察与前沿技术追踪视为生命线。通过构建一支卓越的研发团队&#xff0c;公司专注于自主核心技术的深耕与积累&#xff0c;以精密的硬件与创新的软件筑起坚实的技术壁垒。其精心打造的“技术创新&#xff0d;…

构建现代化的Web UI自动化测试框架:从图片上传测试实践说起

构建现代化的Web UI自动化测试框架&#xff1a;从图片上传测试实践说起如何设计一个可维护、可扩展的Web UI自动化测试框架&#xff1f;本文通过一个图片上传测试实例&#xff0c;详细介绍专业测试框架的搭建与实践。当前测试框架结构 首先&#xff0c;让我们了解一下当前的测试…

Apache IoTDB:大数据时代时序数据库选型的技术突围与实践指南

摘要&#xff1a;时序数据库在大数据时代迎来爆发式增长&#xff0c;IoTDB作为Apache顶级开源项目展现出显著优势&#xff1a;1. 性能卓越&#xff1a;支持千万级数据点/秒写入&#xff0c;18:1高压缩比&#xff0c;查询延迟低至500ms&#xff1b;2. 创新架构&#xff1a;采用树…

2025年8月16日(星期六):雨骑古莲村游记

清晨&#xff0c;当第一缕微光还未完全驱散夜幕的静谧&#xff0c;我们这群由校长领衔的骑行爱好者已整装待发。咖啡节早市尚未开摊&#xff0c;空气中弥漫着一种期待与宁静交织的氛围&#xff0c;仿佛连时间都在为我们即将开启的旅程而放慢脚步。今天的目标是古莲村&#xff0…

Pandas数据预处理中缺失值处理

一、缺失值的概念表现形式1.数据库中常用null表示2.部分编程语言中用NA表示3.可能表现为空字符串&#xff08;‘’&#xff09;或特定数值4.在Pandas中统一用NaN表示&#xff08;来自NumPy库&#xff0c;NaN、NAN、nan本质一致&#xff09;NaN的特性1.与任何值都不相等&#xf…

计算机网络:(十五)TCP拥塞控制与拥塞控制算法深度剖析

> 当网络变成"堵城",TCP如何化身智能交通指挥家?揭秘百万级并发背后的流量控制艺术! ### 一、生死攸关:为什么需要拥塞控制? **真实灾难案例**:1986年劳伦斯伯克利实验室网络大崩溃,因缺乏拥塞控制导致全网瘫痪36小时。TCP拥塞控制由此诞生,核心解决**资…

python中的单下划线“_”与双下划线“__”的使用场景及“左右双下划线”(魔术方法:`__xxx__`)

在Python中&#xff0c;单下划线“_”和双下划线“__”的使用场景和含义有显著区别&#xff0c;主要体现在命名约定和语法 一、单下划线“_”的使用场景 单下划线更多是编程约定&#xff08;而非强制语法&#xff09;&#xff0c;用于传递特定的“暗示”&#xff0c;不影响代码…

我们为什么需要时序数据库?

引言在当今数据驱动的世界中&#xff0c;时间序列数据正以前所未有的速度增长。从物联网设备传感器、金融交易记录到应用程序性能监控&#xff0c;时间序列数据无处不在。传统的关系型数据库在处理这类数据时往往力不从心&#xff0c;这时时序数据库(Time Series Database, TSD…

python-林粒粒的视频笔记1

python的方法和函数指什么 可变类型和不可变类型 不可变类型&#xff0c;比如字符串通过方法调用后&#xff0c;字符串本身的值不改变 要改变需要重新赋值才能进行改变 比如可变数据类型类型&#xff0c;调用方法后可以直接改变原列表 因此&#xff0c;可变数据类型需要再重新赋…

CentOS 7的下载与安装

一 、CentOS 7的下载与安装 注意&#xff1a; CentOS 7 已于2024年6月30日停止维护&#xff01; 1、下载 由于 centos 7 已经停止维护&#xff0c;部分镜像网站移除了对centos 7的支持&#xff0c;这里找到了部分现在还可以使用的镜像网站 阿里云开源镜像站&#xff1a;http…

矿物分类系统开发笔记(二):模型训练[删除空缺行]

目录 一、阶段衔接与开发目标 二、数据准备 三、模型选择与训练 1. 逻辑回归&#xff08;LR&#xff09; 2. 随机森林&#xff08;RF&#xff09; 3. 高斯朴素贝叶斯&#xff08;GNB&#xff09; 4. 支持向量机&#xff08;SVM&#xff09; 5. AdaBoost 6. XGBoost 四…

通信方式:命名管道

一、命名管道 1. 命名管道的原理 有了匿名管道&#xff0c;理解命名管道就非常简单了。 对于普通文件而言&#xff0c;两个进程打开同一个文件&#xff0c;OS是不会将文件加载两次的&#xff0c;这两个进程都会指向同一个文件&#xff0c;那么&#xff0c;也就享有同一份 in…

如何将数据库快速接入大模型实现智能问数,实现chatbi、dataagent,只需短短几步,不需要配置工作流!

智能问数系统初始化操作流程 一、系统初始化与管理员账号创建登录与初始化提示&#xff1a;首次访问系统登录页&#xff0c;若系统未初始化&#xff0c;会弹出 “系统未完成初始化&#xff0c;请初始化管理员账号” 提示&#xff0c;点击【去创建】。填写管理员信息&#xff1a…