Красно-чёрное дерево: различия между версиями
Перейти к навигации
Перейти к поиску
Ctrlalt (обсуждение | вклад) (Новая страница: «== Правила == * Каждый узел является красным или чёрным. * Корень и (воображаемые) nullptr-потом...») |
Ctrlalt (обсуждение | вклад) (→Ссылки) |
||
| Строка 121: | Строка 121: | ||
Теория: | Теория: | ||
* [https://neerc.ifmo.ru/wiki/index.php?title=Красно-черное_дерево neerc.ifmo.ru/wiki — Красно-черное_дерево] | |||
* [https://disk.yandex.ru/i/7LKoFkz7vP7-8A Вставка в красно-чёрное дерево] | |||
* [https://algs4.cs.princeton.edu/lectures/keynote/33BalancedSearchTrees.pdf algs4.cs.princeton.edu — Balanced Search Trees] | |||
Демонстрация: | Демонстрация: | ||
* [https://www.cs.usfca.edu/~galles/visualization/RedBlack.html www.cs.usfca.edu — Red/Black Tree] | |||
Код: | Код: | ||
* [https://github.com/kevin-wayne/algs4/blob/master/src/main/java/edu/princeton/cs/algs4/RedBlackBST.java kevin-wayne/algs4/RedBlackBST.java] | |||
Текущая версия от 23:12, 26 апреля 2023
Правила
- Каждый узел является красным или чёрным.
- Корень и (воображаемые) nullptr-потомки листьев — чёрные.
- Родитель красного узла обязан быть чёрным (потомок и родитель не могут быть красными одновременно, не может быть двух красных узлов подряд);
- Все простые пути пути от любой вершины до любого листа в её поддереве содержат одинаковое количество чёрных узлов.
Код
class RBTree {
struct Node {
int key;
Node *l = nullptr, *r = nullptr, *p = nullptr;
char color = 'R';
Node *other(Node *n) {
return l == n ? r : l;
}
} *root = nullptr;
bool find(Node *node, int key) const {
if (!node)
return false;
if (key == node->key)
return true;
return find(key < node->key ? node->l : node->r, key);
}
void rotateLeft(Node *x) {
Node *y = x->r;
x->r = y->l;
if (y->l)
y->l->p = x;
y->p = x->p;
if (!x->p)
root = y;
else if (x == x->p->l)
x->p->l = y;
else
x->p->r = y;
y->l = x;
x->p = y;
}
void rotateRight(Node *x) {
Node *y = x->l;
x->l = y->r;
if (y->r)
y->r->p = x;
y->p = x->p;
if (!x->p)
root = y;
else if (x == x->p->r)
x->p->r = y;
else
x->p->l = y;
y->r = x;
x->p = y;
}
void fix(Node *me) {
if (me->color == 'B')
return;
Node *dad = me->p;
if (dad && dad->color == 'B')
return;
Node *grandDad = dad->p, *uncle = grandDad ? grandDad->other(dad) : nullptr;
if (uncle && uncle->color == 'R') {
dad->color = uncle->color = 'B';
grandDad->color = 'R';
return;
}
if (me == dad->r && dad == grandDad->l) {
rotateLeft(dad);
return fix(me->l);
}
if (me == dad->l && dad == grandDad->r) {
rotateRight(dad);
return fix(me->r);
}
dad->color = 'B';
grandDad->color = 'R';
if (me == dad->l) {
rotateRight(grandDad);
} else {
rotateLeft(grandDad);
}
}
void insert(Node *&node, int key) {
if (!node) {
node = new Node({ key });
return;
}
if (key < node->key) {
insert(node->l, key);
node->l->p = node;
fix(node->l);
} else {
insert(node->r, key);
node->r->p = node;
fix(node->r);
}
}
public:
bool find(int key) const {
return find(root, key);
}
void insert(int key) {
insert(root, key);
root->color = 'B';
}
};
Ссылки
Теория:
- neerc.ifmo.ru/wiki — Красно-черное_дерево
- Вставка в красно-чёрное дерево
- algs4.cs.princeton.edu — Balanced Search Trees
Демонстрация:
Код: