mirror of https://github.com/PrimeDecomp/prime.git
More things for red_black_tree
This commit is contained in:
parent
7bff97b8be
commit
447aa387af
|
@ -41,8 +41,8 @@ private:
|
||||||
node_color mColor;
|
node_color mColor;
|
||||||
uchar mValue[sizeof(P)];
|
uchar mValue[sizeof(P)];
|
||||||
|
|
||||||
node(const P& value, node_color color = kNC_Red)
|
node(node* left, node* right, node* parent, node_color color, const P& value)
|
||||||
: mLeft(nullptr), mRight(nullptr), mColor(color), mParent(nullptr) {
|
: mLeft(left), mRight(right), mParent(parent), mColor(color) {
|
||||||
construct(get_value(), value);
|
construct(get_value(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,24 +55,27 @@ private:
|
||||||
void set_right(node* n) { mRight = n; }
|
void set_right(node* n) { mRight = n; }
|
||||||
};
|
};
|
||||||
struct header {
|
struct header {
|
||||||
node* mNode;
|
node* mLeftmost;
|
||||||
};
|
node* mRightmost;
|
||||||
|
node* mRootNode;
|
||||||
|
|
||||||
struct unknown {
|
void set_root(node* n) { mRootNode = n; }
|
||||||
node* x0_node;
|
void set_leftmost(node* n) { mLeftmost = n; }
|
||||||
const header* x4_header;
|
void set_rightmost(node* n) { mRightmost = n; }
|
||||||
bool x8_;
|
|
||||||
|
|
||||||
unknown(node* a, const header* h, bool b) : x0_node(a), x4_header(h), x8_(b) {}
|
node* get_root() const { return mRootNode; }
|
||||||
|
node* get_leftmost() const { return mLeftmost; }
|
||||||
|
node* get_rightmost() const { return mRightmost; }
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct const_iterator {
|
struct const_iterator {
|
||||||
node* mNode;
|
node* mNode;
|
||||||
const header* mHeader;
|
const header* mHeader;
|
||||||
|
bool x8_;
|
||||||
|
|
||||||
const_iterator(node* node, const header* header)
|
const_iterator(node* node, const header* header, bool b)
|
||||||
: mNode(node), mHeader(header) {}
|
: mNode(node), mHeader(header), x8_(b) {}
|
||||||
|
|
||||||
const P* operator->() const { return mNode->get_value(); }
|
const P* operator->() const { return mNode->get_value(); }
|
||||||
bool operator==(const const_iterator& other) const {
|
bool operator==(const const_iterator& other) const {
|
||||||
|
@ -96,21 +99,24 @@ public:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
struct iterator : public const_iterator {
|
||||||
|
iterator(node* node, const header* header, bool b) : const_iterator(node, header, b) {}
|
||||||
|
};
|
||||||
|
|
||||||
unknown insert_into(node* n, const P& item);
|
iterator insert_into(node* n, const P& item);
|
||||||
unknown insert(const P& item) { return insert_into(x10_rootNode, item); }
|
iterator insert(const P& item) { return insert_into(x8_header.get_root(), item); }
|
||||||
|
|
||||||
const_iterator begin() const {
|
const_iterator begin() const {
|
||||||
// TODO
|
// TODO
|
||||||
return const_iterator(nullptr, nullptr);
|
return const_iterator(x8_header.get_leftmost(), &x8_header, false);
|
||||||
}
|
}
|
||||||
const_iterator end() const {
|
const_iterator end() const {
|
||||||
// TODO
|
// TODO
|
||||||
return const_iterator(nullptr, nullptr);
|
return const_iterator(nullptr, &x8_header, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iterator find(const T& key) const {
|
const_iterator find(const T& key) const {
|
||||||
node* n = x10_rootNode;
|
node* n = x8_header.get_root();
|
||||||
node* needle = nullptr;
|
node* needle = nullptr;
|
||||||
while (n != nullptr) {
|
while (n != nullptr) {
|
||||||
if (!x1_cmp(x2_selector(*n->get_value()), key)) {
|
if (!x1_cmp(x2_selector(*n->get_value()), key)) {
|
||||||
|
@ -127,17 +133,53 @@ public:
|
||||||
if (noResult) {
|
if (noResult) {
|
||||||
needle = nullptr;
|
needle = nullptr;
|
||||||
}
|
}
|
||||||
return const_iterator(needle, nullptr);
|
return const_iterator(needle, &x8_header, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
// x0_allocator.deallocate(x10_rootNode);
|
||||||
|
node* root = x8_header.get_root();
|
||||||
|
if (root != nullptr) {
|
||||||
|
free_node_and_sub_nodes(root);
|
||||||
|
}
|
||||||
|
x8_header.set_root(nullptr);
|
||||||
|
x8_header.set_leftmost(nullptr);
|
||||||
|
x8_header.set_rightmost(nullptr);
|
||||||
|
x4_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
~red_black_tree() { clear(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Alloc x0_allocator;
|
Alloc x0_allocator;
|
||||||
Cmp x1_cmp;
|
Cmp x1_cmp;
|
||||||
S x2_selector;
|
S x2_selector;
|
||||||
int x4_count;
|
int x4_count;
|
||||||
header x8_headerA;
|
header x8_header;
|
||||||
header xc_headerB;
|
|
||||||
node* x10_rootNode;
|
node* create_node(node* left, node* right, node* parent, node_color color, const P& value) {
|
||||||
|
node* n;
|
||||||
|
x0_allocator.allocate(n, 1);
|
||||||
|
new (n) node(left, right, parent, color, value);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_node_and_sub_nodes(node* n) {
|
||||||
|
if (node* left = n->get_left()) {
|
||||||
|
free_node_and_sub_nodes(left);
|
||||||
|
}
|
||||||
|
if (node* right = n->get_right()) {
|
||||||
|
free_node_and_sub_nodes(right);
|
||||||
|
}
|
||||||
|
free_node(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_node(node* n) {
|
||||||
|
n->~node();
|
||||||
|
x0_allocator.deallocate(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rebalance(node* n) { rbtree_rebalance(&x8_header, n); }
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool kUnknownValueNewRoot = true;
|
static bool kUnknownValueNewRoot = true;
|
||||||
|
@ -145,42 +187,38 @@ static bool kUnknownValueEqualKey = false;
|
||||||
static bool kUnknownValueNewItem = true;
|
static bool kUnknownValueNewItem = true;
|
||||||
|
|
||||||
template < typename T, typename P, int U, typename S, typename Cmp, typename Alloc >
|
template < typename T, typename P, int U, typename S, typename Cmp, typename Alloc >
|
||||||
typename red_black_tree< T, P, U, S, Cmp, Alloc >::unknown
|
typename red_black_tree< T, P, U, S, Cmp, Alloc >::iterator
|
||||||
red_black_tree< T, P, U, S, Cmp, Alloc >::insert_into(node* n, const P& item) {
|
red_black_tree< T, P, U, S, Cmp, Alloc >::insert_into(node* n, const P& item) {
|
||||||
if (n == nullptr) {
|
if (n == nullptr) {
|
||||||
x0_allocator.allocate(n, 1);
|
x8_header.set_root(create_node(nullptr, nullptr, nullptr, kNC_Red, item));
|
||||||
new (n) node(item);
|
|
||||||
x10_rootNode = n;
|
|
||||||
x4_count += 1;
|
x4_count += 1;
|
||||||
x8_headerA.mNode = x10_rootNode;
|
x8_header.set_leftmost(x8_header.get_root());
|
||||||
xc_headerB.mNode = x10_rootNode;
|
x8_header.set_rightmost(x8_header.get_root());
|
||||||
return unknown(x10_rootNode, &x8_headerA, kUnknownValueNewRoot);
|
return iterator(x8_header.get_root(), &x8_header, kUnknownValueNewRoot);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
node* newNode = nullptr;
|
node* newNode = nullptr;
|
||||||
while (newNode == nullptr) {
|
while (newNode == nullptr) {
|
||||||
bool firstComp = x1_cmp(x2_selector(*n->get_value()), x2_selector(item));
|
bool firstComp = x1_cmp(x2_selector(*n->get_value()), x2_selector(item));
|
||||||
if (!firstComp && !x1_cmp(x2_selector(item), x2_selector(*n->get_value()))) {
|
if (!firstComp && !x1_cmp(x2_selector(item), x2_selector(*n->get_value()))) {
|
||||||
return unknown(n, &x8_headerA, kUnknownValueEqualKey);
|
return iterator(n, &x8_header, kUnknownValueEqualKey);
|
||||||
}
|
}
|
||||||
if (firstComp) {
|
if (firstComp) {
|
||||||
if (n->get_left() == nullptr) {
|
if (n->get_left() == nullptr) {
|
||||||
x0_allocator.allocate(newNode, 1);
|
newNode = create_node(nullptr, nullptr, n, kNC_Red, item);
|
||||||
new (newNode) node(item, kNC_Black);
|
|
||||||
n->set_left(newNode);
|
n->set_left(newNode);
|
||||||
if (n == x8_headerA.mNode) {
|
if (n == x8_header.get_leftmost()) {
|
||||||
x8_headerA.mNode = newNode;
|
x8_header.set_leftmost(newNode);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
n = n->get_left();
|
n = n->get_left();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (n->get_right() == nullptr) {
|
if (n->get_right() == nullptr) {
|
||||||
x0_allocator.allocate(newNode, 1);
|
newNode = create_node(nullptr, nullptr, n, kNC_Black, item);
|
||||||
new (newNode) node(item, kNC_Black);
|
|
||||||
n->set_right(newNode);
|
n->set_right(newNode);
|
||||||
if (n == xc_headerB.mNode) {
|
if (n == x8_header.get_rightmost()) {
|
||||||
xc_headerB.mNode = newNode;
|
x8_header.set_rightmost(newNode);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
n = n->get_right();
|
n = n->get_right();
|
||||||
|
@ -188,8 +226,8 @@ red_black_tree< T, P, U, S, Cmp, Alloc >::insert_into(node* n, const P& item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
x4_count += 1;
|
x4_count += 1;
|
||||||
rbtree_rebalance(&x8_headerA, newNode);
|
rebalance(newNode);
|
||||||
return unknown(newNode, &x8_headerA, kUnknownValueNewItem);
|
return iterator(newNode, &x8_header, kUnknownValueNewItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue