首页 > 其他分享 >平衡二叉搜索树

平衡二叉搜索树

时间:2024-09-26 18:15:28浏览次数:9  
标签:左子 右子 二叉 搜索 二叉树 平衡 节点

PART 0:引子

二叉树想必大家都很熟悉,它在编程中具有很广泛的应用,而二叉树又分为很多种,这里介绍的了两种二叉树和一种他们的结合体。

PART 1:二叉搜索树

二叉搜索树的定义

二叉搜索树要求任意一个节点的左子节点小于它,右子节点大于它。

如图

在二叉搜索树上查找的时间复杂度相比线性结构一般要快一些,但是它有可能退化为链表,那样的话就和线性结构并无二致了。当然,这不是我们在这里要解决的问题。

二叉搜索树的查找

由于二叉搜索树的节点有一定顺序,查找起来其实非常方便,可以用递归实现:

//这里用的是int类型,运用时根据实际需求可以改变
int find(Node x,int key){
    //在以x为根结点的子树中查找并返回键key所对应的值
    //如果找不到,就返回null
    if(x==null) return null;
    if(key<x.key) return find(x.left,key);
    else if(key>x.left) return find(x.right,key);
    else return x.value;
}

下面用一个动图给大家演示一下在这个二叉搜索树里查找32的过程

最大值与最小值

根据二叉搜索树的定义,最大值就是最右端的节点,而最小值就是最左端的节点,只需要从根节点一直往右或往左走就行了。

二叉搜索树的插入

插入和查找其实很相似,只需要在树上查找要插入的元素的值,如果树上已经有了该元素,则不必插入,如果没有,那么终止的位置就是要插入的位置

Node insert(Node x,int key,int value){
    //如果key存在于以x为根节点的子树中则更新它的值;
    //如果不在就创建新节点插入到合适的位置;
    if(x==null) return new Node(key,value);
    if(key<x.key) x.left=insert(x.left,key,value);
    else if(key>x.key) x.right=insert(x.right,key,value);
    else x.value=value;
    return x;
}

如图:

二叉搜索树的删除

删除分为三种情况:

1. 要删除的节点没有子节点

直接删,不用管。

如图,我们要删除 \(27\)

2. 要删除的节点只有一个子节点

将它父亲指向它的指针修改为指向它的子节点,然后删除它。

如图,我们要删除 \(50\)

3. 要删除的节点有多个子节点

这是最麻烦的一种情况,有两种做法,取它左子树上最大的点或右子树上最小的点来代替它。

如图,我们要删除节点 \(20\),这里取的是右子树上最小的点

PART 2:平衡二叉树

平衡二叉树的定义

平衡二叉树要求任意一个节点的左子树和右子树的高度差小于等于 \(1\),当然,也可以是空树

如图,这就是一个平衡二叉树

平衡因子

在上图中,我们在每一个节点上都标记了一个数字,这就是平衡二叉树的平衡因子。

平衡因子就是是某节点的左子树和右子树的高度差。在平衡二叉树中,平衡因子只能为 \(0,1,-1\) 这三者之一,否则就不满足平衡二叉树的定义。

如图,下面是平衡因子的三种情况的图示

平衡二叉树的调整

上面介绍了平衡二叉树,那么如果一颗二叉树不是平衡二叉树,我们应该怎么将其调整为平衡二叉树呢?

这里有四种调整情方法,对应四种不合法的情况:

左单旋(RR)

如图,这是一颗平衡二叉树

在这棵树上插入节点99,得到的树如下所示

这样的话,这棵树就失去了平衡,因此我们要将他调整为一颗平衡树,
由于右子树高于左子树,所以我们将这颗树逆时针旋转,流程如下:

1. 节点的右子节点替代此节点位置

2. 右子节点的左子树变为该节点的右子树

3. 节点本身变为右子节点的左子树

这样,这棵树就又恢复了平衡。

这种情况是在节点的右子节点的右侧插入节点,因此又称为 RR。

右单旋(LL)

右单旋的情况与左单旋类似,操作流程如下:

1. 节点的左子节点代表此节点

2. 节点的左子节点的右子树变为节点的左子树

3. 将此节点作为子节点节点的右子树。

这种情况是在节点的左子节点的左侧插入节点,因此又称为 LL。

先左旋,再右旋(LR)

若 \(A\) 的左孩子节点 \(B\) 的右子树 \(E\) 插入节点 \(F\),导致节点 \(A\) 失衡,如图:

这个时候,仅仅一次旋转无法将其转化为平衡树,需要两步操作:

1. 对失衡节点 \(A\) 的左子节点 \(B\) 进行左旋

2. 对失衡节点 \(A\) 进行右旋

经过这两步操作,使得树恢复了平衡,同时原来根节点的左子节点的右子节点 \(E\) 成为了新的根节点。

先右旋,再左旋(RL)

与上面类似,在右子节点的左子树上插入节点也需要两部操作:

1. 对失衡节点 \(A\) 的右子节点 \(C\) 进行右旋

2. 对失衡节点 \(A\) 进行左旋

经过这两步操作,使得树恢复了平衡,同时原来根节点的右子节点左子节点 \(D\) 成为了新的根节点。

