На этом шаге мы рассмотрим еще один двухкратный поворот.
Этот алгоритм ничем не отличается от рассмотренного на предыдущем шаге, только поворот осуществляется в другую сторону.
Приведем текст алгоритма:
p1 =(*p).Right; p2 = (*p1).Left; (*p1).Left = (*p2). Right; (*p2). Right = p1; (*p).Right = (*p2). Left; (*p2). Left = *p; p = p2;
Рассмотрим его использование на конкретном примере.
Пусть дано следующее дерево:
Рис.1. Исходное дерево
Иллюстрируем алгоритм с помощью схем "до и после" Д.Кнута:
p1 = (*p).Right; p2 = (*p1).Left;
Рис.2. Определение p1 и p2
(*p1).Left = (*p2). Right;
Рис.3. Переприкрепление
(*p2). Right = p1;
Рис.4. Определение правого поддерева "нового" корня
(*p).Right = (*p2). Left;
Рис.5. Переприкрепление
(*p2). Left = *p;
Рис.6. Определение правого поддерева "нового" корня
p = p2;
Рис.7. Установка начальных значений
В результате получилось следующее сбалансированное дерево:
Рис.8. Результат балансировки
Проиллюстрируем эту несбалансированность и ее устранение следующими рисунками:
Рис.9. Несбалансированность (отмечены узлы, вызвавшие несбалансированность)
Рис.10. Несбалансированность устранена (отмечены узлы, вызвавшие несбалансированность)
Итак, все случаи, в которых после вставки необходима дополнительная балансировка для сохранения свойств АВЛ-дерева, ограничиваются разобранными случаями и случаями зеркального отражения этих структур.
На следующем шаге мы разберем алгоритм построения АВЛ-дерева.