public class RBTree<K extends Comparable<K>, V> {public static boolean RED = true;public static boolean BLACK = false;public Node root;class Node {K key;V val;Node left, right;boolean color;int size;//高度
Node(K key, V val, boolean color, int size) {this.key = key;this.val = val;this.color = color;this.size = size;}public String toString() {return "(K:" + key + " V:" + val + " 色:" + (color==true?"红":"黑") + " s:" + size+ " 左:" + left + " 右:" + right +")";}}public RBTree() {}public boolean isRed(Node x) {if (null == x)return false;//null是黑色return x.color == RED;}public int size(Node x) {if (x == null)return 0;return x.size;}public int size() {return size(root);}public boolean isEmpty() {return root == null;}public V get(K key) {if (key == null)throw new IllegalArgumentException();return get(root, key);}public V get(Node n, K key) {while (n != null) {if (key.compareTo(n.key) == 0)return n.val;else if (key.compareTo(n.key) < 0)n = n.left;elsen = n.right;}return null;}private Node rotateLeft(Node h) {Node x = h.right;h.right = x.left;//节点重挂x.left = h;//旋转x.color = x.left.color;x.left.color = RED;x.size = h.size;h.size = size(h.left) + size(h.right) + 1;return x;}private Node rotateRight(Node h) {//h.left和h.left.left是红色就右旋转h,Node x = h.left;h.left = x.right;//节点重挂x.right = h;//旋转x.color = x.right.color;x.right.color = RED;x.size = h.size;h.size = size(h.left) + size(h.right) + 1;return x;}private void flipColors(Node h) {// 颜色翻转h.color = !h.color;h.left.color = !h.left.color;h.right.color = !h.right.color;}public void put(K key, V val) throws Exception {if (key == null || val == null)throw new Exception();root = put(root, key, val);root.color = BLACK;}//红黑树调整是从下到上,比较路上的所有节点,依次调整,不在比较路上的节点不用调整,调整时候看的也只是左右2个子节点。private Node put(Node h, K key, V val) {//递归看形参,进去时候依次是5.0 4.0 3.0 2.0 1.0,出来时候是反过来的,依次是1.0搞完然后2.0搞完然后3.0搞完然后4.0然后5.0。if (h == null)return new Node(key, val, RED, 1);int cmp = key.compareTo(h.key);// key < h.keyif (cmp < 0) {// 放到h的左边,返回新的h的左边,因为有可能会翻转什么的,所以返回新的左节点。h.left = put(h.left, key, val);} else if (cmp > 0) {// 放到h的右边,返回新的h的右边,h.right = put(h.right, key, val);} else {h.val = val;}//每次给h增加左节点或者右节点之后,都要调整节点h。递归从下到上依次调整。if (isRed(h.right) && !isRed(h.left))// h的右节点红色,左节点是null或者黑色。节点的右边不能是红色(性质)。h = rotateLeft(h);if (isRed(h.left) && isRed(h.left.left))h = rotateRight(h);if (isRed(h.left) && isRed(h.right))flipColors(h);h.size = size(h.left) + size(h.right) + 1;return h;}public int getHeight() {return getHeight(root);}private int getHeight(Node p) {// 递归:一个函数里面依赖包含另一个函数。if (p == null)return 0;return Math.max(getHeight(p.left), getHeight(p.right)) + 1;}@SuppressWarnings("unchecked")public static void main(String[] args) throws Exception {RBTree rb = new RBTree();rb.put(5.0, 5.00);rb.put(4.0, 4.00);rb.put(3.0, 3.00);rb.put(3.5, 3.50);rb.put(2.9, 2.90);rb.put(3.6, 3.60);rb.put(3.55, 3.550);}
}

左倾红黑树的另一种定义是满足下列条件的二叉查找树:

