Красно-черное дерево — различия между версиями
Анна (обсуждение | вклад) (→Преимущества красно-чёрных деревьев) |
Анна (обсуждение | вклад) (→Свойства) |
||
Строка 15: | Строка 15: | ||
# Все простые пути из любого узла x до листьев содержат одинаковое количество чёрных узлов | # Все простые пути из любого узла x до листьев содержат одинаковое количество чёрных узлов | ||
# Чёрный узел может иметь чёрного родителя | # Чёрный узел может иметь чёрного родителя | ||
+ | |||
+ | Определим ослабленное красно-чёрное дерево как красно-чёрное дерево, корень которого может быть как чёрным, так и красным. Тогда корень всегда может быть изменен с красного на чёрный с сохранением всех свойств. Но вот при изменении цвета корня с чёрного на красный дерево может перестать удовлетворять свойствам <tex>3</tex> и <tex>4</tex>. Тогда даже если мы перекрасим все вершины так, чтобы у красного узла не было красных потомков, свойство <tex>4</tex> все равно может не выполняться. | ||
{{Определение | {{Определение |
Версия 12:09, 13 мая 2015
Определение: |
Красно-чёрное дерево (англ. red-black tree) — двоичное дерево поиска, в котором баланс осуществляется на основе "цвета" узла дерева, который принимает только два значения: "красный" (англ. red) и "чёрный" (англ. black). |
При этом все листья дерева являются фиктивными и не содержат данных, но относятся к дереву и являются чёрными.
Для экономии памяти фиктивные листья можно сделать одним общим фиктивным листом.
Содержание
Свойства
Красно-чёрным называется бинарное поисковое дерево, у которого каждому узлу сопоставлен дополнительный аттрибут — цвет и для которого выполняются следующие свойства (англ. red-black properties):
- Каждый узел промаркирован красным или чёрным цветом
- Корень и конечные узлы(листья) дерева — чёрные
- У красного узла родительский узел — чёрный
- Все простые пути из любого узла x до листьев содержат одинаковое количество чёрных узлов
- Чёрный узел может иметь чёрного родителя
Определим ослабленное красно-чёрное дерево как красно-чёрное дерево, корень которого может быть как чёрным, так и красным. Тогда корень всегда может быть изменен с красного на чёрный с сохранением всех свойств. Но вот при изменении цвета корня с чёрного на красный дерево может перестать удовлетворять свойствам
и . Тогда даже если мы перекрасим все вершины так, чтобы у красного узла не было красных потомков, свойство все равно может не выполняться.
Определение: |
Будем называть чёрной высотой (англ. black-height) вершины | число чёрных вершин на пути из в лист, не учитывая саму вершину .
Высота красно-черного дерева
Теорема: | ||||||
Красно-чёрное дерево с ключами имеет высоту . | ||||||
Доказательство: | ||||||
Если обычная высота дерева равна , то черная высота дерева будет не меньше и, по лемме, количество внутренних вершин в дереве
Прологарифмировав неравенство, имеем:
| ||||||
Операции
Вставка элемента
Каждый элемент вставляется вместо листа, поэтому для выбора места вставки идём от корня до тех пор, пока указатель на следующего сына не станет
(то есть этот сын — лист). Вставляем вместо него новый элемент с -потомками и красным цветом. Теперь проверяем балансировку. Если отец нового элемента красный, то достаточно рассмотреть только два случая:1. "Дядя" этого узла тоже красный. Тогда просто перекрашиваем "отца" и "дядю" в чёрный цвет, а "деда" — в красный. Проверяем, не нарушает ли он теперь балансировку. Если в результате этих перекрашиваний мы дойдём до корня, то в нём в любом случае ставим чёрный цвет.
2. "Дядя" чёрный. Если выполнить только перекрашивание, то может нарушиться постоянство чёрной высоты дерева по всем ветвям. Поэтому выполняем поворот. Если добавляемый узел был правым потомком, то необходимо сначала выполнить левое вращение, которое сделает его левым потомком.
Удаление вершины
При удалении вершины могут возникнуть три случая в зависимости от количества её детей:
- Если у вершины нет детей, то изменяем указатель на неё у родителя на .
- Если у неё только один ребёнок, то делаем у родителя ссылку на него вместо этой вершины.
- Если же имеются оба ребёнка, то находим вершину со следующим значением ключа. У такой вершины нет левого ребёнка. Удаляем уже эту вершину описанным во втором пункте способом, скопировав её ключ в изначальную вершину.
Проверим балансировку дерева. Так как при удалении красной вершины свойства дерева не нарушаются, то восстановление балансировки потребуется только при удалении чёрной. Рассмотрим ребёнка удалённой вершины.
1. Если брат этого ребёнка красный, то делаем вращение вокруг ребра между отцом и братом, тогда брат становится родителем отца. Красим его в чёрный, а отца - в красный цвет.
2. Если брат текущей вершины был чёрным, то получаем три случая:
- Оба ребёнка у брата чёрные. Красим брата в красный цвет и рассматриваем далее отца вершины.
- Если у брата правый ребёнок чёрный, а левый красный, то перекрашиваем брата и его левого сына и делаем вращение.
- Если у брата правый ребёнок красный, то перекрашиваем брата в цвет отца, его ребёнка и отца - в чёрный, делаем вращение и выходим из алгоритма.
Продолжаем тот же алгоритм, пока текущая вершина чёрная и мы не дошли до корня дерева. Из рассмотренных случаев ясно, что при удалении выполняется не более трёх вращений.
Объединение красно-чёрных деревьев
Объединение двух красно-чёрных деревьев
и по элементу x выполняется, когда и . Найдём чёрные высоты деревьев. Предположим также, что . Тогда в дереве ищем среди чёрных вершин, имеющих чёрную высоту , вершину с наибольшим ключом. Пусть — поддерево с корнем . Объединяем это дерево с в одно с красным корнем . Теперь родителем вершины становится бывший отец вершины . Осталось восстановить свойства красно-черного дерева, чтобы у красной вершины не было красных детей. Делается аналогично алгоритму добавления вершины.Так как общее время выполнения каждой из операций порядка высоты дерева ,то все они выполняются за
.Рассмотрим пример объединения двух красно-чёрных деревьев и вершины
:Узнаём чёрную высоту левого и правого дерева. Чёрная высота левого и правого деревьев равна
и соответственно. Так как чёрная высота левого дерева больше, то ищем в левом дереве чёрную вершину, имеющую чёрную высоту правого дерева, с наибольшим ключом. Чёрная высота вершины левого дерева равна высоте правого дерева и ключ является наибольшим. Поэтому вершина становится левым сыном вершины , а правое дерево будет правым сыном. Вершина станет правым сыном вершины :Далее проверяем: не нарушили ли мы свойства красно-чёрного дерева. Так как присутствует нарушение(у красной вершины есть красный сын), то перекрасим вершины и сделаем поворот:
Преимущества красно-чёрных деревьев
При вставке выполняется не более
вращений.Использует всего 1 бит дополнительной памяти для хранения цвета вершины. Но на самом деле в современных вычислительных системах память выделяется кратно байтам, поэтому это не является преимуществом относительно, например, АВЛ-дерева, которое хранит 2 бита. То есть используются целые числа, так как работа с битами требует дополнительных процессорных вычислений. Однако есть реализации красно-чёрного дерева, которые хранят значение цвета в бите. Пример — Boost Multiindex. В этой реализации уменьшается потребление памяти красно-чёрным деревом, так как бит цвета хранится не в отдельной переменной, а в одном из указателей узла дерева (этот прием опасен выходом за границу доступной памяти).
Красно-чёрные деревья являются наиболее активно используемыми на практике самобалансирующимися деревьями поиска. В частности, ассоциативные контейнеры библиотеки STL(map, set, multiset, multimap) основаны на красно-чёрных деревьях.
Источники информации
- Википедия — Красно-чёрное дерево
- AlgoList — Красно-черные деревья
- Lectures.stargeo — Конспект лекций
- Курс kiev-clrs — Лекция 10. Красно-чёрные деревья