首页 > 其他分享 >4月23日AVL树的插入实现

4月23日AVL树的插入实现

时间:2023-04-23 23:33:39浏览次数:32  
标签:结点 parent 23 旋转 AVL 插入 查找 平衡 节点

在计算机的使用中查找是个很重要的算法,但是一般的简单查找算法效率都不高,其中比较显著的方法是二分查找,但是二分查找的局限性很大,他只能在有序的数组中进行查找,所以想要用二分查找就必须先要对查找的数据进行排序,但是排序的时间复杂度又是一个问题。所以就提出了用树形的储存方式去存放数据排序和查找。

二叉搜索树将存入的数据以特定的顺序存储,将大的数以迭代的方式存在结点的右边将小的数存在左边,这样不仅在查找时时间复杂度与二分查找持平而且中序遍历这棵树还能得到所有数据的升序序列。但是二叉搜索树还有一个缺点,这个缺点与快速排序的缺点有点像,就是快速排序再排有序的数据时会严重退化,时间复杂会变成O(n2)搜索二叉树也是这样子,再不断存入有序数据时会不断加大树的深度,是树的结构严重不平衡,以至于查找时时间复杂度变为O(n).所以就有了二叉平衡搜索树也叫AVL树。

AVL树:他是高度平衡的二叉搜索树,他的所有左右树的根节点的最大深度相差不会超过一,实现了无论什么情况下查找的时间复杂度都与二分查找相同,且不需要提前排序。

 

首先是结点的数据结点模型:节点中包含左右子树根节点的指针,键值对,与二叉搜索树不同的是又新增了双亲结点的指针,和一个平衡因子。双亲结点的作用是用来调节平衡因子的,平衡因子的作用是用来检测树的平衡度。

 

1:首先判段根节点是否为空的情况,若不为空定义一个cur用来迭代定位要插入的位置,再定义一个结点指针parent用来记录cur的双亲。

 

2:不断迭代cur直至其为空,再用构造函数把cur构造了,然后将cur连接到树的特定位置。

 

3:此时就要用到parent了,用while循环判断parent不为空则向上更新每个结点的平衡因子,若cur是parent的右孩子这此结点的平衡因子加一,若为左则减一。

 

4:每次跟新完平衡因子后若平衡因子为零则表示,之前此结点为-1或1,被调节为零不影响整个树的平衡,此时退出循环。若为-1或1则树的变化在可接受范围之内,不用进行调节,但是还是要向上更新,因为上面可能还会有变化,若为-2或者2则需要进行旋转调节。

 

 

5:旋转调节分为左旋转和右旋转,和右左旋转和左右旋转四种。

1>:左单旋转:将根节点称为parent将根节点的左子树成为subL,首先将subL的右子树结点与parent的左子树链接,然后判断这个结点是否为空,若为空则不需要考虑空结点的双亲结点,若不为空则需要将其双亲结点设为parent.此时还要考虑sub和parent,若parent是根节点则不需要考虑sub的双亲结点,直接将根节点设为sub,将sub的双亲结点设为空即可,若不为根节点则需要先用Pparent将parent的双亲结点保存,然后将parent的双亲结点设为sub,ran然后将根据parent的位置将sub与Pparent链接。然后更新parent的结点和sub的结点的平衡因子为0,此时左单旋就结束了。

 2>:右单旋:右单旋与左单旋大致相似但是方向不一样。

 

左右单旋的情况是,parent结点的平衡因子为2且sub的结点平衡因子为1且符号与parent相同,就是说树的平衡严重偏向一边,需要用到单旋调节,而若是平衡不是偏得很严重,就用双旋处理。就是子树的平衡偏转与其根节点的平衡偏向不一样。

3>:右左双旋:顾名思义先右旋转在左旋转,对其parent的右子树进行一次右旋转,然后对其parent结点进行一次左旋转,因为右左旋转有两种情况所以需要根据情况来判断其中每个参与旋转的节点的平衡因子的更新情况。左右旋转同理。

 

 需要注意的一点是判断插入位置平衡因子的BFmark需要提前保存,不然会影响判断。

标签:结点,parent,23,旋转,AVL,插入,查找,平衡,节点
From: https://www.cnblogs.com/qjwxlj/p/17348123.html

相关文章

  • 2023.04.23
    组合计数选讲CandyRetributionSource:JapaneseStudentChampionship2019QualificationFBeautifulBracketSequence(hardversion)Source:CodeforcesContest1264D2......
  • 2023 4 23
    #include<iostream>#include<string>usingnamespacestd;classshape{public:virtualvoidsetvalues(floata,floatb)=0;virtualfloatarea()=0;};classrectangle:publicshape{private:floatlength,width;public:voidsetvalu......
  • 4.23日站立会议
      ......
  • 2023/4/23每周一记
    getcap提权,redis-cli写码,docker提权,备份提权当我们需要将本地8080端口映射到远程服务器上的80端口时,可以使用以下命令:ssh-L8080:localhost:80user@remote此时只需要访问neo4j初始化验证账号密码时,需要关闭网页翻译插件,否则会报错redis-cli写马configsetdir/vat/www......
  • 2023.16 后端技术
    让notionAI写一篇后端技术发展报告,它生成的内容如下:随着互联网和移动设备的普及,后端技术得到了迅速发展。本报告将介绍后端技术的发展历程和当前的趋势。发展历程1.传统LAMP架构早期互联网时代,后端技术以LAMP架构为主流。LAMP架构指的是Linux、Apache、MySQL和PHP,这些技术的组合......
  • 4、23
    明天月考了,今晚复习学校内容补一下昨天的收获:1)学会高斯消元2)学会Lucas定理3)看懂博弈论里Nim游戏4)多重背包:二进制分组优化要点:1、不要当成二进制拆分intv,w,s; v=read(),w=read(),s=read(); intk=0; thingnow={v,w}; while(s) { if(s&1) { ......
  • 每日会议20230423
    进度汇报:吕金帅:张博文:赵纪旭:正在努力完成小程序购物车的登录界面的编写和小程序购物车结算功能模拟的编写; 具体目标:完成数据库表的创建;完成小程序购物车的登录界面的编写和小程序购物车结算功能模拟的编写;......
  • 2023-04-23 算法面试中常见的动态规划问题
    动态规划1什么是动态规划以菲波那切数列求和为例,通过1.普通的递归2.引入记忆数组memo3.自下而上地解决问题,即动态规划动态规划的定义dynamicprogramming(alsoknownasdynamicoptimization)isamethodforsolvingacomplexproblembybreakingitdowninto......
  • 2022.4.23编程一小时打卡
    一、问题描述:定义一个基类,派生出子类,基类有fn1(),fn2(),fn1()是虚函数;子类也有这俩个函数,在主函数中声明子类的一个对象,并通过指针调用这俩个函数。观察程序运行过程。二、解题思路:首先,定义一个基类BaseClass类,其派生出子类DerivedClass类,在主函数中定义基类的指针,调用这俩个函......
  • 总结20230423
    代码时间(包括上课):3h代码量(行):100行博客数量(篇):1篇相关事项:1、完成了数据库实验报告一。2、正在努力完成小程序购物车的登录功能。3、正在努力完成小程序模拟支付的功能。......