一. 红黑树的定义
- 1.每个节点或者是红色的,或者是黑色的
- 2.根节点是黑色的(一棵空树也是红黑树)。
- 3.每个叶子节点(最后的空节点)是黑色的,定义空节点都是黑色的。
- 4.如果一个节点是红色的,那么他的孩子节点都是黑色的。
- 5.从任意一个节点到叶子节点,经过的黑色节点是一样的。
学习红黑树之前,必须先学2-3树
二. 2-3树
学习2-3树,不仅对于理解红黑树有帮助,对于B树的数据结构也有帮助。
- 2-3 树满足二分搜索树的基本性质,2-3树不是二叉树。
- 节点可以存放一个元素活着2个元素。
- 2-3树是一颗绝对平衡的树:任何一个节点左右子树的高度一定是相同的。
如何维护2-3的平衡
三. 红黑树和2-3树的等价性
红黑树是保持“黑”平衡的二叉树,严格意义上,不是平衡二叉树,最大高度为2logN O(logN)
AVL的高度logN. 比AVL树的高度高,查询的时候比AVL慢一点. 如果只查询的时候,AVL快一点。
五. 红黑树添加新元素
2-3树中添加一个新元素: 或者添加晋2-节点,形成3-节点,或者添加进3-节点,暂时形成一个4-节点。
永远添加红色节点。然后维护红黑树。
添加节点之后,保持最终根节点的颜色为黑色。
红黑树的左旋转 、右旋转、颜色翻转
红黑树的添加
总结的流程如下:维护的时机和AVL树一样,添加节点后回溯向上维护。
六. 红黑树的Java简单实现
package com.mk.coffee.test.dataStructure.redblackTree;
/**
* 红黑树 《算法导论》:
* <p>
* 1.每个节点或者是红色的,或者是黑色的
* 2.根节点是黑色的(一棵空树也是红黑树)。
* 3.每个叶子节点(最后的空节点)是黑色的,定义空节点都是黑色的。
* 4.如果一个节点是红色的,那么他的孩子节点都是黑色的。连接的可能2/3节点,都是黑色的。
* 5.从任意一个节点到叶子节点,经过的黑色节点是一样的。(2-3树绝对平衡,经过的节点个数相同)
* 黑色节点的右孩子节点一定是黑色的。
* <p>
* 《算法4》 红黑树的发明人 Robert Sedgewick 是 Donald Knuth的学生。
* <p>
* 红黑树与 2-3 树的等价性
* 理解2-3树和红黑树之间的关系。
* 红色节点都是左孩子
* 红黑树是保持"黑平衡"的二叉树,严格意义来说不是平衡二叉树。
* 节点数 为N,最大高度2logN,O(logN)
* 红黑树比AVL 查找慢一点 ,红黑树2logN, AVLlogN
* <p>
* 添加的情况下,RBT好 AVL 28S RBT20S
* 查询的情况下:AVL好
* <p>
* Java java.util.中的 TreeMap 和 TreeSet 基于红黑树
* 红黑树的其他实现。
* 总结:
* 对于完全随机的数据,普通的二分搜索树就很好用!
* 确定:极端的情况退化成链表(或者高度不平衡)
* 对于查询较多的情况下,AVL树很好用!
* 红黑树牺牲了平衡性(2logN的高度)
* 统计性能更优(综合增删改查所有的操作,平均性能,红黑树性能最高)
* <p>
* <p>
* 更多的问提
* <p>
* <p>
* 伸展树Splay Tree:局部性原理: 刚被访问的内容下次高概率被再次访问。
*
* @author makui
* @date 2020/03/26
*/
public class RedBlackTree<K extends Comparable<K>, V> {
//RED BLACk 代表红黑色
private static final boolean RED = true;
private static final boolean BLACK = false;
private class Node {
public K key;
public V value;
public Node left, right;
public boolean color;
public Node(K key, V value) {
this.key = key;
this.value = value;
this.left = null;
this