PART 3:二叉搜索平衡树

还记得上文中提到的二叉搜索树退化的事吗,退化成链后,二叉树相比于线性结构就没有任何的优势了,这个时候就要推出我们的二叉搜索平衡树。什么意思呢,就是使二叉搜索树满足平衡树的条件,这样的话可以防止它的退化,一旦有退化的趋势,就可以通过旋转将其再次变为平衡树。实际上,在平衡树的状态下,二叉搜索树的时间复杂度应该是最优的,是 \(O(\log n)\)。

对于平衡二叉树的操作,其实在上面两个部分已经分开讲完了,这里不再赘述。

标签:左子,右子,二叉,搜索,二叉树,平衡,节点
From: https://www.cnblogs.com/NightTide/p/18434016

相关文章

  • 信息学奥赛复赛复习04-CSP-J2019-04-加工零件-位运算、整数映射0或1、结构体、初始化
    PDF文档公众号回复关键字:2024092612019CSP-J题目4加工零件[题目描述]凯凯的工厂正在有条不紊地生产一种神奇的零件,神奇的零件的生产过程自然也很神奇。工厂里有n位工人,工人们从1∼n编号。某些工人之间存在双向的零件传送带。保证每两名工人之间最多只存在一条传送带......
  • 搜索技术汇总
    搜索效率谷歌>公众号>短视频>百度Google搜索指令B站讲解最详细的GOOGLE搜索指令大全谷歌搜索技巧大全|谷歌高级搜索语法指令(上)谷歌搜索技巧大全|谷歌高级搜索语法指令(下)关键词搜索("")在想要搜索的内容上加上英文双引号"",关键词信息完整出现,搜索结果更加精准。......
  • [Python手撕]判断二叉搜索树
    #Definitionforabinarytreenode.#classTreeNode:#def__init__(self,val=0,left=None,right=None):#self.val=val#self.left=left#self.right=rightclassSolution:defisValidBST(self,root:Optional[TreeNod......
  • 2024.9.25 Python,单词替换,优美的排列 II,sort的用法前K个高频单词,广度优先搜索腐烂的橘
    1.单词替换在英语中,我们有一个叫做词根(root)的概念,可以词根后面添加其他一些词组成另一个较长的单词——我们称这个词为衍生词(derivative)。例如,词根help,跟随着继承词“ful”,可以形成新的单词“helpful”。现在,给定一个由许多词根组成的词典dictionary和......
  • uniapp - 详解安卓App打包后使用uni.chooseLocation地址列表一直加载转圈问题,Android
    前言网上的教程都无法解决问题,本文提供强力解决方案。在uni-app安卓App平台端开发中,详解uniApp打包成Android安卓后用chooseLocation打开地图选择位置空白卡住不动问题,选择地址列表什么也没有且一直处于加载状态(永远不会加载出来卡住了),另外点击搜索框后也无法搜索地点......
  • BST-二叉搜索树
    g#前言从图的角度出发,树是一种特殊的图。图的大多数算法,树都可以适用。对树操作中,你可以发现有关图算法思想的体现。不过,本篇不是完全从图的角度解读树,重点在初学者视角(一般学习数据结构顺序是从树开始的,包括笔者也是如此,但是笔者后续学习离散数学和图的算法回顾树......
  • 区间质数搜索——埃拉托斯特尼筛法和欧拉筛法
    参考资料【中国大学生计算机设计大赛国赛二等奖微课与教学辅助《埃拉托斯特尼筛法》】【中国大学生计算机设计大赛《素数筛选—欧拉线性筛选法详解》】Eratosthenes筛法-CSDN博客【算法/数论】欧拉筛法详解:过程详述、正确性证明、复杂度证明-CSDN博客水平有限,欢迎交流!练习题......
  • 时序预测 | Matlab实现SSA-TCN麻雀搜索算法优化时间卷积网络时序预测-递归预测未来数
    时序预测|Matlab实现SSA-TCN麻雀搜索算法优化时间卷积网络时序预测-递归预测未来数据(单输入单输出)目录时序预测|Matlab实现SSA-TCN麻雀搜索算法优化时间卷积网络时序预测-递归预测未来数据(单输入单输出)预测效果基本介绍程序设计参考资料预测效果基本介绍1.Matlab实现SSA-TCN......
  • SimpleAISearch:C# + DuckDuckGo 实现简单的AI搜索
    SimpleAISearch:C#+DuckDuckGo实现简单的AI搜索 合集-C#(79)  最近AI搜索很火爆,有Perplexity、秘塔AI、MindSearch、Perplexica、memfree、khoj等等。在使用大语言模型的过程中,或许你也遇到了这种局限,就是无法获取网上最新的信息,导致回答的内容不是基于最新的信......
  • 推荐3款卓越的 .NET 开源搜索组件库
    推荐3款卓越的.NET开源搜索组件库 思维导航前言Elasticsearch.NETLucene.NETSolrNet优秀项目和框架精选前言最近有不少同学提问;.NET有哪些开源的搜索组件库可以推荐的吗?,今天大姚给大家推荐3款卓越的.NET开源搜索组件库,希望可以帮助到有需要的同学。Elasti......