数据结构和算法(八)--2-3查找树

news2025/7/18 3:14:31

目录

一、平衡树

1、2-3查找树

1.1、定义

1.2、查找

1.3、插入

1.3.1、向2-结点中插入新键

1.3.2、向一棵只含有一个3-结点的树中插入新键

1.3.3、向一个父结点为2-结点的3-结点中插入新键

1.3.4、向一个父结点为3-结点的3-结点中插入新键

1.3.5、分解根结点

1.4、2-3树的性质

1.5、2-3树的实现


一、平衡树

    二叉查找树,它的查询效率比单纯的链表和数组的查询效率要高很多,大部分情况下,确实是这样的,但不幸的是,在最坏情况下,二叉查找树的性能还是很糟糕。

    例如,我们依次往二叉查找树中插入9,8,7,6,5,4,3,2,1这9个数据,那么最终构造出来的树是长得下面这个样子:

    我们会发现,如果我们要查找1这个元素,查找的效率依旧会很低。效率低的原因在于这个树并不平衡,全部是向左边分支,如果我们有一种方法,能够不受插入数据的影响,让生成的树都像完全二叉树那样,那么即使在最坏情况下,查找的效率依旧会很好。

1、2-3查找树

    为了保证查找树的平衡性,我们需要一些灵活性,因此在这里我们允许树中的一个结点保存多个键。确切的说,我们将一棵标准的叉查找树中的结点称为2-结点(含有一个键和两条链),而现在我们引入3-结点,它含有两个键和三条链。2-结点和3结点中的每条链都对应着其中保存的键所分割产生的一个区间。

1.1、定义

一棵2-3查找树要么为空,要么满足满足下面两个要求:

  1、2-结点:含有一个键(及其对应的值)和两条链,左链接指向2-3树中的键都小于该结点,右链接指向的2-3树中的键都大于该结点。
  2、3-结点:含有两个键(及其对应的值)和三条链,左链接指向的2-3树中的键都小于该结点,中链接指向的2-3树中的键都位于该结点的两个键之间,右链接指向的2-3树中的键都大于该结点。

1.2、查找

    将二叉查找树的查找算法一般化我们就能够直接得到2-3树的查找算法。要判断一个键是否在树中,我们先将它和根结点中的键比较如果它和其中任意一个相等,查找命中;否则我们就根据比较的结果找到指向相应区间的连接,并在其指向的子树中递归地继续查找。如果这个是空链接,查找未命中。

对于H的命中查找

1.3、插入

1.3.1、向2-结点中插入新键

    往2-3树中插入元素和往二叉查找树中插入元素一样,首先要进行查找,然后将节点挂到未找到的节点上。2-3树之所以能够保证在最差的情况下的效率的原因在于其插入之后仍然能够保持平衡状态。如果查找后未找到的节点是一个2-结点,那么很容易,我们只需要将新的元素放到这个2-结点里面使其变成一个3-结点即可。但是如果查找的节点结束于一个3-结点,那么可能有点麻烦。

1.3.2、向一棵只含有一个3-结点的树中插入新键

    假设2-3树只包含一个3-结点,这个结点有两个键,没有空间来插入第三个键了,最自然的方式是我们假设这个结点能存放三个元素暂时使其变成一个4.结点,同时他包含四条链接。然后,我们将这个4.结点的中间元素提升,左边的键作为其左子结点,右边的键作为其右子结点。插入完成,变为平衡2-3查找树,树的高度从0变为1。

1.3.3、向一个父结点为2-结点的3-结点中插入新键

    和上面的情况一样一样,我们也可以将新的元素插入到3-结点中,使其成为一个临时的4-结点,然后,将该结点中的中间元素提升到父结点即2-结点中,使其父结点成为一个3-结点,然后将左右结点分别挂在这个3-结点的恰当位置。

1.3.4、向一个父结点为3-结点的3-结点中插入新键

    当我们插入的结点是3-结点的时候,我们将该结点拆分,中间元素提升至父结点,但是此时父结点是一个3-结点,插入之后,父结点变成了4结点,然后继续将中间元素提升至其父结点,直至遇到一个父结点是2-结点,然后将其变为3-结点,不需要继续进行拆分。

1.3.5、分解根结点

    当插入结点到根结点的路径上全部是3-结点的时候,最终我们的根结点会编程一个临时的4-结点,此时,就需要将根结点拆分为两个2-结点,树的高度加1。

