Hello ”树“先生

ZYNQ:Hello World 实验-PS-串口打印“Hello World” PS-串口打印“Hello World” 阅读详情

恭喜发现宝藏!微信搜索公众号【TechGuide】关注更多新鲜好文和互联网大厂的笔经面经。
作者@TechGuide【全网同名】
点赞再看,养成习惯,您动动手指对原创作者意义非凡🤝

当你的才华还撑不起你的野心时,你应该静下心去学习 。

20200929
文章末尾已更新最小生成树、线段树等内容


前言

首先思考这样一个问题:为什么有树?因为树的光合作用可以吸,呸 ,因为分层次管理(增删改查)数据(在很多场景下)有着更高的效率!
在这里插入图片描述
值得注意的是,无论是顺序表、链表、队列还是现在的各种纷繁复杂的树形数据结构,每一个数据结构的提出都是因为解决了其他数据结构解决不了或者效果不够好的问题。

正文

1. 二叉树

在这里插入图片描述
关于二叉树基本概念的介绍这里就不再赘述,以下我们重点介绍两个概念,即:

  • 二叉搜索树
  • 平衡二叉树

2. 二叉搜索树

二叉搜索树中,当前根节点的左边全部比根节点小,当前根节点的右边全部比根节点大。这样的排布无疑对数据的查找是有帮助的,从根节点出发,与节点键值比较递归的与左/右子树根节点比较,最后相等即可判定找到。
在这里插入图片描述
但是二叉树在动态查找过程中会有一个问题,由于树的查找效率与树的高度直接相关,如果多次的增删节点使得二叉搜索树变得”瘦高“,其效果会退化成一个链表结构,而且,在不同的节点插入顺序的情况下,会形成不同深度的树形结构(如上图),经过分析ASL(平均查找长度),我们可以知道中间最”平衡”的二叉树效率最高。所以综上,我们就可以引出我平衡二叉树来解决这个问题了。

平衡二叉树(AVL树)任意节点的左右子树高度差的绝对值不超过1。高度h = O ( l g ( N ) ) O(lg(N)) O(lg(N))。

很多小伙伴不知道AVL代表什么,实际是发明这种数据结构的科学家们的首字母构成的。

怎么解决二叉搜索树碰到的不平衡的问题呢?既然你歪了一点,那自然第一个想到的就是再调整。如何调整呢?可以通过右旋,或者左旋来调整树形结构。

RR旋转:
在这里插入图片描述
LL旋转:
在这里插入图片描述
LR旋转:
在这里插入图片描述
RL旋转:
在这里插入图片描述
判断方法是根据谁破坏了谁的平衡(即时一个节点的高度差(平衡因子)大于1了),就做相应的旋转即可。

这里插播一条关于堆的介绍。可以用树来实现堆(优先队列)。
用二叉搜索树?NOOOO!如果一直删最大值,二叉搜索树又退化成链表了。但是是不是就没戏了呢?也不是,做一些调整又可以避免这个缺点了,那就是把最大/小值存在一棵完全二叉树的根节点位置,这样就算删去也不会影响平衡因子了。但是,这样操作之后剩下的部分如何调整成一个正常的树形结构呢?
好,以上是我们关于堆的一些小思考,事实上,堆可以用数组表示的完全二叉树构成,并且其任意节点是其子树所有节点的最大值/最小值。

哈夫曼树

引出哈夫曼树要解决的问题就是如何根据节点不同的查找频率构造更加有效的搜索树?

比如下列示例,根据学生成绩分布构造一棵搜索树:
在这里插入图片描述
先给出一个概念: 带权路径长度。这里的全职可以理解为查询频率。
在这里插入图片描述
构造哈夫曼树的方法也很简单,就是每次把权值最小的两颗二叉树合并即可。比如:
在这里插入图片描述
那么先1,2得到3,再3,3得到6,再4,5得到9,再6,9得到15即可。得到的哈夫曼树如下图:
在这里插入图片描述

3. B树

既然有了AVL树了,AVL树的查找又稳定,查找、插入、删除的时间复杂度都为 O ( l o g N ) O(logN) O(logN),不是挺好的吗?为什么还需要B树呢?

  1. 这是因为B树由于要维持自身的平衡,所以进行插入和删除结点操作的时候,需要对结点进行频繁的旋转。
  2. 同时,AVL树每一个节点只能存放一个元素,并且每个节点只有两个子节点。当进行查找时,就需要多次磁盘IO,(数据是存放在磁盘中的,每次查询是将磁盘中的一页数据加入内存,树的每一层节点存放在一页中,不同层数据存放在不同页。)这样如果需要多层查询就需要多次磁盘IO。

