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;
|
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) {
|
static void DeleteNode(RedBlackTreeNodeType *pos, RedBlackTreeNodeType *&tree_root) {
|
||||||
if (pos->parent == nullptr && pos->left == nullptr && pos->right == nullptr) {
|
if (pos->parent == nullptr && pos->left == nullptr && pos->right == nullptr) {
|
||||||
// Case 0: The only node in the tree.
|
// Case 0: The only node in the tree.
|
||||||
@ -280,11 +356,12 @@ class map {
|
|||||||
}
|
}
|
||||||
if (pos->left == nullptr && pos->right == nullptr) {
|
if (pos->left == nullptr && pos->right == nullptr) {
|
||||||
// Case 2
|
// Case 2
|
||||||
if (pos->color == RedBlackTreeColorType::RED) {
|
if (pos->color == RedBlackTreeColorType::BLACK) {
|
||||||
pos->GetSelfPath(tree_root) = nullptr;
|
pos->DeleteFixUp(tree_root);
|
||||||
delete pos;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
pos->GetSelfPath(tree_root) = nullptr;
|
||||||
|
delete pos;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// Case 3
|
// Case 3
|
||||||
RedBlackTreeNodeType *replacement = (pos->left != nullptr ? pos->left : pos->right);
|
RedBlackTreeNodeType *replacement = (pos->left != nullptr ? pos->left : pos->right);
|
||||||
@ -295,16 +372,16 @@ class map {
|
|||||||
replacement->color = RedBlackTreeColorType::BLACK;
|
replacement->color = RedBlackTreeColorType::BLACK;
|
||||||
delete pos;
|
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;
|
size_t node_count;
|
||||||
RedBlackTreeNodeType *tree_root;
|
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:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -497,7 +574,7 @@ class map {
|
|||||||
map() : node_count(0), tree_root(nullptr) {}
|
map() : node_count(0), tree_root(nullptr) {}
|
||||||
map(const map &other) {
|
map(const map &other) {
|
||||||
node_count = other.node_count;
|
node_count = other.node_count;
|
||||||
CopyFrom(tree_root, other.tree_root);
|
RedBlackTreeNodeType::CopyFrom(tree_root, other.tree_root);
|
||||||
}
|
}
|
||||||
map(map &&other) {
|
map(map &&other) {
|
||||||
node_count = other.node_count;
|
node_count = other.node_count;
|
||||||
@ -513,7 +590,7 @@ class map {
|
|||||||
if (tree_root) tree_root->ReleaseAll();
|
if (tree_root) tree_root->ReleaseAll();
|
||||||
delete tree_root;
|
delete tree_root;
|
||||||
node_count = other.node_count;
|
node_count = other.node_count;
|
||||||
CopyFrom(tree_root, other.tree_root);
|
RedBlackTreeNodeType::CopyFrom(tree_root, other.tree_root);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
map &operator=(map &&other) {
|
map &operator=(map &&other) {
|
||||||
|
Reference in New Issue
Block a user