1.4、2-3树的性质

    通过对2-3树插入操作的分析,我们发现在插入的时候,2-3树需要做一些局部的变换来保持2-3树的平衡。
一棵完全平衡的2-3树具有以下性质:
    1、任意空链接根结点的路径长度都是相等的。
    2、4-结点变换为3-结点时,树的高度不会发生变化,只有当根结点是临时的4-结点,分解根结点时,树高+1。
    3、2-3树与普通二叉查找树最大的区别在于,普通的二叉查找树是自顶向下生长,而2-3树是自底向上生长

1.5、2-3树的实现

    直接实现2-3树比较复杂,因为:

  • 需要处理不同的结点类型,非常繁琐
  • 需要多次比较操作来将结点下移;
  • 需要上移来拆分4-结点;
  • 拆分4-结点的情况有很多种;

    2-3查找树实现起来比较复杂,在某些情况插入后的平衡操作可能会使得效率降低。但是2-3查找树作为一种比较重要的概念和思路对于我们后面要讲到的红黑树、B树和B+树非常重要。

数据结构和算法(一)

数据结构--栈、队列、链表、散列表、排序二叉树

再小的努力,乘以365都很明显!
每天⽤⼼记录⼀点点。内容也许不重要,但习惯很重要!
一个程序员最重要的能力是:写出高质量的代码!!
有道无术,术尚可求也,有术无道,止于术。
无论你是年轻还是年长,所有程序员都需要记住:时刻努力学习新技术,否则就会被时代抛弃!

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

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

相关文章

Unity-Shader详解-其二

