Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 51

Структури даних, аналіз

і алгоритми комп'ютерної
обробки інформації
Лекції Бичкова Олексія
КРАХ ОСВІТИ – ЦЕ КРАХ
НАЦІЇ
Зміст
• Червоно-чорні бінірні дерева
Червоно-чорні бінірні дерева
Червоно-чорні бінарні дерева це бінарні
дерева з додатковим атрибутом – колір:
червоний або чорний.
Властивості: жоден простий шлях від від
кореня до найдальшого листа не більше ніж
у двічі довше чим від кореня до
найближчого.
Червоно-чорні бінірні дерева
Червоно-чорне дерево широко
використовується переважно для зберігання
впорядкованих даних, його часова складність
становить O(lgn), а ефективність дуже
висока.
Червоно-чорні бінірні дерева
Якщо вузол не має батьківського вузла або
дочірних то відповідні вказівники на NUL
називаються вказівниками на зовнішнішні
вузли.
Усі інши вузли називаютья внутрішніми.
Червоно-чорні бінірні дерева
Властивості:
1. Кожен вузол червоний або чорний
2. Корінь дерева – чорний
3. Кожен лист дерева (NUL) – чорний
4. Якщо вузол червоний, то дочірні від нього – чорні.
5. Для кожного вузла всі прості шляхи від нього до
листя, що є потомками даного вузла, мають
однакову кулість чорних вузлів.
Червоно-чорні бінірні дерева

Для спрощення операцій зробим так:


