just about got an idea for iterator but just realized that I need to implement a red-black tree rather than a generic binary tree

This commit is contained in:
Pagwin 2024-11-19 14:09:05 -05:00
parent 8a73e0d950
commit be847faa8c
No known key found for this signature in database
GPG key ID: 81137023740CA260

41
Map.hpp
View file

@ -11,6 +11,9 @@
#include <vector> #include <vector>
namespace cs440 { namespace cs440 {
enum class Color { Red, Black };
// https://en.wikipedia.org/wiki/Red%E2%80%93black_tree
template <typename Key_T, typename Mapped_T> class Map { template <typename Key_T, typename Mapped_T> class Map {
private: private:
using ValueType = std::pair<const Key_T, Mapped_T>; using ValueType = std::pair<const Key_T, Mapped_T>;
@ -18,6 +21,7 @@ private:
// left = parent * 2 + 1 // left = parent * 2 + 1
// right = parent * 2 + 2 // right = parent * 2 + 2
std::vector<std::optional<ValueType>> store; std::vector<std::optional<ValueType>> store;
std::vector<Color> coloration;
public: public:
class Iterator; class Iterator;
@ -46,21 +50,45 @@ public:
current{current} {} current{current} {}
ConstIterator to_const() const { return ConstIterator(this); } ConstIterator to_const() const { return ConstIterator(this); }
Iterator &operator++() { Iterator &operator++() {
// TODO: implement this backward_traversal.push_back(current);
std::size_t next = current * 2 + 2;
while (next < parent.size() && parent.at(next).has_value()) {
forward_traversal.push_back(next);
next = next * 2 + 1;
}
current = forward_traversal.back();
forward_traversal.pop_back();
if (this->forward_traversal.empty()) {
// deref can just check for nullopt to see if it's end
current = next;
} else {
// pop from stack
current = forward_traversal.back();
forward_traversal.pop_back();
}
return *this;
} }
Iterator operator++(int) { Iterator operator++(int) {
Iterator tmp = *this; Iterator tmp = *this;
++(*this); ++(*this);
return tmp; return tmp;
} }
Iterator &operator--() {} Iterator &operator--() {
std::size_t tmp = backward_traversal.back();
backward_traversal.pop_back();
if (tmp > current) {
forward_traversal.push_back(current);
}
current = tmp;
return *this;
}
Iterator operator--(int) { Iterator operator--(int) {
Iterator tmp = *this; Iterator tmp = *this;
--(*this); --(*this);
return tmp; return tmp;
} }
ValueType &operator*() const { return this->store_iter->value(); } ValueType &operator*() const { return parent.at(current); }
ValueType *operator->() const { return &this->store_iter->value(); } ValueType *operator->() const { return &**this; }
friend bool operator==(Iterator const &lhs, Iterator const &rhs) { friend bool operator==(Iterator const &lhs, Iterator const &rhs) {
return lhs.store_iter == rhs.store_iter; return lhs.store_iter == rhs.store_iter;
} }
@ -234,13 +262,16 @@ public:
Mapped_T &operator[](const Key_T &key) { return this->at(key); } Mapped_T &operator[](const Key_T &key) { return this->at(key); }
// TODO: single insert // TODO: single insert
// OH NO IT SHOULD BE RED-BLACK
std ::pair<Iterator, bool> insert(const ValueType &) {} std ::pair<Iterator, bool> insert(const ValueType &) {}
template <typename IT_T> void insert(IT_T range_beg, IT_T range_end) { template <typename IT_T> void insert(IT_T range_beg, IT_T range_end) {
std::for_each(range_beg, range_end, std::for_each(range_beg, range_end,
[&](ValueType &val) { this->insert(val); }); [&](ValueType &val) { this->insert(val); });
} }
// TODO: erase via iterator // TODO: erase via iterator
void erase(Iterator pos) {} void erase(Iterator pos) {
// RED BLACK TREE oh no
}
void erase(const Key_T &key) { this->erase(this->find(key)); } void erase(const Key_T &key) { this->erase(this->find(key)); }
void clear() { this->store = {}; } void clear() { this->store = {}; }
friend bool operator==(const Map &lhs, const Map &rhs) { friend bool operator==(const Map &lhs, const Map &rhs) {