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