Download Cap. 6 - Universidad de La Serena

Document related concepts

Árbol de intervalo wikipedia , lookup

Recorrido de árboles wikipedia , lookup

Árbol binario wikipedia , lookup

Árbol-B wikipedia , lookup

Árbol binario de búsqueda wikipedia , lookup

Transcript
Diseño y Análisis de Algoritmos
Dr. Eric Jeltsch F.
CAPITULO 6 - Estructuras de Datos Avanzadas
Contenidos:
1. Estructura de Datos Avanzadas.
2. SkipList,
3. Trie, Arboles Sufijo, Arboles Búsqueda Digital, Arboles Trie y Patricia,
4. Algoritmos de Selección, Arboles Min –Max, y otros.
5. Enfasis en transformaciones, rotaciones, buscar, insertar y borrar con sus costos asociados y
aplicaciones.
Skip lists
Se sabe que una de las maneras más simples de implementar el TDA diccionario es utilizando una
lista enlazada, pero también se sabe que el tiempo de búsqueda promedio es O(n) cuando el
diccionario posee n elementos. Es decir, el costo de una búsqueda en el caso peor es lineal en el
número de nodos. Por otra parte, claramente es imposible realizar una búsqueda binaria, ya sea por
bisección o por trisección, sobre una lista enlazada ordenada; porque no existe manera de calcular
desde las direcciones de dos elementos i y j, con valores xi y xj para X, la dirección de un elemento
con un valor de X intermedio entre xi y xj . Esto se debe a que las celdas que contienen elementos de
la lista pueden provenir arbitrariamente desde cualquier parte de la memoria.
De hecho, ésa fue la razón que nos llevó a acotar el uso de dicho tipo de listas; a pesar de que las
modificaciones estructurales sobre ellas eran poco costosas (de orden (1)).
Es así como la localización es secuencial y, por lo tanto, el peor caso de localización exitosa sería
de N celdas consultadas (el peor caso de localización sería de N +1 celdas consultadas). La figura
siguiente muestra un ejemplo de lista enlazada simple con “head”, donde los elementos están
ordenados ascendentemente:
La existencia de las Skip List, se debe William Pugh:
De manera que, es posible modificar la estructura de datos de la lista y así mejorar el tiempo de
búsqueda promedio. La siguiente figura muestra una lista enlazada en donde a cada nodo par se le
________________________________________________________________________
Escuela Ingeniería en Computación, Universidad de La Serena
1
Diseño y Análisis de Algoritmos
Dr. Eric Jeltsch F.
agrega una referencia al nodo ubicado dos posiciones más adelante en la lista. Modificando
ligeramente el algoritmo de búsqueda, a lo más techo(n/2)+1 nodos son examinados en el peor caso.
Tal como se puede apreciar, para n=10,
Esta idea se puede extender agregando una referencia cada cuatro nodos. En este caso, a lo más
techo(n/4)+2 nodos son examinados:
El caso límite para este argumento se muestra en la siguiente figura. Cada 2i nodo posee una
referencia al nodo 2i posiciones más adelante en la lista. El número total de punteros se ha
duplicado (con respecto a la lista enlazada inicial). Ahora el tiempo de una búsqueda está acotado
superiormente por techo(log2 n), porque la búsqueda consiste en avanzar al siguiente nodo (por el
puntero alto) o bajar al nivel siguiente de punteros y seguir avanzando…En esencia, se trata de una
búsqueda binaria. Notar que el número total de referencias solo ha sido doblado, pero ahora a lo
más techo(log2 n) nodos son examinados durante la búsqueda. Note que la búsqueda en esta
estructura de datos es básicamente una búsqueda binaria, por lo que el tiempo de búsqueda en el
peor caso es O(log n).
El problema que tiene esta estructura de datos es que es demasiado rígida para permitir inserciones
de manera eficiente. Por lo tanto, es necesario relajar levemente las condiciones descritas
anteriormente para permitir inserciones eficientes.
Se define un nodo de nivel k como aquel nodo que posee k referencias. Se observa de la figura
anterior que, aproximadamente, la mitad de los nodos son de nivel 1, que un cuarto de los nodos son
de nivel 2, etc. En general, aproximadamente n/2i nodos son de nivel i. Cada vez que se inserta un
nodo, se elige el nivel que tendrá aleatoriamente en concordancia con la distribución de
probabilidad descrita. Con esta idea logramos mejorar los esfuerzos de localización, pero a costa de
aumentar la cantidad de punteros; es decir, de aumentar el espacio utilizado para la representación
de la estructura. En general, si tenemos una lista con n elementos, tendremos a lo sumo log n
punteros por celda. En la mayoría de las celdas no se necesitarían tantos punteros, porque la mitad
de los elementos necesitan sólo un único campo de puntero, y de los restantes elementos sólo la
mitad necesitaría un puntero adicional, y así sucesivamente. De manera que, hay n/2 celdas con sólo
1 puntero, n/4 celdas con 2 punteros, n/8 celdas con 3 punteros; y en general, n/2i celdas con i
punteros.
i
La skip list en sí misma se puede implementar como una estructura de registro de dos campos:
Cabecera, la cual sería una celda ficticia para comenzar las listas, y Nivel, el cual sería un entero
que daría el nivel más grande de cualquier celda presente actualmente en la lista. Una celda tendría,
además de los campos para almacenar X e Y, una tabla de apuntadores a las siguientes celdas de
________________________________________________________________________
Escuela Ingeniería en Computación, Universidad de La Serena
2
Diseño y Análisis de Algoritmos
Dr. Eric Jeltsch F.
acuerdo a las listas en las que dicha celda participa. El tamaño de esta tabla dependería del nivel de
la celda, pero dicho número no necesitaría ser almacenado en la celda. Inicialmente el Nivel de una
skip list sería 0 y todos los apuntadores apuntarían a la celda ficticia final cuyo valor almacenado en
el campo X sería, como ya habíamos expresado, el valor considerado “” para cualquier valor
posible de X. La siguiente figura muestra la situación inicial de una skip list con máximo nivel = 3:
Por ejemplo, se puede lanzar una moneda al aire, y mientras salga cara se aumenta el nivel del nodo
a insertar en 1 (partiendo desde 1). Esta estructura de datos es denominada skip list. La siguiente
figura muestra un ejemplo de una skip list:
Búsqueda en una skip list
Suponga que el elemento a buscar es X. Se comienza con la referencia superior de la cabecera. Se
realiza un recorrido a través de este nivel (pasos horizontales) hasta que el siguiente nodo sea mayor
que X o sea null. Cuando esto ocurra, se continúa con la búsqueda pero un nivel más abajo (paso
vertical). Cuando no se pueda bajar de nivel, esto es, ya se está en el nivel inferior, entonces se
realiza una comparación final para saber si el elemento X está en la lista o no. El algoritmo sería
algo así:
- Comenzando con los punteros del mayor nivel, seguirlos hasta que se encuentre un
elemento con valor de X mayor o igual que el x buscado.
- Si en dicha celda el valor de X encontrado es igual al x buscado, paramos y la búsqueda tuvo
éxito; si en otro caso es mayor que el x buscado, volvemos hacia atrás un puntero y continuamos
siguiendo los punteros del siguiente nivel más bajo.
- Si un puntero de nivel 0 guía a un elemento con valor de X mayor que el x buscado, paramos y la
búsqueda fracasó.
Ejemplo:
-
Se empieza con el puntero más alto de la “head”.
________________________________________________________________________
Escuela Ingeniería en Computación, Universidad de La Serena
3
Diseño y Análisis de Algoritmos
-
Dr. Eric Jeltsch F.
Se continúa por ese nivel hasta encontrar un nodo con clave mayor que la buscada (o
NIL), entonces se desciende un nivel y se continúa de igual forma.
Cuando el avance se detiene en el nivel 1, se está frente al nodo con la clave buscada o tal
clave no existe en la lista.
Inserción en una skip list
Se procede como en la búsqueda, manteniendo una marca en los nodos donde se realizaron pasos
verticales, hasta llegar al nivel inferior. El nuevo elemento se inserta en la posición en donde
debiera haberse encontrado, se calcula aleatoriamente su nivel y se actualizan las referencias de los
nodos marcados dependiendo del nivel del nuevo nodo de la lista.
Para insertar un elemento en una skip list necesitaríamos primero tener una rutina que genere los
números aleatorios apropiados del nivel. En general, se puede contar con una función Random()
disponible en la mayoría de los lenguajes de programación, la cual devuelve un número aleatorio k
en el rango 0 k < 1 con distribución uniforme.
Ejemplo:
Primero: para insertar un nuevo elemento hay que decidir de qué nivel debe ser.
• En una lista de las del “caso límite” la mitad de los nodos son de nivel 1, una cuarta parte de nivel
2 y, en general, 1/2i nodos son de nivel i.
• Se elige el nivel de un nuevo nodo de acuerdo con esas probabilidades: se tira una moneda al aire
hasta que salga cara, y se elige el número total de lanzamientos realizados como nivel del nodo.
Distribución geométrica de parámetro p = 1/2. (En realidad se puede plantear con un parámetro
arbitrario, p, y luego seleccionar qué valor de p es más adecuado).
Segundo: hay que saber dónde insertar.
• Se hace igual que en la búsqueda, guardando traza de los nodos en los que se desciende de nivel.
Se determina aleatoriamente el nivel del nuevo nodo y se inserta, enlazando los punteros
convenientemente.
En la dirección dada más abajo, encontraran una buena simulación de la inserción de una clave, en
este caso 11, aunque la probabilidad no aparece mencionada, sino que se genera aleatoriamente.
________________________________________________________________________
Escuela Ingeniería en Computación, Universidad de La Serena
4
Diseño y Análisis de Algoritmos
Dr. Eric Jeltsch F.
http://eupt2.unizar.es/asignaturas/itig/estructuras_de_datos/temario/Skip-Lists.html
Borrado en una skip list
La eliminación en una skip list es bastante similar a la inserción, primero se debe localizar al
elemento manteniendo, como ya habíamos mencionado máximo nivel +1 apuntadores, donde punti
mantendrá un puntero a la celda de más a la derecha de nivel i o superior que es anterior a la
posición de la celda que contiene el x buscado. Pero, para poder utilizar la misma rutina de
Localización para todas las otras rutinas, es necesario que la localización exitosa llegue
indefectiblemente hasta el nivel 0 y no se detenga en niveles mayores para así poder registrar, en los
punteros auxiliares, las direcciones de todas las celdas que son factibles de modificación luego de la
baja. Por lo tanto, luego de que la localización tenga éxito y conociendo las direcciones de las
celdas anteriores a la celda que se quiere dar de baja, en las listas de cada uno de los niveles, se
procede a actualizar sólo los apuntadores de los niveles hasta el nivel de la celda a dar de baja.
Por ejemplo, si se desea eliminar el elemento 10 de la lista anterior, la localización exitosa nos
brindaría la siguiente información útil:
y luego de la modificación estructural la skip list quedaría como:
Los apuntadores que aparecen remarcados son los únicos que se modifican para reflejar la baja de la
celda de nivel 1 conteniendo el valor 10. Por ser la celda de nivel 1 sólo se modifican los
apuntadores hasta dicho nivel, en este caso para reflejar la baja en las listas de nivel 0 y de nivel 1.
Por otra parte, al considerar el llamado dictionary problem, el que consiste de un conjunto S de nº
reales, almacenados en una estructura de datos tal que las siguientes operaciones pueden ser
realizadas eficientemente:
_ Search(x): Dado un nº x, reportar la existencia en S.
_ Insert(x): Dado un nº x, insertar en la estructura de dato.
_ Delete(x): Dado un nº x, borrar o eliminar de la estructura de dato.
Una de las estructuras estandares para resolver este problema son los árboles binarios balanceados.
Los que soportan las operaciones antes señaladas en tiempo caso peor O(log n) y espacio de O(n).
________________________________________________________________________
Escuela Ingeniería en Computación, Universidad de La Serena
5
Diseño y Análisis de Algoritmos
Dr. Eric Jeltsch F.
Por ejemplo, si conocemos la clase de los árboles binarios balanceados, podríamos tomar como
representantes a los AVL-trees, red-black-trees u otros. Lo que es claro que este tipo de estructuras
de datos para mantener su performance necesitan usar el balanceo como una operación
fundamental, la cual veremos que en los Red-black no resulta muy fácil de realizar, por la variedad
de casos.
________________________________________________________________________
Escuela Ingeniería en Computación, Universidad de La Serena
6
Diseño y Análisis de Algoritmos
Dr. Eric Jeltsch F.
Árbol de Búsqueda Digital
Un árbol de búsqueda digital es un árbol binario en donde cada nodo contiene un elemento, estos
elementos son llamadas claves. El elemento a asignar al nodo está dado por la representación
binaria de las claves. Para comprender mejor es necesario entender algunos conceptos. Número de
bit: viene dado por el dígito binario correspondiente al nivel del nodo padre que lo contiene. Nivel:
es la altura del árbol asociada a cada nodo.
Supongamos que nuestro número de bits en la representación binaria de una clave leída de izquierda
a derecha comienza con 1, mientras que los bits dos, tres y cuatro son 0. Entonces la llave sería
1000. Esto determina que las claves en el subárbol izquierdo de un nodo de nivel i, tiene el bit i
igual a cero, mientras que los que están en el subárbol derecho de un nodo a este nivel, tiene bit i =
1.
________________________________________________________________________
Escuela Ingeniería en Computación, Universidad de La Serena
7
Diseño y Análisis de Algoritmos
Dr. Eric Jeltsch F.
Ejemplo: Se muestra un ejemplo de árbol de búsqueda digital, con las claves 1000, 0010, 1001,
0001, 1100 y 0000.
a
1000
b
d
f
c
0010
1001
e
0001
1100
0000
Fig. 1
Búsqueda: Una búsqueda en un árbol de búsqueda digital se desarrolla de la siguiente manera.
Suponemos que buscamos la clave k = 0011 en el árbol de la Fig. 1, k es comparada con a, que es la
clave raíz. Como k es diferente a la raíz y como el primer bit de k es 0, nos movemos al hijo
izquierdo b, de la raíz. Luego, como k es distinta a la clave del nodo b y el segundo bit de k es 0,
nos movemos al hijo izquierdo de b, es decir a d. Como k es diferente de la clave del nodo d, y
como el tercer bit de k es 1, nos movemos a la derecha de d. El nodo d no tiene hijo derecho donde
moverse. Con esto concluimos que k=0011 no está en el árbol de búsqueda. Notar que si
hubiésemos querido insertar k en el árbol, entonces debería haber sido insertado a la derecha de d.
Obteniendo la Fig. 2
a
b
d
f
0000
0010
1000
c
1001
e
0001
g
0001
1100
Fig. 2
Los procedimientos del árbol de búsqueda digital para buscar, insertar y eliminar son similares a los
procedimientos para árboles de búsqueda binaria, la diferencia sustantiva es que el subárbol a
mover está determinado por un bit en la clave de búsqueda, más que por el resultado de la
comparación de la clave de búsqueda y la clave del nodo actual.
Tries
El término trie viene de la palabra retrieval que significa "recuperación". Los tries, en general,
tienen la propiedad de ser sufijos (o prefijos), es decir, que consideran los inicios de las cadenas de
entrada para su configuración. Un trie es una estructura índice que es particularmente útil cuando
las claves varían en largo.
________________________________________________________________________
Escuela Ingeniería en Computación, Universidad de La Serena
8
Diseño y Análisis de Algoritmos
Dr. Eric Jeltsch F.
Ejemplo: En Fig. 3, se representa un trie
Fig. 3
Búsqueda: La búsqueda en un trie de una clave x, se realiza descomponiendo x en sus
componentes caracteres y seguir las ramas determinadas por esos caracteres. La búsqueda toma los
caracteres de la izquierda a derecha, uno por una. Por ejemplo, si queremos buscar la palabra
GATO en la Fig. 2, descomponemos la palabra en sus caracteres (G-A-T-O), y nos situamos en la
G, que es el primer carácter leído de izquierda a derecha. En el siguiente nodo seguimos por la A,
que es el segundo carácter, y así, continuamos con el carácter T , para finalmente ir a la palabra que
contiene, GATO. Como es la única palabra al nivel de T, podemos decir que GATO es la única
palabra con sufijo GAT, no así si nos situáramos en la A, puesto que entonces, se puede decir que
existen dos palabras con sufijo GA: GARRA y GATO.
Tries patricia
Los tries patricia, son la versión más compacta respecto de los tries, y que se basan en que sus
nodos pueden etiquetarse con más de un carácter, esto es para eliminar los caminos que son
comunes a nodo hoja
1
3
4
0000
2
4
0010
0001
1000
1100
1001
Fig. 4
________________________________________________________________________
Escuela Ingeniería en Computación, Universidad de La Serena
9
Diseño y Análisis de Algoritmos
Dr. Eric Jeltsch F.
Trie patricia con punteros hacia atrás, es la transformación de un trie
0
1
3
4
0001
0000
2
0010
4
1100
1001
1000
Fig. 5
Búsqueda: Para buscar un elemento con clave k comenzamos en el nodo raíz y seguimos el camino
determinado por los bits en k. Por ejemplo, buscar(0000), significa comenzar la inspección desde el
nodo raíz, para luego seguir por el nodo que apunta el hijo izquierdo del nodo raíz, es decir 0000.
El campo número-bit en este nodo es 1, el rótulo número-bit corresponde al número de bits de la
clave. Como el primer bit de k es 0, concluimos que la búsqueda se mueve el nodo con 0010. Ahora
se usa el tercer bit de k, como es 0, la búsqueda se mueve al nodo con 0001. El campo número-bit
ahora es 4 y el cuarto bit de k es cero, así es que seguimos al campo hijo izquierdo. Esto nos lleva a
un nodo con campo de número-bit menor que el nodo desde donde veníamos. En consecuencia, fue
utilizado un puntero y luego se compararon las claves de este nodo con k, y si encontramos una
concordancia, entonces la búsqueda es exitosa.
Ahora, supongamos que buscamos un k = 1011. Comenzamos en el nodo raíz, la búsqueda se
realiza moviéndose sucesivamente a los nodos con rótulos 0000, 1001, 1000, 1001. Se compara k
con 1001. Como k no es igual a 1001, concluimos que no hay elemento con esta llave.
Ejemplo: Dado el árbol patricia el cual posee las claves (00000, 00010,00101,01011,01101).
Buscar(00010), como la segunda posición en el bit es 0, nos indica que nos movemos hacia el hijo
izquierdo del nodo. Consideramos el siguiente número de bits (Skip), el cual es mayor.e nivel, el
Skip es 3 por lo cual nos fijamos en el tercer bit, que tiene valor 0 y nos indica nuevamente que
debemos movernos a la izquierda del nodo respecto del que estabamos. En este nivel el Skip es 4
por lo que nos fijamos en la cuarta posición de la clave buscada el cual tiene valor 1, lo que nos
invita a desplazarnos hacia el hijo derecho del nodo el cual estamos visitando. Aquí nos detenemos
a fijarnos en el Skip existente en este nodo ( que es 2 y el anterior era 3), lo que obviamente nos
dice que es menor, y solo cuando ocurre esta situación se comparan las claves de los nodos, es decir
________________________________________________________________________ 10
Escuela Ingeniería en Computación, Universidad de La Serena
Diseño y Análisis de Algoritmos
Dr. Eric Jeltsch F.
en este caso:
If(2<3) true
Comparar 00010 = =00010 (true).
Por lo cual tuvimos éxito en la búsqueda, si la comparación diera resultado falso será por la no
existencia del nodo en el trie patricia.
Arboles Interval
Son un caso particular de los árboles Red-Black, que se usan por lo general para representar sucesos
que suceden a través del tiempo.
Ejemplo: Tenemos un estudio realizado a 10 ardillas de laboratorio en sus respectivas jaulas, las
cuales cuentan con sus ruedas de entrenamiento. El estudio consta de observar durante 30 minutos a
cada una de las ardillas, y obtener el intervalo de tiempo en el cual ellas juegan en su rueda. Los
resultados obtenidos son los siguientes:
Al = [0,3] , significa que la 1º ardilla usó su rueda entre los 0 y los 3 minutos.
A2 = [16,21]
A3 = [17,19]
A4 = [8,9]
A5 = [15,23]
A6 = [5,8] , es decir, la 6º ardilla empezó a los 5 minutos y terminó a los 8 minutos
A7 = [25,30]
A8 = [6,10]
A9 = [26,26]
A10 = [19,20]
Para el estudio de este tipo de árboles, debemos tener claro que son y como representar los
intervalos.
Un ejemplo generalizado de intervalo es el siguiente:
A = [x, y], significa que nuestro intervalo A, irá desde el número natural x hasta el número y. Por
ejemplo, el intervalo [10,15] contendrá los elementos {10,11,12,13,14,15}. Cabe destacar que en
esta oportunidad estudiaremos los intervalos cerrados, es decir tomando como elementos los límite
del intervalo. Las "partes" del intervalo A = [x, y], son x será llamado límite inferior del intervalo e
y será llamado límite superior de A. Cualquier intervalo ya insertado en un árbol interval, cumple
con la tricotomía interval, esto es, que cumple exactamente una de las siguientes propiedades.
Siendo A y B Intervalos:
a) A y B se traslapan (esto significa que A ∩ B ≠ Ø)
b) High[A] < Low[B]
c) High[B] < Low[A]
a)
b)
A
B
________________________________________________________________________ 11
Escuela Ingeniería en Computación, Universidad de La Serena
Diseño y Análisis de Algoritmos
c)
Dr. Eric Jeltsch F.
B
A
En cada nodo de un Arbol Interval encontramos:
 El intervalo en si.
 Puntero al nodo padre.
 Puntero a los nodos hijos Izquierdo y Derecho.
 Valor Max
