write erase
This commit is contained in:
103
map/src/map.hpp
103
map/src/map.hpp
@ -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) {
|
||||
|
Reference in New Issue
Block a user