为了解决AVL树上述的问题,就出现了B树。

B树也是一种平衡查找树,只不过是一种多路的平衡查找树。它的结构规则是这样的:

(1)排序方式:所有节点关键字是按递增次序排列,并遵循左小右大原则;

(2)子节点数:非叶节点的子节点数>1,且<=M ,且M>=2,空树除外(注:M阶代表一个树节点最多有多少个查找路径,M=M路,当M=2则是2叉树,M=3则是3叉);

(3)关键字数:枝节点的关键字数量大于等于ceil(m/2)-1个且小于等于M-1个;

(4)所有叶子节点均在同一层、叶子节点除了包含了关键字和关键字记录的指针外也有指向其子节点的指针只不过其指针地址都为null对应下图最后一层节点的空格子;

在这里插入图片描述
关于B树的查询和插入、删除等操作,这里有一篇非常形象的文章,看一遍操作就理解透彻了【传送门】

看完了吗?回来,我总结一下:

  1. 查询时,就是通过与节点比较,再按照节点划分值域得到指向下一个节点的指针,再去比较,直到找到,或者到null。
  2. 插入时,就是一个节点内的关键字数达到拆分条件时,取出中间值作为父节点,再次添加新节点。
  3. 删除节点时,关键字数小于一定值就需要合并关键值。

说明:
B树相对于平衡二叉树的不同是,每个节点包含的关键字增多了,特别是在B树应用到数据库中的时候,数据库充分利用了磁盘块的原理(磁盘数据存储是采用块的形式存储的,每个块的大小为4K,每次IO进行数据读取时,同一个磁盘块的数据可以一次性读取出来)把节点大小限制和充分使用在磁盘快大小范围;把树的节点关键字增多后树的层级比原来的二叉树少了,减少了数据查找的次数和复杂度;


缺点:
Buuuut,B树也有它的问题,那就是,B树的查找不稳定,最好的情况就是在根节点查到了,最坏的情况就是在叶子结点查到。另外,B树在遍历方面比较麻烦,由于需要进行中序遍历,所以也会进行一定数量的磁盘IO。
为了解决这些问题,出现了B+树。

4. B+树

在这里插入图片描述
规则(引自这里):

(1)B+跟B树不同B+树的非叶子节点不保存关键字记录的指针,只进行数据索引,这样使得B+树每个非叶子节点所能保存的关键字大大增加;

(2)B+树叶子节点保存了父节点的所有关键字记录的指针,所有数据地址必须要到叶子节点才能获取到。所以每次数据查询的次数都一样;

(3)B+树叶子节点的关键字从小到大有序排列,左边结尾数据都会保存右边节点开始数据的指针。

特点:

1、B+树的层级更少:相较于B树B+每个非叶子节点存储的关键字数更多,树的层级更少所以查询数据更快;

2、B+树查询速度更稳定:B+所有关键字数据地址都存在叶子节点上,所以每次查找的次数都相同所以查询速度要比B树更稳定;

3、B+树天然具备排序功能:B+树所有的叶子节点数据构成了一个有序链表,在查询大小区间的数据时候更方便,数据紧密性很高,缓存的命中率也会比B树高。

4、B+树全节点遍历更快:B+树遍历整棵树只需要遍历所有的叶子节点即可,,而不需要像B树一样需要对每一层进行遍历,这有利于数据库做全表扫描。

B树相对于B+树的优点是,如果经常访问的数据离根节点很近,而B树的非叶子节点本身存有关键字其数据的地址,所以这种数据检索的时候会比B+树更快。

5. 红黑树

红黑树也叫RB树,RB-Tree。是一种自平衡的二叉查找树,它的节点的颜色为红色和黑色。它不严格控制左、右子树高度或节点数之差小于等于1。也是一种解决二叉查找树极端情况的数据结构。

红黑树规定了:

1.节点是红色或黑色。

2.根节点是黑色。

3.每个叶子节点都是黑色的空节点(NIL节点)。

4 每个红色节点的两个子节点都是黑色。也就是说从每个叶子到根的所有路径上不能有两个连续的红色节点)。

5.从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