  1. 红链接均为左链接。
  2. 没有两条红链接相连。
  3. 任意空链接到根结点的路径上的黑链接数量相同。

2-3树规定,2节点为黑色,3节点小红大黑,并且父节点链接的是大黑节点。小红在大黑的坐下,中间值节点在小红的右边。

2-3树规定了红黑树最终的样子和颜色,但是中间的旋转和变色过程   是通过2-3树的变换过程推到出来的,规则如下:

红黑树就是用红链接表示 3-结点的 2-3 树

那么红黑树的插入、构造就可转化为 2-3 树的问题,即:在脑中用 2-3 树来操作,得到结果,再把结果中的 3-结点转化为红链接即可。

而 2-3 树的插入,前面已有详细图文,实际也很简单:有空则插,没空硬插,再分裂。 这样,我们就不用记那么复杂且让人头疼的红黑树插入旋转的各种情况了。只要清楚 2-3 树的插入方式即可。

2-3树:2个子节点或者3个子节点。

2-3树是平衡的3路查找树,其中2(2-node)是指拥有两个分支的节点,3(3-node)是指拥有三个分支的节点。B-树是一种平衡的多路查找树,2-3树属于b-树,其也同样具有B-树的性质,如m阶B-树,节点至多有m个分支、m-1个关键字;内部节点的分支数至少为m/2取上限;所有叶节点都出现在同一层次上,并且不带任何信息(这是由构造树的逻辑决定的,实际上指向这些节点的引用为null)。

2-3查找树的定义如下:

1. 要么为空,要么:

2 对于2节点,该节点保存一个key及对应value,以及两个指向左右节点的节点,左节点也是一个2-3节点,所有的值都比key要小,有节点也是一个2-3节点,所有的值比key要大。

1. 对于3节点,该节点保存两个key及对应value,以及三个指向左中右的节点。左节点也是一个2-3节点,所有的值均比两个key中的最小的key还要小;中间节点也是一个2-3节点,中间节点的key值在两个跟节点key值之间;右节点也是一个2-3节点,节点的所有key值比两个key中的最大的key还要大。

3个子节点根节点就有2个元素,2个子节点根就有一个元素。

永远都是在叶节点处插入新节点,当3-node变为4-node时,需要拆分节点,此时树高就有可能增加

删除节点比插入节点麻烦一些,先来看删除底部节点,在搜索过程中就需要对节点做相应的变化,以保证搜索路径上的都是3-node或临时的4-node,在删除当前节点TT一定是3-node4-node,就可以安全删除了,删除之后树的变化规则与插入一致。删除其他节点可以转化为删除底部节点,只需要将删除元素与底部节点元素交换即可。

2-3树作为一种平衡查找树,查询效率比普通的二叉排序树要稳定许多,其操作逻辑也非常清晰。2-3树可以采用红黑树实现,使用二叉树结构从逻辑上模拟了2-3树,在插入删除节点时,又具有二叉平衡树的便利。

B-tree树即B树,B即Balanced,平衡的意思。因为B树的原英文名称为B-tree,

转载于:https://www.cnblogs.com/yaowen/p/11142701.html

左倾红黑树——左倾2-3树(不是jdk1.8的TreeMap的红黑树)相关推荐

  1. B树,B+树,红黑树应用场景AVL树,红黑树,B树,B+树,Trie树

    B B+运用在file system database这类持续存储结构,同样能保持lon(n)的插入与查询,也需要额外的平衡调节.像mysql的数据库定义是可以指定B+ 索引还是hash索引. C++ ...

  2. 为什么HashMap使用红黑树而不使用AVL树

    在Jdk1.8版本后,Java对HashMap做了改进,在链表长度大于8的时候,将后面的数据存在红黑树中,以加快检索速度. 那么很多人就有疑问为什么是使用红黑树而不是AVL树,AVL树是完全平衡二叉树 ...

  3. 【爬树合集】难啃的骨头——红黑树

    [爬树合集]难啃的骨头--红黑树 写在前面 红黑树应用: 1.红黑树在Linux非实时任务调度中的应用 2.红黑树在Linux虚拟内存中的应用 3.红黑树在检测树的平衡性上的应用 4.epoll在内核 ...

