Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Двоичные деревья поиска и красно-черные деревья....doc
Скачиваний:
1
Добавлен:
05.11.2018
Размер:
235.01 Кб
Скачать

14 Красно-чёрные деревья

В главе 13 мы показали, что основные операции с двоичным деревом поиска высоты h могут быть выполнены за O(h) действий. Деревья эффективны, если их высота мала. Но малая высота не гарантируется, и в худшем случае деревья не более эффективны, чем списки. Красно-чёрные деревья — один из «сбалансированных» деревьев поиска; специальные операции балансировки гарантируют, что высота дерева не превзойдёт O(logn).

14.1. Свойства красно-чёрных деревьев

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

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

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

Двоичное дерево поиска называется красно-чёрным деревом, если оно дает следующими свойствами (будем называть их RB-свойствами, по-английс red-black properties):

  1. каждая вершина — либо красная, либо чёрная;

  2. каждый лист (nil) — чёрный;

  3. если вершина красная, оба её ребёнка чёрные;

  4. все пути, идущие вниз от корня к листьям, содержат одинаковое количество чёрных вершин.

Пример красно-чёрного дерева показан на рис. 14.1.

Рис. 14.1. Красно-чёрное дерево. Чёрные вершины показаны как тёмные, красные как серые. Каждая вершина либо красная, либо черная. Все nil-листья чёрные. Дети красной вершины -- чёрные. Для каждой вершины все пути от неё вниз к листьям содержат одинаковое количество чёрных вершин. Около каждой вершины (кроме листьев) записана её чёрная высота. Чёрная высота листьев равна 0.

Рассмотрим произвольную вершину х красно-чёрного дерева и пути, ве­дущие вниз от неё к листьям. Все они содержат одно и то же число чёрных вершин (добавим к ним путь из корня в х и применим свойство 4). Число чёрных вершин в любом из них (саму вершину х мы не считаем) будем называть чёрной высотой (black-height) вершины х и обозначать bh(ж). Чёрной высотой дерева будем считать чёрную высоту его корня.

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

Лемма 14.1. Красно-чёрное дерево с п внутренними вершинами (т. е. не считая NIL-листъев) имеет высоту не больше 21og(n + l).

Доказательство. Сначала покажем, что поддерево с корнем в х содержит по меньшей мере 2bh(x) — 1 внутренних вершин. Доказательство проведём индукци­ей от листьев к корню. Для листьев чёрная высота равна 0, и поддерево в самом деле содержит не менее 2bh(x) 1 = 2° — 1 — 0 внутренних вершин. Пусть теперь вершина х не является листом и имеет чёрную высоту k. Тогда оба её ребёнка имеют чёрную высоту не меньше k1 (красный ребёнок будет иметь высоту А:, чёрный — k1). По предположению индукции левое и правое поддеревья вер­шины х содержат не менее 2k-1 — 1 вершин, и потому поддерево с корнем в х содержит по меньшей мере 2k-1 — 1 + 2k-1 — 1 + 1 = 2k — 1 внутренних вершин. Чтобы завершить доказательство леммы, обозначим высоту дерева через h. Согласно свойству 3, по меньшей мере половину всех вершин на пути от корня к листу, не считая корень, составляют чёрные вершины. Следовательно, чёрная высота дерева не меньше h/2. Тогда

Перенесём 1 налево и перейдём к логарифмам. Получим log(n + 1)h/2, или 2log(n + 1)h Тем самым для красно-чёрных деревьев операции search, minimum, successor и predecessor выполняются за время O(logn), так как их выполнения есть O(h) для дерева высоты h, а красно-чёрное дерево с n шинами имеет высоту О (log n).

Сложнее обстоит дело с процедурами TREE-INSERT и TREE-DELETE из главы 13: проблема в том, что они могут испортить структуру красно-чёрного дерева, нарушив RB-свойства. Поэтому эти процедуры придется модифицировать. Мы увидим в разделах 14.3 и 14.4, как можно реализовать добавление, удаление элементов за время O(logn) с сохранением RB-свойств.