write erase

This commit is contained in:
2024-03-26 12:02:04 +00:00
parent e27b18df67
commit 237d44c3da

View File

@ -263,6 +263,82 @@ class map {
path_of_successor = node;
}
}
void DeleteFixUp(RedBlackTreeNodeType *&tree_root) {
assert(this->left == nullptr && this->right == nullptr);
assert(this->color == RedBlackTreeColorType::BLACK);
RedBlackTreeNodeType *sibling = GetSibling();
assert(sibling != nullptr);
if (sibling->color == RedBlackTreeColorType::RED) {
// Case 1
parent->color = RedBlackTreeColorType::RED;
sibling->color = RedBlackTreeColorType::BLACK;
if (this == parent->left) {
parent->RotateLeft(tree_root);
} else {
parent->RotateRight(tree_root);
}
this->DeleteFixUp(tree_root);
return;
}
RedBlackTreeNodeType *close_nephew = nullptr;
RedBlackTreeNodeType *distant_nephew = nullptr;
if (this == parent->left) {
close_nephew = sibling->left;
distant_nephew = sibling->right;
} else {
close_nephew = sibling->right;
distant_nephew = sibling->left;
}
if (sibling->color == RedBlackTreeColorType::BLACK && this->parent->color == RedBlackTreeColorType::RED &&
(close_nephew == nullptr || close_nephew != nullptr && close_nephew->color == RedBlackTreeColorType::BLACK) &&
(distant_nephew == nullptr ||
distant_nephew != nullptr && distant_nephew->color == RedBlackTreeColorType::BLACK)) {
// Case 2
assert(close_nephew == nullptr);
assert(distant_nephew == nullptr);
sibling->color = RedBlackTreeColorType::RED;
this->parent->color = RedBlackTreeColorType::BLACK;
return;
}
if (sibling->color == RedBlackTreeColorType::BLACK && this->parent->color == RedBlackTreeColorType::BLACK &&
(close_nephew == nullptr || close_nephew != nullptr && close_nephew->color == RedBlackTreeColorType::BLACK) &&
(distant_nephew == nullptr ||
distant_nephew != nullptr && distant_nephew->color == RedBlackTreeColorType::BLACK)) {
// Case 3
assert(close_nephew == nullptr);
assert(distant_nephew == nullptr);
sibling->color = RedBlackTreeColorType::RED;
this->parent->DeleteFixUp(tree_root);
return;
}
if (close_nephew != nullptr && close_nephew->color == RedBlackTreeColorType::RED) {
// Case 4
if (this == parent->left) {
sibling->color = RedBlackTreeColorType::RED;
close_nephew->color = RedBlackTreeColorType::BLACK;
sibling->RotateRight(tree_root);
} else {
sibling->color = RedBlackTreeColorType::RED;
close_nephew->color = RedBlackTreeColorType::BLACK;
sibling->RotateLeft(tree_root);
}
this->DeleteFixUp(tree_root);
return;
}
assert(distant_nephew != nullptr && distant_nephew->color == RedBlackTreeColorType::RED);
// Then it must be Case 5
if (this == parent->left) {
sibling->color = parent->color;
parent->color = RedBlackTreeColorType::BLACK;
distant_nephew->color = RedBlackTreeColorType::BLACK;
parent->RotateLeft(tree_root);
} else {
sibling->color = parent->color;
parent->color = RedBlackTreeColorType::BLACK;
distant_nephew->color = RedBlackTreeColorType::BLACK;
parent->RotateRight(tree_root);
}
}
static void DeleteNode(RedBlackTreeNodeType *pos, RedBlackTreeNodeType *&tree_root) {
if (pos->parent == nullptr && pos->left == nullptr && pos->right == nullptr) {
// Case 0: The only node in the tree.
@ -280,11 +356,12 @@ class map {
}
if (pos->left == nullptr && pos->right == nullptr) {
// Case 2
if (pos->color == RedBlackTreeColorType::RED) {
pos->GetSelfPath(tree_root) = nullptr;
delete pos;
return;
if (pos->color == RedBlackTreeColorType::BLACK) {
pos->DeleteFixUp(tree_root);
}
pos->GetSelfPath(tree_root) = nullptr;
delete pos;
return;
}
// Case 3
RedBlackTreeNodeType *replacement = (pos->left != nullptr ? pos->left : pos->right);
@ -295,16 +372,16 @@ class map {
replacement->color = RedBlackTreeColorType::BLACK;
delete pos;
}
static void CopyFrom(RedBlackTreeNodeType *&target, const RedBlackTreeNodeType *source) {
if (source == nullptr) return;
target = new RedBlackTreeNodeType(source->val, nullptr, nullptr, nullptr, source->color);
CopyFrom(target->left, source->left);
CopyFrom(target->right, source->right);
target->SetChildrensParent();
}
};
size_t node_count;
RedBlackTreeNodeType *tree_root;
void CopyFrom(RedBlackTreeNodeType *&target, const RedBlackTreeNodeType *source) {
if (source == nullptr) return;
target = new RedBlackTreeNodeType(source->val, nullptr, nullptr, nullptr, source->color);
CopyFrom(target->left, source->left);
CopyFrom(target->right, source->right);
target->SetChildrensParent();
}
public:
/**
@ -497,7 +574,7 @@ class map {
map() : node_count(0), tree_root(nullptr) {}
map(const map &other) {
node_count = other.node_count;
CopyFrom(tree_root, other.tree_root);
RedBlackTreeNodeType::CopyFrom(tree_root, other.tree_root);
}
map(map &&other) {
node_count = other.node_count;
@ -513,7 +590,7 @@ class map {
if (tree_root) tree_root->ReleaseAll();
delete tree_root;
node_count = other.node_count;
CopyFrom(tree_root, other.tree_root);
RedBlackTreeNodeType::CopyFrom(tree_root, other.tree_root);
return *this;
}
map &operator=(map &&other) {