在这里插入图片描述
这里有关于红黑树具体操作的详细演示,比较繁杂,但是总结起来就是:

红黑树在查找方面和AVL树操作几乎相同。但是在插入和删除操作上,AVL树每次插入删除会进行大量的平衡度计算,红黑树是牺牲了严格的高度平衡的优越条件为代价,它只要求部分地达到平衡要求,结合变色,降低了对旋转的要求,从而提高了性能。红黑树能够以O(log2 n)的时间复杂度进行搜索、插入、删除操作。此外,由于它的设计,任何不平衡都会在三次旋转之内解决。

相比于BST,因为红黑树可以能确保树的最长路径不大于两倍的最短路径的长度,所以可以看出它的查找效果是有最低保证的。在最坏的情况下也可以保证O(logN)的,这是要好于二叉查找树的。因为二叉查找树最坏情况可以让查找达到O(N)。

总结

1、从平衡二叉树、B树、B+树、B*树总体来看它们的贯彻的思想是相同的,都是采用二分法和数据平衡策略来提升查找数据的速度;

  1. 不同点是他们一个一个在演变的过程中通过IO从磁盘读取数据的原理进行一步步的演变,每一次演变都是为了让节点的空间更合理的运用起来,从而使树的层级减少达到快速查找数据的目的;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

以上截图来自于北理工ACM培训课

Java技术栈/面试题合集(8)-Redis篇 Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。它的数据是存储在内存中的,因此读写速度非常快,每秒可以处理超过 10 万次读写操作。由于这些特性,Redis 被广泛应用于缓存、分布式锁、计数器、限流等场景RedLock 是 Redis 官方提出的一种分布式锁算法,旨在解决分布式系统中多节点环境下的互斥资源访问问题。 阅读详情

相关推荐

ESP32连接OneNet云平台实现多设备联动控制完整示例

通过esp32连接onenet云平台,实现远程设备间的智能联动控制,利用MQTT协议完成数据通信,esp32连接onenet云平台后可高效稳定地上传与下发指令,提升物联网系统响应速度与自动化水平。

weixin_42360733的博客 540

mysql详解之B+树的查询时间复杂度

在内存里(不考虑磁盘io的特殊性),n叉树的查询时间复杂度都是O(logN)。

yunduanyou的博客 8959

RK3588开发板RKNPU2环境部署实战:更新rknn_server与librknnrt.so详解

本文详细介绍了在RK3588开发板上更新rknn_server与librknnrt.so核心组件的完整实战流程。通过adb工具推送文件、设置权限并执行同步操作,确保RKNPU2环境部署成功,从而解决推理速度慢或初始化失败等问题,提升AI模型运行效率与稳定性。

weixin_29194817的博客 324

mysql通过传入父级id查询所有子节点以及子节点的子节点的简单SQL

需求,根据传入的父节点查下一级和下下级所有节点,比如:这里传入父节点id为2,要查询2下的所有节点也就是:6,7,9,10节点 查询SQL: sql: select * from item_type WHERE type_pid=2 or type_pid IN(select type_id from item_type where type_pid=2) 结果截图: 够简单吧!原理一看就...

qq_41407029的博客 1061

UIPath 获取网页元素做遍历点击的实现

UIPath 获取网页元素做遍历点击的实现

geekqian的博客 1万+

HFSS的边界条件与激励方式

在电磁场理论学习中我们知道,电磁场问题的求解都归结于麦克斯韦(Maxwell)方程组的求解,在HFSS中波动方程的求解同样是由微分形式的麦克斯韦方程推导出来的。而边界条件定义了求解区域的边界以及不同物体交界处的电磁场特性,是求解麦克斯韦方程的基础。 只有在假定场矢量是单值、有界、并且沿空间连续分布的前提下,微分形式的麦克斯韦方程组才是有效的;而在求解区域的边界,不同介质的交界处和场源处,场矢量是不连续的,那么场的导数也就失去了意义。 边界条件就是定义跨越不连续边界处的电磁场特性,因此,正确地理解、定义并

ASH_GUARDIAN的博客 1万+

以mysql为例,通过sql查找所有父节点和所有子节点

此sql查询id=2的所有子节点id,并包括当前id=2的节点,如果不想包括当前节点,去掉。此sql查询id=3的所有父节点sql,parent_id:父id。

scorpio_meng的博客 5305

079、LVGL基础控件:消息框(Msgbox)