前向渲染和延迟渲染 前向渲染和延迟渲染总的来说是我们的两种主要的渲染方式。 我们在Unity的Project Settings中的Graphic界面能够找到渲染队列的设定: 我们也可以在Main Camera这里进行设置: 那这里我们首先介绍一下两种渲染(Forward R…

深入浅出理解并应用自然语言处理(NLP)中的 Transformer 模型

1 引言 随着信息技术的飞速发展,自然语言处理(Natural Language Processing, NLP)作为人工智能领域的一个重要分支,已经取得了长足的进步。从早期基于规则的方法到如今的深度学习技术,NLP 正在以前所未有的速度改变着我…

当自动驾驶遇上“安全驾校”:NVIDIA如何用技术给无人驾驶赋能?

自动驾驶技术的商业化落地,核心在于能否通过严苛的安全验证。国内的汽车企业其实也在做自动驾驶,但是吧,基本都在L2级别。换句话说就是在应急时刻内,还是需要人来辅助驾驶,AI驾驶只是决策层,并不能完全掌握…

【OSG学习笔记】Day 9: 状态集(StateSet)与渲染优化 —— 管理混合、深度测试、雾效等渲染状态

干货开始。_ 一、StateSet核心概念与作用 StateSet 是OSG(OpenSceneGraph)中管理渲染状态的核心类,用于封装 OpenGL 渲染状态(如混合、深度测试、雾效、材质、纹理、着色器等),并将这些状态应用于节点或几何体。 通过合理组织 StateSet,可实现: 渲染状态的高效复用:…

Operating System 实验七 Linux文件系统实验

实验目标: 使用dd命令创建磁盘镜像文件ext2.img并格式化为ext2文件系统,然后通过mount命令挂载到Linux主机文件系统。查看ext2文件系统的超级块的信息,以及数据块的数量、数据块的大小、inode个数、空闲数据块的数量等信息 在文件系统中创建文件xxxxx.txt(其中xxxxx为你的学…

linux中shell脚本的编程使用

linux中shell脚本的编程使用 1.shell的初步理解1.1 怎么理解shell1.2 shell命令 2.shell编程2.1 什么是shell编程2.2 C语言编程 和 shell编程的区别 3.编写和运行第一个shell脚本程序3.1 编写时需要注意以下几点:3.1.1 shell脚本没有main函数,没有头文件…

图像畸变-径向切向畸变实时图像RTSP推流

实验环境 注意:ffmpeg进程stdin写入两张图片的时间间隔不能太长,否则mediamtx会出现对应的推流session超时退出。 实验效果 全部代码 my_util.py #进度条 import os import sys import time import shutil import logging import time from datetime i…

手搓雷达图(MATLAB)

看下别人做出来什么效果 话不多说,咱们直接开始 %% 可修改 labels {用户等级, 发帖数, 发帖频率, 点度中心度, 中介中心度, 帖子类型计分, 被列为提案数}; cluster_centers [0.8, 4.5, 3.2, 4.0, 3.8, 4.5, 4.2; % 核心用户0.2, 0.5, 0.3, 0.2, 0.1, 0.0, 0.0;…

汽车零配件供应商如何通过EDI与主机厂生产采购流程结合

当前,全球汽车产业正经历深刻的数字化转型,供应链协同模式迎来全新变革。作为产业链核心环节,汽车零部件供应商与主机厂的高效对接已成为企业发展的战略要务。然而,面对主机厂日益严格的数字化采购要求,许多供应商在ED…

闻性与空性:从耳根圆通到究竟解脱的禅修路径

一、闻性之不动:超越动静的觉性本质 在《楞严经》中,佛陀以钟声为喻揭示闻性的奥秘:钟声起时,闻性显现;钟声歇时,闻性不灭。此“不动”并非如磐石般凝固,而是指觉性本身超越生灭、来去的绝对性…

第34课 常用快捷操作——按“空格键”旋转图元

概述 旋转某个图元,是设计过程中常需要用到的操作,无论是在原理图中旋转某个图形,还是在PCB图中旋转某个元素。 旋转操作的快捷键是空格键。下面作详细介绍。 按空格键旋转图元 当我们选中一个图元时,按下空格键,即…

基于亚马逊云科技构建音频转文本无服务器应用程序

Amazon Transcribe是一项基于机器学习模型自动将语音转换为文本的服务。它提供了多种可以提高文本转录准确性的功能,例如语言自定义、内容过滤、多通道音频分析和说话人语音分割。Amazon Transcribe 可用作独立的转录服务,也可以集成到应用程序中提供语音…

K8S Service 原理、案例

一、理论介绍 1.1、3W 法则 1、是什么? Service 是一种为一组功能相同的 pod 提供单一不变的接入点的资源。当 Service 存在时,它的IP地址和端口不会改变。客户端通过IP地址和端口号与 Service 建立连接,这些连接会被路由到提供该 Service 的…

实验四 进程调度实验

一、实验目的 1、了解操作系统CPU管理的主要内容。 2、加深理解操作系统管理控制进程的数据结构--PCB。 3、掌握几种常见的CPU调度算法(FCFS、SJF、HRRF、RR)的基本思想和实现过程。 4、用C语言模拟实现CPU调度算法。 5、掌握CPU调度算法性能评价指…

linux blueZ 第四篇:BLE GATT 编程与自动化——Python 与 C/C++ 实战

本篇聚焦 BLE(Bluetooth Low Energy)GATT 协议层的编程与自动化实践,涵盖 GATT 基础、DBus API 原理、Python(dbus-next/bleak)示例、C/C++ (BlueZ GATT API)示例,以及自动发现、读写特征、订阅通知、安全配对与脚本化测试。 目录 BLE GATT 基础概念 BlueZ DBus GATT 模…

Linux线程与进程:探秘共享地址空间的并发实现与内

Linux系列 文章目录 Linux系列前言一、线程的概念二、线程与地址空间2.1 线程资源的分配2.2 虚拟地址到物理地址的转换 三 、线程VS进程总结 前言 在Linux操作系统中,线程作为CPU调度的基本单位,起着至关重要的作用。深入理解线程控制机制,是…

科学养生,开启健康生活新方式

在快节奏的现代生活中,健康养生已成为人们关注的焦点。科学的养生方式不仅能增强体质,还能有效预防疾病,提升生活质量。​ 合理饮食是健康养生的基础。日常饮食应遵循均衡原则,保证蛋白质、碳水化合物、脂肪、维生素和矿物质的合…

外贸图片翻译软件推荐用哪些?不损原图画质的跨境图片翻译器,收藏!

在跨境电商的 “江湖” 里,卖家们怀揣着全球 “捞金” 的梦想扬帆起航,可谁能想到,一个看似不起眼的 “小怪兽”—— 图片翻译难题,却常常让大家在 “出海” 途中 “栽跟头”。 电商跨境图片翻译全能王——风车AI翻译 [fengchef…