刚看到韩顺平老师的数据结构与算法对于平衡二叉树的讲解(最后会附上地址),有如下理解,希望能帮助大家!哪里需要改正的欢迎指正!

平衡二叉树:一种二叉排序树(BST Binary Sort Tree)的升级,传统的二叉排序树容易形成类似链表的结构,造成平均查询次数较高,所以引入平衡二叉树,使得左右子树的高度差不超过1;
我们知道了平衡二叉树的原理之后,就要在添加结点后就要判断是否需要将此树转化成平衡二叉树!如下例:4,3,5,2,1,0
如图,当添加到1这个结点的时候,4的左子树高为2,4的右子树高为0。 两者高度差为2,此时这棵树不是平衡二叉树,那么就需要将其转换成平衡二叉树(先按照这个例子来进行,下面会说明其他情况):具体操作如下:
先将必要类和方法写出:

class Node{int value;Node left;Node right;public Node(int value) {super();this.value = value;}//添加结点public void add(Node node) {if(node==null) {System.out.println("此结点为空,不可添加");    return;}if(this.value>node.value) {if(this.left==null) {this.left=node;}else {this.left.add(node);}}else {if(this.right==null) {this.right=node;}else {this.right.add(node);}}}@Overridepublic String toString() {return "Node [value=" + value + "]";}//中序遍历public void infixOrder() {if(this.left!=null) {this.left.infixOrder();}System.out.println(this);if(this.right!=null) {this.right.infixOrder();}}
}

同时:我们还要写计算左子树高和右子树高的方法!这个方法可以帮助我们判断当添加数据之后是否需要进行转化。

 //计算左子树的高度public int leftHeigh() {if(left==null) {return 0;}return left.height();}//计算右子树的高度public int rightHeigh() {if(right==null) {return 0;}return right.height();}//计算结点的树高度public int height() {return Math.max(left==null ? 0 : left.height(), right==null?0:right.height())+1;}

当有了这些方法之后就可以进行转换了:举韩老师在课堂上的例子4,3,6,5,7,8
当我们添加完8后,发现不满足平衡二叉树的条件了,就需要对其进行操作使其转化成平衡二叉树,这里的操作叫做左旋(当然还有右旋,双旋,放到后面来讲那些例子)!
操作如下:将其分为两步,很简单就是赋值的两步操作;
第一步.创建新节点,
新结点的值=当前结点的值(也就是4);
新结点的左节点=当前节点的左节点(3)
新结点的右节点=当前结点的右结点的左节点(5)
第二步.修改当前节点
当前结点的值=当前节点的右节点
当前节点的右子树=当前节点的右子树的右子树
当前节点的左子树=新结点

