(注:以下图片全部源于《算法 第4版》)

左倾红黑树的原理及简单实现

  • 左倾红黑树的简介
  • 左倾红黑树的定义
  • 左倾红黑树与2-3树的对比
  • 左倾红黑树的颜色表示
  • 左倾红黑树的一些基本操作
    • 1、颜色判断
    • 2、旋转
      • 左旋转
      • 右旋转
    • 3、颜色转换
    • 4、插入
      • 向单个2-结点中插入新键
      • 向树底部的2-结点插入新键
      • 向一棵双键树中插入新键
        • (1) 新键最大
        • (2) 新键最小
        • (3) 新键介于两者之间
  • 左倾红黑树的代码实现

左倾红黑树的简介

左倾红黑树(LLRB)是一种类型的自平衡二叉查找树。它是红黑树的变体,并保证对操作相同渐近的复杂性,但被设计成更容易实现。
由于每一棵红黑树都是一颗二叉排序树,因此,在对红黑树进行查找时,可以采用运用于普通二叉排序树上的查找算法,在查找过程中不需要颜色信息。

左倾红黑树的定义

  • 红链接均为左连接
  • 没有任何一个结点同时和两条红链接相连
  • 该树的任意空链接到根结点的路径上的黑链接数量相同。

左倾红黑树与2-3树的对比


红黑树可以看作成是2-3树的一种表现形式,红链接连接的结点可以看作为是一个3-结点。

左倾红黑树的颜色表示

public class MyRedBlackBST<Key extends Comparable<Key>, Value> {private static class Node<Key, Value> {private Key key;private Value val;private Node<Key, Value> left;private Node<Key, Value> right;private int colour;public Node(Key key, Value val, int colour) {this.key = key;this.val = val;this.colour = colour;}}
}

左倾红黑树的一些基本操作

1、颜色判断

private static final int RED = 0;
private static final int BLACK = 1;private boolean isRed(Node x) {if (x == null) {return false;}return x.colour == RED;
}

2、旋转

左旋转


private Node<Key, Value> rotateLeft(Node<Key, Value> x) {Node<Key, Value> y = x.right;x.right = y.left;y.left = x;y.colour = x.colour;x.colour = RED;return y;
}

右旋转


private Node<Key, Value> rotateRight(Node<Key, Value> x) {Node<Key, Value> y = x.left;x.left = y.right;y.right = x;y.colour = x.colour;x.colour = RED;return y;
}

3、颜色转换

当一个结点左右两个链接均为红色时需要进行颜色转换操作

private void flipColours(Node<Key, Value> x) {x.colour = RED;x.left.colour = BLACK;x.right.colour = BLACK;
}

4、插入

向单个2-结点中插入新键

向树底部的2-结点插入新键

向一棵双键树中插入新键

(1) 新键最大

(2) 新键最小

(3) 新键介于两者之间

左倾红黑树的代码实现

/*** @Author: Victor Gong* @Description: 红黑树的简单实现* @Date: Created in 20:56 2020/12/24*/
public class MyRedBlackBST<Key extends Comparable<Key>, Value> {private static class Node<Key, Value> {private Key key;private Value val;private Node<Key, Value> left;private Node<Key, Value> right;private int colour;public Node(Key key, Value val, int colour) {this.key = key;this.val = val;this.colour = colour;}}private static final int RED = 0;private static final int BLACK = 1;/**** @return 当前结点是否为红色*/private boolean isRed(Node<Key, Value> x) {if (x == null) {return false;}return x.colour == RED;}/*** 左旋转x的右链接*/private Node<Key, Value> rotateLeft(Node<Key, Value> x) {Node<Key, Value> y = x.right;x.right = y.left;y.left = x;y.colour = x.colour;x.colour = RED;return y;}/*** 右旋转x的左链接*/private Node<Key, Value> rotateRight(Node<Key, Value> x) {Node<Key, Value> y = x.left;x.left = y.right;y.right = x;y.colour = x.colour;x.colour = RED;return y;}/*** 当左右指针均为红色时进行颜色转换*/private void flipColours(Node<Key, Value> x) {x.colour = RED;x.left.colour = BLACK;x.right.colour = BLACK;}private Node<Key, Value> root;  //根结点public MyRedBlackBST() {}/*** 存放数据*/public void put(Key key, Value val) {root = put(root, key, val);root.colour = BLACK;    //根结点颜色为黑}private Node<Key, Value> put(Node<Key, Value> x, Key key, Value val) {if (x == null) {return new Node<>(key, val, RED);}int cmp = key.compareTo(x.key);if (cmp < 0) {  //比根结点小x.left = put(x.left, key, val);} else if (cmp > 0) {x.right = put(x.right, key, val);} else {x.val = val;}/*使树保持平衡*///当右侧结点为红色而左侧结点为黑色时,左旋if (isRed(x.right) && !isRed(x.left)) {x = rotateLeft(x);}//当左侧有两个连续的红色时,右旋if (isRed(x.left) && isRed(x.left.left)) {x = rotateRight(x);}//当左右结点均为红色时,颜色变换if (isRed(x.right) && isRed(x.left)) {flipColours(x);}return x;}/*** 获取key对应的值*/public Value get(Key key) {return get(root, key) == null ? null : get(root, key).val;}private Node<Key, Value> get(Node<Key, Value> x, Key key) {if (x == null) {return null;}int cmp = key.compareTo(x.key);if (cmp < 0) {  //比根结点小return get(x.left, key);} else if (cmp > 0) {return get(x.right, key);} else {return x;}}/**** @return 是否包含指定的key*/public boolean containsKey(Key key) {return get(key) != null;}/**** @return 是否包含指定的value*/public boolean containsValue(Value val) {return containsValue(root, val);}private boolean containsValue(Node<Key, Value> x, Value val) {if (x == null) {return false;}if (x.val == val) {return true;}return containsValue(x.left ,val) || containsValue(x.right ,val);}@Overridepublic String toString() {StringBuilder s = new StringBuilder();midOrder(root, s);return s.toString();}/*** 中序遍历*/private void midOrder(Node<Key, Value> x, StringBuilder s) {if (x.left != null) {midOrder(x.left, s);}s.append(x.key + " ");if (x.right != null) {midOrder(x.right, s);}}
}

