STL关联式容器之平衡二叉搜索树

news2025/1/19 23:18:22

 平衡二叉搜索树

        在STL关联式容器介绍-CSDN博客中对二叉搜索树做了简要的描述;但是因为没有对二叉搜索树对数的深度及插入后树的结构进行调整,二叉搜索树可能失去平衡,造成搜寻效率低落的情况。如下所示:

        所谓树形平衡与否,并没有一个绝对的测量标准。“平衡”的大致意义是:没有任何一个节点过深(深度过大)。不同的平衡条件,造就不同的效率表现,以及不同的实现复杂度。有数种特殊结构如AVL-tree、RB-tree、AA-tree,均可实现出平衡二叉搜索树,它们都比一般的(无法绝对维持平衡的)二叉搜索树复杂,因此,插入节点和删除节点的平均时间也比较长,但是它们可以避免极难应付的最坏(高度不平衡)的情况,而且由于它们总是保持某种程度的平衡,所以元素的访问(搜寻)时间平均而言也就比较少。

AVL tree(Adelson-Velskii-Landis tree)

        Adelson-Velskii-Landis树(AVL树)是由苏联数学家乔治·阿德尔森-维尔斯基(Georgy Adelson-Velskii)和叶夫根尼·兰迪斯(Evgenii Landis)于1962年提出的。它们首次在一篇论文《An algorithm for the organization of information》中介绍了这一数据结构,目的是为了提高二叉搜索树的效率。

        AVL tree是一个"加上了额外平衡条件"的二叉搜索树。其平衡条件的建立是为了确保整棵树的深度为O(logN)。直观上的最佳平衡条件是每个节点的左右子树有着相同的高度,但未免太过严苛,我们很难插入新元素而又保持这样的平衡条件。AVL tree于是退而求其次,要求任何节点的左右子树高度相差最多为1.这是一个较弱的条件,但仍能够保证“对数深度”平衡状态。

        下面来看一个满足AVL条件的二叉搜索树;

        该树的任意节点的左右子树的高度差都没超过1。

        不过此时如果插入节点11,如下图所示

插入节点11后,22节点对应左右子树的高度分别为4和2,18节点左右子树高度分别为2和1,所以该树已经不再满足AVL的特性;需要对其进行调整以满足AVL特性;

        前面说过,只要调整“插入节点到根节点”路径上,平衡状态被破坏之各节点中最深的那一个,便可使整棵树重新获得平衡。假设该最深节点为X;

        现在根据插入节点与不满足条件的X节点的位置关系不同分成四种情况,而后根据这四种情况采用不同的调整方法:

 1.插入点位于X的左子节点的左子树--左左

  2.插入点位于X的左子节点的右子树--左右

  3.插入点位于X的右子节点的左子树--右左

  4.插入点为于X的右子节点的右子树--右右

情况1,4彼此对称,称为外侧插入,可以采用单旋转操作调整解决。情况2,3彼此对称,可以采用双旋转操作调整解决。

下图为外侧示例:

下图为内侧示例:

单旋转

        在外侧状态下,如下图所示:

在外侧插入情况下,k2“插入前平衡,插入后不平衡”的唯一情况如上图所示。A子树成长了一层,致使它比C子树深度多2.B子树不可能和A子树位于同一层,否则k2在插入前就处于不平衡状态了。B子树也不可能和C子树位于同一层,否则第一个违反平衡条件的将是k1而不是k2.

        为了调整平衡状态,我们希望将A子树提高一层,并将C子树下降一层,调整后如下图所示:

这么做是因为,二叉所搜树的规则使我们知道,k2>k1,所以k2必须成为新树形k1的右子节点。二叉树的规则也告诉我们B子树的所有节点的键值是在k1和k2之间,所以新树形中的B子树必须落在k2的左侧。

        以上所有调整都只需要将指针稍作搬移,即可高效完成。完成后的新树形符合AVL的平衡条件,不需要再调整。

        对于右右的外侧插入,可以采用类似的方法完成。

双旋转

上图所示,左侧为内侧插入所造成的不平衡状态。单旋转无法解决这种情况。第一,我们不能再以k3为根节点,其次,我们不能将k3和k1做一次单旋转,因为旋转之后,还是不平衡。(以此方式旋转,k1,成为父节点,其左节点高度为1,右节点高度将是3)。唯一的可能是以k2为新的根节点。这使得k1,必须成为k2的左子节点,k3必须成为k2的右子节点。这么一来也就决定了四个子树的位置。新的树形满足AVL-tree的平衡条件,并且像单旋转的情况一样,恢复了节点插入之前的高度,因此保证不需要再做调整。

        其旋转过程经历了两次单旋转;如下所示;首先对k1,k2做一次单旋转得到如下所示树形:

而后针对k3,k2做一次单旋,其树形如下所示:

        RB-tree是另一个被广泛使用的平衡二叉树,也是SGI STL唯一实现的一种搜索树,作为关联式容器的底部机制使用。TB-tree的平衡条件不同于AVL-tree,但同样运用了单旋转和 双旋转的修正操作。下一节,我们将再对RB-tree进行学习。

参考文档《STL源码剖析--侯捷》

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

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

相关文章

Django启用国际化支持(2)—实现界面内切换语言:activate()

文章目录 ⭐注意⭐1. 配置项目全局设置:启用国际化2. 编写视图函数3. 配置路由4. 界面演示5、扩展自动识别并切换到当前语言设置语言并保存到Session设置语言并保存到 Cookie ⭐注意⭐ 以下操作依赖于 Django 项目的国际化支持。如果你不清楚如何启用国际化功能&am…

Java基础——继承和多态

目录 一、继承 继承的定义: 继承的基本用法: 如何调用父类的方法? 二、多态 多态性的好处 多态中的强制类型转换: 包的命名规则——域名倒叙 一、继承 继承的定义: 继承是面向对象编程中的一种机制&#xff0c…

2024-11-17 -MATLAB三维绘图简单实例

1. x -1:0.05:1; y x; [X, Y] meshgrid(x, y); f (X, Y) (sin(pi * X) .* sin(pi * Y)) .^ 2.*sin(2.*X2.*Y); mesh(X, Y, f(X, Y)); % 调用函数f并传递X和Y xlabel(X-axis); ylabel(Y-axis); zlabel(Z-axis); title(Surface Plot of (sin(pi * X) .* sin(pi * Y)) .^ 2.*…

resnet50,clip,Faiss+Flask简易图文搜索服务

一、实现 文件夹目录结构&#xff1a; templates -----upload.html faiss_app.py 前端代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widt…

Flink监控checkpoint

Flink的web界面提供了一个选项卡来监控作业的检查点。这些统计信息在任务终止后也可用。有四个选项卡可以显示关于检查点的信息:概述(Overview)、历史(History)、摘要(Summary)和配置(Configuration)。下面依次来看这几个选项。 Overview Tab Overview选项卡列出了以…

如何用Excel批量提取文件夹内所有文件名?两种简单方法推荐

在日常办公中&#xff0c;我们有时需要将文件夹中的所有文件名整理在Excel表格中&#xff0c;方便管理和查阅。手动复制文件名既费时又易出错&#xff0c;因此本文将介绍两种利用Excel自动提取文件夹中所有文件名的方法&#xff0c;帮助你快速整理文件信息。 方法一&#xff1…

微信小程序-prettier 格式化

一.安装prettier插件 二.配置开发者工具的设置 配置如下代码在setting.json里&#xff1a; "editor.formatOnSave": true,"editor.defaultFormatter": "esbenp.prettier-vscode","prettier.documentSelectors": ["**/*.wxml"…

Debezium日常分享系列之:Debezium3版本Debezium connector for JDBC

Debezium日常分享系列之&#xff1a;Debezium3版本Debezium connector for JDBC 概述JDBC连接器的工作原理消费复杂的Debezium变更事件至少一次的传递多个任务数据和列类型映射主键处理删除模式幂等写入模式演化引用和大小写敏感性连接空闲超时数据类型映射部署Debezium JDBC连…

前端页面自适应等比例缩放 Flexible+rem方案

在移动互联网时代&#xff0c;随着智能手机和平板电脑的普及&#xff0c;前端开发者面临的一个重要挑战是如何让网页在不同尺寸和分辨率的设备上都能良好地显示。为了应对这一挑战&#xff0c;阿里巴巴的前端团队开发了 flexible.js&#xff0c;旨在提供一种简单有效的解决方案…

Argo workflow 拉取git 并使用pvc共享文件

文章目录 拉取 Git 仓库并读取文件使用 Kubernetes Persistent Volumes&#xff08;通过 volumeClaimTemplates&#xff09;以及任务之间如何共享数据 拉取 Git 仓库并读取文件 在 Argo Workflows 中&#xff0c;如果你想要一个任务拉取 Git 仓库中的文件&#xff0c;另一个任…

AWTK VSCode 实时预览插件端口冲突的解决办法

AWTK XML UI 预览插件&#xff1a;在 vscode 中实时预览 AWTK XML UI 文件&#xff0c;在 Copilot 的帮助下&#xff0c;可以大幅提高界面的开发效率。 主要特色&#xff1a; 真实的 UI 效果。可以设置主题&#xff0c;方便查看在不同主题下界面的效果。可以设置语言&#xf…

x-cmd pkg | helix - 用 Rust 打造的文本编辑器,内置 LSP 和语法高亮,兼容 Vim 用户习惯

目录 简介快速上手安装使用 功能特点竞品和相关项目进一步阅读 简介 helix 是用 Rust 开发的文本编辑器&#xff0c;以 Modal editing&#xff08;模态编辑&#xff09;为核心特性&#xff0c;类似于 Vim。它结合了经典的 Vim 模式编辑和现代开发工具的特性&#xff08;如 LSP…

资源管理功能拆解——如何高效配置和管理项目资源?

在任何一个项目中&#xff0c;资源的合理配置和高效管理是决定项目成败的关键因素。无论是人力、物资还是时间&#xff0c;每一个资源的使用都直接关系到项目的执行效果和企业的成本控制。因此&#xff0c;如何在项目管理中实现资源的高效配置和监控&#xff0c;成为了企业管理…

SpringCloud OpenFeign负载均衡远程调用 跨服务调用 连接池优化

介绍 Spring Cloud OpenFeign 是 Spring Cloud 的一部分&#xff0c;提供了一种声明式的 HTTP 客户端方式来简化服务间的通信。通过 OpenFeign&#xff0c;开发者可以像调用本地方法一样&#xff0c;轻松地调用远程服务&#xff0c;而不需要手动处理 HTTP 请求、响应和连接等底…

Android Studio开发学习(五)———LinearLayout(线性布局)

一、布局 认识了解一下Android中的布局&#xff0c;分别是: LinearLayout(线性布局)&#xff0c;RelativeLayout(相对布局)&#xff0c;TableLayout(表格布局)&#xff0c; FrameLayout(帧布局)&#xff0c;AbsoluteLayout(绝对布局)&#xff0c;GridLayout(网格布局) 等。 二、…

Android WMS概览

WMS&#xff08;WindowManagerService&#xff09;是 Android 系统的核心服务&#xff0c;负责管理应用和系统的窗口&#xff0c;包括窗口的创建、销毁、布局、层级管理、输入事件分发以及动画显示等。它通过协调 InputManager 和 SurfaceFlinger 实现触摸事件处理和窗口渲染&a…

C++ 【string】使用及函数

详解 C std::string 是 C 标准库中的一个类&#xff0c;它用于处理字符串数据。它是容器适配器&#xff08;container adapter&#xff09;&#xff0c;基于 basic_stringbuf 和 basic_ostream 类&#xff0c;提供了高效、安全的字符串操作。 以下是 std::string 的一些关键特…

基于的图的异常检测算法OddBall

OddBall异常检测算法出自2010年的论文《OddBall: Spotting Anomalies in Weighted Graphs》&#xff0c;它是一个在加权图(weighted graph)上检测异常点的算法&#xff0c;基本思路为计算每一个点的一度邻域特征&#xff0c;然后在整个图上用这些特征拟合出一个函数&#xff0c…

最新版xAI LLM 模型Grok-2 上线

xAI&#xff01;Grok-2 最新版开启公测&#xff01;”。这是我注册成功的截图&#xff0c;使用国内的邮箱就可以注册使用了&#xff01; Grok API公测与免费体验: Grok API开启公测&#xff0c;提供免费体验128k上下文支持&#xff0c;。Grok-Beta与马斯克: 马斯克庆祝特朗普当…

华为云stack网络服务流量走向

1.同VPC同子网同主机内ECS间互访流量走向 一句话通过主机内部br-int通信 2.同VPC同子网跨主机ECS间互访流量走向 3.同VPC不同子网同主机ECS间互访流量走向 去往本机的mac地址都记录在br-tun流表里 4.同VPC不同子网跨主机ECS间互访流量走向 5.对等连接流量走向&#xff08;跨V…