红黑树是一种自平衡的二叉查找树,是在普通的二叉查找树的基础上增加了一些限制和规则,使得它能够自我调整来保持平衡。它的作用主要有以下几个方面:
查找和插入元素的时间复杂度都是O(logN),其中N为树中节点的个数,因此红黑树可以高效地进行查找和插入操作。
在很多需要动态维护有序序列数据结构的场景中,红黑树可以非常高效地实现这个目标。
红黑树还可以用于高效地实现区间查询等数据结构,比如线段树。在这种场景下,红黑树作为线段树的底层数据结构,能够提升线段树查询、更新的效率。
总之,红黑树是一种非常有用的数据结构,其自平衡特性使得它具有高效的查找和插入等操作,因此被广泛应用于数据处理和算法实现的领域。
左旋是将当前节点往左旋转的操作。具体步骤如下:
- 将当前节点的右子节点(称为y)设为当前节点(称为x)的父节点。
- 将y的左子节点设为x的右子节点。
- 如果y的左子节点非空,将x设为y的左子节点的父节点。
- 将y的左子节点设为x。
- 将y的父节点设为原本x的父节点。
- 如果原本x的父节点为空,则将y设为红黑树的根节点;否则,如果x是其父节点的左子节点,则将y设为其父节点的左子节点;否则,将y设为其父节点的右子节点。
左旋是将当前节点往左旋转的操作。具体步骤如下:
- 将当前节点的右子节点(称为y)设为当前节点(称为x)的父节点。
- 将y的左子节点设为x的右子节点。
- 如果y的左子节点非空,将x设为y的左子节点的父节点。
- 将y的左子节点设为x。
- 将y的父节点设为原本x的父节点。
- 如果原本x的父节点为空,则将y设为红黑树的根节点;否则,如果x是其父节点的左子节点,则将y设为其父节点的左子节点;否则,将y设为其父节点的右子节点。
左右旋的作用:
通过左旋和右旋操作可以改变节点之间的位置关系,从而保持红黑树的平衡性。这两个操作在插入或删除节点时经常被用到,以确保红黑树的性质得到维护和恢复。
插入操作:
- 首先根据传入的键值创建一个新节点,并将其颜色设置为红色。
- 通过比较键值大小,将新节点插入到正确的位置上,确保满足二叉查找树的性质。
- 调用修复插入操作来保证红黑树的性质:
- 如果插入节点的父节点是黑色节点,那么不需要进行调整,红黑树的性质没有被破坏。
- 如果插入节点的父节点是红色节点,那么可能会破坏红黑树的性质,需要进行相应的调整。
修复插入操作: 在红黑树中,有三种情况需要进行调整,分别是:插入节点的父节点是红色的情况下,叔节点是红色的情况下,和插入节点的父节点是红色且叔节点是黑色的情况下。调整的目标是使得插入节点的父节点是黑色,叔节点和祖父节点是红色,保持红黑树的性质。
- 左旋转和右旋转:通过旋转操作来调整节点的位置,使得红黑树保持平衡。
- 颜色翻转:通过改变节点的颜色来维护红黑树的性质。
插入操作:
- 首先根据传入的键值创建一个新节点,并将其颜色设置为红色。
- 通过比较键值大小,将新节点插入到正确的位置上,确保满足二叉查找树的性质。
- 调用修复插入操作来保证红黑树的性质:
- 如果插入节点的父节点是黑色节点,那么不需要进行调整,红黑树的性质没有被破坏。
- 如果插入节点的父节点是红色节点,那么可能会破坏红黑树的性质,需要进行相应的调整。
修复删除操作: 删除节点可能会破坏红黑树的性质,需要进行相应的调整。
- 如果删除的节点是红色的,不会影响红黑树的性质,直接删除即可。
- 如果删除的节点是黑色的,可能会导致红黑树的性质被破坏,需要进行相应的修复。修复的目标是保持每个节点到其后代叶节点的黑色节点数量相同。
// 红黑树节点类
class RBNode {
int data;
RBNode parent;
RBNode left;
RBNode right;
int color;
public RBNode(int data) {
this.data = data;
this.parent = null;
this.left = null;
this.right = null;
this.color = 1; // 默认节点为红色
}
}
// 红黑树类
class RedBlackTree {
private RBNode root;
public RedBlackTree() {
root = null;
}
}
// 左旋操作
private void leftRotate(RBNode x) {
RBNode y = x.right;
x.right = y.left;
if (y.left != null) {
y.left.parent = x;
}
y.parent = x.parent;
if (x.parent == null) {
root = y;
} else if (x == x.parent.left) {
x.parent.left = y;
} else {
x.parent.right = y;
}
y.left = x;
x.parent = y;
}
// 右旋操作
private void rightRotate(RBNode y) {
RBNode x = y.left;
y.left = x.right;
if (x.right != null) {
x.right.parent = y;
}
x.parent = y.parent;
if (y.parent == null) {
root = x;
} else if (y == y.parent.left) {
y.parent.left = x;
} else {
y.parent.right = x;
}
x.right = y;
y.parent = x;
}
// 插入节点
public void insert(int key) {
RBNode newNode = new RBNode(key);
RBNode current = root;
RBNode parent = null;
while (current != null) {
parent = current;
if (key < current.data) {
current = current.left;
} else {
current = current.right;
}
}
newNode.parent = parent;
if (parent == null) {
root = newNode;
} else if (key < parent.data) {
parent.left = newNode;
} else {
parent.right = newNode;
}
// 调整红黑树
fixInsert(newNode);
}
// 插入后修正红黑树平衡性
private void fixInsert(RBNode node) {
while (node.parent != null && node.parent.color == 1) {
// 当前节点的父节点是祖父节点的左子节点
if (node.parent == node.parent.parent.left) {
RBNode uncle = node.parent.parent.right;
// Case 1: 叔叔节点是红色
if (uncle != null && uncle.color == 1) {
node.parent.color = 0;
uncle.color = 0;
node.parent.parent.color = 1;
node = node.parent.parent;
} else {
// Case 2: 叔叔节点是黑色,且当前节点是右子节点
if (node == node.parent.right) {
node = node.parent;
leftRotate(node);
}
// Case 3: 叔叔节点是黑色,且当前节点是左子节点
node.parent.color = 0;
node.parent.parent.color = 1;
rightRotate(node.parent.parent);
}
} else {
// 当前节点的父节点是祖父节点的右子节点
RBNode uncle = node.parent.parent.left;
// Case 1: 叔叔节点是红色
if (uncle != null && uncle.color == 1) {
node.parent.color = 0;
uncle.color = 0;
node.parent.parent.color = 1;
node = node.parent.parent;
} else {
// Case 2: 叔叔节点是黑色,且当前节点是左子节点
if (node == node.parent.left) {
node = node.parent;
rightRotate(node);
}
// Case 3: 叔叔节点是黑色,且当前节点是右子节点
node.parent.color = 0;
node.parent.parent.color = 1;
leftRotate(node.parent.parent);
}
}
}
root.color = 0;
}
// 删除节点
public void delete(int key) {
RBNode z = search(key);
if (z == null) {
return;
}
RBNode x, y;
if (z.left == null || z.right == null) {
y = z;
} else {
y = successor(z);
}
if (y.left != null) {
x = y.left;
} else {
x = y.right;
}
if (x != null) {
x.parent = y.parent;
}
if (y.parent == null) {
root = x;
} else if (y == y.parent.left) {
y.parent.left = x;
} else {
y.parent.right = x;
}
if (y != z) {
z.data = y.data;
}
if (y.color == 0) {
fixDelete(x);
}
}
// 查找节点
public RBNode search(int key) {
RBNode current = root;
while (current != null && current.data != key) {
if (key < current.data) {
current = current.left;
} else {
current = current.right;
}
}
return current;
}
// 查找后继节点
private RBNode successor(RBNode x) {
if (x.right != null) {
RBNode current = x.right;
while (current.left != null) {
current = current.left;
}
return current;
} else {
RBNode y = x.parent;
while (y != null && x == y.right) {
x = y;
y = y.parent;
}
return y;
}
}
// 删除节点后修正红黑树平衡性
private void fixDelete(RBNode node) {
while (node != root && node.color == 0) {
if (node == node.parent.left) {
RBNode brother = node.parent.right;
if (brother.color == 1) {
brother.color = 0;
node.parent.color = 1;
leftRotate(node.parent);
brother = node.parent.right;
}
if (brother.left.color == 0 && brother.right.color == 0) {
brother.color = 1;
node = node.parent;
} else {
if (brother.right.color == 0) {
brother.left.color = 0;
brother.color = 1;
rightRotate(brother);
brother = node.parent.right;
}
brother.color = node.parent.color;
node.parent.color = 0;
brother.right.color = 0;
leftRotate(node.parent);
node = root;
}
} else {
RBNode brother = node.parent.left;
if (brother.color == 1) {
brother.color = 0;
node.parent.color = 1;
rightRotate(node.parent);
brother = node.parent.left;
}
if (brother.right.color == 0 && brother.left.color == 0) {
brother.color = 1;
node = node.parent;
} else {
if (brother.left.color == 0) {
brother.right.color = 0;
brother.color = 1;
leftRotate(brother);
brother = node.parent.left;
}
brother.color = node.parent.color;
node.parent.color = 0;
brother.left.color = 0;
rightRotate(node.parent);
node = root;
}
}
}
node.color = 0;
}
// 红黑树节点类
class RBNode {
int data;
RBNode parent;
RBNode left;
RBNode right;
int color;
public RBNode(int data) {
this.data = data;
this.parent = null;
this.left = null;
this.right = null;
this.color = 1; // 默认节点为红色
}
}
// 红黑树类
class RedBlackTree {
private RBNode root;
public RedBlackTree() {
root = null;
}
// 左旋操作
private void leftRotate(RBNode x) {
RBNode y = x.right;
x.right = y.left;
if (y.left != null) {
y.left.parent = x;
}
y.parent = x.parent;
if (x.parent == null) {
root = y;
} else if (x == x.parent.left) {
x.parent.left = y;
} else {
x.parent.right = y;
}
y.left = x;
x.parent = y;
}
// 右旋操作
private void rightRotate(RBNode y) {
RBNode x = y.left;
y.left = x.right;
if (x.right != null) {
x.right.parent = y;
}
x.parent = y.parent;
if (y.parent == null) {
root = x;
} else if (y == y.parent.left) {
y.parent.left = x;
} else {
y.parent.right = x;
}
x.right = y;
y.parent = x;
}
// 插入节点
public void insert(int key) {
RBNode newNode = new RBNode(key);
RBNode current = root;
RBNode parent = null;
while (current != null) {
parent = current;
if (key < current.data) {
current = current.left;
} else {
current = current.right;
}
}
newNode.parent = parent;
if (parent == null) {
root = newNode;
} else if (key < parent.data) {
parent.left = newNode;
} else {
parent.right = newNode;
}
// 调整红黑树
fixInsert(newNode);
}
// 插入后修正红黑树平衡性
private void fixInsert(RBNode node) {
while (node.parent != null && node.parent.color == 1) {
// 当前节点的父节点是祖父节点的左子节点
if (node.parent == node.parent.parent.left) {
RBNode uncle = node.parent.parent.right;
// Case 1: 叔叔节点是红色
if (uncle != null && uncle.color == 1) {
node.parent.color = 0;
uncle.color = 0;
node.parent.parent.color = 1;
node = node.parent.parent;
} else {
// Case 2: 叔叔节点是黑色,且当前节点是右子节点
if (node == node.parent.right) {
node = node.parent;
leftRotate(node);
}
// Case 3: 叔叔节点是黑色,且当前节点是左子节点
node.parent.color = 0;
node.parent.parent.color = 1;
rightRotate(node.parent.parent);
}
} else {
// 当前节点的父节点是祖父节点的右子节点
RBNode uncle = node.parent.parent.left;
// Case 1: 叔叔节点是红色
if (uncle != null && uncle.color == 1) {
node.parent.color = 0;
uncle.color = 0;
node.parent.parent.color = 1;
node = node.parent.parent;
} else {
// Case 2: 叔叔节点是黑色,且当前节点是左子节点
if (node == node.parent.left) {
node = node.parent;
rightRotate(node);
}
// Case 3: 叔叔节点是黑色,且当前节点是右子节点
node.parent.color = 0;
node.parent.parent.color = 1;
leftRotate(node.parent.parent);
}
}
}
root.color = 0;
}
// 删除节点
public void delete(int key) {
RBNode z = search(key);
if (z == null) {
return;
}
RBNode x, y;
if (z.left == null || z.right == null) {
y = z;
} else {
y = successor(z);
}
if (y.left != null) {
x = y.left;
} else {
x = y.right;
}
if (x != null) {
x.parent = y.parent;
}
if (y.parent == null) {
root = x;
} else if (y == y.parent.left) {
y.parent.left = x;
} else {
y.parent.right = x;
}
if (y != z) {
z.data = y.data;
}
if (y.color == 0) {
fixDelete(x);
}
}
// 删除节点后修正红黑树平衡性
private void fixDelete(RBNode node) {
while (node != root && node.color == 0) {
if (node == node.parent.left) {
RBNode brother = node.parent.right;
if (brother.color == 1) {
brother.color = 0;
node.parent.color = 1;
leftRotate(node.parent);
brother = node.parent.right;
}
if (brother.left.color == 0 && brother.right.color == 0) {
brother.color = 1;
node = node.parent;
} else {
if (brother.right.color == 0) {
brother.left.color = 0;
brother.color = 1;
rightRotate(brother);
brother = node.parent.right;
}
brother.color = node.parent.color;
node.parent.color = 0;
brother.right.color = 0;
leftRotate(node.parent);
node = root;
}
} else {
RBNode brother = node.parent.left;
if (brother.color == 1) {
brother.color = 0;
node.parent.color = 1;
rightRotate(node.parent);
brother = node.parent.left;
}
if (brother.right.color == 0 && brother.left.color == 0) {
brother.color = 1;
node = node.parent;
} else {
if (brother.left.color == 0) {
brother.right.color = 0;
brother.color = 1;
leftRotate(brother);
brother = node.parent.left;
}
brother.color = node.parent.color;
node.parent.color = 0;
brother.left.color = 0;
rightRotate(node.parent);
node = root;
}
}
}
node.color = 0;
}
// 查找节点
public RBNode search(int key) {
RBNode current = root;
while (current != null && current.data != key) {
if (key < current.data) {
current = current.left;
} else {
current = current.right;
}
}
return current;
}
// 查找后继节点
private RBNode successor(RBNode x) {
if (x.right != null) {
RBNode current = x.right;
while (current.left != null) {
current = current.left;
}
return current;
} else {
RBNode y = x.parent;
while (y != null && x == y.right) {
x = y;
y = y.parent;
}
return y;
}
}
// 修改节点
public void modify(int oldKey, int newKey) {
RBNode node = search(oldKey);
if (node != null) {
delete(oldKey);
insert(newKey);
}
}
// 中序遍历红黑树
private void inorderTraversal(RBNode node) {
if (node != null) {
inorderTraversal(node.left);
System.out.print(node.data + " ");
inorderTraversal(node.right);
}
}
public void printTree() {
inorderTraversal(root);
}
}
public class Main {
public static void main(String[] args) {
RedBlackTree tree = new RedBlackTree();
tree.insert(10);
tree.insert(15);
tree.insert(13);
tree.insert(16);
tree.insert(5);
tree.insert(7);
System.out.println("红黑树中序遍历结果:");
tree.printTree();
}
}