El valor Max será igual al número Máximo entre el intervalo del nodo, el Máximo de su subárbol
derecho y el máximo de su subárbol izquierdo. Aquí vemos un ejemplo
[16, 21]
30
[0, 3]
3
[17, 30]
30
Podemos ver que en el intervalo que contiene a [0,3] se encuentra el valor max = 3, ya que es el
máximo de su intervalo y no tiene subárboles. Igual para su nodo hermano. En el nodo padre
encontramos el valor max = 30, ya que de entre el máximo de él (21), el máximo del subárbol
izquierdo (3) y del derecho (30), éste último es el mas grande.
Como los árboles Interval son un tipo especial de árboles Red-Black, debemos de recordar sus
propiedades.
 Cada nodo puede ser Rojo o Negro.
 La raíz del árbol siempre es negra.
 Cada nodo ingresado es Rojo.
 Un nodo rojo no puede tener hijos de su mismo color.
 Todo camino desde la raíz hasta las hojas (nodos null) debe tener la misma cantidad de
nodos negros.
Sabemos que los árboles Red-Black son un tipo de árbol binario de búsqueda, y se insertan los
nodos de la misma forma tomando como índice Low[x], teniendo presente actualizar el valor max
de cada nodo. Veamos un ejemplo de inserción con los datos de las ardillas.
[0, 3]
3
Búsqueda
El objetivo funda mental de la búsqueda en este tipo de árboles, es encontrar el primer nodo que
contenga un intervalo que traslape al intervalo buscado. Para esto, utilizamos el siguiente método:
________________________________________________________________________ 12
Escuela Ingeniería en Computación, Universidad de La Serena
Diseño y Análisis de Algoritmos







