平衡二叉树

  • 平衡二叉树(Java) -- 左旋旋右旋旋
    • 平衡二叉树 -- 代码

平衡二叉树(Java) – 左旋旋右旋旋

  平衡二叉树全称平衡二叉搜索树,所以首先具备了二叉搜索树的特性,因为二叉搜索树并未对树的高做限制,只要求了左小右大,这就可能再极端情况下,出现左斜树或右斜树,这是查找就从O(logn)的期望退化成了O(n),即使不那么极端,树的高度也是没办法控制在一个稳定值上,这就使得当数据量庞大时,查找耗时过多;这就产生了如何对一棵树进行优化,使其高度稳定,这就首先需要对树的高度进行获取和记录,通过左旋和右旋使二叉搜索树达到平衡,也就是使各节点左子树和右子树的高度差不超过1,这样的查找时间复杂度就能稳定在O(logn)级别;
  因为二叉搜索树中形成不平衡的情况有很多种,所以旋转方式有4种,分别是左单旋,右单旋,左右双旋,右左双旋,而左右双旋其实就是先右旋然后左旋,右左双旋就是先左旋然后右旋;还有就是左单旋与右单旋对称,左右双旋与右左双旋对称~~

平衡二叉树 – 代码

  平衡二叉树在进行插入和删除时都可能使二叉搜索树中某节点上的左右子树高度不平衡(高度差大于1),所以在进行插入和删除操作时为了维护平衡二叉树的属性,就需要获取受影响节点的左右子树的高度,当高度差大于1时(因为一直在维护,所以高度差最大为2)~~
  在转转转部分是维持平衡二叉树高度的主要方法,如果不用这些方法就是一个二叉搜索树~~

/*** 平衡二叉树
**/
public class AVLTree<Key extends Comparable<Key>, Data> {private Node root;private int size;public AVLTree() {root = null;size = 0;}/*** 功能方法*/// 定位方法,找到需要进行操作的节点,然后根据各中不同的需求进行操作private Node goLocate(Node node, Key key) {if(node == null) return null;if(key.compareTo(node.key) == 0) return node;else if(key.compareTo(node.key) > 0) return goLocate(node.right,key);else return goLocate(node.left,key);}// 计算左右分支高度差private Indicator checkHeight(Node reporter) {int lHeight = getHeight(reporter.left);int rHeight = getHeight(reporter.right);if(lHeight - rHeight > 1) {return Indicator.LRED;} else if(lHeight - rHeight < -1) {return Indicator.RRED;}return Indicator.GREEN;}// 插入方法public void insert(Key key, Data data) {// 注意:这里让root=,就是为了当root为空时设定根节点,否则群龙无首root = goInsert(root,key,data);}// 插入实现方法public Node goInsert(Node node, Key key, Data data) {if(node == null) {size++;return new Node(key,data);}// 键值已存在,直接更新数据if(key.compareTo(node.key) == 0) {node.data = data;return node;}// 插入的节点在左子树,可能需要旋的情况是右旋或左右旋else if(key.compareTo(node.key) < 0) {node.left = goInsert(node.left, key, data);Indicator indicator = checkHeight(node);// 若插入节点在左子树的左子树,则进行右旋;若在左子树的右子树,则进行左右旋if (indicator == Indicator.LRED) {if (key.compareTo(node.left.key) < 0) {// 注意:这里node=,是必须的,否则会断了连接,因为转完后,当前子树的老大已经换人,// 返回去的节点自然需要是新老大,如果是旧老大,相当于丢了一整条支路node = singleRightTurn(node);} else if(indicator == Indicator.RRED) {node = doubleLeftRightTurn(node);}}} else {node.right = goInsert(node.right, key, data);Indicator indicator = checkHeight(node);// 若插入节点在右子树的右子树,则进行左旋;若在右子树的左子树,则进行右左旋if (indicator == Indicator.LRED) {if (key.compareTo(node.left.key) < 0) {node = singleLeftTurn(node);} else if(indicator == Indicator.RRED) {node = doubleRightLeftTurn(node);}}}return node;}public Data getData(Key key) {assert size != 0;return goLocate(root,key).data;}public boolean isExisted(Key key) {return goLocate(root,key) != null;}public boolean isEmpty() {return size == 0;}public int count() {return size;}/*** 转转转,使深度平衡主要实现的四个实现方法*/// 左单旋,适用:右边延长三个节点一条线,第一个节点为reporter,相较于其哥们节点,其小弟节点为+1深度,其小小节点为+2深度private Node singleLeftTurn(Node reporter) {Node newBoss = reporter.right;// 原老大reporter到新老大newBoss左边去了,原来新老大左边部分要到原老大右边去reporter.right = newBoss.left;newBoss.left = reporter;return newBoss;}// 右单旋,适用:左边延长三个节点一条线,第一个节点为reporter,相较于其哥们节点,其小弟节点为+1深度,其小小节点为+2深度private Node singleRightTurn(Node reporter) {Node newBoss = reporter.left;reporter.left = newBoss.right;newBoss.right = reporter;return newBoss;}// 左右双旋,先左旋再右旋;适用:右单旋的情况下,其小小弟改为在右边private Node doubleLeftRightTurn(Node reporter) {reporter.left = singleLeftTurn(reporter.left);return singleRightTurn(reporter);}// 右左双旋,先右旋再左旋;适用:左单旋的情况下,其小小弟改为在左边private Node doubleRightLeftTurn(Node reporter) {reporter.right = singleRightTurn(reporter.right);return singleLeftTurn(reporter);}/*** 指示灯,用于指示高度是否超过规定*/enum Indicator {LRED, RRED, GREEN}/*** 高度获取*/// 获取当前子树的高度private int getHeight(Node node) {if(node == null)return 0;return Math.max(getHeight(node.left), getHeight(node.right)) + 1;}/*** 节点内部类*/private class Node {private Key key;private Data data;private Node left, right;public Node(Key key, Data data) {this.key = key;this.data = data;left = right = null;}}
}

