左倾红黑树的原理及简单实现
(注:以下图片全部源于《算法 第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);}}
}
左倾红黑树的原理及简单实现相关推荐
- 从二叉查找树到平衡树:avl, 2-3树,左倾红黑树(含实现代码),传统红黑树...
参考:自平衡二叉查找树 ,红黑树, 算法:理解红黑树 (英文pdf:红黑树) 目录 自平衡二叉树介绍 avl树 2-3树 LLRBT(Left-leaning red-black tree左倾红黑树 ...
- 左倾红黑树的go语言实现
简介 红黑树经常能在计算机底层代码中见到,比如 C++的map,multimap, set, multiset Linux中rdtree用以管理内存和进程 Java中的HashMap 左倾红黑树是对红 ...
- 红黑树进阶—左倾红黑树(LLBR)介绍
红黑树已经有很长的历史,在许多现代编程语言的符号表中都有使用,但是其缺点也很明显,其代码实现过于繁杂.因此出现的红黑树的修改版--左倾红黑树 左倾红黑树的代码实现相比于典型的红黑树来说要简单不少,但是 ...
- 从2-3树谈到左倾红黑树
2-3树 定义 顾名思义,2-3树,就是有2个儿子或3个儿子的节点.2-3树就是由这些节点构成.所以2-3-4树的每个节点都是下面中的一个: 空节点:空节点. 2-节点:包含一个元素和两个儿子. 3- ...
- 左倾红黑树——左倾2-3树(不是jdk1.8的TreeMap的红黑树)
public class RBTree<K extends Comparable<K>, V> {public static boolean RED = true;public ...
- 红黑树结构原理的图文讲解(非代码)
1.引言 HashMap的基本结构是数组,链表和红黑树.以数组为基本形态,数组中的元素先以链表形式储存,当链表的长度超过8时(包含数组上的那个链表头)就会将链表转换为红黑树,以加快修改和查询效率.当然 ...
- 左倾红黑树Go语言实现
文章目录 左倾红黑树的定义 红黑树性质 Node数据结构 旋转 插入 颜色转换 删除 实现 Keys Contains DeleteMin.DeleteMax Rank.Get Ceil Floor ...
- 数据结构——左倾红黑树
左倾红黑树 前提了解 红黑树和平衡多叉树的对应关系 左倾红黑树 基于自顶向下2-3-4树的左倾红黑树 基于2-3树的左倾红黑树 重要代码 左右旋转变色 翻转变色 向2-3左倾红黑树插入 向2-3-4左 ...
- 左倾红黑树(LLRBT)删除操作及相关性质总结答疑
Left-leaning Red Black Tree 看算法4(算法 第4版 Algorithms 4th Edition)3.4节时,后面的习题有实现左倾红黑树删除操作的代码,刚开始看得云里雾里的 ...
最新文章
- ASP条件语句之IF语句
- oracle中聚合比较函数,Oracle聚合函数/分析函数
- 《Docker——容器与容器云》:第一章 从容器到容器云
- w8计算机配置要求,win8系统最低配置要求有哪些|win8系统是否有最低配置要求-系统城...
- Ubuntu18.04上安装RTX 2080Ti显卡驱动
- MyBatisPlus_查询篇_入门试炼_01
- HDFS +zookeeper实现高可用
- xvidcore-1.3.2\xvidcore\dshow 工程编译
- java 点云数据处理_点云数据处理学习笔记
- 1252 :[蓝桥杯2015初赛]奇妙的数字 C/C++
- 在ArcGIS中ArcCatalog(Arcmap)快速选中多个要素
- 抖音短视频去水印方法 2018短视频伪原创
- 311、FirebaseAnalytics和Google Analytics总结
- json发送数据加密方法_发送加密的电子邮件和安全邮件的最佳免费方法
- 【2】SCI易中期刊推荐——遥感图像领域(中科院2区)
- php正则怎么用,php正则及常用正则函数怎么用
- 如何完美解决catia出现-运行异常,单击“确定终止”-问题
- 微软工程院 硕士_微软工程院招聘NLP算法研究员实习生|NLP算法工程师实习生_北京实习招聘...
- VS编译运行时出现exe文件无法打开的原因
- java有哪些注解_JAVA常用注解
热门文章
- 生物蛋白质数据库类型【总结】
- 谷歌浏览器无法打开localhost:3000,打开localhost就跳转测试地址问题
- android课程设计致谢,课程设计致谢老师
- Linux系统中普通用户输入命令后出现“不在sudoers文件中,此事将被报告”的问题
- 20款精美APP和Web设计模板素材(附演示链接)
- 十进制如何转化成二进制c语言,c语言怎么将十进制转化成二进制
- 天池- IJCAI-18 阿里妈妈搜索广告转化预测新手入门经历(一:数据预处理、特征工程)
- 范登堡(van den berg)CPT使用记录
- ubuntu护眼第二大神器 Redshift
- win7计算机各硬盘显示容量,Win7系统磁盘分区不显示容量怎么设置