Чему равна максимальная высота красно черного дерева

30. Красно – черные деревья. Свойства. Вращение. Высота красно – черного дерева.

Красно-черные деревья пред­ставляют собой одну из множества «сбалансированных» схем деревьев поиска, ко­торые гарантируют время выполнения операций над динамическим множеством O(log2n) даже в наихудшем случае.

Красно-черное дерево (red-black tree) — это двоичное дерево поиска, вершины которого разделены на красные (red) и черные (black). Таким образом каждая вершина хранит один дополнительный бит — её цвет.

При этом выполняются определённые требования, которые гарантируют, что глубины любых двух листьев отличаются не более чем в два раза.

Каждая вершина красно-черного дерева имеет поля color (цвет), key (ключ), left (левый ребенок), right (правый ребенок) и p (родитель). Если у вершины отсутствует ребенок или родитель, то соответствующее поле содержит NIL.

Двоичное дерево поиска называется красно-черным, если оно обладает следующими свойствами:

  1. каждая вершина — либо черная, либо красная ;
  2. корень дерева является черным;
  3. каждый лист (NIL) — чёрный ;
  4. если вершина красная, оба её ребенка чёрные ;
  5. все пути, идущие вниз от корня к листьям, содержат одинаковое количество чёрных вершин.

Повороты

Операции над деревом поиска Tree_Insert и Tree_Delete, будучи приме­нены к красно-черному дереву с n ключами, выполняются за время O(log2n). Поскольку они изменяют дерево, в результате их работы могут нарушаться крас­но-черные свойства. Для восстановления этих свойств мы должны изменить цвета некоторых узлов дерева, а также структу­ру его указателей. Изменения в структуре указателей будут выполняться при помощи поворотов (rotations), которые представляют собой локальные операции в дереве поиска, сохраняющие свойство бинарного дерева поиска. На рис. показаны два типа поворотов — левый и правый (здесь — произвольные поддеревья). При выполнении левого поворота в узлех предполагается, что его правый дочерний узел у не является листом nil [T]. Левый поворот выполняется «вокруг» связи между х и у, делая у новым корнем поддерева, левым дочерним узлом которого становится х, а бывший левый потомок узла у — правым потомком х.

Читайте также:  Крепежи пластины для дерева

Операции поворота в бинарном дереве поиска

В псевдокоде процедуры Left_Rotate предполагается, что right[х] nil [Т], а родитель корневого узла — nil[T]. Left_Rotate(T, х)

  1. у right[x] Устанавливаем у.
  2. right[x] left[y] Левое поддерево у становится правым поддеревом х

3 if left[y]nil[T] 4 then p[left[y]] х

  1. р[у]р[х] Перенос родителя х в у
  2. if p[x] = nil[T]
  1. then root[T]у
  2. else if x = left[p[х]]

9 then left [p[x]] у 10 else right[p[x]] у

  1. left[y] xx левый дочерний у
  2. p[x]у

31. Добавление вершины в красно – черном дереве.

Сначала выполняется обычная операция включения в двоичное дерево Tree_Insert и новая вершина помечается красным цветом. После этого восстанавливаются RB-свойства, если они нарушены путем перекраски вершин и вращений. Рассмотрим случаи нарушения RB-свойств на примере включения в дерево: При включении х нарушено третьеRB-свойство для вершины 5 (оба сына должны быть черные). Т.е. RB-свойство нарушается, если родитель нового узла красный. Как можно восстановить его: Случай 1: Если родитель красный, то родитель родителя – черный (в силу RB-свойства 2). Если у деда (7) второй сын – у ( дядя нового узла х) тоже красный, то можно перекрасить указанных предков: сделать деда красным, а родителя и дядю – черными. Это не изменит черную высоту дерева и восстановит третье свойство для родителя(5). После перекраски. Т.е. теперь 5 – черная вершина, которая может иметь и красного и черного сына. Но появился новый красный узел х(7). Теперь нарушено 3-еRB-свойство родителя узла 7 (2), т.к. этот узел тоже красный. К сожалению дядя (14) не красный и перекраску делать нельзя, не нарушив черной высоты. Тогда используем LL – поворот родителя х – (2). Исправлено нарушение 3-го свойства для узла 2, но нарушено для узла 7. Случай 3 отличается от случая 2 тем, что х является левым, а не правым сыном своего родителя. В этом случае делаем правый поворот родителя (11). Красную вершину 7, оказавшуюся в корне, окрашиваем в черную, а вершины 2 и 11 – в красные. Это не нарушит RB-свойство 4). RB_Insert (T, x)

  1. Tree_Insert (T, x)
  2. color [x] ← RED
  3. while x ≠ root [T] and color [p[x]] = RED
  4. dv if p[x] = left [p[p[x]]]
  5. then y ← right [p[p[x]]]
  6. if color [y] = RED
  7. then color [p[x]] ← BLACK случай 1
  8. color [y] ← BLACK случай 1
  9. color [p[p[x]]] ← RED случай 1
  10. x ← p[p[x]] случай 1
  11. else if x = right [p[x]]
  12. then x ← p[x] случай 2
  13. Left_Rotate (T, x) случай 2
  14. color [p[x]] ← BLACK случай 3
  15. color [p[p[x]]] ← RED случай 3
  16. Right_Rotate (T, p[p[x]]) случай 3
  17. else (симметричный текст с заменой left ↔ right)
  18. color [root[T]] ← BLACK
Читайте также:  Javascript обход всего дерева

При включении, если выпадает случай 3, выполняется не более одного вращения, и в случае 2 – не более двух вращений.

Источник

Оцените статью