这里第一步的操作实质上可以理解成,将上面三个点记录下来,作为第二步当前结点的右节点
第二步的操作为:将当前节点的值修改成6,并将当前节点的左右结点修改,如图,到此,转化过程就到此结束了,(这里的白色6因为没有被任何的GC roots指向,将会被回收)
左旋的代码

 public void leftRotate() {//创建新节点Node node=new Node(this.value);//对新结点进行操作node.left=this.left;node.right=this.right.left;//修改当前节点this.value=this.right.value;this.right=this.right.right;this.left=node;}

在add方法加上左旋转的代码

     if(this.rightHeigh()-this.leftHeigh()>1) {this.leftRotate();}

右旋

其实右旋和左旋的操作相似,举个例子10,12,8,9,7,6
当添加6后,发现需要调整,调整的操作也为两步
第一步.创建新节点,
新结点的值=当前结点的值(也就是10);
新结点的右节点=当前节点的右节点(12)
新结点的左节点=当前结点的左结点的右节点(9)
第二步.修改当前节点
当前结点的值=当前节点的左节点的值(8)
当前节点的左子树=当前节点的左子树的左子树
当前节点的右子树=新结点

右旋方法

 //右旋转public void rightRotate() {//创建新节点Node node = new Node(this.value);//操作新节点node.left=this.left.right;node.right=this.right;//修改当前节点this.value=this.right.value;this.left=this.left.left;this.right=node;}

在add方法添上如下代码

     if(this.leftHeigh()-this.rightHeigh()>1) {this.rightRotate();}

双旋

但是当我们遇到这样的情况该怎么办呢?
如:左子树高>右子树---->采用右旋(但是当前节点的左子树的左子树高>它的左子树的右子树)
举例:10,7,11,6,8,9
7的左子树高(1)<右子树高(2)

我们发现直接右旋无法将其转化成平衡二叉树!
解决办法:
当我们发现:7的左子树高(1)<右子树高(2),先对7进行左旋,将其转化成左子树高>右子树高的形式,操作步骤如下图,
先将左子树(7)进行左旋之后,我们就可以直接将整棵树进行右旋了!
小结一下:当发现整个树需要右旋的时候,我们要先判断对于它的左子树,是否存在 它的左子树的左子树高<它的左子树的右子树高的情况,若存在,则需要先对左子树进行左旋!再对其进行右旋!

对于整棵树要先左旋的情况,我们要先判断对于它的右子树,是否存在 它的左=右子树的左子树高>它的左=右子树的右子树高的情况,若存在,则需要先对左子树进行右旋!再对整棵树进行左旋!
对add进行调整修改

     //左子树高>右子树高===>右旋转if(this.leftHeigh()-this.rightHeigh()>1) {if(this.left!=null&&this.left.leftHeigh()<this.left.rightHeigh()) {this.left.leftRotate();}this.rightRotate();}//右子树高》左子树高---》左旋转if(this.rightHeigh()-this.leftHeigh()>1) {if(this.right!=null&&this.right.leftHeigh()>this.right.rightHeigh()) {this.right.rightRotate();}this.leftRotate();}

至此,对于左旋,右旋,双旋的情况进行了详细的分析!建议大家在纸上画一下左旋右旋的示意图,希望对大家有帮助!
韩顺平老师数据结构与算法连接:
https://www.bilibili.com/video/BV1E4411H73v?p=135

搞懂平衡二叉树的左旋右旋双旋(Java实现)相关推荐

  1. 平衡二叉树的左旋右旋详解 看不懂你打我

    平衡二叉树的左旋右旋 看不懂你打我 左旋右旋的操作 为什么要左旋右旋 左旋右旋能保持排序二叉排序树的性质吗 下次写平衡二叉树的LL.RR.LR.RL. 左旋右旋的操作 1.左旋:对X节点左旋,即以X的 ...

  2. avl树左旋右旋的理解

    一直没搞懂非平衡二叉树变平衡二叉树时左旋右旋,今天下定决心搞懂,然后在众多博客中终于找到了这样一篇,非常形象,记录如下: AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大 ...

  3. 左旋右旋问题一次搞定!!!

    左旋右旋问题的解决 编程思想 1.在左右旋函数中实现该函数功能首先要想好如何存放移位后的字符元素 2.左旋时将字符串首元素赋给临时变量tmp而后将字符串元素依次前移一位 3.将tmp的值再赋给字符串的 ...

  4. nyoj202 红黑树 (二叉树的左旋右旋)

    题目202 题目信息 运行结果 本题排行 讨论区 红黑树 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 什么是红黑树呢?顾名思义,跟枣树类似,红黑树是一种叶子是黑色果子 ...

  5. 二叉树旋转--左旋|右旋

    二叉树旋转 二叉树的旋转主要是应用在AVL树中,当添加一个节点时候导致左右两个子树的高度差不在是-1 , 1 , 0而变成了2 或者-2.此时就需要用到左旋/右旋了.当然左右旋或者有左旋也是基于左旋和 ...

  6. HashMap 数据结构之红黑树, 红黑树在什么时候左旋 右旋 如何旋转

    树结构是数据结构中最经典最常用的结构之一,也是面试中常问的面试题,最近学习了一下红黑树的知识,记录整理一下 文章目录 一.红黑树的特征 二.变色左旋和右旋 1.变色规则 2.左旋 3.右旋 总结 前言 ...

  7. 字符串左旋右旋——三步旋转法和移相法

    题目:实现一个函数,可以左旋字符串中的k个字符. AABCD左旋一个字符得到ABCDA AABCD左旋两个字符得到BCDAA 方法一:三步旋转法 左旋程序思路:首先根据画图得知左旋后的结果,然后在分析 ...

  8. 详解红黑树之左旋右旋

    为什么要左旋右旋? 为了使得左右子树的高度差在一定范围内,需要通过旋转调整,这样就可以保持平稳的搜索效率 左旋: 步骤 1.设原来E的父节点是father,那么左旋之后需要改变的是: 2.S和fath ...

  9. 字符串的左旋右旋问题(C语言实现,三种方法求解)

    字符串左旋右旋问题其实是同理的,下边以左旋为例: 方法一 思路:左旋一次就是将整个字符串向左移一个字符,第一个字符(arr[0])移动到最右侧.这样循环操作左旋次数就是最终左旋结果,如上图所示. 实现 ...

最新文章

  1. “AI”战疫在行动,一文盘点百度大脑增援疫情防控的AI操作
  2. 继承单例模式 php_详解PHP单例模式之继承碰见的问题
  3. Fatal Error[Pe1696]:cannot open source file “sys.h”
  4. N - Dragon Balls(并查集+深度的意义
  5. 图文并茂: 二进制与十进制间的转换方法
  6. Tokenizers: How machines read
  7. 创建IPSEC连接安全
  8. css sgc加密,ASP+SGC实现柱状图
  9. fat32源码c语言,FAT32文件系统基本原理与数据恢复编程
  10. 十二星座物语,女生最喜欢的星座性格【1】
  11. 数据管理能力成熟度DCMM-简介
  12. 蓝桥杯练习题十四 - 次数差(c++)
  13. wordpress友联_WordPress快速添加友情链接
  14. python opencv 剪切图片
  15. jQuery中的end()的定义与用法
  16. PbS包覆钙钛矿量子点;PbS包覆CsPbI3量子点的透射电镜图和高分辨透射电子显微镜图像和光致发光光谱图齐岳生物
  17. web前端期末大作业 HTML+CSS+JavaScript---介绍自己的家乡-宁夏js菜单下拉
  18. sony z5p卸载垃圾程序脚本
  19. 你应该知道的SQL中常用函数
  20. android--相机开发

热门文章

  1. 自定义View:仿抖音直播点赞效果
  2. oracle ebs gfm加载页,EBS附件下载 fnd_gfm fnd_lobs
  3. linux opencv打开图片路径,OpenCV读取图像_显示图像_保存图像
  4. 学习DesignJava
  5. 夸女人的JAVA代码_Java是一个事业成功的女人
  6. PCA(主成分分析)与FA(因子分析)的直白理解
  7. 解决homebrew install卡住问题
  8. 音、视频编码格式介绍
  9. 搭建kafka消息队列服务
  10. logstash中Ruby代码把@timestamp时间戳格式转换