Zrównoważone drzewa wyszukiwania binarnego są niezbędne do zagwarantowania wyszukiwania O (log n) (lub podobnych operacji). W dynamicznym środowisku, w którym wiele kluczy jest losowo wstawianych i / lub usuwanych, drzewa mogą zdegenerować się do połączonych list, które są straszne przy wyszukiwaniu. Tak więc istnieją różne rodzaje równoważących się drzew binarnych, które przeciwdziałają temu efektowi (takie jak drzewa AVL lub drzewa rozrośnięte ). Drzewa te są oparte na różnych rodzajach rotacji, które ponownie równoważą drzewo.
Rotacje
W tym wyzwaniu przyjrzymy się tylko pojedynczym obrotom w prawo, taki obrót (obrót w lewo byłby symetryczny) wygląda następująco:
5 3
/ \ / \
3 6 => 1 5
/ \ / \
1 4 4 6
Jeżeli którykolwiek z liści 1
, 4
lub 6
miał prawo sub-trees lewo lub obrót po prostu trzymać je tam. Jeśli jest to poddrzewo większego drzewa, po prostu „odetniemy” go w węźle 5
i „ponownie dołączymy” obrócone drzewo (teraz węzeł 3
) do tego węzła.
Wyzwanie
Biorąc pod uwagę drzewo wyszukiwania binarnego 1 i klucz, obróć drzewo w tym węźle, jak opisano powyżej. Kluczem podanym w powyższym przykładzie byłoby 5
.
Reguły i I / O
- możesz użyć dowolnego typu dla kluczy, o ile istnieje sprzeczność między kluczami wybranymi przez ciebie a kluczami przypadków testowych
- możesz wybrać dowolną reprezentację dla drzew binarnych, o ile nie ma dwuznaczności (np.
[3,[]]
jest niejednoznaczna, chyba że określono inaczej) i jest to naturalne dla wybranego języka - ponieważ dane wejściowe będą zawsze drzewem wyszukiwania binarnego, nie ma duplikatów kluczy
- możesz założyć, że klucz jest zawarty w drzewie
- możesz założyć, że węzeł zawierający klucz ma lewe dziecko
- możesz nie przyjąć właściwą poddrzewo pod warunkiem kluczem
- możesz nie przyjąć, że drzewo jest niezrównoważony przed obrotem
- możesz nie przyjąć, że drzewo jest równoważony po obrocie
- możesz użyć dowolnej domyślnej metody We / Wy
- Twoje zgłoszenie może być funkcją zwracającą drzewo lub pełny program drukujący rozwiązanie
Przypadki testowe
Te przykłady przedstawiają drzewo w następujący sposób
- jeśli to liść:
[]
- jeśli jest to drzewo z kluczem,
x
a oba poddrzewa są liśćmi:[x]
- jeśli jest to drzewo z kluczem
x
i poddrzewamileft
right
:[x,left,right]
Pierwszym przykładem jest ten przedstawiony w sekcji Obroty . Jeśli z jakiegoś powodu potrzebujesz ich graficznej reprezentacji, oto 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: co oznacza, że dla dowolnego węzła wszystkie klucze w lewym poddrzewie będą mniejsze niż ten klucz, a wszystkie klucze w prawym poddrzewie będą większe niż ten
2: aby zapobiec gniciu linków, umieściłem je jako komentarz
data B=B[B]Int
pozwoliłoby zaoszczędzić trochę więcej bajtów.