红黑树c++实现
红黑树算法详解
红黑树算法详解
c++实现
c++实现参考
(一)使用示例:
#include <iostream>
using namespace rb_tree;
using namespace std;
int main() {
red_black_tree<int, int> tree{};
tree.insert(1, 100);
tree.insert(45324, -1);
tree.insert(-4324, 47845);
tree.insert(424324, 214);
tree.insert(7, -253456);
tree.insert(6, 214);
tree.remove(6);
tree.remove(7);
tree.remove(1);
int res = 0;
cout << static_cast<int>(tree.search(45324, res)) << endl;
cout << res << endl;
}
(二)代码(关键代码已注释):
namespace rb_tree {
enum class node_color { black, red };
enum class func_return { success, duplicate, not_found };
template <typename K, typename V>
class rb_tree_node {
public:
explicit rb_tree_node(const node_color color = node_color::black): color(color) {
}
rb_tree_node(const K& key, const V& value, const node_color color = node_color::black): key(key), value(value),
color(color) {
}
rb_tree_node<K, V>* parent = nullptr;
rb_tree_node<K, V>* l_child = nullptr;
rb_tree_node<K, V>* r_child = nullptr;
K key;
V value;
node_color color;
};
template <typename K, typename V>
class red_black_tree {
public:
red_black_tree();
~red_black_tree();
red_black_tree(const red_black_tree&) = delete;
red_black_tree operator=(const red_black_tree&) = delete;
red_black_tree(const red_black_tree&&) = delete;
red_black_tree operator=(const red_black_tree&&) = delete;
func_return insert(const K& key, const V& value);
func_return remove(const K& key);
func_return search(const K& key, V& value);
private:
void destroy(rb_tree_node<K, V>* node);
static rb_tree_node<K, V>* get_grandparent(rb_tree_node<K, V>* node);
static rb_tree_node<K, V>* get_uncle(rb_tree_node<K, V>* node);
rb_tree_node<K, V>* get_sibling(rb_tree_node<K, V>* node);
void insert_fix_up(rb_tree_node<K, V>* node);
void remove_fix_up(rb_tree_node<K, V>* node);
void rotate_left(rb_tree_node<K, V>* node);
void rotate_right(rb_tree_node<K, V>* node);
rb_tree_node<K, V>* root_;
rb_tree_node<K, V>* sentinel_;
};
template <typename K, typename V>
red_black_tree<K, V>::red_black_tree() {
sentinel_ = new rb_tree_node<K, V>();
root_ = sentinel_;
}
template <typename K, typename V>
red_black_tree<K, V>::~red_black_tree() {
destroy(root_);
delete sentinel_;
sentinel_ = nullptr;
}
template <typename K, typename V>
void red_black_tree<K, V>::destroy(rb_tree_node<K, V>* node) {
if (node != nullptr && node != sentinel_) {
destroy(node->l_child);
destroy(node->r_child);
delete node;
}
}
template <typename K, typename V>
rb_tree_node<K, V>* red_black_tree<K, V>::get_grandparent(rb_tree_node<K, V>* node) {
if (node != nullptr && node->parent != nullptr)
return node->parent->parent;
return nullptr;
}
template <typename K, typename V>
rb_tree_node<K, V>* red_black_tree<K, V>::get_uncle(rb_tree_node<K, V>* node) {
auto g = get_grandparent(node);
if (g != nullptr)
return node->parent == g->l_child ? g->r_child : g->l_child;
return nullptr;
}
template <typename K, typename V>
rb_tree_node<K, V>* red_black_tree<K, V>::get_sibling(rb_tree_node<K, V>* node) {
if (node != nullptr && node->parent != nullptr) {
auto p = node->parent;
return node == p->l_child ? p->r_child : p->l_child;
}
return nullptr;
}
template <typename K, typename V>
void red_black_tree<K, V>::rotate_left(rb_tree_node<K, V>* node) {
if (node == nullptr || node->r_child == nullptr)
return;
auto t = node->r_child;
node->r_child = t->l_child;
if (t->l_child)
t->l_child->parent = node;
if (node == root_) {
root_ = t;
t->parent = nullptr;
}
else {
auto p = node->parent;
t->parent = p;
if (node == p->l_child)
p->l_child = t;
else
p->r_child = t;
}
t->l_child = node;
node->parent = t;
}
template <typename K, typename V>
void red_black_tree<K, V>::rotate_right(rb_tree_node<K, V>* node) {
if (node == nullptr || node->l_child == nullptr)
return;
auto t = node->l_child;
node->l_child = t->r_child;
if (t->r_child)
t->r_child->parent = node;
if (node == root_) {
root_ = t;
t->parent = nullptr;
}
else {
auto p = node->parent;
t->parent = p;
if (node == p->l_child)
p->l_child = t;
else
p->r_child = t;
}
t->r_child = node;
node->parent = t;
}
template <typename K, typename V>
func_return red_black_tree<K, V>::insert(const K& key, const V& value) {
auto t = root_;
decltype(t) p = nullptr;
while (t != sentinel_) {
p = t;
if (t->key == key)
return func_return::duplicate;
t = t->key < key ? t->r_child : t->l_child;
}
auto new_node = new rb_tree_node<K, V>(key, value, node_color::red);
new_node->l_child = sentinel_;
new_node->r_child = sentinel_;
[[unlikely]]if (root_ == sentinel_) {
root_ = new_node;
}
else {
new_node->parent = p;
if (p->key > key)
p->l_child = new_node;
else
p->r_child = new_node;
}
insert_fix_up(new_node);
root_->color = node_color::black;
sentinel_->parent = nullptr;
return func_return::success;
}
template <typename K, typename V>
void red_black_tree<K, V>::insert_fix_up(rb_tree_node<K, V>* node) {
decltype(node) u = nullptr;
decltype(node) g = nullptr;
while (node != root_ && node->parent->color == node_color::red) {
u = get_uncle(node);
g = get_grandparent(node);
if (u->color == node_color::red) {
node->parent->color = node_color::black;
u->color = node_color::black;
g->color = node_color::red;
node = g;
}
else {
auto p = node->parent;
if (g->l_child == p) {
if (node == p->r_child) {
node = p;
rotate_left(node);
p = node->parent;
}
g->color = node_color::red;
p->color = node_color::black;
rotate_right(g);
}
else {
if (node == p->l_child) {
node = p;
rotate_right(node);
p = node->parent;
}
g->color = node_color::red;
p->color = node_color::black;
rotate_left(g);
}
break;
}
}
}
template <typename K, typename V>
func_return red_black_tree<K, V>::remove(const K& key) {
auto d = root_;
while (d != sentinel_) {
if (d->key == key)
break;
d = d->key < key ? d->r_child : d->l_child;
}
if (d == sentinel_)
return func_return::not_found;
decltype(d) sub = nullptr;
if (d->l_child == sentinel_ && d->r_child == sentinel_)
sub = d;
else if (d->l_child == sentinel_)
sub = d->r_child;
else if (d->r_child == sentinel_)
sub = d->l_child;
else {
sub = d->l_child;
while (sub->r_child != sentinel_)
sub = sub->r_child;
}
if (d != sub) {
d->key = sub->key;
d->value = sub->value;
}
decltype(d) sub_child = sub->l_child;
if (auto p = sub->parent) {
if (sub == p->l_child)
p->l_child = sub_child;
else
p->r_child = sub_child;
}
else
root_ = sub_child;
sub_child->parent = sub->parent;
if (sub->color == node_color::black)
remove_fix_up(sub_child);
delete sub;
sentinel_->parent = nullptr;
return func_return::success;
}
template <typename K, typename V>
void red_black_tree<K, V>::remove_fix_up(rb_tree_node<K, V>* node) {
decltype(node) s = nullptr;
while (node != root_ && node->color == node_color::black) {
s = get_sibling(node);
if (s == s->parent->l_child) {
if (s->color == node_color::red) {
s->color = node_color::black;
s->parent->color = node_color::red;
rotate_right(s->parent);
s = node->parent->l_child;
}
if (s->l_child->color == node_color::black && s->r_child->color == node_color::black) {
s->color = node_color::red;
if (node->parent->color == node_color::red) {
node->parent->color = node_color::black;
break;
}
node = node->parent;
}
else {
if (s->l_child->color == node_color::black) {
s->color = node_color::red;
s->r_child->color = node_color::black;
rotate_left(s);
s = node->parent->l_child;
}
s->color = s->parent->color;
s->parent->color = node_color::black;
s->l_child->color = node_color::black;
rotate_right(s->parent);
break;
}
}
else {
if (s->color == node_color::red) {
s->color = node_color::black;
s->parent->color = node_color::red;
rotate_left(s->parent);
s = node->parent->r_child;
}
if (s->l_child->color == node_color::black && s->r_child->color == node_color::black) {
s->color = node_color::red;
if (node->parent->color == node_color::red) {
node->parent->color = node_color::black;
break;
}
node = node->parent;
}
else {
if (s->r_child->color == node_color::black) {
s->color = node_color::red;
s->l_child->color = node_color::black;
rotate_right(s);
s = node->parent->r_child;
}
s->color = s->parent->color;
s->parent->color = node_color::black;
s->r_child->color = node_color::black;
rotate_left(s->parent);
break;
}
}
}
}
template <typename K, typename V>
func_return red_black_tree<K, V>::search(const K& key, V& value) {
auto t = root_;
while (t != sentinel_) {
if (t->key == key) {
value = t->value;
return func_return::success;
}
t = t->key > key ? t->l_child : t->r_child;
}
return func_return::not_found;
}
}
|