Los árboles de búsqueda binarios balanceados son esenciales para garantizar búsquedas O (log n) (u operaciones similares). En un entorno dinámico donde muchas claves se insertan y / o eliminan al azar, los árboles pueden degenerar en listas vinculadas que son horribles para las búsquedas. Por lo tanto, hay varios tipos de árboles binarios autoequilibrados que contrarrestan este efecto (como los árboles AVL o los árboles de separación ). Estos árboles se basan en diferentes tipos de rotaciones que reequilibran el árbol.
Rotaciones
En este desafío, solo veremos rotaciones derechas individuales, tal rotación (la rotación izquierda sería simétrica) se ve así:
5 3
/ \ / \
3 6 => 1 5
/ \ / \
1 4 4 6
Si alguna de las hojas 1
, 4
o 6
tuviera subárboles a la izquierda o derecha, una rotación simplemente las mantendría allí. Si este es un subárbol de un árbol más grande, simplemente lo "cortaríamos" en el nodo 5
y "volveríamos a unir" el árbol girado (ahora nodo 3
) a ese nodo.
Desafío
Dado un árbol de búsqueda binario 1 y una tecla, gire a la derecha el árbol en ese nodo como se describió anteriormente. La clave proporcionada en el ejemplo anterior sería 5
.
Reglas y E / S
- puede usar cualquier tipo de teclas siempre que haya una biyección entre las teclas de su elección y las de los casos de prueba
- puede elegir cualquier representación para árboles binarios siempre que no haya ambigüedad (por ejemplo,
[3,[]]
es ambigua a menos que se especifique lo contrario) y es natural para su idioma de elección - Como la entrada siempre será un árbol de búsqueda binario, no hay claves duplicadas
- puede suponer que la clave está contenida en el árbol
- puede suponer que el nodo que contiene la clave tiene un hijo izquierdo
- es posible que no asuma un subárbol derecho en la clave proporcionada
- es posible que no se asuma que el árbol está desequilibrado antes de la rotación
- es posible que no se asuma que el árbol está equilibrado después de la rotación
- puede usar cualquier método de E / S predeterminado
- su envío puede ser una función que devuelve el árbol o un programa completo que imprime la solución
Casos de prueba
Estos ejemplos representan un árbol de la siguiente manera
- si es una hoja:
[]
- si es un árbol con clave
x
y ambos subárboles son hojas:[x]
- si es un árbol con clave
x
y subárbolesleft
right
:[x,left,right]
El primer ejemplo es el proporcionado en la sección Rotaciones . Si por alguna razón necesita una representación gráfica de ellos, aquí 2 que vaya.
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: lo que significa que para cualquier nodo todas las claves en el subárbol izquierdo serán más pequeñas que esa clave y todas las claves en el subárbol derecho son mayores que
2: para evitar la rotura de enlaces, los incruste como comentario
data B=B[B]Int
ahorraría algunos bytes más.