30. Красно – черные деревья. Свойства. Вращение. Высота красно – черного дерева.
Красно-черные деревья представляют собой одну из множества «сбалансированных» схем деревьев поиска, которые гарантируют время выполнения операций над динамическим множеством O(log2n) даже в наихудшем случае.
Красно-черное дерево (red-black tree) — это двоичное дерево поиска, вершины которого разделены на красные (red) и черные (black). Таким образом каждая вершина хранит один дополнительный бит — её цвет.
При этом выполняются определённые требования, которые гарантируют, что глубины любых двух листьев отличаются не более чем в два раза.
Каждая вершина красно-черного дерева имеет поля color (цвет), key (ключ), left (левый ребенок), right (правый ребенок) и p (родитель). Если у вершины отсутствует ребенок или родитель, то соответствующее поле содержит NIL.
Двоичное дерево поиска называется красно-черным, если оно обладает следующими свойствами:
- каждая вершина — либо черная, либо красная ;
- корень дерева является черным;
- каждый лист (NIL) — чёрный ;
- если вершина красная, оба её ребенка чёрные ;
- все пути, идущие вниз от корня к листьям, содержат одинаковое количество чёрных вершин.
Повороты
Операции над деревом поиска Tree_Insert и Tree_Delete, будучи применены к красно-черному дереву с n ключами, выполняются за время O(log2n). Поскольку они изменяют дерево, в результате их работы могут нарушаться красно-черные свойства. Для восстановления этих свойств мы должны изменить цвета некоторых узлов дерева, а также структуру его указателей. Изменения в структуре указателей будут выполняться при помощи поворотов (rotations), которые представляют собой локальные операции в дереве поиска, сохраняющие свойство бинарного дерева поиска. На рис. показаны два типа поворотов — левый и правый (здесь
Операции поворота в бинарном дереве поиска
В псевдокоде процедуры Left_Rotate предполагается, что right[х]
- у
right[x] Устанавливаем у. - right[x]
left[y] Левое поддерево у становится правым поддеревом х
3 if left[y]
- р[у]
р[х] Перенос родителя х в у - if p[x] = nil[T]
- then root[T]
у - else if x = left[p[х]]
9 then left [p[x]]
- left[y]
x x— левый дочерний у - p[x]
у
31. Добавление вершины в красно – черном дереве.
Сначала выполняется обычная операция включения в двоичное дерево Tree_Insert и новая вершина помечается красным цветом. После этого восстанавливаются RB-свойства, если они нарушены путем перекраски вершин и вращений. Рассмотрим случаи нарушения RB-свойств на примере включения в дерево: П
- Tree_Insert (T, x)
- color [x] ← RED
- while x ≠ root [T] and color [p[x]] = RED
- dv if p[x] = left [p[p[x]]]
- then y ← right [p[p[x]]]
- if color [y] = RED
then color [p[x]] ← BLACK случай 1 color [y] ← BLACK случай 1 color [p[p[x]]] ← RED случай 1 x ← p[p[x]] случай 1 - else if x = right [p[x]]
then x ← p[x] случай 2 Left_Rotate (T, x) случай 2 color [p[x]] ← BLACK случай 3 color [p[p[x]]] ← RED случай 3 Right_Rotate (T, p[p[x]]) случай 3 - else (симметричный текст с заменой left ↔ right)
- color [root[T]] ← BLACK
При включении, если выпадает случай 3, выполняется не более одного вращения, и в случае 2 – не более двух вращений.
Источник