Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
40
Добавлен:
19.04.2015
Размер:
80.88 Кб
Скачать

Красно-черные деревья поиска

Красно-черные деревья - один из способов балансировки деревьев. Название происходит от стандартной раскраски узлов таких деревьев в красный и черный цвета. Цвета узлов используются при балансировке дерева. Во время операций вставки и удаления поддеревья может понадобиться повернуть, чтобы достигнуть сбалансированности дерева. Оценкой как среднего время, так и наихудшего является O(log n).

Теория Красно-черное дерево - это бинарное дерево с следующими свойствами:

  • Каждый узел покрашен либо в черный, либо в красный цвет.

  • Листьями объявляются NIL-узлы (т.е. "виртуальные" узлы, наследники узлов, которые обычно называют листьями; на них "указывают" NULL указатели). Листья покрашены в черный цвет.

  • Если узел красный, то оба его потомка черны.

  • На всех ветвях дерева, ведущих от его корня к листьям, число черных узлов одинаково.

ВСТАВКА

Чтобы вставить узел, мы сначала ищем в дереве место, куда его следует добавить. Новый узел всегда добавляется как лист, поэтому оба его потомка являются NIL-узлами и предполагаются черными. После вставки красим узел в красный цвет. После этого смотрим на предка и проверяем, не нарушается ли красно-черное свойство. Если необходимо, мы перекрашиваем узел и производим поворот, чтобы сбалансировать дерево.

Рассмотрим ситуацию, когда предок нового узла красный: при этом будет нарушено свойство 3. Достаточно рассмотреть следующие два случая:

  • Красный предок, красный "дядя": Ситуацию красный-красный иллюстрирует рис. 1. Простое перекрашивание избавляет нас от красно-красного нарушения. После перекраски нужно проверить "дедушку" нового узла (узел B), поскольку он может оказаться красным. Обратите внимание на распространение влияния красного узла на верхние узлы дерева. В самом конце корень мы красим в черный цвет корень дерева. Если он был красным, то при этом увеличивается черная высота дерева.

  • Красный предок, черный "дядя": На рис. 3.7 представлен другой вариант красно-красного. Здесь узлы может понадобиться вращать, чтобы скорректировать поддеревья. В этом месте алгоритм может остановиться из-за отсутствия красно-красных конфликтов и вершина дерева (узел A) окрашивается в черный цвет.

Каждая корректировка, производимая при вставке узла, заставляет нас подняться в дереве на один шаг. В этом случае до остановки алгоритма будет сделано 1 вращение (2, если узел был правым потомком). Метод удаления аналогичен.

Вращения

{-------------LL------------}

T^.left:=p1^.right;

p1^.right:=T;

P1^.lred:=false;

T:=P1

{-------------LR------------}

P2:=P1^.right; P1^.rred:=false;

P1^.right:=P2^.left;

P2^.left:=P1;

T^.left:=P2^.right;

P2^.right:=T; T:=P2

{------------RR------------}

T^.right:=p1^.left;

p1^.left:=T;

P1^.rred:=false;

T:=P1

{------------RL------------}

P2:=P1^.left; P1^.lred:=false;

P1^.left:=P2^.right;

P2^.right:=P1;

T^.right:=P2^.left;

P2^.left:=T; T:=P2

Поиск вершины

Процедура поиска аналогична поиску в бинарном дереве.

Добавление вершины

Добавление вершины в красно-черное дерево производится за время O(log n).

После добавления вершины выполняются все свойства красно-черного дерева, кроме одного: красная вершина x может иметь красного родителя, и это нарушение единственно. Восстанавливается это свойство очень просто: пока вершина x не корень дерева и имеет красного родителя выполняем следующие действия:

  • Если дядя вершины x красного цвета, то красим его и отца вершины x в черный цвет, а дедушку вершины x в красный цвет. Далее вершиной x становится дедушка.

  • Если дядя вершины х черного цвета, то проверяем являются ли вершина x и его отец одинаковыми детьми (т.е. оба ЛЕВЫЕ или ПРАВЫЕ дети). Если не являются одинаковыми детьми, то делаем соответствующие вращение (становятся одинаковыми детьми). Красим отца в черный цвет. Далее делаем соответствующее вращение; Будем полагать, что во всех красно-черных деревьях корень черный и поддерживать это свойство.

Удаление вершины

Как и другие операции, удаление вершины из красно-чёрного дерева требует времени O(log n). Удаление вершины несколько сложнее добавления.

Для начала находим вершину z в дереве, которую требуется удалить. Возможны три случая:

  • если у вершины z нет детей, для удаления z достаточно поместить NIL в соответствующее поле его родителя (вместо z).

  • если у z один ребенок, то можно вырезать z, соединив его родителя напрямую с его ребенком.

  • если у z двое детей, то мы находим следующий (в смысле порядка на ключах) за z элемент y; у него нет левого ребенка. Теперь можно скопировать ключ и дополнительные данные из вершины y в вершину z, а саму вершину y удалить выше описанным способом.

Если была удалена черная вершина, то надо восстановить свойства красно-черного дерева (при удалении красной вершины свойства дерева не нарушаются). Пусть вершина x - ребенок удаленной вершины. Пока вершина x не корень дерева и она чёрная вершина выполняем следующие действия:

  • если у вершины x брат красного цвета, то делаем ВРАЩЕНИЕ (брат становится родителем отца), при этом брата красим в черный, а отца в красный.

  • если у вершины x брат чёрного цвета, то

    • если у брата оба ребенка черные, то красим брата в красный цвет. Теперь вершиной x будет его отец.

    • если у брата его "одинаковый" ребёнок черного цвета, то красим брата в красный цвет и делаем вращение.

    • иначе красим брата в цвет отца, отца красим в черный цвет. Делаем вращение и выходим из цикла.

Красно-чёрные деревья являются одними из наиболее активно используемых на практике самобалансирующихся деревьев поиска.

Временная сложность поиска: O(log n) в лучшем случае. Поскольку красно-чёрное дерево, в худшем случае, выше, поиск в нём медленнее, но проигрыш по времени не превышает 39%.

Максимальная длина пути – 2 log N. Операции поиска – за O(log N).

Соседние файлы в папке Структуры и алгоритмы компьютерной обработки данных