平衡二叉树(Java) -- 左旋旋右旋旋相关推荐

  1. 图示讲解AVL平衡二叉树的左旋和右旋

    AVLTree 高度平衡的搜索二叉树 一棵平衡树,或是空树,或是具有以下性质的二叉搜索树:左子树和右子树都是AVL树,且左右子树的高度之差的绝对值不超过1. 该二叉树,根结点的右子树高度为3,左子树高 ...

  2. 平衡二叉树的左旋和右旋

    文章目录 复习树 1. 树的概念 2. 二叉树(Binary Tree) 3. 满二叉树 4. 完全二叉树 5. 二叉堆 6. 二叉搜索树 左旋和右旋 7. 平衡二叉树(平衡二叉搜索树) 本文章是我的 ...

  3. 平衡搜索树中的左单旋右单旋双旋

    本文要点: 平衡搜索树的左单旋.右单旋.左右双旋.右左双旋 在平衡搜索树中进行插入结点时,有可能会破坏整棵树的平衡.为了保证平衡不被破坏,就要对一些节点进行旋转,从而来降低树的高度,这样也能保证树的平 ...

  4. 平衡二叉树AVL左旋,右旋,双旋——java

    概念分析 平衡二叉树也叫平衡二叉搜索树,又被称为AVL树,它能保证查询效率较高 他具有以下特点:它是一颗空树或者它的左右两颗子树的高度差的绝对值不大于一,并且左右子树都是平衡二叉树,其也满足二叉排序树 ...

  5. [ 数据结构 ] 平衡二叉树(AVL)--------左旋、右旋、双旋

    0 引出 数列{1,2,3,4,5,6},要求创建一颗二叉排序树(BST), 并分析问题所在 回顾:二叉搜索树 左子树全部为空,从形式上看,更像一个单链表. 插入速度没有影响 查询速度明显降低(因为需 ...

  6. 平衡二叉树(C++) -- 左旋旋右旋旋

    平衡二叉树 平衡二叉树(C++) -- 左旋旋右旋旋 平衡二叉树 -- 左单旋 平衡二叉树 -- 右单旋 平衡二叉树 -- 左右双旋 平衡二叉树 -- 右左双旋 平衡二叉树 -- 插入和删除实现 平衡 ...

  7. Java 平衡二叉树之单旋(左旋,右旋)与双旋

    1.平衡二叉树 平衡二叉树也叫平衡二叉搜索树(Self-balancing binary search tree)又被称为AVL树, 可以保证查询效率较高. 具有以下特点:它是一 棵空树或它的左右两个 ...

  8. 搞懂平衡二叉树的左旋右旋双旋(Java实现)

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

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

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

最新文章

  1. 一款NPN三极管测量: BC547C
  2. 分布式 WebSocket 集群解决方案
  3. Zedboard学习(七):VGA显示
  4. Redis的List操作
  5. Java程序员:不要因未知而让云成本大涨
  6. java转文件编码bom_编码转换:UTF-8 BOM to GBK
  7. 谈谈JAVA工程狮面试中经常遇到的面试题目------什么是MVC设计模式
  8. fastapi 传输文件存文件_揭秘|国内影视文件传输的真相,跨境文件传输更不简单...
  9. HttpModule的认识
  10. AsyncTask实现登录功能,上传图片,get,post
  11. 第四章 生命周期函数--36 结合Node手写JSONP服务器剖析JSONP原理
  12. HTML全面深入学习-用label获得焦点
  13. multisim红绿灯元器件在哪里_实验一:Multisim交通灯仿真.ppt
  14. IDEA Auto build completed with errors解决办法
  15. 我为什么鼓励工程师写博客
  16. 美国3D理发师可剪出球星脸发型
  17. 关于Java中Match类的appendReplacement()方法的一个坑{ character to be escaped }
  18. iptables下udp穿越结尾篇----iptables与socks5
  19. 书籍特别推荐:2018-06薛兆丰经济学讲义+魔鬼经济学(四本)
  20. 如何有效防止系统邮件被视为垃圾邮件

热门文章

  1. 用机顶盒或网络电视机实现监控摄像头预览,完成简单的录相机功能,用机顶盒远程观看摄像头,多个监控可以同时观看,实时观看,也可以用机顶盒或网络电视观看局域网内的监控画面
  2. 抖音创始人张一鸣:10 年面试 2000 人,我发现混的好的人,全都有同一个特质...
  3. MacOS深色模式访达窗口依然是浅色
  4. 宝,运维100+服务器很头疼怎么办?用行云管家!
  5. 苹果cms如何添加播放器预加载和缓冲广告
  6. 《深度学习推荐系统》学习笔记(5)——Embedding(论文)
  7. html如何做滑动门效果,JS+CSS实现简单滑动门(滑动菜单)效果
  8. TensorFlow实战——CNN(VGGNet19)——图像风格转化
  9. 如何启用计算机双通道内存的方法,双通道内存 你会正确使用吗?
  10. java-PDF读取一页某一区域内容