Червоно-чорні бінірні дерева
Червоно-чорні бінірні дерева
Вузол T.nul має чорний колір.
Усі вузли, що мали дочрні вказівники NUL
тепер можна розглядати як звичайні вузли.
Кількість чорних вузлів на будь-якому
простому шляху від вузла x (крім сам вузол)
до листа називатимемо чорною висотою
вузла і позначати як bh(x).
Червоно-чорні бінірні дерева
Відповідно до властивості 5 червоно-чорних
дерев чорна висота вузла - точне значення,
оскільки всі низхідні прості шляхи з вузла
містять однакову кількість чорних вузлів.
Чорною висотою дерева вважатимемо чорну
висоту його кореня.
Червоно-чорні бінірні дерева
Червоно-чорне дерево з n внутрішніми
вузлами має висоту, що не перевищує
2lg (n+1).
Тому такі операції над ними, як SEARCH,
MINIMUM, MAXIMUM, PREDECESSOR і
SUCCESSOR, при використанні червоно-
чорних дерев виконуються за час O(lgn).
Червоно-чорні бінірні дерева
Операції TREE-INSERT і TREE-DELETE над деревом
пошуку з n ключами теж виконуються за час О(Ign).
Оскільки вони змінюють дерево, в результаті їх
роботи можуть порушуватись чорно-червоні
властивості. Для відновлення цих властивостей
необхідно змінити кольори деяких вузлів дерева, а
також структуру його вказівників
Червоно-чорні бінірні дерева
Для відновлення цих властивостей необхідно
змінити кольори деяких вузлів дерева, а також
структуру його вказівників.
Зміни в структурі покажчиків будуть виконуватися
за допомогою поворотів, які являють собою
локальні операції в дереві пошуку, що зберігають
властивість бінарного дерева пошуку (не плутайте з
відображенням)
Червоно-чорні бінірні дерева
Червоно-чорні бінірні дерева
LEFT-ROTATE(T,x)
у = х.right
х.right = у.left
if (у.left != Т.nul)
у.left.parent = х
у.parent = х.parent
Червоно-чорні бінірні дерева
if (х.parent == Т.nul)
Т.root = y
elseif (х == х.parent.left)
х.parent.left = y
else х.parent.right = y
y.left = х
х.parent = y
Червоно-чорні бінірні дерева
Червоно-чорні бінірні дерева
Вставка.
Вставка вузла в червоно-чорне дерево з n вузлами
може бути виконана за час O(lgn).
Для вставки вузла z у дерево Т ми використовуємо
трохи модифіковану версію процедури TREE-
INSERT, яка вставляє вузол у дерево, ніби це було
звичайне бінарне дерево пошуку, а потім забарвлює
його в червоний колір.
Червоно-чорні бінірні дерева
Для того, щоб вставка зберігала червоно-чорні
властивості дерева, після неї викликається
допоміжна процедура RB-INSERT-FIXUP, яка
перефарбовує вузли та виконує повороти.
Червоно-чорні бінірні дерева
RB-INSERT (T, z)
y = T.nul
х = T.root
while (x!=Т.nul)
y=x
if (z.key < x.key)
x = x.left
else x = x.right
z.parent = у
Червоно-чорні бінірні дерева
if (у == T.nul)
T.root = z
elseif (z.key < y.key)
y.left = z
else y.right=z
z.left = T.nul
z.right = T.nul
z.color = RED
RB-INSERT-FIXUP (T, z)
Червоно-чорні бінірні дерева
Ми бачимо, що всі NUL в TREE-INSERT замінені на
T.nul. Для підтримки коректності структури дерева
в RB-INSERT виконується присвоєння Т.nul
атрибутам z.left і z.right.
Також ми призначаємо вузлу z червоний колір.
Після присвоювання червоного коліру z
викликається допоміжна процедура RB-INSERT-
FIXUP(Т, z), призначення якої відновити червоно-
чорні властивості дерева.
Червоно-чорні бінірні дерева
RB-INSERT-FIXUP(Т, z)
1 while (z.parent. color == RED)
2 if (z.parent == z.parent.parent.left)
3 у = z.parent.parent. right
4 if y.color == RED
5 z.parent.color = BLACK
6 y.color = BLACK
7 z.parent.parent.color = RED
8 z = z.parent.parent
9 elseif (z == z.parent.right)
Червоно-чорні бінірні дерева
10 z = z.parnt
11 LEFT-ROTATE(T, z)
12 z.parent.color = BLACK
13 z.parent.parent.color = RED
14 RIGHT-ROTATE (T, z.parent.parent)
15 else (те саме, що й у частині then, але із
заміною "правого" (right) "лівим" (left) і навпаки)
16 Т.root.color = BLACK
Червоно-чорні бінірні дерева
Цикл while зберігає на початку кожної ітерації циклу
такий інваріант, що складається із трьох частин:
а. Вузол z червоний.
б. Якщо z.parent - коріння, то z.parent - чорний.
в. Якщо є порушення червоно-чорних властивостей, це
порушення лише одне — або порушення властивості 2,
або властивості 4. Якщо порушено властивість 2, це
викликано тим, що коренем дерева є червоний вузол z;
якщо порушено властивість 4, то в цьому випадку
червоними є вузли z і z.parent.
Червоно-чорні бінірні дерева
Вставка (продовження пояснення).
Кожен елемент вставляється замість листа,
тому для вибору місця вставки йдемо від
кореня доти, доки вказівник на наступного
сина не стане nul (тобто цей син – лист).
Вставляємо замість нього новий елемент з
nul-нащадками та червоним кольором.
Червоно-чорні бінірні дерева
Червоно-чорні бінірні дерева
Тепер перевіряємо балансування.
Якщо батько нового елемента чорний, жодна
з властивостей дерева не порушена.
Червоно-чорні бінірні дерева
Якщо він червоний, то порушується
властивість 3

Для виправлення достатньо розглянути два


випадки:
Червоно-чорні бінірні дерева

"Дядько" цього вузла теж червоний. Тоді, щоб


зберегти властивості 3 і 4, просто
перефарбовуємо "батька" та "дядька" у
чорний колір, а "діда" - у червоний.
Червоно-чорні бінірні дерева

У такому разі чорна висота в цьому піддереві


