著名的黑平衡BST——红黑树(Red Black Tree)

设计背景

AVL树通过严格的平衡因子制度来触发自平衡操作,它是一种高度平衡的BST,在数据的查询上有着显著的优势,但在某些场景下,过于频繁的自平衡操作可能会带来多余的时间消耗。
在树领域中还有一种著名的自平衡BST——红黑树(Red Black Tree),它通过特殊的机制来降低自平衡触发的次数,以牺牲平衡性来节省开销,其属于弱平衡的BST。
红黑树是一种综合性能折中的选择,适合增删改查等多重操作发生的情况。
在这里插入图片描述


结构分析

【结构类型】树形结构
【底层实现】Node模型(key+value+左指针+右指针)
【核心方法】
public void add(K key, V value); //向AVL树添加元素
private Node leftRotate(Node y); //左旋转
private Node rightRotate(Node y); //右旋转
private void flipColors(Node node); //颜色翻转
【基本性质】

  1. 每一个节点非黑即红
  2. 整棵树的根节点是黑色的
  3. 所有叶子节点都是黑色的
  4. 如果一个节点是红色的,那么它的两个子节点都是黑色的
  5. 从任意一个节点到叶子节点,所经过的黑色节点数是相等的

平衡策略

本文以左倾红黑树为标准进行举例

1. 左旋转

在这里插入图片描述
代码演示:

// 旋转节点
y.right = x.left;
x.left = y;
// 更新颜色
x.color = y.color;
y.color = RED;

2. 右旋转

在这里插入图片描述

// 右旋转
z.left = x.right;
x.right = z;
// 更新颜色
x.color = z.color;
z.color = RED;

3. 颜色翻转

在这里插入图片描述
代码演示:

x.color = RED;
x.left = BLACK;
x.right = BLACK;

平衡机制

当插入新元素时,将检测是否符合自平衡条件:
在这里插入图片描述
代码演示:

// 如果当前节点为红色,并且当前节点的左子树为黑色,触发左旋转
if (isRed(node.right) && !isRed(node.left)) {
	node = leftRotate(node);
}
// 如果当前节点的左子树为红色,并且当前节点的左子树的左子树也为红色,触发右旋转
if (isRed(node.left) && isRed(node.left.left)) {
	node = rightRotate(node);
}
// 如果当前节点的左右子树均为红色,触发颜色翻转
if (isRed(node.left) && isRed(node.right)) {
	flipColors(node);
}

(附:由于红黑树删除节点的情况十分复杂,其思想也不具备延展性,故本文不涉及删除等其它操作的演示,详细设计可参考《算法导论》或其它博客)

发布了48 篇原创文章 · 获赞 4 · 访问量 6154

猜你喜欢

转载自blog.csdn.net/Knightletter/article/details/103358679
今日推荐