
- •Определение и свойства авл-дерева
- •Повороты при балансировке
- •Алгоритм на псевдокоде
- •Алгоритм на псевдокоде
- •Алгоритм на псевдокоде
- •Алгоритм на псевдокоде
- •28. Добавление вершины в авл – дерево.
- •Алгоритм на псевдокоде
- •29. Удаление вершины в авл – дереве.
- •Алгоритм на псевдокоде
- •Алгоритм на псевдокоде
- •Алгоритм на псевдокоде
- •Алгоритм на псевдокоде
- •Алгоритм на псевдокоде
- •30. Красно – черные деревья. Свойства. Вращение. Высота красно – черного дерева.
- •Повороты
- •Операции поворота в бинарном дереве поиска
- •31. Добавление вершины в красно – черном дереве.
- •32. Удаление вершины в красно – черном дереве.
32. Удаление вершины в красно – черном дереве.
Удаление из RB-дерева также требует O(log n)времени. Удаление вершины несколько сложнее добавления. Для упрощения удаления в дереве используется вместо значения NIL фиктивные элементы nil[T]. Более того, физически в дереве присутствует один фиктивный элемент, на который ссылаются все листья дерева и узлы, имеющие одного сына. Фиктивный элемент имеет те же поля, что и другие узлы, т.е. p, left, right, key и color, причем в алгоритмах играют роль только поля p и color. Цвет фиктивного элемента всегда черный. Благодаря фиктивному элементу все узлы внутренние.
Операция RB_Delete работает такаже, как и Interative_Tree_Delete. Но вырезав вершину, она вызывает вспомогательную операцию RB_FixUp, которая перекрашивает узлы или производит вращения для восстановления RB-свойств после удаления узла. Эта операция используется, если вырезан черный узел.
RB_Delete (T, z)
if left[x] = nil [T] or right[T] = nil [T]
then y ← 2
else y ← Tree_Successor (z)
if left [y] ≠ nil [T]
then x ← left [y]
else x ← right [y]
p [x] ← p[y] вырезание, в фиктивный элемент записывается родитель у
if p [y] = nil
then root [T] ← x
else if y = left [p[y]]
then left [p [y]] ← x
else right [p[y]] ← x
if y ≠ z
then key [z] ← key [y]
копируем дополнительные данные из вершины у
if color [y] = BLACK
then RB_FixUp (T, x)
return y
Отличия RB_Delete от Interative_Tree_Delete:
вместо nil используется nil[T];
в строке 7 нет проверки if x ≠nil и p[x]←p[y] выполняется всегда, т.е. фиктивный элемент начинает ссылаться на родителя вырезаемого узла;
используется RB_FixUp в случае вырезания черного узла. Вырезание его приводит к нарушению четвертого RB-свойства . Вырезание красного узла не приводит к нарушению RB-свойств.
При удалении черного узла возможны 2 ситуации:
В
первом случае нарушение можно
компенсировать перекрасив узел х в
черный цвет. Это позволит ликвидировать
и нарушение третьего свойства, если
родитель вырезанного узла у – красный.
Во втором случае применяется перестройка в корне поддерева, где возникло нарушение четвертого свойства. Причем узел х считается дважды черным, способным поделиться своей чернотой с вышележащими на пути к нему узлами.
Нужно перестроить вышележащие узлы таким образом, чтобы избавиться от дважды черного узла, не нарушив RB-свойств дерева.
Если х – корень, тогда лишняя чернота просто удаляется из дерева. Иначе выполняется циклическая перестройка корней поддеревьев, лежащих на пути к х, путем перекрашивания и вращений влево или вправо. Перестройка учитывает 4 возможных случая, которые могут встретиться на пути.
Р
ассмотрим
эти случаи:
Э
то
наиболее благоприятный случай. Можно
перекрасить родителя х в черный цвет,
х сделать обычным черным узлом, а w
– красным. На этом перестройка
заканчивается. Если родитель х – черный,
то он становится дважды черным и
перестройка поднимается в верхнее
поддерево.
Е
сли
новый х – корень дерева, то лишняя
чернота просто удаляется из дерева.
Почти случай 1.
Этот случай можно свести к первому, чтобы братом х стал черный узел. Для этого сделаем левый поворот родителя узла х.
3
).
Теперь разберемся со случаями, отличными
от 1, т.е. когда сыновья w
разного цвета: Перекрасив родителя х
в черный цвет, а w – в
красный , мы нарушим свойство 3 для w.
П
оэтому
сделаем сначала правый поворот узла w.
Для случая 4 важно, что правый сын узла w – красный. Перекрашивать нельзя. Левый сын может быть и красным и черным. Опять же действие по схеме случая 1 не годится, т.к. это приведет к нарушению свойства 3.
Тогда произведем вращение влево родителя х. Узел х отдает свою черноту родителю, а правый сын узла w перекрашивается в черный цвет. Узел w берет цвет корня поддерева до поворота.
В этом случае происходит полное поглощение излишней черноты и на этом перестройка прекращается.
Итак, рассмотрев действия в различных случаях, подробно рассмотрим только операцию RB_FixUp (T, x).
RB_FixUp (T, x)
while x ≠ root [T] and color [x] = BLACK
dv if x = left [p[x]]
then w ← right [p[x]]
if color [w] = RED случай 2
then color [w] ← BLACK
color [p[x]] ← RED
Left_Rotate (T, p[x])
w ← right [p[x]]
if color [left [w]] = BLACK and color [right [w]] = BLACK
then color [w] ←RED случай 1
x ← p[x]
else if color [right [w]] = BLACK случай 3
then color [left [w]] ← BLACK
color [w] ← RED
Right_Rotate (T, w)
w ← right [p[x]]
color [w] ← color [p[x]] случай 4
color [p[x]] ← BLACK
color [right [w]] ← BLACK
Left_Rotate [T, p[x]]
x ← root [T]
else (симметричный фрагмент с заменой left на right)
color [x] ← BLACK
Операция RB_Delete выполняется за O(log n). Обычно производится не более трех вращений.