починаючі з В) однакова для всіх листків і у
всіх червоних вершин "батьки" чорні.
Червоно-чорні бінірні дерева
Перевіряємо вверх, чи не порушено
балансування:
Якщо батько діда нового елемента чорний,
жодна з властивостей дерева не порушена.
Червоно-чорні бінірні дерева
Якщо він червоний, то порушується
властивість 3 і повторюємо попередню
процедуру.
Червоно-чорні бінірні дерева
Якщо в результаті цих перефарбувань
(виконання попередньої) процедури ми
дійдемо до кореня, то в ньому в будь-якому
разі ставимо чорний колір, щоб дерево
задовольняло властивість 2.
Червоно-чорні бінірні дерева
Червоно-чорні бінірні дерева
Видалення вершини.
При видаленні вершини можуть виникнути
три випадки в залежності від кількості дітей:
1. Якщо вершина не має дітей, то змінюємо
вказівник на неї у батька на nul.
2. Якщо у неї лише одна дитина, то робимо у
батька посилання на неї замість цієї вершини.
Червоно-чорні бінірні дерева
3. Якщо є обидві дитини, то знаходимо
вершину з наступним значенням ключа. У
такої вершини немає лівої дитини, оскільки
така вершина знаходиться в правому
піддереві вихідної вершини і вона найлівіша
в ньому, інакше б ми взяли її ліву дитину.
Червоно-чорні бінірні дерева
Іншими словами спочатку ми переходимо в
праве піддерево, а потім спускаємося вниз по
лівому піддереву доти , поки у вершини є
ліва дитина.
Видаляємо вже цю вершину описаним у
другому пункті способом, скопіювавши її
ключ у початкову вершину.
Червоно-чорні бінірні дерева
Перевіримо балансування дерева. Так як при
видаленні червоної вершини властивості
дерева не порушуються, відновлення
балансування знадобиться тільки при
видаленні чорної.
Розглянемо дитину віддаленої вершини:
Червоно-чорні бінірні дерева
1. Якщо брат цієї дитини червоний, то
робимо обертання навколо ребра між батьком
та братом, тоді брат стає батьком батька.
Фарбуємо його у чорний, а батька – у
червоний колір, зберігаючи таким чином
чорну висоту дерева.
Червоно-чорні бінірні дерева

Хоча всі шляхи, як і раніше, містять однакову


кількість чорних вузлів, зараз x має чорного
брата і червоного батька. Таким чином, ми
можемо перейти до наступного кроку.
Червоно-чорні бінірні дерева
2. Якщо брат поточної вершини був чорним,

то отримуємо три випадки:


Червоно-чорні бінірні дерева
а) Обидві дитини у брата чорні. Фарбуємо
брата у червоний колір та розглядаємо далі
батька вершини. Робимо його чорним, це не
вплине на кількість чорних вузлів на шляхах,
що проходять через b, але додасть один вузол
до числа чорних вузлів на шляхах, що
проходять через x, відновлюючи тим самим
вплив віддаленого чорного вузла.
Червоно-чорні бінірні дерева
Таким чином, після видалення вершини
чорна висота від батька цієї вершини до всіх
листків у цьому піддереві буде однаковою.
Червоно-чорні бінірні дерева
б) Якщо у брата права дитина чорна, а ліва
червона,

то перефарбовуємо брата та його лівого сина


у протилежні кольори і робимо обертання.
Червоно-чорні бінірні дерева
Червоно-чорні бінірні дерева
Всі шляхи, як і раніше, містять однакову
кількість чорних вузлів, але тепер у x є
чорний брат з червоним правим нащадком, і
ми переходимо до наступного випадку.
Ні x, ні його батько не впливають на цю
трансформацію.
Червоно-чорні бінірні дерева
Якщо у брата права дитина червона,

то перефарбовуємо брата в колір батька; його


дитину і батька - в чорну; робимо обертання.
Червоно-чорні бінірні дерева
Червоно-чорні бінірні дерева
Піддерево, як і раніше, має той же колір кореня,
тому властивість 3 і 4 не порушуються. Але у них
тепер з'явився додатковий чорний предок:
• або a став чорним;
• або він і був чорним і b був доданий як чорний
дід.
Червоно-чорні бінірні дерева
Таким чином, шляхи що проходять через x
проходять через один додатковий чорний вузол.
Продовжуємо алгоритм, поки поточна вершина
чорна і ми не дійшли до кореня дерева.
Виходимо з алгоритму.

You might also like