feat: add isRed and setChild
This commit is contained in:
1 parent
a4b9260215
commit
cb70b0769a
1 file changed
+157
@@ -0,0 +1,157 @@
|
||||
#include "rbt.h"
|
||||
|
||||
static bool isRed(const RbtNode* n)
|
||||
{
|
||||
return n != nullptr && n->red;
|
||||
}
|
||||
|
||||
static void setChild(RbTree* t, RbtNode* parent, RbtNode* oldChild, RbtNode* newChild)
|
||||
{
|
||||
if (parent == nullptr)
|
||||
t->root = newChild;
|
||||
else if (parent->left == oldChild)
|
||||
parent->left = newChild;
|
||||
else
|
||||
parent->right = newChild;
|
||||
}
|
||||
|
||||
static void rotateLeft(RbTree* t, RbtNode* x)
|
||||
{
|
||||
RbtNode* y = x->right;
|
||||
x->right = y->left;
|
||||
if (y->left != nullptr)
|
||||
y->left->parent = x;
|
||||
y->parent = x->parent;
|
||||
setChild(t, x->parent, x, y);
|
||||
y->left = x;
|
||||
x->parent = y;
|
||||
}
|
||||
|
||||
static void rotateRight(RbTree* t, RbtNode* x)
|
||||
{
|
||||
RbtNode* y = x->left;
|
||||
x->left = y->right;
|
||||
if (y->right != nullptr)
|
||||
y->right->parent = x;
|
||||
y->parent = x->parent;
|
||||
setChild(t, x->parent, x, y);
|
||||
y->right = x;
|
||||
x->parent = y;
|
||||
}
|
||||
|
||||
static void insertFixup(RbTree* t, RbtNode* z)
|
||||
{
|
||||
while (isRed(z->parent)) {
|
||||
RbtNode* parent = z->parent;
|
||||
RbtNode* grandparent = parent->parent;
|
||||
|
||||
if (parent == grandparent->left) {
|
||||
RbtNode* uncle = grandparent->right;
|
||||
if (isRed(uncle)) {
|
||||
parent->red = false;
|
||||
uncle->red = false;
|
||||
grandparent->red = true;
|
||||
z = grandparent;
|
||||
} else {
|
||||
if (z == parent->right) {
|
||||
z = parent;
|
||||
rotateLeft(t, z);
|
||||
parent = z->parent;
|
||||
}
|
||||
parent->red = false;
|
||||
grandparent->red = true;
|
||||
rotateRight(t, grandparent);
|
||||
}
|
||||
} else {
|
||||
RbtNode* uncle = grandparent->left;
|
||||
if (isRed(uncle)) {
|
||||
parent->red = false;
|
||||
uncle->red = false;
|
||||
grandparent->red = true;
|
||||
z = grandparent;
|
||||
} else {
|
||||
if (z == parent->left) {
|
||||
z = parent;
|
||||
rotateRight(t, z);
|
||||
parent = z->parent;
|
||||
}
|
||||
parent->red = false;
|
||||
grandparent->red = true;
|
||||
rotateLeft(t, grandparent);
|
||||
}
|
||||
}
|
||||
}
|
||||
t->root->red = false;
|
||||
}
|
||||
|
||||
static void removeFixup(RbTree* t, RbtNode* x, RbtNode* xParent)
|
||||
{
|
||||
while (x != t->root && !isRed(x)) {
|
||||
if (x == xParent->left) {
|
||||
RbtNode* w = xParent->right;
|
||||
if (isRed(w)) {
|
||||
w->red = false;
|
||||
xParent->red = true;
|
||||
rotateLeft(t, xParent);
|
||||
w = xParent->right;
|
||||
}
|
||||
if (!isRed(w->left) && !isRed(w->right)) {
|
||||
w->red = true;
|
||||
x = xParent;
|
||||
xParent = x->parent;
|
||||
} else {
|
||||
if (!isRed(w->right)) {
|
||||
if (w->left != nullptr)
|
||||
w->left->red = false;
|
||||
w->red = true;
|
||||
rotateRight(t, w);
|
||||
w = xParent->right;
|
||||
}
|
||||
w->red = xParent->red;
|
||||
xParent->red = false;
|
||||
if (w->right != nullptr)
|
||||
w->right->red = false;
|
||||
rotateLeft(t, xParent);
|
||||
x = t->root;
|
||||
xParent = nullptr;
|
||||
}
|
||||
} else {
|
||||
RbtNode* w = xParent->left;
|
||||
if (isRed(w)) {
|
||||
w->red = false;
|
||||
xParent->red = true;
|
||||
rotateRight(t, xParent);
|
||||
w = xParent->left;
|
||||
}
|
||||
if (!isRed(w->left) && !isRed(w->right)) {
|
||||
w->red = true;
|
||||
x = xParent;
|
||||
xParent = x->parent;
|
||||
} else {
|
||||
if (!isRed(w->left)) {
|
||||
if (w->right != nullptr)
|
||||
w->right->red = false;
|
||||
w->red = true;
|
||||
rotateLeft(t, w);
|
||||
w = xParent->left;
|
||||
}
|
||||
w->red = xParent->red;
|
||||
xParent->red = false;
|
||||
if (w->left != nullptr)
|
||||
w->left->red = false;
|
||||
rotateRight(t, xParent);
|
||||
x = t->root;
|
||||
xParent = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (x != nullptr)
|
||||
x->red = false;
|
||||
}
|
||||
|
||||
void rbtInit(RbTree* t)
|
||||
{
|
||||
t->root = nullptr;
|
||||
t->count = 0;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user