Збалансовані дерева бінарного пошуку є важливими для гарантування O (log n) пошуку (або подібних операцій). У динамічному середовищі, де безліч клавіш вставлено і / або видалено, дерева можуть перерости у пов’язані списки, які є жахливими для пошуку. Таким чином, існують різні види самоврівноважуючих бінарних дерев, які протидіють цьому ефекту (наприклад, AVL-дерева чи хитрі дерева ). Ці дерева засновані на різних видах обертів, які врівноважують дерево.
Обертання
У цьому виклику ми розглянемо лише поодинокі праві обертання; таке обертання (ліве обертання було б симетричним) виглядає приблизно так:
5 3
/ \ / \
3 6 => 1 5
/ \ / \
1 4 4 6
Якщо будь-яке з листя 1
, 4
або 6
ліве або праве під деревце, обертання просто утримало б їх там. Якщо це піддерево більшого дерева, ми просто "відріжемо його" на вузлі 5
і "прикріпимо" повернене дерево (тепер вузол 3
) до цього вузла.
Виклик
Дано дерево бінарного пошуку 1 та клавішу праворуч поверніть дерево на цьому вузлі, як описано вище. Ключовим моментом у наведеному вище прикладі буде 5
.
Правила та введення / виведення
- Ви можете використовувати будь-який тип для клавіш до тих пір, поки між клавішами на ваш вибір та типовими тестами є біекція
- ви можете вибрати будь-яке представлення для двійкових дерев, якщо немає двозначності (наприклад
[3,[]]
, неоднозначно, якщо не вказано інше), і це природно для вашої мови вибору - оскільки вхід завжди буде двійковим деревом пошуку, не буде дублікатів ключів
- ви можете припустити, що ключ міститься в дереві
- ви можете припустити, що у вузла, що містить ключ, є ліва дитина
- ви не можете припустити потрібне піддерево під наданим ключем
- ви можете не припускати, що дерево не є рівноважним перед обертанням
- ви можете не припускати, що дерево врівноважується після обертання
- Ви можете використовувати будь-який метод вводу / виводу за замовчуванням
- ваше подання може бути функцією, що повертає дерево або повною програмою друкує рішення
Тестові справи
Ці приклади являють собою дерево наступним чином
- якщо це лист:
[]
- якщо це дерево з ключем,
x
і обидва підряди - це листя:[x]
- якщо це дерево з ключем
x
та підрядкамиleft
right
:[x,left,right]
Перший приклад - поданий у розділі Обертання . Якщо вам чомусь потрібне графічне зображення, тут ви переходите 2 .
5 [5,[3,[1],[4]],[6]] -> [3,[1],[5,[4],[6]]]
5 [5,[3,[1],[4]],[]] -> [3,[1],[5,[4],[]]]
5 [5,[3,[],[4]],[6]] -> [3,[],[5,[4],[6]]]
5 [5,[3,[1],[]],[]] -> [3,[1],[5]]
4 [8,[4,[2,[1],[3]],[6,[5],[7]]],[12,[10,[9],[11]],[14,[13],[15]]]] -> [8,[2,[1],[4,[3],[6,[5],[7]]]],[12,[10,[9],[11]],[14,[13],[15]]]]
8 [10,[8,[6,[4,[2,[],[3]],[5]],[7]],[9]],[11]] -> [10,[6,[4,[2,[],[3]],[5]],[8,[7],[9]]],[11]]
10 [10,[8,[6,[4,[2,[],[3]],[5]],[7]],[9]],[11]] -> [8,[6,[4,[2,[],[3]],[5]],[7]],[10,[9],[11]]]
9 [6,[3,[2],[5]],[9,[8],[12,[11],[15,[14],[]]]]] -> [6,[3,[2],[5]],[8,[],[9,[],[12,[11],[15,[14],[]]]]]]
7 [7,[5,[3,[1],[4]],[6]],[8]] -> [5,[3,[1],[4]],[7,[6],[8]]]
15 [17,[9,[5,[2,[0],[4]],[8]],[15,[13,[11,[10],[12]],[14]],[16]]],[40,[27,[21,[19,[18],[20]],[24,[22],[25]]],[28]],[44,[42,[41],[]],[51,[47],[59,[55],[61]]]]]] -> [17,[9,[5,[2,[0],[4]],[8]],[13,[11,[10],[12]],[15,[14],[16]]]],[40,[27,[21,[19,[18],[20]],[24,[22],[25]]],[28]],[44,[42,[41],[]],[51,[47],[59,[55],[61]]]]]]
21 [17,[9,[5,[2,[0],[4]],[8]],[15,[13,[11,[10],[12]],[14]],[16]]],[40,[27,[21,[19,[18],[20]],[24,[22],[25]]],[28]],[44,[42,[41],[]],[51,[47],[59,[55],[61]]]]]] -> [17,[9,[5,[2,[0],[4]],[8]],[15,[13,[11,[10],[12]],[14]],[16]]],[40,[27,[19,[18],[21,[20],[24,[22],[25]]]],[28]],[44,[42,[41],[]],[51,[47],[59,[55],[61]]]]]]
1: означає, що для будь-якого вузла всі клавіші в лівому піддереві будуть меншими за цей ключ, а всі ключі в правому піддереві є більшими за нього
2: щоб запобігти гниттю посилань, я вклав їх як коментар
data B=B[B]Int
дозволить заощадити ще кілька байт.