《LVGL消息框控件深度解析与避坑指南》 文章深入剖析了LVGL消息框控件的核心特性和使用技巧。消息框本质是带按钮的模态容器,而非独立窗口。作者分享了创建消息框的正确姿势、标题/内容设置方法、安全的按钮事件处理方式(避免直接调用close函数导致栈溢出),并详细介绍了模态/非模态实现、样式自定义、动态更新等实用技巧。针对常见问题如内存管理、按钮数量限制、动画效果等给出了专业建议,特别强调了消息框作为用户交互关键环节的优化重要性,建议通过异步删除、合理父对象选择等方式提升稳定性。文章包含大量实际项目经验总结,

m0_50546716的博客 150

b+树的时间复杂度

b+树会先从根节点开始往下找到叶子节点,查找过程类似二分查找,每次查询都能缩小查询范围的一半,所以时间复杂度是O(logn)

qq_21277357的博客 1153

MIKE水动力笔记7_实测数据与模型输出结果的拟合对比

上一博文【MIKE水动力笔记6】主要讲解如何自己制作实测数据的时间序列文件dfs0,而本博文讲解如何进行实测数据与模型输出结果的拟合对比。

晏长街的博客 1万+

【国密】基于SM2的协同签名与协同解密方案

两方协同签名指客户端与服务端协同完成签名、验签操作,具体实现方案参考了信工所专利[3]。在业务应用中,两方或多方的协同签名一般采用门限签名方案可以用来构造。门限密码算法在多方协作的相关场景中应用十分广泛,可以实现数据联合授权、认证、密钥安全恢复、密钥安全交换等需求,在诸多分布式多方计算协议中均可见其身影。在上述两方协同签名方案中,最巧妙的地方在于签名值s分量的构造,通过一些列数学变换,得以恢复。以下从两方协同签名方案介绍入手,介绍门限密码在协同签名中的应用。解决上述问题的关键在于门限密码算法的巧妙构造。

听雨草堂 8375

嵌入式linux2.6.12内核源码树配置及hello_world模块实验

前面说到要编写Linux 2.6的驱动,必须建立内核源码树,前面建立的源码树是针对i686平台的,但是我么嵌入式系统用的是arm平台,所以也要建立arm平台的内核源码树。 首先下载与你嵌入式系统平台版本号一致的linux内核,我的版本为2.6.30. 第一步:先解压源代码 tar -jxvf linux-2.6.30.tar.bz2 第二步:进入刚才解压后的目录linux-2.6

自由的代价永远是警惕 983

【华为OD机考】2025C+B+2024E+D卷真题【完全原创题解 | 详细考点分类 | 不断更新题目 | 六种主流语言Py+Java+Cpp+C+Js+Go】

可上练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)

weixin_48157259的博客 1万+

ubuntu 2.6.22 内核树建立

<br />本文是参考了网上多篇帖子而写的算不上什么原创。唯一值得欣慰的只不过在本机上实现罢了。因为毕竟失败了几次。也因为本人是初学驱动编程 很多简单的问题在我来说是相当的困难的。望有识之士不要笑话。最后,希望本文能给刚学驱动而还没开头的人提供一些帮助。 <br /><br /> 刚看 O'REILLY 写的《LINUX 设备驱动程序》时。作者一再强调在编写驱动程序时必须 建立内核树。所谓内核树,我的理解和网上资料说的一致就是内核源码的一种逻辑形式。那怎么建立呢?为此上网“翻云覆雨”起来而结果却是“惨败

jxth152913的专栏 436

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

linux 内核源码树的建立

刚看 O'REILLY 写的《LINUX 设备驱动程序》时。作者一再强调在编写驱动程序时必须 建立内核树。先前的内核只需要有一套内核头文件就够了,但因为2.6的内核模块吆喝内核源码树中的目标文件连接,通过这种方式,可得到一个更加健壮的模块装载器,但也需要这些目标文件存在于内核目录树中。所谓内核树,我的理解和网上资料说的一致就是内核源码的一种逻辑形式。那怎么建立呢?为此上网“翻云覆雨”起来...

weixin_30301449的博客 97

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

64位Ubuntu14.04系统下加载内核模块hello world

