C++ 语言 红黑树的旋转平衡操作

C++阿木 发布于 2025-06-14 8 次阅读


阿木博主一句话概括:C++ 红黑树旋转平衡操作详解

阿木博主为你简单介绍:红黑树是一种自平衡的二叉查找树,它通过一系列的旋转操作来保持树的平衡,从而保证查找、插入和删除操作的时间复杂度均为O(log n)。本文将围绕C++语言,详细介绍红黑树的旋转平衡操作,包括左旋、右旋以及相关的旋转操作代码实现。

一、

红黑树是一种特殊的二叉查找树,它通过在树中添加颜色信息来保证树的平衡。红黑树中的节点具有以下性质:

1. 每个节点非红即黑。
2. 根节点是黑色。
3. 所有叶子节点(NIL节点)是黑色。
4. 如果一个节点是红色的,则它的两个子节点都是黑色的。
5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

红黑树的旋转操作是保持树平衡的关键,主要包括左旋和右旋两种操作。下面将详细介绍这两种旋转操作及其在C++中的实现。

二、左旋操作

左旋操作是红黑树中常用的旋转操作之一,主要用于处理节点插入或删除后可能出现的左倾斜问题。左旋操作的步骤如下:

1. 将节点y的右子节点作为y的新右子节点。
2. 将节点y的父节点x的左子节点指向y。
3. 将节点y的父节点x的父节点指向y。
4. 将节点y的左子节点指向x。

下面是左旋操作的C++代码实现:

cpp
struct Node {
int data;
Node left;
Node right;
Node parent;
bool color; // true表示红色,false表示黑色
};

void leftRotate(Node x) {
Node y = x->right;
x->right = y->left;
if (y->left != nullptr) {
y->left->parent = x;
}
y->parent = x->parent;
if (x->parent == nullptr) {
root = y; // x是根节点
} else if (x == x->parent->left) {
x->parent->left = y;
} else {
x->parent->right = y;
}
y->left = x;
x->parent = y;
}

三、右旋操作

右旋操作与左旋操作类似,主要用于处理节点插入或删除后可能出现的右倾斜问题。右旋操作的步骤如下:

1. 将节点y的左子节点作为y的新左子节点。
2. 将节点y的父节点x的右子节点指向y。
3. 将节点y的父节点x的父节点指向y。
4. 将节点y的右子节点指向x。

下面是右旋操作的C++代码实现:

cpp
void rightRotate(Node y) {
Node x = y->left;
y->left = x->right;
if (x->right != nullptr) {
x->right->parent = y;
}
x->parent = y->parent;
if (y->parent == nullptr) {
root = x; // y是根节点
} else if (y == y->parent->left) {
y->parent->left = x;
} else {
y->parent->right = x;
}
x->right = y;
y->parent = x;
}

四、旋转平衡操作的应用

在红黑树中,旋转平衡操作主要应用于以下几种情况:

1. 插入操作:在插入节点后,可能会破坏红黑树的性质,此时需要通过旋转操作来恢复树的平衡。
2. 删除操作:在删除节点后,可能会破坏红黑树的性质,此时需要通过旋转操作来恢复树的平衡。
3. 查找操作:在查找过程中,可能会遇到节点倾斜的情况,此时需要通过旋转操作来保持树的平衡。

下面是旋转平衡操作的C++代码实现:

cpp
void fixViolation(Node node) {
Node parent = node->parent;
Node grandParent = parent->parent;

// 情况1:父节点是红色的,祖父节点是黑色的
if (parent->color == RED && grandParent->color == BLACK) {
// 情况2.1:父节点是左孩子,祖父节点是左孩子
if (parent == grandParent->left) {
rightRotate(grandParent);
}
// 情况2.2:父节点是右孩子,祖父节点是右孩子
else {
leftRotate(grandParent);
}
}
// 情况2:父节点是黑色的,祖父节点是红色的
else if (parent->color == BLACK && grandParent->color == RED) {
// 情况3.1:父节点是左孩子,祖父节点是左孩子
if (parent == grandParent->left) {
rightRotate(parent);
fixViolation(node);
}
// 情况3.2:父节点是右孩子,祖父节点是右孩子
else {
leftRotate(parent);
fixViolation(node);
}
}
// 情况3:父节点是祖父节点的左孩子,祖父节点的右孩子是红色的
else if (parent == grandParent->left && grandParent->right->color == RED) {
rightRotate(grandParent);
}
// 情况4:父节点是祖父节点的右孩子,祖父节点的左孩子是红色的
else if (parent == grandParent->right && grandParent->left->color == RED) {
leftRotate(grandParent);
}

root->color = BLACK;
parent->color = RED;
grandParent->color = RED;
}

五、总结

本文详细介绍了C++语言中红黑树的旋转平衡操作,包括左旋、右旋以及相关的旋转操作代码实现。通过旋转平衡操作,红黑树可以保持树的平衡,从而保证查找、插入和删除操作的时间复杂度均为O(log n)。在实际应用中,旋转平衡操作是红黑树维护平衡的关键,对于理解红黑树的工作原理具有重要意义。