左倾红黑树的原理及简单实现相关推荐

  1. 从二叉查找树到平衡树:avl, 2-3树,左倾红黑树(含实现代码),传统红黑树...

    参考:自平衡二叉查找树 ,红黑树, 算法:理解红黑树 (英文pdf:红黑树) 目录 自平衡二叉树介绍 avl树 2-3树 LLRBT(Left-leaning red-black tree左倾红黑树 ...

  2. 左倾红黑树的go语言实现

    简介 红黑树经常能在计算机底层代码中见到,比如 C++的map,multimap, set, multiset Linux中rdtree用以管理内存和进程 Java中的HashMap 左倾红黑树是对红 ...

  3. 红黑树进阶—左倾红黑树(LLBR)介绍

    红黑树已经有很长的历史,在许多现代编程语言的符号表中都有使用,但是其缺点也很明显,其代码实现过于繁杂.因此出现的红黑树的修改版--左倾红黑树 左倾红黑树的代码实现相比于典型的红黑树来说要简单不少,但是 ...

  4. 从2-3树谈到左倾红黑树

    2-3树 定义 顾名思义,2-3树,就是有2个儿子或3个儿子的节点.2-3树就是由这些节点构成.所以2-3-4树的每个节点都是下面中的一个: 空节点:空节点. 2-节点:包含一个元素和两个儿子. 3- ...

  5. 左倾红黑树——左倾2-3树(不是jdk1.8的TreeMap的红黑树)

    public class RBTree<K extends Comparable<K>, V> {public static boolean RED = true;public ...

  6. 红黑树结构原理的图文讲解(非代码)

    1.引言 HashMap的基本结构是数组,链表和红黑树.以数组为基本形态,数组中的元素先以链表形式储存,当链表的长度超过8时(包含数组上的那个链表头)就会将链表转换为红黑树,以加快修改和查询效率.当然 ...

  7. 左倾红黑树Go语言实现

    文章目录 左倾红黑树的定义 红黑树性质 Node数据结构 旋转 插入 颜色转换 删除 实现 Keys Contains DeleteMin.DeleteMax Rank.Get Ceil Floor ...

  8. 数据结构——左倾红黑树

    左倾红黑树 前提了解 红黑树和平衡多叉树的对应关系 左倾红黑树 基于自顶向下2-3-4树的左倾红黑树 基于2-3树的左倾红黑树 重要代码 左右旋转变色 翻转变色 向2-3左倾红黑树插入 向2-3-4左 ...

  9. 左倾红黑树(LLRBT)删除操作及相关性质总结答疑

    Left-leaning Red Black Tree 看算法4(算法 第4版 Algorithms 4th Edition)3.4节时,后面的习题有实现左倾红黑树删除操作的代码,刚开始看得云里雾里的 ...

最新文章

  1. ASP条件语句之IF语句
  2. oracle中聚合比较函数,Oracle聚合函数/分析函数
  3. 《Docker——容器与容器云》:第一章 从容器到容器云
  4. w8计算机配置要求,win8系统最低配置要求有哪些|win8系统是否有最低配置要求-系统城...
  5. Ubuntu18.04上安装RTX 2080Ti显卡驱动
  6. MyBatisPlus_查询篇_入门试炼_01
  7. HDFS +zookeeper实现高可用
  8. xvidcore-1.3.2\xvidcore\dshow 工程编译
  9. java 点云数据处理_点云数据处理学习笔记
  10. 1252 :[蓝桥杯2015初赛]奇妙的数字 C/C++
  11. 在ArcGIS中ArcCatalog(Arcmap)快速选中多个要素
  12. 抖音短视频去水印方法 2018短视频伪原创
  13. 311、FirebaseAnalytics和Google Analytics总结
  14. json发送数据加密方法_发送加密的电子邮件和安全邮件的最佳免费方法
  15. 【2】SCI易中期刊推荐——遥感图像领域(中科院2区)
  16. php正则怎么用,php正则及常用正则函数怎么用
  17. 如何完美解决catia出现-运行异常,单击“确定终止”-问题
  18. 微软工程院 硕士_微软工程院招聘NLP算法研究员实习生|NLP算法工程师实习生_北京实习招聘...
  19. VS编译运行时出现exe文件无法打开的原因
  20. java有哪些注解_JAVA常用注解

热门文章

  1. 生物蛋白质数据库类型【总结】
  2. 谷歌浏览器无法打开localhost:3000,打开localhost就跳转测试地址问题
  3. android课程设计致谢,课程设计致谢老师
  4. Linux系统中普通用户输入命令后出现“不在sudoers文件中,此事将被报告”的问题
  5. 20款精美APP和Web设计模板素材(附演示链接)
  6. 十进制如何转化成二进制c语言,c语言怎么将十进制转化成二进制
  7. 天池- IJCAI-18 阿里妈妈搜索广告转化预测新手入门经历(一:数据预处理、特征工程)
  8. 范登堡(van den berg)CPT使用记录
  9. ubuntu护眼第二大神器 Redshift
  10. win7计算机各硬盘显示容量,Win7系统磁盘分区不显示容量怎么设置