您好,登录后才能下订单哦!
红黑树是一种自平衡的二叉查找树,它在计算机科学中有着广泛的应用。红黑树通过引入颜色属性来维护树的平衡,从而保证了在最坏情况下基本操作的时间复杂度为O(log n)。本文将详细介绍红黑树的基本概念、性质、节点结构、基本操作及其在C++中的实现。
红黑树是一种二叉查找树,每个节点都带有一个额外的存储位表示节点的颜色,可以是红色或黑色。通过对任何一条从根到叶子的路径上各个节点着色方式的限制,红黑树确保没有一条路径会比其他路径长出两倍,因而是接近平衡的。
红黑树具有以下性质:
这些性质确保了红黑树的平衡性,使得红黑树在最坏情况下也能保持O(log n)的时间复杂度。
红黑树的节点结构通常包含以下信息:
在C++中,红黑树的节点结构可以定义如下:
enum Color { RED, BLACK };
struct Node {
int key;
Color color;
Node* left;
Node* right;
Node* parent;
Node(int key, Color color = RED, Node* left = nullptr, Node* right = nullptr, Node* parent = nullptr)
: key(key), color(color), left(left), right(right), parent(parent) {}
};
红黑树的插入操作与普通二叉查找树的插入操作类似,但在插入后需要进行平衡调整以保持红黑树的性质。插入操作的基本步骤如下:
插入后的平衡调整主要分为以下几种情况:
情况1:新节点的叔节点是红色
情况2:新节点的叔节点是黑色,且新节点是父节点的右子节点
情况3:新节点的叔节点是黑色,且新节点是父节点的左子节点
红黑树的删除操作与普通二叉查找树的删除操作类似,但在删除后需要进行平衡调整以保持红黑树的性质。删除操作的基本步骤如下:
删除后的平衡调整主要分为以下几种情况:
情况1:删除的节点的兄弟节点是红色
情况2:删除的节点的兄弟节点是黑色,且兄弟节点的两个子节点都是黑色
情况3:删除的节点的兄弟节点是黑色,且兄弟节点的左子节点是红色,右子节点是黑色
情况4:删除的节点的兄弟节点是黑色,且兄弟节点的右子节点是红色
红黑树的查找操作与普通二叉查找树的查找操作相同。从根节点开始,比较要查找的键值与当前节点的键值:
查找操作的时间复杂度为O(log n)。
在C++中,红黑树的节点类可以定义如下:
enum Color { RED, BLACK };
struct Node {
int key;
Color color;
Node* left;
Node* right;
Node* parent;
Node(int key, Color color = RED, Node* left = nullptr, Node* right = nullptr, Node* parent = nullptr)
: key(key), color(color), left(left), right(right), parent(parent) {}
};
红黑树类的实现主要包括插入、删除和查找操作。以下是红黑树类的定义及其基本操作的实现。
class RedBlackTree {
private:
Node* root;
Node* nil;
void leftRotate(Node* x) {
Node* y = x->right;
x->right = y->left;
if (y->left != nil) {
y->left->parent = x;
}
y->parent = x->parent;
if (x->parent == nil) {
root = y;
} else if (x == x->parent->left) {
x->parent->left = y;
} else {
x->parent->right = y;
}
y->left = x;
x->parent = y;
}
void rightRotate(Node* y) {
Node* x = y->left;
y->left = x->right;
if (x->right != nil) {
x->right->parent = y;
}
x->parent = y->parent;
if (y->parent == nil) {
root = x;
} else if (y == y->parent->right) {
y->parent->right = x;
} else {
y->parent->left = x;
}
x->right = y;
y->parent = x;
}
void insertFixup(Node* z) {
while (z->parent->color == RED) {
if (z->parent == z->parent->parent->left) {
Node* y = z->parent->parent->right;
if (y->color == RED) {
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
} else {
if (z == z->parent->right) {
z = z->parent;
leftRotate(z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
rightRotate(z->parent->parent);
}
} else {
Node* y = z->parent->parent->left;
if (y->color == RED) {
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
} else {
if (z == z->parent->left) {
z = z->parent;
rightRotate(z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
leftRotate(z->parent->parent);
}
}
}
root->color = BLACK;
}
public:
RedBlackTree() {
nil = new Node(0, BLACK);
root = nil;
}
void insert(int key) {
Node* z = new Node(key);
Node* y = nil;
Node* x = root;
while (x != nil) {
y = x;
if (z->key < x->key) {
x = x->left;
} else {
x = x->right;
}
}
z->parent = y;
if (y == nil) {
root = z;
} else if (z->key < y->key) {
y->left = z;
} else {
y->right = z;
}
z->left = nil;
z->right = nil;
z->color = RED;
insertFixup(z);
}
};
class RedBlackTree {
private:
Node* root;
Node* nil;
void transplant(Node* u, Node* v) {
if (u->parent == nil) {
root = v;
} else if (u == u->parent->left) {
u->parent->left = v;
} else {
u->parent->right = v;
}
v->parent = u->parent;
}
void deleteFixup(Node* x) {
while (x != root && x->color == BLACK) {
if (x == x->parent->left) {
Node* w = x->parent->right;
if (w->color == RED) {
w->color = BLACK;
x->parent->color = RED;
leftRotate(x->parent);
w = x->parent->right;
}
if (w->left->color == BLACK && w->right->color == BLACK) {
w->color = RED;
x = x->parent;
} else {
if (w->right->color == BLACK) {
w->left->color = BLACK;
w->color = RED;
rightRotate(w);
w = x->parent->right;
}
w->color = x->parent->color;
x->parent->color = BLACK;
w->right->color = BLACK;
leftRotate(x->parent);
x = root;
}
} else {
Node* w = x->parent->left;
if (w->color == RED) {
w->color = BLACK;
x->parent->color = RED;
rightRotate(x->parent);
w = x->parent->left;
}
if (w->right->color == BLACK && w->left->color == BLACK) {
w->color = RED;
x = x->parent;
} else {
if (w->left->color == BLACK) {
w->right->color = BLACK;
w->color = RED;
leftRotate(w);
w = x->parent->left;
}
w->color = x->parent->color;
x->parent->color = BLACK;
w->left->color = BLACK;
rightRotate(x->parent);
x = root;
}
}
}
x->color = BLACK;
}
public:
RedBlackTree() {
nil = new Node(0, BLACK);
root = nil;
}
void deleteNode(Node* z) {
Node* y = z;
Node* x;
Color yOriginalColor = y->color;
if (z->left == nil) {
x = z->right;
transplant(z, z->right);
} else if (z->right == nil) {
x = z->left;
transplant(z, z->left);
} else {
y = minimum(z->right);
yOriginalColor = y->color;
x = y->right;
if (y->parent == z) {
x->parent = y;
} else {
transplant(y, y->right);
y->right = z->right;
y->right->parent = y;
}
transplant(z, y);
y->left = z->left;
y->left->parent = y;
y->color = z->color;
}
if (yOriginalColor == BLACK) {
deleteFixup(x);
}
delete z;
}
Node* minimum(Node* x) {
while (x->left != nil) {
x = x->left;
}
return x;
}
};
class RedBlackTree {
private:
Node* root;
Node* nil;
public:
RedBlackTree() {
nil = new Node(0, BLACK);
root = nil;
}
Node* search(int key) {
Node* x = root;
while (x != nil && key != x->key) {
if (key < x->key) {
x = x->left;
} else {
x = x->right;
}
}
return x;
}
};
红黑树在计算机科学中有着广泛的应用,主要包括以下几个方面:
std::map
和std::set
通常使用红黑树作为底层数据结构。红黑树是一种高效的自平衡二叉查找树,通过引入颜色属性和一系列平衡调整操作,红黑树能够在最坏情况下保持O(log n)的时间复杂度。本文详细介绍了红黑树的基本概念、性质、节点结构、基本操作及其在C++中的实现。红黑树在计算机科学中有着广泛的应用,是数据结构与算法学习中的重要内容。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。