  4. 遍历HashMap源码——红黑树原理、HashMap红黑树实现与反树型化(三)

    本章将是HashMap源码的最后一章,将介绍红黑树及其实现,HashMap的remove方法与反树型化.长文预警~~ 遍历HashMap源码--红黑树原理.HashMap红黑树实现与反树型化 什么是红 ...

  5. 面试题:为什么用红黑树不用普通的AVL树

    在Jdk1.8版本后,Java对HashMap做了改进,在链表长度大于8的时候,将后面的数据由链表改为了存在红黑树中,以加快检索速度. 有疑问为什么是使用红黑树而不是AVL树,AVL树是完全平衡二叉树 ...

  6. java map 红黑树_Java集合-TreeMap和红黑树

    TreeMap是一种通过实现了红黑树数据结构的Map集合. [图片有英文注释的均摘抄于国外文章] 首先,先来看一些基础概念. 1. 二叉排序树 二叉排序树的定义和性质: (1)若左子树不空,则左子树上 ...

  7. 【红黑树】都这样讲了,不会还有人不会红黑树吧

    文章目录 1. 简介红黑树 and 红黑树的性质 2. 在红黑树中操作元素 2.1 在红黑树中查找一个元素 2.2 在红黑树中插入元素 3. 手撕红黑树 4. 通过总体聊聊AVL树和红黑树 1. 简介 ...

  8. 通过TreeMap理解红黑树

    本文以Java TreeMap为例,从源代码层面,结合详细的图解,剥茧抽丝地讲解红黑树(Red-Black tree)的插入,删除以及由此产生的调整过程. 总体介绍 Java TreeMap实现了So ...

  9. 那个丧心病狂的红蓝眼睛逻辑问题推理:第N天有N个红眼睛自杀,还是什么都不会发生?

    题目设定是这样的,一个岛上有100个人,其中有5个红眼睛,95个蓝眼睛.这个岛有三个奇怪的宗教规则. 1. 他们不能照镜子,不能看自己眼睛的颜色.  2. 他们不能告诉别人对方的眼睛是什么颜色.  3 ...

最新文章

  1. Blender 2.9中的真实感三维产品全流程制作学习教程
  2. linux下vsftp
  3. JS魔法堂:判断节点位置关系
  4. 并发编程-02并发基础CPU多级缓存和Java内存模型JMM
  5. ssh协议是tcp还是udp_DNS 支持 TCP 和 UDP 双协议,但为何偏偏只钟情 UDP?
  6. linux之errno值为104(connetction reset by peer)
  7. c 语言生成json 文件,如何用c语言反序列化JSON文件#
  8. 在Mybatis中处理sql中的大于号小于号
  9. python-scrapy框架学习笔记
  10. 192B Walking in the Rain
  11. Linux下MariaDB 安装及root密码设置(修改)
  12. js 闭包与垃圾回收-待删
  13. 基于Web的MIS系统环境配置和相关含义(拷贝版)
  14. Hyperledger fabric 链码容器是一直运行的吗
  15. 修改mysql root 账号密码
  16. python3内建排序函数:sorted()详解
  17. 如何控制积分成本?常见的积分成本的核算方法
  18. vue-awesome-swiper滑动失效的问题解决方案
  19. XMind2020介绍、下载
  20. xz压缩解压工具的安装

热门文章

  1. java接口的一些理解(未完待续)
  2. 近年现场比赛补题(From 2013 to 2018)[持续更新]
  3. 2021-08-15 minikube在阿里云centos系统上的安装实践
  4. java创建对象的五种方式
  5. 喂,你要多吃点含乳酸菌的食品
  6. openstack-Keystone 服务部署基于centos 7
  7. Summed-area table
  8. 网络营销的手段有哪些?(二)
  9. 【STM32】使用STM32cubeMX的库读写FLASH数据
  10. Unity 你以为SetParent()是个很简单的API???!!