[转载至](https://blog.csdn.net/lucien_zhou/article/details/71274447) 64位Ubuntu14.04系统下加载内核模块hello world ...

苏木的博客 419

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

【反射和表达式树实现调用方法】

分别用反射和表达式树实现调用方法

maomeideliu的博客 206

[算法学习笔记] 《Hello算法》第7章 树

本系列为《Hello算法》学习笔记,仅供学习,不做商用,如有侵权,联系我删除即可!二叉树(binary tree)是一种非线性数据结构,代表“祖先”与“后代”之间的派生关系,体现了“一分为二”的分治逻辑。与链表类似,二叉树的基本单元是节点,每个节点包含值、左子节点引用和右子节点引用。 每个节点都有两个引用(指针),分别指向左子节点(left-child node)和右子节点(right-child node),该节点被称为这两个子节点的父节点(parent node)。当给定一个二叉树的节点时,我们将该

努力学习 851

“Hello world”的历史

“Hello world”的历史 这是最着名的节目。被称为每个程序员几乎所有编程语言的第一个例子,这个消息来自哪里? 作为一个功能,计算机程序只是告诉计算机显示“Hello,World!”这个词。传统上,它是开发人员用来测试系统的第一个程序。对于程序员来说,在屏幕上看到两个单词意味着他们的代码可以编译,加载,运行,他们可以看到输出。 这是一个测试,标志着一个程序的开始。在过去的几十年里,它已经发展...

全机房最蒟蒻的博客 1211

树莓派4B从拆封到python编程—“Hello world”

树莓派从拆封到python编程—“Hello world” 前言 2 3 4 5 6

qq_34318698的博客 4479

一个极简的“Hello World”程序:susam/hello

一个极简的“Hello World”程序:susam/hello susam/hello 是一个开源项目,该项目展示了一个使用 MS-DOS 下的 DEBUG.EXE 工具编写的仅 23 字节的“Hello World”程序。该项目主要使用汇编语言编写。 项目基础介绍 该项目包含了一个名为 HELLO.COM 的二进制文件,它能在 MS-DOS 系统上运行,打印出“Hello, world”字符串...

gitblog_00949的博客 318

Linux生成系统树,Linux内核源码树建立加载hello模块

Linux内核源码树建立加载hello模块在加载模块之前,书中说要先建立内核源码树,那么,如何建立内核源码树呢?首先,要先知道你的OS的内核版本,用uname -r可以查得到在/url/src/目录下可以看到对应的版本目录如果没有可以用apt-cache search linux-source获取内核用sudo apt-get install linux-source-3.13.0下载内核下载完成...

weixin_28829339的博客 187

近 50 种花式 “Hello, World”

当我们学习一门编程语言时,都是从“Hello, World!”开始。所有程序员在其职业生涯中,都至少接触过一个经典的“Hello, World!” 程序。通常程序员会使用多种编程语言,多的甚至实现了十几种。 还有一种称为TTHW(Time to “Hello, World!”)的方法,来衡量程序员创建一个新的“Hello, World!”程序的时间。 你可以用多少种不同的语言编写一个“Hello,...

Android 开发架构 344

c hello world_教你用50种语言写“Hello, World”

当我们学习一门新的语言时,“Hello, World!“通常是我们所写的第一个程序。相信作为一名程序员的你,职业生涯中至少完成了一个“Hello, World!“程序。程序员一般也都会使用多门语言,甚至有多数人都会使用十几种语言。甚至有一个名为TTHW的指标来衡量一个程序员接触一门新的编程语言时,成功写出“Hello, World!“并运行所需要的时间。然而,如果我问你,你会用多少种编程语言写“H...

weixin_39921504的博客 328

hello算法笔记之树

节点的「平衡因子 Balance Factor」定义为节点左子树的高度减去右子树的高度,同时规定空节点的平衡因子为 0。知识点3、删除节点O(logn):当待删除节点的子节点数量 =0 时,表示待删除节点是叶节点,可以直接删除;AVL 树的特点在于「旋转 Rotation」操作,它能够在不影响二叉树的中序遍历序列的前提下,使失衡节点重新恢复平衡。红黑树的平衡条件相对宽松,因此在红黑树中插入与删除节点所需的旋转操作相对较少,在节点增删操作上的平均效率高于 AVL 树。最底层节点尽量靠左填充。

weixin_72100405的博客 919

【Qt】多种控件实现“hello world“

使用编辑框和按钮的方式来实现hello world

dab112的博客 1385
上一篇: 一文理清哈希(散列)表
下一篇: 【美团&字节】四道编程题(含思路)2020/09/06
TechGuide
博客等级 码龄9年 1万+粉丝 148原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TechGuide

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值