平衡树原理讲解

news/2024/7/23 15:45:21 标签: 数据结构, 算法

平衡树——Treap

文章目录

  • 平衡树——Treap
    • BST
    • 平衡树
      • 左旋、右旋`zag(o)、zig(o)`
        • 左旋
        • 右旋

BST

定义

  1. 空树是二叉搜索树。

  2. 若二叉搜索树的左子树不为空,则其左子树上所有点的附加权值均小于其根节点的值。

  3. 若二叉搜索树的右子树不为空,则其右子树上所有点的附加权值均大于其根节点的值。

  4. 二叉搜索树的左右子树均为二叉搜索树。

性质

二叉搜索树的中序遍历是一个有序序列

操作

插入insert(o, v)

  1. o o o 为空,直接返回一个值为 v v v 的新节点。

  2. o o o 的权值等于 v v v,该节点的附加域该值出现的次数自增 1 1 1

  3. o o o 的权值大于 v v v,在 o o o 的左子树中插入权值为 v v v 的节点。

  4. o o o 的权值小于 v v v,在 o o o 的右子树中插入权值为 v v v 的节点。

删除del(o, v)

先在二叉搜索树中找到权值为 v 的节点,分类讨论如下:

  1. 若该节点的附加 cnt \textit{cnt} cnt 大于 1 1 1,只需要减少 cnt \textit{cnt} cnt

  2. 若该节点的附加 cnt \textit{cnt} cnt 1 1 1

    • o o o 为叶子节点,直接删除该节点即可。

    • o o o 为链节点,即只有一个儿子的节点,返回这个儿子。

    • o o o 有两个非空子节点,一般是用它左子树的最大值或右子树的最小值代替它,然后将它删除。

找前驱 / 后继get_prev(o)、get_next(o)

前(后)驱表示中序遍历中前(后)一个位置,以前驱为例

  1. 存在左子树,则找到左子树中最右边的元素,并返回。
  2. 不存在左子树,找第一个祖先节点中节点 o o o位于其右子树中,返回这个祖先节点

查找最大 / 最小值get_min(o)、get_max(o)

由二叉搜索树的性质可得,二叉搜索树上的最小值为二叉搜索树左链的顶点,最大值为二叉搜索树右链的顶点。

求元素排名get_rank(o)

排名定义为将数组元素排序后第一个相同元素之前的数的个数加一

查找一个元素的排名,首先从根节点跳到这个元素,若向右跳,答案加上左儿子节点个数加当前节点重复的数个数,最后答案加上终点的左儿子子树大小加一。

查找排名为 k k k的元素get_value_by_rank

在一棵子树中,根节点的排名取决于其左子树的大小。

若其左子树的大小大于等于 k k k,则该元素在左子树中;

若其左子树的大小在区间 [ k − cnt , k − 1 ] [k-\textit{cnt},k-1] [kcnt,k1] cnt \textit{cnt} cnt 为当前结点的值的出现次数)中,则该元素为子树的根节点;

若其左子树的大小小于 k − cnt k-\textit{cnt} kcnt,则该元素在右子树中。

平衡树

对于一般的二叉搜索树,有可能退化为链表。想象一棵每个结点只有右孩子的二叉搜索树,那么它的性质就和链表一样,插入与查找时间都是 O ( n ) O(n) O(n)
二叉搜索树的「平衡」概念是指:每一个结点的左子树和右子树高度差最多为 1。

可以对不满足平衡条件的二叉搜索树进行调整,使不平衡的二叉搜索树变得平衡。

调整要保证的标准还有二叉搜索树先天自带的条件:二叉搜索树,按照中序遍历,得到从小到大的结点值序列。对于任意一个结点,左子树各结点的最大值,小于该结点的值;该结点的值,小于右子树各结点的最小值。只有保证这一点才能称为一个二叉搜索树。

左旋、右旋zag(o)、zig(o)

左旋

左旋,左旋也称为「左单旋转」或「RR 平衡旋转」。对于结点 A A A 的左旋操作是指:将 A A A 的右孩子 B B B 向左上旋转,代替 A A A 成为根节点,将 A A A 结点向左下旋转成为 B B B 的左子树的根结点, B B B 的原来的左子树变为 A A A 的右子树。

右旋

右旋,右旋也称为「右单旋转」或「LL 平衡旋转」。对于结点 A A A 的右旋操作是指:将 A A A 的左孩子 B B B 向右上旋转,代替 A A A 成为根节点,将 A A A 结点向右下旋转成为 B B B 的右子树的根结点, B B B 的原来的右子树变为 A A A 的左子树。

在这里插入图片描述


http://www.niftyadmin.cn/n/397513.html

相关文章

VBA中如何调用自定义函数

一、问题提出 在VBA中我要把B列中所有的非空单元格的值都判断一遍,如果大于60就在其旁边的单元格写入"及格",反之就写入不及格。如下图所示: 由于B列的非空单元格数量无法确定,所以我们就要定义一个自定义的函数来获取…

【Ubuntu系统】

在Ubuntu系统中,无论是写文档还是在程序中写注释,都经常需要用到中文输入法。本文简单介绍了三种输入法框架,然后详细介绍了在Ubuntu 20.04系统中,IBus框架和Fcitx框架支持的中文输入法的配置和安装。 一、添加中文语言支持 在安…

系统架构设计师笔记第5期:计算机硬件

计算机硬件是指计算机系统中的物理部分,包括各种电子元件、电路板、外部设备以及其它与计算机相关的实体组件。计算机硬件是支持和实现计算机的数据处理、存储、输入、输出等功能的基本物理组成部分。 计算机硬件包括以下几个主要方面: 中央处理器&…

第二十五章 开发Productions - ObjectScript Productions - 发送请求消息

文章目录 第二十五章 开发Productions - ObjectScript Productions - 发送请求消息发送请求消息使用 SendRequestSync() 方法使用 SendRequestAsync() 方法使用 SendDeferredResponse() 方法每个调用间隔仅处理一个事件 第二十五章 开发Productions - ObjectScript Productions…

chatgpt赋能python:Python圆柱体积计算器:简单、高效、快速解决计算难题

Python圆柱体积计算器:简单、高效、快速解决计算难题 圆柱体积是一个在日常生活、工程学、数学等领域都十分普遍的概念,可以用来计算许多实际问题中的体积,比如容器的容量、建筑材料的用量等等。在本文中,我们将介绍如何使用Pyth…

局部探索测试的要素

局部探索测试的要素 局部探索测试是软件测试过程中的一种方法,旨在发现一个系统、软件或应用程序的局部缺陷和问题。局部探索测试不是全面测试,而是通过对特定功能、模块或环节进行测试来检查其中潜在的缺陷,从而提高软件的质量和可靠性。 局…

我踩过的那些坑,浅谈一下如何更优雅地使用 Linux

前言 相信很多尝鲜过桌面 Linux 系统的朋友,对它一个很深刻的印象就是稳定性差:不知道怎么就把系统搞崩了,又找不到问题的具体原因和解决方法,只能尝试重装,直到心力交瘁地回到了 Windows 或 macOS。但另一方面&#…

Centos7更换OpenSSL版本

OpenSSL 1.1.0 用户应升级至 1.1.0aOpenSSL 1.0.2 用户应升级至 1.0.2iOpenSSL 1.0.1 用户应升级至 1.0.1u 查看openssl版本 openssl version -v选择升级版本 我的版本是OpenSSL 1.0.2系列,所以要升级1.0.2i https://www.openssl.org/source/old/1.0.2/openssl-…