finish more details and ready to write erase

This commit is contained in:
2024-03-26 02:49:30 +00:00
parent c585b59f7a
commit 347cfcf8e9

View File

@ -115,7 +115,7 @@ class map {
return;
}
RedBlackTreeNodeType *uncle = GetUncle();
RedBlackTreeColorType *grand_parent = GetGrandParent();
RedBlackTreeNodeType *grand_parent = GetGrandParent();
if (uncle != nullptr && uncle->color == RedBlackTreeColorType::RED) {
// Case 4
parent->color = RedBlackTreeColorType::BLACK;
@ -157,17 +157,19 @@ class map {
* @param val The value to be inserted.
* @param allow_replacement Whether to allow replacement if the key already exists.
*
* @return Whether the insertion is successful.
* @return Whether the insertion is successful and where the insertion is.
*
* @note Note that tree_root is a reference to the root of the tree. This function will modify the tree_root if
* necessary.
*/
bool Insert(RedBlackTreeNodeType *&tree_root, const value_type &val, bool allow_replacement) {
std::pair<RedBlackTreeNodeType *, bool> Insert(RedBlackTreeNodeType *&tree_root, const value_type &val,
bool allow_replacement) {
if (comparer(val.first, this->val.first)) {
if (left == nullptr) {
left = new RedBlackTreeNodeType(val, nullptr, nullptr, this, RedBlackTreeColorType::RED);
left->parent = this;
left->InsertFixUp(tree_root);
return std::pair<RedBlackTreeNodeType *, bool>(left, true);
} else {
return left->Insert(tree_root, val, allow_replacement);
}
@ -176,16 +178,17 @@ class map {
right = new RedBlackTreeNodeType(val, nullptr, nullptr, this, RedBlackTreeColorType::RED);
right->parent = this;
right->InsertFixUp(tree_root);
return std::pair<RedBlackTreeNodeType *, bool>(right, true);
} else {
return right->Insert(tree_root, val, allow_replacement);
}
} else {
if (allow_replacement) {
this->val = val;
return true;
this->val.second = val.second;
return std::pair<RedBlackTreeNodeType *, bool>(this, false);
}
}
return false;
return std::pair<RedBlackTreeNodeType *, bool>(this, false);
}
/**
* @brief The definition of ReleaseAll.
@ -200,9 +203,27 @@ class map {
delete left;
delete right;
}
RedBlackTreeNodeType *Find(const decltype(val.first) &key) {
if (comparer(key, val.first)) {
if (left == nullptr) return nullptr;
return left->Find(key);
} else if (comparer(val.first, key)) {
if (right == nullptr) return nullptr;
return right->Find(key);
} else {
return this;
}
}
};
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:
/**
@ -222,6 +243,7 @@ class map {
map *domain;
public:
friend const_iterator;
iterator() : raw_pointer(nullptr), domain(nullptr) {}
iterator(const iterator &other) : raw_pointer(other.raw_pointer), domain(other.domain) {}
iterator(RedBlackTreeNodeType *raw_pointer, map *domain) : raw_pointer(raw_pointer), domain(domain) {}
@ -304,6 +326,7 @@ class map {
const map *domain;
public:
friend iterator;
const_iterator() : raw_pointer(nullptr), domain(nullptr) {}
const_iterator(const const_iterator &other) : raw_pointer(other.raw_pointer), domain(other.domain) {}
const_iterator(const iterator &other) : raw_pointer(other.raw_pointer), domain(other.domain) {}
@ -375,46 +398,90 @@ class map {
value_type *operator->() const noexcept { return &raw_pointer->val; }
};
map() : node_count(0), tree_root(nullptr) {}
// TODO copy constructor
map(const map &other) {}
map(const map &other) {
node_count = other.node_count;
CopyFrom(tree_root, other.tree_root);
}
map(map &&other) {
node_count = other.node_count;
tree_root = other.tree_root;
other.node_count = 0;
other.tree_root = nullptr;
}
/**
* TODO assignment operator
*/
map &operator=(const map &other) {}
map &operator=(const map &other) {
if (this == &other) return *this;
if (tree_root) tree_root->ReleaseAll();
delete tree_root;
node_count = other.node_count;
CopyFrom(tree_root, other.tree_root);
}
map &operator=(map &&other) {
if (this == &other) return *this;
if (tree_root) tree_root->ReleaseAll();
delete tree_root;
node_count = other.node_count;
tree_root = other.tree_root;
other.node_count = 0;
other.tree_root = nullptr;
}
~map() {
if (tree_root) tree_root->ReleaseAll();
delete tree_root;
}
/**
* TODO
* access specified element with bounds checking
* Returns a reference to the mapped value of the element with key equivalent to key.
* If no such element exists, an exception of type `index_out_of_bound'
*/
T &at(const Key &key) {}
const T &at(const Key &key) const {}
T &at(const Key &key) {
RedBlackTreeNodeType *result = tree_root->Find(key);
if (result == nullptr) throw index_out_of_bound();
return result->val.second;
}
const T &at(const Key &key) const {
RedBlackTreeNodeType *result = tree_root->Find(key);
if (result == nullptr) throw index_out_of_bound();
return result->val.second;
}
/**
* TODO
* access specified element
* Returns a reference to the value that is mapped to a key equivalent to key,
* performing an insertion if such key does not already exist.
*/
T &operator[](const Key &key) {}
T &operator[](const Key &key) {
auto result = tree_root->Insert(tree_root, value_type(key, T()), false);
if (result.second) ++node_count;
return result.first->val.second;
}
/**
* behave like at() throw index_out_of_bound if such key does not exist.
*/
const T &operator[](const Key &key) const {}
const T &operator[](const Key &key) const { return at(key); }
/**
* return a iterator to the beginning
*/
iterator begin() {}
const_iterator cbegin() const {}
iterator begin() {
if (tree_root == nullptr) return iterator(nullptr, this);
RedBlackTreeNodeType *tmp = tree_root;
while (tmp->left != nullptr) tmp = tmp->left;
return iterator(tmp, this);
}
const_iterator cbegin() const {
if (tree_root == nullptr) return const_iterator(nullptr, this);
RedBlackTreeNodeType *tmp = tree_root;
while (tmp->left != nullptr) tmp = tmp->left;
return const_iterator(tmp, this);
}
/**
* return a iterator to the end
* in fact, it returns past-the-end.
*/
iterator end() {}
const_iterator cend() const {}
iterator end() { return iterator(nullptr, this); }
const_iterator cend() const { return const_iterator(nullptr, this); }
/**
* checks whether the container is empty
* return true if empty, otherwise false.
@ -427,7 +494,12 @@ class map {
/**
* clears the contents
*/
void clear() {}
void clear() {
if (tree_root) tree_root->ReleaseAll();
delete tree_root;
tree_root = nullptr;
node_count = 0;
}
/**
* insert an element.
* return a pair, the first of the pair is
@ -438,8 +510,11 @@ class map {
if (tree_root == nullptr) {
tree_root = new RedBlackTreeNodeType(value, nullptr, nullptr, nullptr, RedBlackTreeNodeType::BLACK);
node_count = 1;
return pair<iterator, bool>(iterator(tree_root), true);
return pair<iterator, bool>(iterator(tree_root, this), true);
}
auto result = tree_root->Insert(tree_root, value, false);
if (result.second) ++node_count;
return pair<iterator, bool>(iterator(result.first, this), result.second);
}
/**
* erase the element at pos.
@ -454,16 +529,28 @@ class map {
* since this container does not allow duplicates.
* The default method of check the equivalence is !(a < b || b > a)
*/
size_t count(const Key &key) const {}
size_t count(const Key &key) const {
if (tree_root == nullptr) return 0;
return tree_root->Find(key) == nullptr ? 0 : 1;
}
/**
* Finds an element with key equivalent to key.
* key value of the element to search for.
* Iterator to an element with key equivalent to key.
* If no such element is found, past-the-end (see end()) iterator is returned.
*/
iterator find(const Key &key) {}
const_iterator find(const Key &key) const {}
iterator find(const Key &key) {
if (tree_root == nullptr) return end();
return iterator(tree_root->Find(key), this);
}
const_iterator find(const Key &key) const {
if (tree_root == nullptr) return cend();
return const_iterator(tree_root->Find(key), this);
}
};
// Define the static member comparer.
template <class Key, class T, class Compare>
Compare map<Key, T, Compare>::comparer = Compare();
} // namespace sjtu