prime/src/Kyoto/rstl/rstl_map.cpp
Henrique Gemignani Passos Lima 99dac1a072 Progress for rbtree_rebalance_for_erase
Former-commit-id: f05b3c0b017e4e61333ab6df889b437289de6627
2022-10-28 11:44:17 +03:00

269 lines
6.4 KiB
C++

#include "rstl/red_black_tree.hpp"
namespace rstl {
struct _node {
_node* mLeft;
_node* mRight;
_node* mParent;
node_color mColor;
};
struct _header {
_node* mLeftmost;
_node* mRightmost;
_node* mRootNode;
};
void rbtree_rotate_left(void* header_void, void* node_void) {
_header* header = static_cast< _header* >(header_void);
_node* node = static_cast< _node* >(node_void);
_node* parent = node->mParent;
_node* right = node->mRight;
_node* l = right->mLeft;
if (parent == nullptr) {
header->mRootNode = right;
right->mParent = nullptr;
} else {
if (parent->mLeft == node) {
parent->mLeft = right;
} else {
parent->mRight = right;
}
right->mParent = node->mParent;
}
node->mParent = right;
right->mLeft = node;
if (l) {
l->mParent = node;
}
node->mRight = l;
}
void rbtree_rotate_right(void* header_void, void* node_void) {
_header* header = static_cast< _header* >(header_void);
_node* node = static_cast< _node* >(node_void);
_node* parent = node->mParent;
_node* left = node->mLeft;
_node* r = left->mRight;
if (parent == nullptr) {
header->mRootNode = left;
left->mParent = nullptr;
} else {
if (node == parent->mLeft) {
parent->mLeft = left;
} else {
parent->mRight = left;
}
left->mParent = node->mParent;
}
node->mParent = left;
left->mRight = node;
if (r) {
r->mParent = node;
}
node->mLeft = r;
}
void rbtree_rebalance(void* header_void, void* node_void) {
_node* node = static_cast< _node* >(node_void);
_header* header = static_cast< _header* >(header_void);
while (node->mParent != nullptr && node->mParent->mColor == kNC_Black) {
_node* p = node->mParent->mParent->mLeft;
if (node->mParent == p) {
p = node->mParent->mParent->mRight;
if ((p != nullptr && p->mColor == kNC_Black)) {
node->mParent->mColor = kNC_Red;
p->mColor = kNC_Red;
node->mParent->mParent->mColor = kNC_Black;
node = node->mParent->mParent;
} else {
if (node == node->mParent->mRight) {
node = node->mParent;
rbtree_rotate_left(header, node);
}
node->mParent->mColor = kNC_Red;
node->mParent->mParent->mColor = kNC_Black;
rbtree_rotate_right(header, node->mParent->mParent);
}
} else if (p != nullptr && p->mColor == kNC_Black) {
node->mParent->mColor = kNC_Red;
p->mColor = kNC_Red;
node->mParent->mParent->mColor = kNC_Black;
node = node->mParent->mParent;
} else {
if (node == node->mParent->mLeft) {
node = node->mParent;
rbtree_rotate_right(header, node);
}
node->mParent->mColor = kNC_Red;
node->mParent->mParent->mColor = kNC_Black;
rbtree_rotate_left(header, node->mParent->mParent);
}
}
header->mRootNode->mColor = kNC_Red;
}
void* rbtree_rebalance_for_erase(void* header_void, void* node_void) {
_header* header = static_cast< _header* >(header_void);
_node* node = static_cast< _node* >(node_void);
_node* next;
_node* result = node;
if (node->mLeft == nullptr) {
next = node->mRight;
} else {
_node* tmp = node->mRight;
if (tmp == nullptr) {
next = tmp;
} else {
do {
result = tmp;
tmp = result->mLeft;
} while (result->mLeft != nullptr);
next = result->mRight;
}
}
if (result != node) {
node->mLeft->mParent = result;
result->mLeft = node->mLeft;
_node* tmp = result;
if (result != node->mRight) {
tmp = result->mParent;
if (next != nullptr) {
next->mParent = result->mParent;
}
result->mParent->mLeft = next;
result->mRight = node->mRight;
node->mRight->mParent = result;
}
if (header->mRootNode == node) {
header->mRootNode = result;
} else {
if (node->mParent->mLeft == node) {
node->mParent->mLeft = result;
} else {
node->mParent->mRight = result;
}
}
result->mParent = node->mParent;
node_color c = result->mColor;
result->mColor = node->mColor;
node->mColor = c;
result = node;
} else {
_node* a1 = result->mParent;
if (next != nullptr) {
next->mParent = a1;
}
if (header->mRootNode == node) {
header->mRootNode = next;
} else {
if (node->mParent->mLeft == node) {
node->mParent->mLeft = next;
} else {
node->mParent->mRight = next;
}
}
if (header->mLeftmost == node) {
if (node->mRight == nullptr) {
header->mLeftmost = node->mParent;
} else {
// prVar1 = next;
_node* prVar1 = next;
if (next == nullptr) {
header->mLeftmost = nullptr;
} else {
_node* newLeftmost;
do {
newLeftmost = prVar1;
prVar1 = newLeftmost->mLeft;
} while (newLeftmost->mLeft != nullptr);
header->mLeftmost = newLeftmost;
}
}
}
if (header->mRightmost == node) {
if (node->mLeft == nullptr) {
header->mRightmost = node->mParent;
} else {
// prVar1 = next;
_node* prVar1 = next;
if (next == nullptr) {
header->mRightmost = nullptr;
} else {
_node* newRightmost;
do {
newRightmost = prVar1;
prVar1 = newRightmost->mRight;
} while (newRightmost->mRight != nullptr);
header->mRightmost = newRightmost;
}
}
}
}
if (result->mColor != kNC_Black) {
while (true) {
}
}
return result;
}
void* rbtree_traverse_forward(const void* header_void, void* node_void) {
const _header* header = static_cast< const _header* >(header_void);
_node* node = static_cast< _node* >(node_void);
if (node == nullptr) {
return header->mLeftmost;
}
_node* right = node->mRight;
if ((right == nullptr) && (node->mParent == nullptr)) {
return nullptr;
}
if ((right == nullptr) && (node->mParent->mLeft == node)) {
return node->mParent;
}
if (right != nullptr) {
_node* result = right;
goto enter_middle;
do {
result = right;
enter_middle:
right = result->mLeft;
} while (right != nullptr);
return result;
}
_node* parent = nullptr;
goto enter_final;
do {
node = parent;
enter_final:
parent = node->mParent;
if (!parent)
break;
} while (parent->mRight == node);
return parent != nullptr ? parent : nullptr;
}
} // namespace rstl