Dr. Eric Jeltsch F.
Pedimos un intervalo a buscar.
Entrando por la raíz, Low[x] deberá ser menor que el valor max en el nodo raíz, ya que de lo
contrario, el intervalo buscado estaría fuera del rango que abarca nuestro árbol.
Debemos preguntar si el intervalo en la raíz traslapa al intervalo buscado. De ser así, la
búsqueda entrega este nodo. En caso contrario, revisamos el valor max del hijo izquierdo de la
raiz.
Si el max del hijo izq. es mayor que el Low del intervalo buscador significa que el rango del
subárbol izquierdo es suficiente para contenerlo, entonces la búsqueda se dirige hacia el lado
izquierdo. Caso contrario, tomaremos la derecha.
Nuevamente preguntamos si el hijo izquierdo traslapa al intervalo buscado.
En caso de que no traslape, se repite el proceso.
En caso de no encontrar ningún nodo que contenga un intervalo que traslape al buscado, la
búsqueda entregara null.
Ejemplo: Buscaremos el Intervalo X=[22,23]








Entramos por la raíz y preguntamos si el intervalo [16,21] traslapa a [22,23].
Como no lo hace, preguntamos si el valor max del hijo izq. (24) es mayor que Low del intervalo
buscado (22).
Como es mayor, vamos al hijo izquierdo.
Preguntamos si (8,9] traslapa a [22,23].
Como no lo hace, revisamos el max del hijo Izq. (3) y preguntamos si es mayor que Low[x]
(22).
No es mayor, por lo tanto seguimos por la derecha.
¿[15,24] traslapa a [22,23]? Sí.
La búsqueda devuelve el nodo que contiene a [15,24]
Tenemos que destacar que esta búsqueda solo entrega el primer intervalo que traslapa al intervalo
buscado, pero puede suceder que bajo el intervalo entregado existan otros nodos que contengan
intervalos que también traslapen, por lo tanto si queremos obtener todos los intervalos que
trasladan, debemos realizar una búsqueda recursiva con los subárboles derecho e izquierdo del nodo
entregado.
________________________________________________________________________ 13
Escuela Ingeniería en Computación, Universidad de La Serena