bug fixing and realizing that I need to fix my way of determining the next and prior node
This commit is contained in:
parent
88194b9a5b
commit
a0ce38e2ee
1 changed files with 26 additions and 32 deletions
58
Map.hpp
58
Map.hpp
|
@ -48,6 +48,7 @@ template <typename Key_T, typename Mapped_T> struct BookKeeping {
|
|||
BookKeeping(BookKeeping const &rhs)
|
||||
: container{rhs.container}, value{rhs.value}, // self{rhs.self},
|
||||
color{rhs.color}, parent{rhs.parent}, left{rhs.left}, right{rhs.right},
|
||||
// TODO: recalc this
|
||||
prev{rhs.prev}, next{rhs.next} {}
|
||||
// if pointing to different containers throws
|
||||
BookKeeping &operator=(BookKeeping const &rhs) {
|
||||
|
@ -61,6 +62,7 @@ template <typename Key_T, typename Mapped_T> struct BookKeeping {
|
|||
this->parent = rhs.parent;
|
||||
this->left = rhs.left;
|
||||
this->right = rhs.right;
|
||||
// TODO: recalc this
|
||||
this->prev = rhs.prev;
|
||||
this->next = rhs.next;
|
||||
return *this;
|
||||
|
@ -68,7 +70,7 @@ template <typename Key_T, typename Mapped_T> struct BookKeeping {
|
|||
// reference to a pointer because the alternatives were worse
|
||||
inline Self *child(Direction dir) {
|
||||
auto ret = c_select(dir);
|
||||
return ret.has_value() ? &container.nodes[left.value()] : nullptr;
|
||||
return ret.has_value() ? &container.nodes[ret.value()] : nullptr;
|
||||
}
|
||||
inline std::optional<std::size_t> c_select(Direction dir) {
|
||||
switch (dir) {
|
||||
|
@ -151,8 +153,9 @@ template <typename Key_T, typename Mapped_T> struct BookKeeping {
|
|||
Self *S = P->child(!dir);
|
||||
Self *C;
|
||||
|
||||
// this tidbit is wrong and wikipedia is wrong to have this assert it seems
|
||||
// this method shouldn't be called in cases where this assert will trip
|
||||
assert(S != nullptr);
|
||||
// assert(S != nullptr);
|
||||
|
||||
C = S->child(dir);
|
||||
P->c_trans(!dir, C);
|
||||
|
@ -438,31 +441,13 @@ private:
|
|||
void handle_root_rotation(Node *grandparent, Node *parent, Node *inserting,
|
||||
Direction dir) {
|
||||
// making inner grandchild into outer grandchild
|
||||
|
||||
if (inserting == parent->child(!dir)) {
|
||||
parent->rotate(dir);
|
||||
inserting = parent;
|
||||
parent = grandparent->child(dir);
|
||||
}
|
||||
// RotateDirRoot(T,G,1-dir);
|
||||
Node *gr_grandparent = grandparent->par();
|
||||
Node *sibling = grandparent->child(!dir);
|
||||
assert(sibling != nullptr);
|
||||
Node *child = sibling->child(dir);
|
||||
grandparent->c_trans(!dir, child);
|
||||
sibling->c_trans(dir, grandparent);
|
||||
grandparent->set_par(sibling);
|
||||
sibling->set_par(gr_grandparent);
|
||||
if (gr_grandparent != nullptr) {
|
||||
Direction grandparent_direction;
|
||||
if (gr_grandparent->l() == grandparent) {
|
||||
grandparent_direction = Direction::Left;
|
||||
} else {
|
||||
grandparent_direction = Direction::Right;
|
||||
}
|
||||
gr_grandparent->c_trans(grandparent_direction, sibling);
|
||||
} else {
|
||||
this->root = sibling - &this->nodes[0];
|
||||
}
|
||||
grandparent->rotate(!dir);
|
||||
|
||||
parent->color = Color::Black;
|
||||
grandparent->color = Color::Red;
|
||||
|
@ -488,28 +473,22 @@ private:
|
|||
|
||||
switch (dir) {
|
||||
case Direction::Left:
|
||||
// TODO: recalc this
|
||||
this->nodes[to_insert.value()].next = parent;
|
||||
this->nodes[to_insert.value()].prev = this->nodes[parent.value()].prev;
|
||||
this->nodes[parent.value()].prev = to_insert;
|
||||
this->nodes[parent.value()].left = to_insert;
|
||||
break;
|
||||
case Direction::Right:
|
||||
// TODO: recalc this
|
||||
this->nodes[to_insert.value()].prev = parent;
|
||||
this->nodes[to_insert.value()].next = this->nodes[parent.value()].next;
|
||||
// TODO: recalc this
|
||||
this->nodes[parent.value()].next = to_insert;
|
||||
this->nodes[parent.value()].right = to_insert;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (dir) {
|
||||
case Direction::Left:
|
||||
this->nodes[parent.value()].left = to_insert;
|
||||
break;
|
||||
case Direction::Right:
|
||||
this->nodes[parent.value()].right = to_insert;
|
||||
break;
|
||||
}
|
||||
|
||||
do {
|
||||
// don't need to keep track of these in between loops they get
|
||||
// recalculated
|
||||
|
@ -539,7 +518,13 @@ private:
|
|||
|
||||
if (!uncle.has_value() ||
|
||||
this->nodes[uncle.value()].color == Color::Black) {
|
||||
// case 5 and 6
|
||||
if (to_insert == this->nodes[parent.value()].c_select(!dir)) {
|
||||
// case 5
|
||||
this->nodes[parent.value()].rotate(dir);
|
||||
to_insert = parent;
|
||||
parent = this->nodes[grandparent.value()].c_select(dir);
|
||||
}
|
||||
// case 6
|
||||
this->handle_root_rotation(grandparent, parent, to_insert,
|
||||
parent_direction);
|
||||
return;
|
||||
|
@ -718,15 +703,18 @@ public:
|
|||
}
|
||||
// 2 children
|
||||
if (ref->l() != nullptr && ref->r() != nullptr) {
|
||||
// TODO: recalc this
|
||||
Ref_T next = ref->next;
|
||||
Ref_T prev = ref->prev;
|
||||
*ref = this->nodes[next.value()];
|
||||
// TODO: recalc this
|
||||
this->nodes[prev.value()].next = next;
|
||||
this->nodes[next.value()].prev = prev;
|
||||
this->erase(Iterator{*this, next});
|
||||
}
|
||||
// single child which is left
|
||||
else if (ref->l() != nullptr && ref->r() == nullptr) {
|
||||
// TODO: recalc this
|
||||
Ref_T next = ref->next;
|
||||
Ref_T prev = ref->prev;
|
||||
*ref = *ref->l();
|
||||
|
@ -735,13 +723,16 @@ public:
|
|||
}
|
||||
// single child which is right
|
||||
else if (ref->l() == nullptr && ref->r() != nullptr) {
|
||||
// TODO: recalc this
|
||||
Ref_T next = ref->next;
|
||||
Ref_T prev = ref->prev;
|
||||
*ref = *ref->r();
|
||||
if (prev.has_value()) {
|
||||
// TODO: recalc this
|
||||
this->nodes[prev.value()].next = next;
|
||||
}
|
||||
if (next.has_value()) {
|
||||
// TODO: recalc this
|
||||
this->nodes[next.value()].prev = prev;
|
||||
}
|
||||
}
|
||||
|
@ -755,8 +746,11 @@ public:
|
|||
ref->next.has_value() ? &this->nodes[ref->next.value()] : nullptr;
|
||||
Node *prev =
|
||||
ref->prev.has_value() ? &this->nodes[ref->prev.value()] : nullptr;
|
||||
|
||||
// TODO: recalc this
|
||||
prev->next = next != nullptr ? std::optional{next - &this->nodes[0]}
|
||||
: std::nullopt;
|
||||
// TODO: recalc this
|
||||
next->prev = prev != nullptr ? std::optional{prev - &this->nodes[0]}
|
||||
: std::nullopt;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue