Está en la página 1de 57

1

Captulo 6.

rboles binarios de bsqueda.


En listas enlazadas de n componentes las operaciones generales de insercin, descarte y
bsqueda son O(n).
Como veremos, en rboles binarios de bsqueda (bst por binary search trees) con n nodos estas
operaciones sern O(log2 n) en promedio.
Un rbol presenta vnculos jerrquicos entre sus componentes y permite representar variadas
situaciones de inters. Por ejemplo: la estructura de un directorio, la conectividad entre vrtices
de un grafo, representacin de expresiones, el almacenamiento de las palabras reservadas,
diccionarios, etc.

6.1. Definiciones.
Un rbol es una coleccin de cero o ms nodos vinculados con una relacin de jerarqua.
Un rbol con cero nodos se denomina rbol vaco.
Un rbol tiene un nodo especial, o punto de entrada a la estructura, denominado raz.
La raz puede tener cero o ms nodos accesibles desde ella. El conjunto de esos nodos forman
subrboles de la raz, y son nodos descendientes de la raz. La raz es el ancestro de sus
descendientes.
El nodo raz no tiene ancestros.
Un subrbol es un nodo con todos sus descendientes.
Un nodo sin descendientes es una hoja. Una hoja no tiene nodos hijos.
Un rbol es un: rbol vaco o un nodo simple o
un nodo que tiene rboles descendientes.
La definicin es recursiva. Se define un rbol en trminos de rboles.
Una trayectoria del nodo ni al nodo nk, es una secuencia de nodos desde ni hasta nk, tal que ni es
el padre de ni+1. Existe un solo enlace o vnculo entre un padre y sus hijos.
Largo de una trayectoria es el nmero de enlaces en la trayectoria. Una trayectoria de k nodos
tiene largo k-1.
Alto de un nodo: largo de la trayectoria ms larga de ese nodo a una hoja.
Profundidad de un nodo: es el largo de la trayectoria de la raz a ese nodo.

Profesor Leopoldo Silva Bijit

20-01-2010

Estructuras de Datos y Algoritmos

Ejemplos de definiciones.
rbol

raz

1
4

0
8

hoja

Figura 6.1. rboles.


El nodo con valor 3 es la raz. Los nodos con valores: 1, 5 y 9 son hojas. Los nodos con valores:
4, 6 y 8 son nodos internos. El nodo con valor 6 es hijo de 3 y padre de 8. El nodo con valor 4
es ancestro del nodo con valor 5. {8, 9} y {4, 5} son subrboles. El nodo con valor 1 es subrbol
de la raz. Los nodos con valores: 1, 6 y 0 son hermanos, por tener el mismo padre. El conjunto
de nodos con valores: {3, 6, 4, 5} es una trayectoria, de largo 3. Alto del nodo con valor 6 es 2.
La profundidad del nodo con valor 5 es 3.
Todos los nodos que estn a igual profundidad estn en el mismo nivel.
La profundidad del rbol es la profundidad de la hoja ms profunda.
Se dice que un rbol es una estructura ordenada, ya que los hijos de un nodo se consideran
ordenados de izquierda a derecha. Tambin es una estructura orientada, ya que hay un camino
nico desde un nodo hacia sus descendientes.

6.2. rbol binario.


Cada nodo puede tener: un hijo izquierdo, o un hijo derecho, o ambos o sin hijos. A lo ms cada
nodo puede tener dos hijos.
Un rbol binario est formado por un nodo raz y un subrbol izquierdo I y un subrbol derecho
D. Donde I y D son rboles binarios. Los subrboles se suelen representar grficamente como
tringulos.
rbol_ binario

Figura 6.2. rbol binario.


Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

Definicin de tipos de datos.


Usualmente el rbol se trata como conjunto dinmico, mediante la creacin de sus nodos bajo
demanda. Es decir, un nodo se crea con malloc, y contiene punteros a otros nodos de la
estructura.
En caso de un rbol binario, debe disponerse al menos de dos punteros. Se ilustra un ejemplo
con una clave entera, no se muestra espacio para la informacin perifrica que puede estar
asociada al nodo. En la implementacin de algunas operaciones conviene disponer de un
puntero al padre del nodo, que tampoco se declara en el molde del nodo.
typedef struct moldenode
{
int clave;
struct moldenode *left;
struct moldenode *right;
} nodo, * pnodo;

6.3. rbol binario de bsqueda.


Para cada nodo de un rbol binario de bsqueda debe cumplirse la propiedad:
Las claves de los nodos del subrbol izquierdo deben ser menores que la clave de la raz.
Las claves de los nodos del subrbol derecho deben ser mayores que la clave de la raz
.
a

Figura 6.3. rbol binario de bsqueda.


Esta definicin no acepta elementos con claves duplicadas.
Se indican en el diagrama de la Figura 6.3, el descendiente del subrbol izquierdo con mayor
clave y el descendiente del subrbol derecho con menor valor de clave; los cuales son el
antecesor y sucesor de la raz.
El siguiente rbol no es binario de bsqueda, ya que el nodo con clave 2, ubicado en el subrbol
derecho de la raz, tiene clave menor que sta.

Profesor Leopoldo Silva Bijit

20-01-2010

Estructuras de Datos y Algoritmos


3
4

1
2

Figura 6.4. No es rbol binario de bsqueda.


Los siguientes son rboles de bsqueda ya que cumplen la propiedad anterior.
5

1
3

Figura 6.5. Varios rboles binarios de bsqueda con distinta forma.


La generacin de estos rboles depende del orden en que se ingresen las claves en los nodos, a
partir de un rbol vaco. El de la izquierda se gener insertando las claves en orden de llegada:
2, 1, 4, 3, 5 (o bien: 2, 4, 1, 5, 3). El de ms a la derecha, se gener con la llegada en el orden: 5,
4, 3, 2, 1.
Los dos rboles de ms a la izquierda, en la Figura 6.5, se denominan balanceados, ya que las
diferencias en altura de los subrboles izquierdo y derecho, para todos los nodos, difieren a lo
ms en uno. Los tres a la derecha estn desbalanceados. El ltimo tiene la estructura de una
lista, y es un rbol degenerado.

6.4. Clculos de complejidad o altura en rboles.


6.4.1. rbol completo.
Se denomina rbol completo, a aqul que tiene presentes todas las hojas en el menor nivel. La
raz es de nivel cero, los hijos de la raz estn en nivel 1; y as sucesivamente.
Deduciremos, de manera inductiva la altura de las hojas en funcin del nmero de nodos.
El caso ms simple de un rbol completo tiene tres nodos, un nivel y altura dos. Hemos
modificado levemente la definicin de altura, como el nmero de nodos que deben ser revisados
desde la raz a las hojas, ya que la complejidad de los algoritmos depender de esta variable.
rbol de nivel 1.
Nodos = 3 = 22-1

Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

Altura = 2

Figura 6.6. rbol completo de nivel 1.


rbol de nivel 2.
Nodos = 7 = 23-1
Altura = 3

Figura 6.7. rbol completo de nivel 2.


rbol de nivel 3.
Nodos = 15 = 24-1
Altura = 4

Figura 6.8. rbol completo de nivel 3.


Se deduce para un rbol de m niveles:
rbol de nivel m.
Nodos = n = 2A-1
Altura = A = m+1
Hojas = 2m
Nodos internos = n Hojas
De la expresin para el nmero de nodos, puede despejarse A, se logra:
A = log2(n+1) = O(log n)
Resultado que es simple de interpretar, ya que cada vez que se sigue una trayectoria por un
determinado subrbol, se descarta la mitad de los nodos. Es decir, se rige por la relacin de
recurrencia: T(n) = T(n/2) +c, con solucin logartmica. Esta propiedad le otorga, a la
estructura de rbol binario de bsqueda, grandes ventajas para implementar conjuntos
dinmicos, en relacin a las listas, que permiten elaborar algoritmos de complejidad O(n).
La demostracin por induccin matemtica completa, del resultado anterior, es sencilla de
deducir a partir del caso m-avo.

Profesor Leopoldo Silva Bijit

20-01-2010

Estructuras de Datos y Algoritmos

Puede demostrarse por induccin completa, el siguiente teorema:


Teorema: Un rbol perfectamente balanceado que tiene n nodos internos tiene (n+1) hojas. El
que se demostrar en 6.4.4.
Tambin se denominan rboles perfectamente balanceados, en stos todas las hojas tienen igual
profundidad.
6.4.2 rboles incompletos con un nivel de desbalance.
Se ilustran los tres casos de rboles, de nivel dos, con un nivel de desbalance, para n= 4, 5 y 6.
Un rbol con 3 nodos es completo en caso de aceptarse slo un nivel de desbalance. Lo mismo
puede decirse de un rbol con 7 nodos y que tenga un nivel de desbalance.
rboles de nivel 2.
Nodos de 4 a 6. De 23-1 hasta 23- 2.
Altura = 3 en peor caso.

Figura 6.9. rboles incompletos de nivel 2.


rboles de nivel 3.
Nodos de 8 a 14. De 24-1 hasta 24-2
Altura = 4 en peor caso.
rboles de m niveles.
Nodos de 2A-1 hasta 2A-2.
Altura A.
La inecuacin:

2A 1

n 2 A 2 tiene como solucin: A <= (1 + log2(n) ) para la primera desigualdad y

A>= log2(n+2) para la segunda.


Se pueden encontrar constantes que acoten, por arriba y por abajo a ambas funciones:
1*log2n <=log2(n+2) <= A <= 1+ log2n <= 1.3* log2n para n>10,079.

> solve(1+(ln(n)/ln(2))<1.3*ln(n)/ln(2));
RealRange ( Open( 10.07936840 ),
Entonces, se tiene:
A = (log n)

Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

Veremos ms adelante la estructura denominada heap, la cual puede interpretarse como un rbol
perfectamente balanceado excepto que en el mayor nivel no est completo. Si no est completo,
se van agregando nodos de izquierda a derecha.
El peor caso para la altura, se tiene con un rbol degenerado en una lista, en el cual la altura
resulta O(n).
6.4.3. rboles construidos en forma aleatoria.
Para n nodos, con claves: 1, 2, 3, , n, se pueden construir n! rboles. Ya que existen n!
permutaciones de n elementos. El orden de los elementos de la permutacin, es el orden en que
se ingresan las claves a partir de un rbol vaco.
Lo que se desea conocer es la altura An, definida como la altura promedio de las bsquedas de
las n claves y promediadas sobre los n! rboles que se generan a partir de las n! permutaciones
que se pueden generar con la n claves diferentes.
Si el orden de llegada de las claves que se insertan al rbol se genera en forma aleatoria, la
probabilidad de que la primera clave, que es la raz, tenga valor i es 1/n. Esto en caso de que
todas las claves sean igualmente probables.
Se ilustra esa situacin en el siguiente diagrama.

i-1

n-i

Figura 6.10. Raz con valor i.


Se considera que el subrbol izquierdo contiene (i-1) nodos; por lo tanto el subrbol derecho
contiene (n-i) nodos. Esto debido a la propiedad de rbol de bsqueda, en el subrbol izquierdo
debe tenerse los (i-1) valores menores que la clave i de la raz.
Denominamos An i al largo promedio de las trayectorias en el subrbol derecho, y Ai 1 al largo
promedio de las trayectorias del subrbol que contiene (i-1) nodos. Esto asume que el resto de
las permutaciones de las (n-1) claves restantes son igualmente probables.
Es decir:
Los i-1 nodos del subrbol izquierdo tienen largo de trayectorias promedio igual a Ai 1 +1.
Los n-i nodos del subrbol derecho tienen largo de trayectorias promedio igual a An
La raz tiene un largo de trayectoria igual a 1.

Profesor Leopoldo Silva Bijit

20-01-2010

+1.

Estructuras de Datos y Algoritmos

El promedio ponderado, de los largos de trayectoria para buscar los n nodos, para el rbol con
clave i en la raz es:

An (i)

(i 1)( Ai

1) 1 (n i )( An
n

1)

Y promediando considerando que el nodo i, en la raz, puede ser: 1, 2, 3, , n


i n

1
n

An

An (i )
i 1

Reemplazando la expresin para An (i ) se tiene:

1
n

An

i n

(
i 1

i 1
( Ai
n

1) 1

1
n

n i
( An
n

1)

efectuando factorizaciones:

An

1
n2

i n

((i 1) Ai

n (n i) An i )

i 1

Sumando el trmino que no depende de i, resulta:

An

1
n2

i n

((i 1) Ai

(n i ) An i )

i 1

El ltimo paso considera que n es una constante, ya que el ndice de la suma es i.


En la ltima sumatoria, los dos factores a sumar, dan origen a iguales sumandos. En ambas
sumatorias se obtiene: 0 A0 1 A1 ...(n 1) Ai 1
Resulta entonces:

An

2
n2

i n

(i 1) Ai

i 1

Efectuando un cambio de variables, se obtiene:

An

2
n2

i n 1

iAi
i 1

Se tiene una relacin de recurrencia de orden (n-1). Se requieren conocer (n-1) trminos para
calcular el n-avo.
La cual puede ser transformada en una relacin de recurrencia de primer orden, por el siguiente
procedimiento:
Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

a) Se reemplaza n por (n-1), en la relacin anterior, con lo que se obtiene:

An

2
(n 1) 2

i n 2

iAi
i 1

b) Se extrae el trmino (n-1) de la sumatoria, de la relacin de recurrencia de orden (n-1), con lo


que se obtiene:

An

2
(n 1) An
n2

2
n2

i n 2

iAi
i 1

Si se despeja la sumatoria de la relacin obtenida en a) y se reemplaza en la sumatoria de la


relacin obtenida en b), quedar una relacin de recurrencia de primer orden; es decir, An en
trminos de An 1 .

An

2
(n 1) An
n2

2 ( An
(
n2

1)(n 1)2
)
2

Arreglando:

An

1
((n2 1) An
2
n

2n 1)

Empleando maple, la solucin de esta recurrencia, para n>1 es:

An
Donde

2 (n

1)

(n

1)
n

3n

(n) es la funcin digama.

La relacin tambin puede resolverse mediante la funcin armnica.

Hn

1 1
1
....
2 3
n

Dando como resultado:

An

n 1
Hn 3
n

El procedimiento no es trivial. Se da el resultado sin desarrollo.


Para verificar que es solucin puede reemplazarse sta en la ecuacin de recurrencia, con lo que
se obtiene:

n 1
Hn 3
n

1
n
((n2 1)(2
Hn
2
n
n 1

3) 2n 1)

La cual es una identidad, ya que se obtiene, luego de un trabajo algebraico:

Profesor Leopoldo Silva Bijit

20-01-2010

10

Estructuras de Datos y Algoritmos

Hn

Hn

1
n

Retomando el clculo, la funcin armnica puede ser aproximada por la funcin gama
(constante de Euler, =0,577.), mediante:

Hn

ln(n)

1
12n2

....

Si n es grande:

Hn

ln(n)

An

2H n 3

Lo cual permite obtener, finalmente:

An

2 ln(n)

(log n)

Resultado que garantiza que en promedio, el largo promedio de cualquier trayectoria en un


rbol generado aleatoriamente es de complejidad logartmica.

1,4 log2(n)

Generado aleatoriamente

balanceado

Figura 6.11. Altura de rbol generado aleatoriamente.


La grfica muestra que para rboles de tipo 1000 nodos, deben recorrerse cerca de nueve nodos
desde la raz hasta las hojas (peor caso), si est balanceado. El largo promedio de los recorridos
es 12 en un rbol generado aleatoriamente, y 1000 en peor caso.
Otra forma de expresar el resultado, es considerando el alargue de la trayectoria en trminos del
largo para un rbol perfectamente balanceado. ste era A = log2(n+1), entonces para n grande:

Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

11

An
A

2 ln(n)
log 2 (n)

2 ln(2) 1,386

El resultado establece que el promedio de alargue es de un 39%. Pero esta cota es para el caso
promedio, adems si n es relativamente grande el alargue es menor. Se muestra una grfica del
alargue, en funcin de n. Para rboles con menos de 2000 nodos el alargue es menor que un
22%.

Figura 6.12. Alargue de altura de rbol generado aleatoriamente.


Si dada la naturaleza de la aplicacin se desea tener un peor caso con complejidad logartmica,
debemos garantizar que el rbol se mantendr lo ms balanceado posible. Existen una serie de
algoritmos que logran este objetivo: rboles: coloreados, 2-3, AVL.
6.4.4. Nmero de comparaciones promedio en un rbol binario de bsqueda.
6.4.4.1. rbol binario externo
Se consideran las hojas como nodos externos.

4
2
1

5
3

Figura 6.13. Nodos internos y externos.


Teorema
Para un rbol binario de bsqueda de n nodos internos el correspondiente rbol binario externo
tiene: (2n + 1) nodos. Hay (n+1) nodos externos u hojas.
Profesor Leopoldo Silva Bijit

20-01-2010

12

Estructuras de Datos y Algoritmos

Demostracin.
Por induccin completa, cuyo mtodo resumimos a continuacin:
Se tiene un conjunto y una propiedad que puede expresarse mediante una frmula P(n), se
verifica:
1 Que la propiedad se cumpla para el primer elemento o los primeros elementos del conjunto.
2 Que dado P(n) se cumpla que: P(n) P(n+1).
La conclusin es: Todos los elementos del conjunto cumplen esa propiedad. Esta forma de
razonamiento tambin se denomina por recurrencia.
Sea ni el nmero de nodos internos, y ne el nmero de nodos externos.
Para ni = 1 se tiene: ne = 2 y se cumple que: ne

ni 1

Figura 6.14. P(1): ne = ni + 1


Para ni = 2 se tiene: ne = 3 y se cumple que: ne = ni + 1

Figura 6.15. P(2): ne = ni + 1


En este caso se pueden formar dos rboles. Si a partir de un rbol vaco, llegan las claves en
orden 2,1 1, 2, se tienen los diagramas anteriores.
Supongamos que para ni = n se tiene que: ne = n+1 entonces:
Para ni = n+1 podemos agregar el nodo interno de dos formas: Una reemplazando a un nodo
externo, o bien intercalndolo entre dos nodos internos.
En el primer caso, disminuye en uno el nmero de nodos externos, pero luego se agregan dos
nodos externos, se tendr:
ne = (n+1) -1 + 2 = (n+1) + 1 = ni + 1 y se cumple la propiedad.

Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

13
a

a
b

Figura 6.16. Primer caso de P(n+1): ne = ni + 1


En el segundo caso:
ne = (n+1) + 1 = ni + 1 tambin se cumple la propiedad.
a

a
b

c
c

Figura 6.17. Segundo caso de P(n): ne = ni + 1


6.4.4.2. Largos de trayectorias interna y externa.
Teorema.
Sea el largo de la trayectoria interna I(n), la suma de las alturas de todos los nodos internos;
y sea el largo de la trayectoria externa E(n), la suma de las alturas de todos los nodos
externos.
Entonces:
E(n) = I(n) + (2 n + 1)

Demostracin por induccin.


La propiedad P(n), se cumple para el caso base, con n = 1.

a=1

a=2

Figura 6.18. P(1): E(n) = I(n) + (2 n + 1)


I(1) = 1, E(1) = 2 + 2 = 4
E(1) = I(1) + (2*1 + 1) = 4
Para n=2, en ambos diagramas:

Profesor Leopoldo Silva Bijit

20-01-2010

14

Estructuras de Datos y Algoritmos


1

2
1

Figura 6.19. P(2): E(n) = I(n) + (2 n + 1)


I(2) = 1 + 2 = 3
E(2) = 3 + 3 + 2 = 8
E(2) = I(2) + (2*2 +1) = 8 Entonces P(2) se cumple.
Ntese que I(n) es el nmero de comparaciones de claves que deben realizarse para encontrar
todos los nodos. Tambin se tiene que E(n) (n+1) es el nmero de comparaciones que deben
realizarse para encontrar las hojas o nodos externos; se cuentan slo las comparaciones de
claves.
La hiptesis inductiva, est basada en asumir P(n) verdadero y demostrar que:
P(n) P(n+1)
Se cumple E(n) = I(n) + (2n+1)
Se reemplaza cualquiera de los nodos externos, digamos uno ubicado a altura d de la raz, por
un nodo interno y sus dos hijos externos:
a

a
d

n
d+1
n+1

Figura 6.20. Primer caso de P(n): E(n) = I(n) + (2 n + 1)


Los nuevos largos, para el rbol con (n+1) nodos internos quedan:
I(n+1) = I(n) + d ya que el nodo b tiene altura d respecto de la raz.
E(n+1) = E(n) d + 2(d+1) ya que pierde un nodo con altura d, pero adquiere dos a distancia
(d+1).
Entonces reemplazando P(n) en el largo externo queda:
E(n+1) = I(n) + (2n+1) d + 2(d+1) = I(n) + d + 2n +1 + 2
Y empleando la relacin para I(n+1), resulta:
E(n+1) = I(n+1) + 2(n+1) + 1 que demuestra que P(n+1) se cumple.

Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

15

Falta analizar la situacin en la que se intercala un nodo a altura d de la raz, entre dos nodos
internos.
a

a
b

c
c

Figura 6.21. Segundo caso de P(n): E(n) = I(n) + (2 n + 1)


Los nuevos largos en funcin de la situacin para n nodos internos, se pueden plantear:
I(n+1) = I(n) + d + k. Con k igual al nmero de nodos internos bajo el insertado.
E(n+1) = E(n) + (d+1) + j. Con j igual al nmero de nodos externos bajo el insertado.
Se tiene que j = k+1, ya que para un rbol de k nodos internos se tienen (k+1) nodos externos.
Reemplazando j y el valor de E(n) mediante la propiedad P(n) se tiene:
E(n+1) = (I(n) + 2n+1) + (d+1) + k+1 = I(n) +d +k + 2n+3.
Reemplazando el valor de I(n+1) se obtiene:
E(n+1) = I(n+1) + 2n+3 = I(n+1) + 2(n+1) +1 que muestra que P(n+1) se cumple.
6.4.4.3. Bsquedas exitosas y no exitosas.
Teorema

S(n)
U(n)

1.39 log2 (n)


1.39 log2 (n + 1)

S(n) = (log2 n)
U(n) = (log2 n)

Sea S(n) el nmero de comparaciones en una bsqueda exitosa en un rbol binario de bsqueda
de n nodos internos, construido aleatoriamente.
Para un rbol dado el nmero esperado de comparaciones para encontrar todas las claves es:
S(n) = I(n)/n
S(1) = 1
S(2) = 3/2
I(1) = 1, I(2) = 3
Sea U(n) el nmero de comparaciones en una bsqueda no exitosa en un rbol binario de
bsqueda de n nodos internos, construido aleatoriamente.
Para un rbol dado, U(n) es el nmero esperado de comparaciones para encontrar todas las hojas
es:

U ( n)

E (n) (n 1)
n 1

Una bsqueda no exitosa termina en uno de los (n+1) nodos externos.


U(1) = 2

Profesor Leopoldo Silva Bijit

20-01-2010

16

Estructuras de Datos y Algoritmos

U(2) = 5/3
E(1) = 4, E(2) =8
U(0) = 0 ya que E(0) =1 y n=0
a=1

Figura 6.22. Evaluacin de U(0).


Relacin entre S(n) y U(n).
Puede expresarse el nmero promedio de comparaciones en una bsqueda exitosa S, en trminos
del nmero de comparaciones no exitosas U, eliminando las variables E e I, empleando la
relacin entre stas, segn:

S ( n)

I ( n)
n

E (n) (2n 1)
n

(n 1)U (n) (n 1) (2n 1)


n

Resulta:

S (n) (1

1
)U (n) 1
n

La insercin de un nuevo valor de clave en un rbol de bsqueda implica un recorrido


descendente, desde la raz hasta una hoja, es decir una bsqueda no exitosa. Esto debido a que
no se aceptan claves repetidas.
Entonces: Se requiere una comparacin adicional para encontrar una clave en una bsqueda
exitosa que lo que se requiere para insertar la clave en una bsqueda no exitosa que precede a su
insercin.
Si la bsqueda encuentra al nodo en la raz se requieren U(0) +1 comparaciones, ya que fue el
primero que se insert.
Si el buscado fue el k-simo insertado, se requieren U(k-1) +1 comparaciones para encontrarlo.
Como el nodo buscado puede haber sido insertado en un rbol vaco o en un rbol que ya
tuviera 1, 2, .. o (n-1) nodos se tiene, el siguiente promedio para las comparaciones:

(U (0) 1) (U (1) 1) ...(U ( n 1) 1)


n
1k n
S ( n)
(U (k 1) 1)
nk1
1k n
1k n 1
S ( n) 1
U (k 1) 1
U (k )
nk1
n k 0
S ( n)

Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

17

Relacin de recurrencia para U(n).


Igualando las dos expresiones para S(n), se obtiene:

1
1k n 1
)U (n) 1 1
U (k )
n
n k 0

(1
Despejando:

(n 1)U (n)

2n

k n 1

U (k )

k 0

Si en la anterior se reemplaza, n por n-1, se obtiene:

nU (n 1)

2(n 1)

k n 2

U (k )

k 0

Restando la segunda a la primera, se obtiene:

(n 1)U (n) nU (n 1) 2 U (n 1)
Despejando U(n), se logra, la relacin de recurrencia de primer orden, con U(0) =0:

U (n) U (n 1)

2
n 1

Que puede resolverse, mediante el siguiente mtodo:


Remplazando n por n-1, n-2, 2, 1 se tienen:

U (n 1) U (n 2)
U (n 2) U (n 3)

2
n
2
n 1

..

U (1) U (0) 1
Las que reemplazadas en la expresin para U(n) permiten expresar:

U (n) U (0)

2
2

2
2
...
3
n 2

2
n 1 n

2
n 1

Sumando y restando uno y factorizando por dos, se tiene:

U (n) U (0) 2( 1 1

1 1
1
1
...
2 3
n 1 n

)
n 1

Reemplazando mediante H(n), la funcin armnica, cuya suma es conocida:


Profesor Leopoldo Silva Bijit

20-01-2010

18

Estructuras de Datos y Algoritmos

H ( n) 1

1 1
1
1
...
2 3
n 1 n

U (n) U (0) 2( H (n 1) 1)
Finalmente, con U(0)=0:

U ( n)

2( H (n 1) 1)

La que puede aproximarse por:

U (n) 2ln(n 1)
Relacin de recurrencia para S(n).
Reemplazando U(n) en la expresin para S(n):

1
)2( H (n 1) 1) 1
n
1
1
S (n) (1 )2( H (n)
1) 1
n
n 1
S (n) (1

Resultando:

S ( n)

2(1

1
) H ( n) 3
n

Aproximando:

S ( n)

2ln(n)

S (n) 2 H (n)
2ln(2) log 2 (n) 1,39log 2 (n)

Finalmente:

S ( n)

(log 2 (n))

1,3log2(n)
S(n)
log2(n+2)

Figura 6.23. S(n) es (log2(n)).

Profesor Leopoldo Silva Bijit

20-01-2010

(log 2 (n))

rboles binarios de bsqueda

19

Teorema
Despus de insertar n claves en un rbol binario de bsqueda T, inicialmente vaco, la altura
promedio de T es (log2 n).

6.5. Recorridos en rboles.


Se denominan recorridos a la forma en que son visitados todos los nodos de un rbol.
Existen tres modos de recorrido, con las siguientes definiciones recursivas.
6.5.1. En orden:
Se visita el subrbol izquierdo en orden;
Se visita la raz;
Se visita el subrbol derecho en orden;
6.5.2. Pre orden:
Se visita la raz;
Se visita el subrbol izquierdo en preorden;
Se visita el subrbol derecho en preorden;
6.5.3. Post orden:
Se visita el subrbol izquierdo en postorden;
Se visita el subrbol derecho en postorden;
Se visita la raz;
6.5.4. Ejemplo de recorridos.
Recorrer el rbol formado con el siguiente conjunto de claves: { n0, n1, n2, n3, n4, n5}, y cuyo
diagrama se ilustra en la figura 6.24.
En orden:
{n1, n3, n4}, n0, {n2, n5}
n3, n1, n4, n0, {n2, n5}
n3, n1, n4, n0, n2, n5
Pre orden
n0, {n1, n3, n4}, {n2, n5}
n0, n1, n3, n4, {n2, n5}
n0, n1, n3, n4, n2, n5
Post orden
{n1, n3, n4}, {n2, n5}, n0
n3, n4, n1, {n2, n5},n0
n3, n4, n1, n5, n2, n0

Profesor Leopoldo Silva Bijit

20-01-2010

20

Estructuras de Datos y Algoritmos


n0

n2

n1
n3

n5

n4

Figura 6.24. rbol con claves {n0, n1, n2, n3, n4, n5}.
6.5.5. rboles de expresiones.
Un rbol puede emplearse para representar la vinculacin entre operadores y operandos.
Notacin in situ, corresponde a recorrido en orden: ( a * b) / (c + d)
/

*
a

Figura 6.25. rbol que representa a: ( a * b) / (c + d)


Notacin polaca inversa, corresponde a recorrido en post orden: a b * c d + /
Tarea: Encontrar expresin in situ para la polaca inversa: a b c / + d e f * - *
6.5.6. rboles de derivacin.
Los compiladores emplean rboles de derivacin para verificar la construccin de sentencias
sintcticamente correctas.

sentencia

if

(Condicin)

if

sentencia

(Condicin)

else

sentencia

sentencia

Figura 6.26. rbol de derivacin.

6.6. Operaciones en rboles binarios.


Al estudiar las operaciones ms frecuentes en rboles y al analizar sus complejidades se podr
notar el poder de esta estructura de datos para implementar los conceptos de buscar y
Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

21

seleccionar. Los rboles son necesarios para dar soporte a esas operaciones bsicas de conjuntos
dinmicos.
6.6.1. Operaciones bsicas
6.6.1.1. Crear rbol vaco.
La variable arbol debe ser un puntero en zona esttica o en el stack. A travs de este puntero se
tiene acceso a las componentes.
pnodo arbol=NULL;
6.6.1.2. Crea nodo inicializado con un valor de clave.
pnodo CreaNodo(int valor)
{ pnodo pi=NULL;
if ( (pi= (pnodo) malloc(sizeof(nodo))) ==NULL) exit(1);
else
{
pi->clave=valor; pi->left=NULL; pi->right=NULL;
}
return(pi);
}
6.6.1.3. Ejemplo de uso.
arbol = CreaNodo(5);

//si el rbol estaba vaco, crea raz del rbol con clave igual a 5.

6.6.2. Operaciones de recorrido


6.6.2.1. Mostrar en orden
Diferentes rboles de bsqueda que almacenen las mismas claves son mostrados en el mismo
orden al efectuar este recorrido.
Un rbol de bsqueda preserva el ordenamiento de sus componentes independiente de su
forma.
Una tcnica de importancia para efectuar diseos recursivos consiste:
a) En conceptualizar lo que realiza la funcin y asumir que sta realiza su objetivo.
b) En establecer las condiciones de trmino de las reinvocaciones.
En el diseo de mostrar en orden, es simple establecer que el trmino se logra cuando no se
encuentran los hijos de las hojas.

Profesor Leopoldo Silva Bijit

20-01-2010

22

Estructuras de Datos y Algoritmos

void RecorraEnOrden(pnodo p)
{
if (p!= NULL) //si lleg a las hojas o es un rbol vaco.
{
RecorraEnOrden(p->left); //primero recorre el subrbol izquierdo.
printf ("%d \n", p->clave); //terminado lo anterior, imprime el nodo apuntado por p
RecorraEnOrden(p->right);
}
}
La complejidad de un recorrido que debe visitar n nodos puede intuirse que ser (n).
Si se tiene un rbol de n nodos, y si se asume arbitrariamente que el subrbol izquierdo tiene k
nodos, se puede plantear que la complejidad temporal del recorrido es:
T(n) = T(k) + (1) + T(n-k-1)
Considerando de costo constante la impresin, y la evaluacin del condicional.
Para simplificar el clculo podemos asumir un rbol balanceado.
T(n) = T(n/2)+ (1)+ T(n/2 -1)
Y para grandes valores de n, podemos simplificar an ms:
T(n) = 2*T(n/2) que tiene por solucin: T(n) = n = (n)
Otro clculo es considerar el peor caso para el subrbol derecho:
T(n) = T(1) + (1) + T(n-2)
La que se puede estudiar como
T(n) = T(n-2) +2 con T(1) =1, T(2) =1 que tiene por solucin
T(n) = n (1/2)(1+(-1)n). El segundo trmino toma valor cero para n par, y menos uno para n
impar. Puede despreciarse para grandes valores de n, resultando: T(n) = (n)
Si se desea mostrar el nivel, de cada nodo, basta una pequea modificacin, agregando un
argumento nivel; cada vez que se desciende un nivel se incrementa ste en uno. Lo cual es un
ejemplo de las posibilidades que tienen los algoritmos recursivos.
void inorder(pnodo t, int nivel)
{
if (t != NULL) {
inorder(t->left, nivel+1);
printf ("%d %d \n", t->clave, nivel);
inorder(t->right, nivel +1);
}
}
Ejemplo de uso:
inorder(arbol, 0); //Imprime considerando la raz de nivel cero.

Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

23

6.6.2.2. Mostrar en post-orden


void prtpostorder(pnodo p)
{
if (p!= NULL)
{
prtpostorder(p->left);
prtpostorder(p->right);
printf ("%d \n", p->clave);
}
}
6.6.2.3. Mostrar en pre-orden
void prtpreorder(pnodo p)
{
if (p!= NULL)
{
printf ("%d \n", p->clave);
prtpreorder(p->left);
prtpreorder(p->right);
}
}
6.6.3. Operaciones de consulta.
Se suele pasar como argumento la raz del rbol.
6.6.3.1. Seleccionar el nodo con valor mnimo de clave.
Considerando la propiedad de orden del rbol de bsqueda, debe descenderse a partir de la raz
por el subrbol izquierdo hasta encontrar un nodo con hijo izquierdo nulo, el cual contiene el
valor mnimo de clave. Debe considerarse que el rbol puede estar vaco.
La implementacin iterativa de esta operacin es sencilla de implementar. Se retorna puntero al
nodo con valor mnimo de clave, y NULL si el rbol est vaco.
pnodo BuscarMinimoIterativo(pnodo t) {
while ( t != NULL){
if ( t->left == NULL ) return (t); //apunta al mnimo.
else t=t->left; //desciende
}
return (t); /* NULL si rbol vaco*/
}

Profesor Leopoldo Silva Bijit

20-01-2010

24

Estructuras de Datos y Algoritmos

t
t->left

Figura 6.27. Variables en BuscarMinimoIterativo.


/* Algoritmo recursivo. Descender siempre por la izquierda */
pnodo BuscaMinimo(pnodo t) {
if (t == NULL) return(NULL); //si rbol vaco retorna NULL
else
// Si no es vaco
if (t->left == NULL) return(t );
// Si no tiene hijo izquierdo: lo encontr.
else return( BuscaMinimo (t->left) ); //busca en subrbol izquierdo.
}
Otra forma de concebir la funcin, es plantear primero las condiciones de trmino, y luego
seguir tratando de hacer lo que la funcin realiza, pero acercndose a la solucin.
pnodo BuscaMinimo(pnodo t)
{
if (t == NULL) return(NULL); //si rbol vaco retorna NULL
if (t->left == NULL) return(t ); // Si no tiene hijo izquierdo: lo encontr.
return( BuscaMinimo (t->left) ); //busca en subrbol izquierdo.
}

t
t

t->left

t
t->left

Figura 6.28. Condiciones en BuscaMinimo


La complejidad del algoritmo es O(a), donde a es la altura del rbol. sta en promedio es
O(log2(n)) , y en peor caso O(n).
6.6.3.2. Seleccionar el nodo con valor mximo de clave.
Algoritmo: Descender a partir de la raz por el subrbol derecho hasta encontrar un nodo con
hijo derecho nulo, el cual contiene el valor mximo de clave. Debe considerarse que el rbol
puede estar vaco.

Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

25

pnodo BuscarMaximoIterativo(pnodo t) {
while ( t != NULL)
{
if ( t->right == NULL ) return (t); //apunta al mximo.
else t=t->right; //desciende
}
return (t); /* NULL Si rbol vaco*/
}
/* Recursivo */
pnodo BuscaMaximo(pnodo t)
{
if (t == NULL) return(NULL); //si rbol vaco retorna NULL
if (t->right == NULL) return(t ); // Si no tiene hijo derecho: lo encontr.
return( BuscaMaximo (t->right) ); //sigue buscando en subrbol derecho.
}
Si en las funciones obtenidas en 6.6.3.2. se cambian left por right y viceversa se obtienen las
funciones anteriores. Esta es una importante propiedad de los rboles binarios de bsqueda.
6.6.3.3. Nodo descendiente del subrbol derecho con menor valor de clave.
Se ilustra un ejemplo de rbol binario de bsqueda, en el cual si t apunta a la raz, se tendr que
el nodo con clave 6 es el menor descendiente del subrbol derecho.
t
5
8

3
2

9
7

Figura 6.29. Menor descendiente subrbol derecho.


Diseo recursivo.
Se emplea la funcin BuscaMnimo, que es recursiva.
pnodo MenorDescendienteSD(pnodo t)
{
if (t == NULL) return(NULL); //si rbol vaco retorna NULL
if (t->right == NULL) return(NULL ); // Si no tiene hijo derecho no hay sucesor.
return( BuscaMinimo (t->right) ); //sigue buscando en subrbol derecho.
}

Profesor Leopoldo Silva Bijit

20-01-2010

26

Estructuras de Datos y Algoritmos

Para el diseo iterativo, cuando existe subrbol derecho, deben estudiarse dos casos, los cuales
se ilustran en la Figura 6.30.
El caso D1, un nodo sin hijo izquierdo, indica que se encontr el mnimo.
El caso D2, debe descenderse por el subrbol derecho de t, por la izquierda, mientras se tengan
hijos por la izquierda.

t
D1

D2

Figura 6.30. Casos en bsqueda del menor descendiente


pnodo MenorDescendienteIterativoSD(pnodo t)
/*menor descendiente de subrbol derecho. */
{ pnodo p;
if (t == NULL) return(NULL); //si rbol vaco retorna NULL
if (t->right == NULL) return(NULL ); // Si no tiene hijo derecho no hay sucesor.
else p = t->right;
while ( p->left != NULL) { /* Mientras no tenga hijo izq descender por la izq. */
p = p->left;
}
/*Al terminar el while p apunta al menor descendiente */
return (p);
/* Retorna el menor */
}
6.6.3.4. Sucesor.
Dado un nodo encontrar su sucesor no es el mismo problema anterior, ya que el nodo podra ser
una hoja o un nodo sin subrbol derecho. Por ejemplo en la Figura 6.29, el sucesor del nodo con
clave 4 es el nodo con clave 5. El sucesor del nodo 2 es el nodo con valor 3.
Se requiere disponer de un puntero al padre del nodo, para que la operacin sea de costo
logartmico, en promedio.
Si un nodo tiene subrbol derecho, el sucesor de ese nodo es el ubicado ms a la izquierda en
ese subrbol (problema que se resolvi en 6.6.3.3); si no tiene subrbol derecho, es el menor
ancestro (que est sobre el nodo en la trayectoria hacia la raz) que tiene a ese nodo en su
subrbol izquierdo.

Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

27
5
8

1
2

3
t

7
4

Figura 6.31. Sucesores de distintos nodos.


Algoritmo:
Si el rbol no es vaco.
Si no tiene subrbol derecho:
Mientras exista el padre y ste apunte al nodo dado por la derecha se asciende:
Hasta encontrar el primer padre por la izquierda.
Si no existe ese padre, se retorna NULL, t era el nodo con valor mximo
Si tiene subrbol derecho, el sucesor es el mnimo del subrbol derecho.
Revisar el algoritmo para los diferentes nodos del rbol de la Figura 6.31, especialmente para
los nodos con claves 4 y 9. En este ltimo caso debe asumirse que se ha definido que el padre
de la raz tiene valor NULL.
pnodo Sucesor(pnodo t)
{ pnodo p;
if (t == NULL) return(NULL); //si rbol vaco retorna NULL
if (t->right == NULL)
{ p = t->padre; //p apunta al padre de t
while( p!=NULL && t == p->right)
{t=p; p=t->padre;} //se asciende
return(p); //
}
else
return( BuscaMinimo (t->right) ); //busca mnimo en subrbol derecho.
}
Como en peor caso debe ascenderse un trayectoria del nodo hacia la raz, el costo ser O(a),
donde a es la altura del rbol.
6.6.3.5. Nodo descendiente del subrbol izquierdo con mayor valor de clave.
Basta intercambiar left por right y viceversa en el diseo desarrollado en 6.6.3.3.
6.6.3.6. Predecesor.
El cdigo de la funcin predecesor es la imagen especular del cdigo de sucesor.

Profesor Leopoldo Silva Bijit

20-01-2010

28

Estructuras de Datos y Algoritmos

6.6.3.7. Buscar
Es una de las operaciones ms importantes de esta estructura. Debido a la propiedad de los
rboles binarios de bsqueda, si el valor buscado no es igual al de nodo actual, slo existen dos
posibilidades: que sea mayor o que sea menor. Lo que implica que el nodo buscado puede
pertenecer a uno de los dos subrboles. Cada vez que se toma la decisin de buscar en uno de
los subrboles de un nodo, se estn descartando los nodos del otro subrbol. En caso de rboles
balanceados, se descarta la mitad de los elementos de la estructura, esto cumple el modelo:
T(n) = T(n/2) +c, lo cual asegura costo logartmico.
pnodo BuscarIterativo( pnodo t, int valor)
{
while ( t != NULL)
{
if ( t->clave == valor ) return (t);
else {
if (t->clave < valor ) t = t->right; //desciende por la derecha
else t = t->left;
//desciende por la izquierda
}
}
return (t); /* NULL No lo encontr*/
}
Es preciso tener implementados los operadores de igualdad y menor que, en caso de que stos
no existan en el lenguaje, para el tipo de datos de la clave. Por ejemplo si la clave es
alfanumrica (un string), una estructura, etc.
Complejidad de la bsqueda.
Si T(a) es la complejidad de la bsqueda en un rbol de altura a.
En cada iteracin, el problema se reduce a uno similar, pero con la altura disminuida en uno, y
tiene costo constante el disminuir la altura.
Entonces:
T(a) = T(a-1)+(1) con T(0) = 0
La solucin de esta recurrencia, es:
T(a) = a*(1) = (a)
Pero en rboles de bsqueda se tiene que: log2 n a n
Entonces:

( log2 n) T(a) (n)

Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

29

pnodo BuscarRecursivo( pnodo t, int valor )


{
if ( t == NULL) return (NULL); /* rbol vaco o hijo de hoja */
else {
if ( t->clave == valor ) return(t); /* lo encontr */
else {
if ( t->clave > valor ) t = BuscarRecursivo ( t->left, valor);
else t = BuscarRecursivo ( t->right, valor);
}
}
return ( t ); /* ! Si se entiende esta lnea, muestra que se entiende el diseo recursivo */
}
En caso de activarse una secuencia de llamados recursivos, los retornos de stos, son pasados a
travs de la asignacin a la variable t.
Pueden eliminarse las asignaciones y el retorno final, del diseo anterior, de la siguiente forma:
pnodo BuscarRecursivo2( pnodo t, int valor )
{
if ( t == NULL) return (NULL); /* rbol vaco o hijo de hoja */
else {
if ( t->clave == valor )
return (t);
/* lo encontr */
else
{
if ( t->clave > valor )
return ( BuscarRecursivo2 ( t->left, valor) );
else
return ( BuscarRecursivo2 ( t->right, valor)) ;
}
}
}
En caso de retorno nulo, no es posible determinar si no encontr el elemento buscado o si se
trataba de un rbol vaco.
6.6.4. Operaciones de modificacin
6.6.4.1. Insertar nodo
Diseo iterativo.
Primero se busca el sitio para insertar. Si el valor que se desea insertar ya estaba en el rbol, no
se efecta la operacin; ya que no se aceptan claves duplicadas. Entonces: se busca el valor; y si
no est, se inserta el nuevo nodo.

Profesor Leopoldo Silva Bijit

20-01-2010

30

Estructuras de Datos y Algoritmos

Es preciso almacenar en la variable local q, la posicin de la hoja en la que se insertar el nuevo


nodo. En la Figura 6.31.a, se desea insertar un nodo con valor 4; se muestra el descenso a partir
de la raz, hasta encontrar el nodo con valor 3, que tiene subrbol derecho nulo.
5

porlado
right
8

1
3

valor
4
9

t
2

Figura 6.31.a. Variables al salir del while.


typedef enum {left, right, vacio} modo;
pnodo InsertarIterativo(pnodo t, int valor)
{ pnodo q= t;
modo porlado=vacio;
while ( t != NULL)
{
if ( t->clave == valor )
{/*lo encontr, no inserta. No se aceptan claves repetidas en conjuntos*/
return (t);
}
else
{ q=t ;
if (t->clave < valor) {t = t->right; porlado=right;}
else {t = t->left; porlado=left; }
}
}
/*Al salir del while q apunta al nodo donde se insertar el nuevo, y porlado la direccin */
/* El argumento t apunta a NULL */
t = CreaNodo(valor); //se pega el nuevo nodo en t.
if (porlado==left) q->left=t; else if(porlado==right) q->right=t;
return (t); /* Apunta al recin insertado. Null si no se pudo insertar*/
}
Si CreaNodo retorna un NULL, si no haba espacio en el heap, sin invocar a exit, se tendr un
retorno nulo, si no se pudo insertar.
Si p y raiz son de tipo pnodo, el siguiente segmento ilustra un ejemplo de uso de la funcin,
considerando la insercin en un rbol vaco:
if (raiz==NULL) raiz=InsertarIterativo(raiz, 4);
else if ( (p=InsertarIterativo(raiz, 4))==NULL ) printf(error);
Dejando en p el nodo recin ingresado, o el ya existente con ese valor de clave.
Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

31

Se recorre una trayectoria de la raz hasta una hoja. Entonces, si a es la altura, la complejidad de
la insercin es: T(a).
Una alternativa al diseo iterativo, es mantener un puntero al puntero izquierdo o derecho, en la
posicin para insertar. En la descripcin del descarte iterativo se dan explicaciones ms
completas sobre la variable local p, que es puntero a un puntero.
En la Figura 6.31.b, se desea insertar un nodo con valor 4; se muestra el descenso a partir de la
raz, hasta encontrar el nodo con valor 3, que tiene subrbol derecho nulo. Ntese que p queda
apuntando a un puntero.
pnodo Insert2(pnodo t, int valor)
{
pnodo *p = &t;
while (*p != NULL) {
if ((*p)->valor < valor) p = &((*p)->right);
else if ((*p)->valor > valor) p = &((*p)->left);
else { /* Ya estaba. No hace nada */
return (*p);
}
}
return( *p = getnodo(valor) );
}
t

5
p

1
3

8
6

9
7

Figura 6.31.b. Variables al salir del while.


La insercin en un rbol vaco debe condicionarse, para poder escribir en la variable externa,
denominada raiz. Si p y raiz son de tipo pnodo, el siguiente segmento ilustra el uso de la
funcin, considerando la insercin en un rbol vaco:
if (raiz==NULL) raiz=Insert2(raiz, 4);
else if ( (p=Insert2(raiz, 4))==NULL ) printf(error);
Dejando en p el nodo recin ingresado, o el ya existente con ese valor de clave.

Profesor Leopoldo Silva Bijit

20-01-2010

32

Estructuras de Datos y Algoritmos

Diseo recursivo.
pnodo InsertarRecursivo( pnodo t, int valor)
{
if (t == NULL) t = CreaNodo(valor); //insertar en rbol vaco o en hoja.
else
if (valor < t->clave) //insertar en subrbol izquierdo.
t->left = InsertarRecursivo(t->left, valor);
else
if (valor > t->clave) //insertar el subrbol derecho
t->right = InsertarRecursivo (t->right, valor);
/* else: valor ya estaba en el rbol. No hace nada. */
return(t);
}
La insercin en un rbol vaco debe poder escribir en la variable externa, denominada raiz. El
siguiente segmento ilustra el uso de la funcin:
raiz=InsertRecursivo(raiz, 4);
Debe notarse que se reescriben los punteros de los nodos que forman la ruta de descenso, lo cual
es una sobrecarga de trabajo innecesario, salvo que el ltimo retorno escribe en la raz. Si desea
conocerse si CreaNodo falla, retornando NULL, habra que comentar la excepcin o salir del
programa.
Trayectoria en el descenso.
Veremos que en el algoritmo recursivo, la trayectoria recorrida desde la raz hasta la posicin
para insertar queda registrada en el stack.
En el rbol de la Figura 6.32, se especifican los valores de los punteros, y se desea insertar un
nodo con clave igual a 7.
raiz
t0
5

t1
8

3
t3
2

t2
9

Figura 6.32. Trayectorias en llamados recursivos.


Se ilustra el stack, despus del llamado: InsertarRecursivo(raiz, 7)

Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

33
t
t0

valor
7

Llamado nmero
1

Figura 6.33. Stack despus de InsertarRecursivo(raiz, 7).


Al ejecutarse el cdigo de la funcin, se determina que 7 es mayor que 5, y se reinvoca
(segundo llamado) con los valores: InsertarRecursivo (t1, 7); despus del llamado, el stack
puede visualizarse:
t
t0
t1

valor
7
7

Llamado nmero
1
2

Figura 6.34. Stack despus de InsertarRecursivo(t1, 7).


Al ejecutarse el cdigo de este segundo llamado se determina que 7 es menor que 8 y se genera
un tercer llamado a la funcin con: InsertarRecursivo (t3, 7); despus de este tercer llamado, el
stack queda:
t
t0
t1
t3

valor
7
7
7

Llamado nmero
1
2
3

Figura 6.35. Stack despus de InsertarRecursivo(t3, 7).


Al ejecutar el cdigo del tercer llamado, se determina que 7 es mayor que 6, y se produce el
cuarto llamado: InsertarRecursivo (t3->right, 7); si denominamos por t4 al valor t3->right, el
esquema que muestra las variables en el stack, queda como sigue:
t
t0
t1
t3
t4

valor
7
7
7
7

Llamado nmero
1
2
3
4

Figura 6.36. Stack despus de InsertarRecursivo(t3->right, 7).


Al iniciar la ejecucin del cdigo del cuarto llamado, se tiene en el stack los valores de los
punteros que recuerdan la trayectoria del descenso hasta la posicin de insercin. Al ejecutar
el cdigo del cuarto llamado se determina que t4 es un puntero nulo, con lo cual, se crea el nodo
y se retorna en t (que es t4, la cuarta encarnacin de t) el valor de un puntero al nodo recin
creado. En este momento se sale del cuarto llamado y el stack queda:

Profesor Leopoldo Silva Bijit

20-01-2010

34

Estructuras de Datos y Algoritmos

t
t0
t1
t3

valor
7
7
7

Llamado nmero
1
2
3

Figura 6.37. Stack despus del retorno del cuarto llamado.


Se regresa a la ejecucin del cdigo del tercer llamado, efectuando la asignacin:
t->right= <valor del puntero retornado t4>
Pero como, dentro del tercer llamado, t tiene el valor de t3, esta instruccin pega efectivamente
el nuevo nodo. Esta instruccin es la ltima del tercer llamado, con lo cual termina retornando el
valor t3. El stack queda ahora:
t
t0
t1

valor
7
7

Llamado nmero
1
2

Figura 6.38. Stack despus del tercer retorno.


Y reanudamos la ejecucin del segundo llamado, que haba quedado pendiente. Efectuando la
asignacin:
t->left = <valor retornado de t por el tercer llamado t3>
Sobrescribiendo un valor igual al existente, copia en t1->left el valor de t3. Obviamente esta
escritura es un costo adicional de la recursividad. Terminando as el segundo llamado, el cual
retorna el valor de t1.
El stack queda:
t
t0

valor
7

Llamado nmero
1

Figura 6.39. Stack despus del retorno del segundo llamado.


Y se reanuda la ejecucin, efectuando:
t->right = <valor retornado de t por el segundo llamado. t1>
La cual sobrescribe, nuevamente en forma innecesaria en t0->left el valor de t1.
De esta forma finaliza, recin, la primera invocacin, retornado el valor de t0.
La expresin: InsertarRecursivo(raiz, 7), despus de ejecutada, tiene el valor de t0.

Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

35

Entonces la forma de invocar a esta funcin es:


raiz=InsertarRecursivo(raiz, 7);
De este modo la insercin en un rbol vaco, liga correctamente el nodo agregado.
Si el valor del nodo que se desea insertar es igual a uno ya perteneciente al rbol, el llamado
tambin retorna t0.
Si el llamado a CreaNodo falla por no disponer de memoria en el heap, y en su diseo se
hubiera retornado un NULL (sin invocar a exit) no habra forma de conocer que la insercin
fall.
El diseo recursivo recorre desde la raz hasta el punto de insercin, quedando la ruta de
descenso en el stack; luego de la insercin, recorre la ruta en sentido inverso; lo cual permite
agregar alguna operacin a los nodos involucrados. La accin debe realizarse antes del retorno.
Ver el punto 6.6.5.11 Insercin en la raz.
La operacin insertar en el lugar de la raz, es ms compleja, ya que requiere modificar el rbol.
Requiere primero insertar el nodo, y luego efectuar rotaciones para llevar ese nodo al lugar de la
raz, preservando la propiedad de un rbol binario de bsqueda. Tambin se puede implementar
si se dispone de una funcin que parta un rbol en dos (split).
6.6.4.2. Descartar nodo
Descarte recursivo.
Primero se busca el nodo cuyo valor de clave es igual al valor pasado como argumento. Si no lo
encuentra retorna NULL. Si lo encuentra, la operacin requiere mayor anlisis, ya que se
producen varios casos. Lo importante es mantener la vinculacin entre el resto de los elementos
del rbol.
a) El nodo que se desea descartar es una hoja.
En este caso, la operacin es trivial, basta escribir un puntero con valor nulo. La estructura se
conserva.

t
Figura 6.40. Descartar hoja
b) El nodo que se desea descartar es un nodo interno.
i) con un hijo

Profesor Leopoldo Silva Bijit

20-01-2010

36

Estructuras de Datos y Algoritmos

En este caso, el padre debe apuntar al nieto, para conservar la estructura de rbol. Ya sea que
slo tenga hijo derecho o izquierdo. Esto implica mantener un puntero al padre, en el descenso.

Figura 6.41. Descartar nodo con un subrbol


ii) con dos hijos.

I D
Figura 6.42. Descartar nodo con dos hijos.
Para conservar la estructura del rbol, se debe buscar I, el mayor descendiente del hijo
izquierdo; o bien D, el menor descendiente del hijo derecho. Luego reemplazar la hoja obtenida
por el nodo a descartar. Se implementa la operacin buscando D.
pnodo Descartar(pnodo t, int valor)
{ pnodo temp;
if (t == NULL) printf("Elemento no encontrado\n");
else
if (valor < t->clave) /* por la izquierda */
t->left = Descartar(t->left, valor);
else
if (valor > t->clave) /* por la derecha */
t->right = Descartar(t->right, valor);
else /* se encontr el elemento a descartar */
if (t->left && t->right) /* dos hijos */
{
/* reemplzelo con el menor del subrbol derecho. D*/
temp = MenorDescendiente(t->right) ;
t->clave = temp->clave; //copia el nodo
t->right = Descartar(t->right, temp->clave); /*borrar la hoja */
}
else
{ /* un hijo o ninguno */
temp = t;
if (t->left == NULL) /* slo hijo derecho o sin hijos */
Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

37

t = t->right;
else
if (t->right == NULL) /* solamente un hijo izquierdo */
t = t->left;
free(temp); /*libera espacio */
}
return(t);
}
La complejidad del descarte de un nodo es mayor que la insercin o la bsqueda.
La operacin puede implementarse en forma iterativa.
Descarte iterativo.
En algoritmos iterativos, es preciso mantener la informacin de la trayectoria del descenso en
una variable auxiliar; en los algoritmos recursivos, se mantiene esa informacin en el stack.
Bastara tener dos punteros, uno al nodo actual, y otro al anterior; sin embargo existe la
dificultad, a diferencia de listas simplemente enlazadas, de que el anterior podra ser un
descenso por la izquierda o por la derecha. Para solucionar lo anterior, se mantiene un puntero
al puntero anterior.
Veamos una ilustracin, para mantener un puntero a un puntero al anterior:
Si se tiene la definicin e inicializacin: pnodo *p = &t;
p

*p

Figura 6.43. Puntero a puntero a nodo.


Entonces (*p)->clave tiene el valor de la clave A. Note que *p equivale a la variable t.
Si se efecta la asignacin: p = &((*p)->right); se modifica el diagrama segn:
t
p
A
q
a

Figura 6.44. Memorizacin de trayectoria de descenso.


Ahora *p contiene la direccin del puntero ilustrado como q en el diagrama.

Profesor Leopoldo Silva Bijit

20-01-2010

38

Estructuras de Datos y Algoritmos

La asignacin: p = &((*p)->left); deja a p apuntando al puntero izquierdo del nodo con valor A.
Con estos conceptos se elabora el siguiente algoritmo iterativo.
pnodo DescarteIterativo(pnodo t, int valor)
{
pnodo *p = &t;
pnodo temp;
while (*p != NULL) {
if ((*p)->clave < valor) p = &((*p)->right);
else if ((*p)->clave > valor) p = &((*p)->left);
else { /* La encontr */
if ((*p)->left == NULL) {temp = *p; *p = (*p)->right; free(temp); }
else if ((*p)->right == NULL) {temp = *p; *p = (*p)->left; free(temp);}
else /* Tiene ambos hijos */
*p = Descarte_Raiz(*p);
return t;
}
}
Error(); /*No encontr nodo con clave igual a valor */
return t;
}
El descarte de la raz, o de un nodo con dos hijos, est basado en encontrar el menor
descendiente del hijo derecho, o el mayor descendiente del hijo izquierdo.
pnodo Descarte_Raiz(pnodo t)
{
pnodo *p = NULL, temp;
if (rand()%2) { /*Existen dos soluciones */
/* Busca mayor descendiente del subrbol izquierdo */
p = &(t->left);
while ((*p)->right != NULL)
p = &((*p)->right);
} else {
/* o Busca menor descendiente del subrbol derecho */
p = &(t->right);
while ((*p)->left != NULL)
p = &((*p)->left);
}
t->clave = (*p)->clave; /*copia los valores del encontrado en la raz. */
if ((*p)->left == NULL) {
temp = *p;
*p = (*p)->right;
} else { /* ((*p)->right == NULL) */
temp = *p;
*p = (*p)->left;
Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

39

}
free(temp);
return t;
}
6.6.4.3. Descartar rbol
Debe notarse que primero deben borrarse los subrboles y luego la raz.
pnodo deltree(pnodo t)
{
if (t != NULL) {
t->left = deltree(t->left);
t->right = deltree(t->right);
free(t);
}
return NULL;
}
6.6.5. Otras operaciones
6.6.5.1. Profundidad del rbol.
int Profundidad(pnodo t)
{
int left=0, right = 0;
if(t==NULL) return 0;
//Si rbol vaco, profundidad 0
if(t->left != NULL) left = Profundidad(t->left); //calcula profundidad subrbol izq.
if(t->right != NULL) right = Profundidad(t->right); //calcula profundidad subrbol der.
if( left > right) //si el izq tiene mayor profundidad
return left+1; //retorna profundidad del subrbol izq + 1
else
return right+1; //retorna profundidad del subrbol der + 1
}
El algoritmo se ha descrito mediante los comentarios.
6.6.5.2. Altura del rbol.
int Altura(pnodo T)
{ int h, max;
if (T == NULL) return -1;
else {
h = Altura (T->left);
max = Altura (T->right);
if (h > max) max = h;
return(max+1);
}
}

Profesor Leopoldo Silva Bijit

20-01-2010

40

Estructuras de Datos y Algoritmos

6.6.5.3. Contar hojas


int NumerodeHojas(pnodo t)
{ int total = 0;
//Si rbol vaco, no hay hojas
if(t==NULL) return 0;
// Si es hoja, la cuenta
if(t->left == NULL && t->right == NULL) return 1;
//cuenta las hojas del subrbol izquierdo
if(t->left!= NULL) total += NumerodeHojas(t->left);
//cuenta las hojas del subrbol derecho
if(t->right!=0) total += NumerodeHojas(t->right); //
return total; //total de hojas en subrbol
}
Nuevamente el algoritmo est descrito a travs de los comentarios.
6.6.5.4. Contar nodos del rbol.
int ContarNodos(pnodo t)
{
if (t == NULL) return 0;
return (1 + ContarNodos(t->left) + ContarNodos(t->right) );
}
6.6.5.5. Contar nodos internos.
Tarea
6.6.5.6. Contar nodos con valores menores que un valor dado.
Tarea
6.6.5.7. Partir rbol.
Algoritmo iterativo, con pasos por referencia.
La descripcin de las funciones split y join, son buenos ejemplos para mostrar si se domina el
concepto de punteros en el lenguaje C.
pnodo split(int key, pnodo t, pnodo *l, pnodo *r)
{
while (t != NULL && t->clave != key) {
if (t->clave < key) {
*l = t;
t = t->right;
l = &((*l)->right);
} else {
*r = t;
t = t->left;
r = &((*r)->left); //plop
}
}
Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

41

if (t == NULL) {
*l = NULL;
*r = NULL;
} else { /* t->clave == key */
*l = t->left;
*r = t->right;
}
return t;
}
6.6.5.8. Insertar nueva raz.
pnodo InsertarRaiz(int key, pnodo t)
{
pnodo l, r;
t = split(key, t, &l, &r);
if (t == NULL) {
t = CreaNodo(key);
t->left = l;
t->right = r;
} else {
t->left = l;
t->right = r;
Error();
}
return t;
}
6.6.5.9. Unir dos rboles.
Los rboles que deben ser unidos cumplen las siguientes relaciones de orden: a<A<b y d<D<e
y tal que b<d. Podran ser dos rboles que se generan al eliminar la raz de un rbol binario de
bsqueda.
Al inicio se tienen las siguientes variables
p

t
r

l
D

Figura 6.45. Variables en unir dos subrboles.


Si los dos subrboles no son vacos, en la primera iteracin se da valor inicial a t, la variable de
retorno que apuntar a la nueva raz. sta puede ser l o r, dependiendo del azar.
Luego se mantiene en p: la direccin del puntero derecho de la raz, si comienza por el subrbol
izquierdo; o la direccin del puntero izquierdo de la raz, si comienza por el subrbol derecho.
Profesor Leopoldo Silva Bijit

20-01-2010

42

Estructuras de Datos y Algoritmos

Finalmente cada iteracin finaliza haciendo descender l por la derecha o r por la izquierda.
En el supuesto que comienza por el subrbol izquierdo, la situacin luego de la primera
iteracin del while, efectuando la parte del if, es:
t
r
A

Figura 6.46. Parte del if dentro del while.


Si en la segunda iteracin, realiza la parte del else, despus de efectuado ste, queda:
t
A

a
p
r

l
b

Figura 6.47. Parte del else dentro del while.


Logrndose que l y r apunten a dos subrboles. Se repite el while, hasta que uno de los dos
subrboles quede vaco. La alternativa final, pega el subrbol restante, a la estructura.
La solucin trivial de agregar el subrbol derecho al nodo con valor mayor de clave del subrbol
cuya raz es l, alarga la altura en la suma de las alturas individuales. Lo mismo ocurre si se une l
al menor elemento de r.
l
A

b
r
D

Figura 6.48. Unin de los rboles.


Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

43

La solucin, propuesta a continuacin, intenta disminuir la altura total del nuevo rbol.
pnodo join(pnodo l, pnodo r)
{
pnodo t = NULL;
pnodo *p = &t;
while (l != NULL && r != NULL) {
if (rand()%2) { //cara y sello.
*p = l;
p = &((*p)->right);
l = l->right;
} else {
*p = r;
p = &((*p)->left);
r = r->left;
}
}
if (l == NULL) *p = r;
else /* (r == NULL) */ *p = l;
return t;
}
La operacin de descartar la raz, DescartarRaiz, tambin puede implementarse en base a la
funcin join, que une dos rboles conservando la propiedad de rbol binario de bsqueda.
La operacin de descartar la raz y pegar los subrboles, se ilustra a continuacin.
pnodo DescartarRaiz(pnodo t)
{
pnodo temp = t;
t = join(t->left, t->right);
free(temp);
return t;
}
Las rutinas split y join usan intensivamente punteros. Entenderlas es un indicador que esos
conceptos y sus principales usos han logrado ser dominados.
6.6.5.10. Rotaciones
Rotaciones simples a la izquierda y a la derecha
Un esquema de las variables, que permiten disear las funciones, se ilustra en las Figuras 6.49 y
6.50.

Profesor Leopoldo Silva Bijit

20-01-2010

44

Estructuras de Datos y Algoritmos

pnodo lrot(pnodo t)
{
pnodo temp=t;
t = t->right;
temp->right = t->left;
t->left = temp;
return t;
}
pnodo rrot(pnodo t)
{
pnodo temp = t;
t = t->left;
temp->left = t->right;
t->right = temp;
return t;
}
Las siguientes funciones son mejores que las anteriores, ya que tienen una asignacin menos,
slo escriben en tres punteros.
/* Rotacin Izquierda*/
pnodo rotL(pnodo t)
{
pnodo temp = t->right;
t->right = temp->left;
temp->left = t;
return ( temp);
}
t
A

temp

temp
t
A

b
antes

b
despus

Figura 6.49. Rotacin izquierda.


/* Rotacin derecha*/
pnodo rotR(pnodo t)
{
pnodo temp = t->left;
t->left = temp->right;
temp->right = t;
return (temp);
}
Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

45
temp
t

temp

t
A

antes

despus

Figura 6.50. Rotacin derecha.


Las rotaciones pueden cambiar la forma del rbol, pero no la relacin de orden; en el caso de las
figuras anteriores se preserva la relacin: a<A<b<B<c.
Solamente afectan a los nodos rotados y sus hijos inmediatos, los ancestros y los nietos no son
modificados.
Pueden disearse funciones que pasen argumentos por referencia. Se ilustra el diseo de la
rotacin simple a la derecha:
void rightRotRef( pnodo * t) //por referencia
{ pnodo temp = (*t)->left;
(*t)->left = temp->right;
temp->right = *t;
*t = temp; //modifica la variable pasada por referencia
}
En este caso se debe pasar la direccin de la variable donde debe escribir la funcin.
rightRotRef( &(root->right));
2

root

root
4

Figura 6.51. Ejemplo de Rotacin derecha de nodos 4-6.


El diagrama a la derecha ilustra la rotacin efectuada, la raz no cambia.
En el diseo basado en retornos por punteros, es preciso escribir en una variable, mediante el
retorno de la funcin.
La siguiente asignacin realiza la misma accin que la invocacin al procedimiento anterior.
Profesor Leopoldo Silva Bijit

20-01-2010

46

Estructuras de Datos y Algoritmos

root->right=rotR(root->right);
6.6.5.11. Insercin en la raz.
En la insercin comn en un rbol binario de bsqueda, los elementos recin insertados quedan
alejados de la raz, lo que implica que toma ms tiempo encontrar los elementos insertados ms
recientemente. Lo cual puede ser un inconveniente si en la aplicacin los elementos recin
insertados tienden a ser buscados ms a menudo que los insertados hace ms tiempo; es decir si
existe localidad temporal en las referencias.
La insercin en la raz coloca el nodo que ser insertado en la posicin de la raz actual. De este
modo los nodos ms recientemente insertados quedan ms cercanos a la raz que los ms
antiguamente insertados.
Para mantener la propiedad del rbol binario de bsqueda, se inserta de manera convencional,
como una hoja, y luego mediante rotaciones se lo hace ascender a la posicin de la raz.
En el diagrama, se ilustra la insercin de un nodo con valor de clave 5, en la posicin de una
hoja. Luego se lo hace ascender, rotando el par 4-5 a la izquierda; luego el par 5-6 a la derecha;
y finalmente el par 2-5 a la izquierda.
2

1
5

Figura 6.52. Insercin de nodo con clave 5 en la raz.


El algoritmo est basado en observar que cuando se desciende por la izquierda desde un nodo n,
durante la bsqueda para insertar, se debe rotar hacia la derecha en n. Y si se desciende por la
rama derecha, ese nodo debe rotarse hacia la izquierda. En el nodo con clave 6, se descendi por
la izquierda; luego el nodo 6 se rota a la derecha.
A medida que se desciende, para buscar la posicin para insertar, se registra el nodo; luego
despus de la insercin, se retorna a cada uno de estos nodos, en orden inverso, y se realiza la
rotacin.

Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

47

/*Inserta un nodo y lo convierte en la nueva raz */


pnodo InserteRaiz(pnodo t, int valor)
{
if (t == NULL) return ( CreaNodo(valor);)
if (valor < t->clave)
{
t->left = InserteRaiz(t->left, valor);
t = rotR(t);
}
else {
t->right = InserteRaiz(t->right, valor);
t = rotL(t);
}
return t;
}
6.6.5.12. Imprimir la forma del rbol.
Las dos rutinas siguientes permiten desplegar un rbol, y pueden ser tiles para verificar las
funciones que los manipulan.
void printNodo(pnodo t, int h)
{ int i;
for(i=0; i<h; i++) putchar(\t); //se emplean tabs para desplegar niveles.
if(t==NULL) {putchar(*) ; putchar(\n) ;}
else printf(%d\n, t->clave);
}
void Mostrar(pnodo t, int h)
{
if(t==NULL) printNodo(t, h);
else {Mostrar(t->right, h+1) ; printNodo(t, h); Mostrar(t->left, h+1);}
}
*
7
2

root

6
*

4
*

*
2
3

*
1
*

Figura 6.53. Impresin de la forma de un rbol.

Profesor Leopoldo Silva Bijit

20-01-2010

48

Estructuras de Datos y Algoritmos

La ejecucin de Mostrar(root,0); muestra un ejemplo del despliegue de un rbol cuyo diagrama


se ilustra en la Figura 6.53 izquierda.

Problemas resueltos.
P6.1.
Para la siguiente estructura de un nodo de un rbol binario de bsqueda:
typedef struct tnode
{ int valor;
char *v; //se apunta a un string
struct tnode *left, *right;
} nodo, * pnodo;
a) Disear funcin que borre el subrbol apuntado por t, liberando todo el espacio que haya sido
solicitado en forma dinmica.
b) Disear funcin que cuente en el subrbol, apuntado por t, los nodos que tengan valores
menores o iguales que k.
Solucin.
a) Puede disearse considerando:
Si el subrbol es vaco, retorna NULL
Si no es vaco: Borra subrbol izquierdo y luego el derecho; despus de lo cual borra el nodo.
Previo a borrar el nodo; es decir, antes de borrar el puntero v, debe consultarse si existe un
string, en caso de haberlo, se borra ste primero, y luego el nodo.
Una posible implementacin es la siguiente:
pnodo BorrarArbol(pnodo t)
{
if (t != NULL) {
t->left = BorrarArbol (t->left);
t->right = BorrarArbol (t->right);
if (t->v != NULL) free(t->v);
free(t);
}
return NULL;
}
Es preciso que la funcin retorne un puntero a nodo, para pasar los datos de los retornos de los
llamados recursivos. El esquema anterior, borra primero las hojas. El recorrido del rbol es
subrbol izquierdo, subrbol derecho y finalmente la raz ( en orden).
Para agregar un string s a un nodo apuntado por t, puede emplearse:

Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

49

#include <string.h>
char * ColocaString( pnodo t, char * s)
{
if ( (t->v = (char *) malloc( (strlen(s)+1)*sizeof(char) ) ) != NULL ) strcpy( t->v, s);
return ( t->v);
}
El espacio adicional se requiere debido a que strlen retorna el largo del string, sin incluir el
carcter de fin de string.
La function retorna NULL, si no pudo pegar el string al nodo, en caso contrario retorna un
puntero al inicio del string.
b) Contar en subrbol apuntado por t los nodos, que tengan valores menores o iguales que el
valor entero k.
int ContarMenor_o_Igual(pnodo t, int k)
{
if (t == NULL) return 0; //Si es subrbol nulo, no lo cuenta
else
if (t->valor < k)
{ // Si el valor es menor que k, contar el nodo y adems los de ambos subrboles
return (1 + ContarMenor_o_Igual (t->left,k) + ContarMenor_o_Igual (t->right,k) );
}
else
if (t->valor == k)
{ // Si valor igual a k, contar el nodo y adems slo los del subrbol izquierdo
return (1 + ContarMenor_o_Igual (t->left, k) );
}
else
{ // Si valor mayor que k, contar slo los nodos del subrbol izq. Sin incluirlo
return ( ContarMenor_o_Igual (t->left, k) );
}
}
El valor retornado por la funcin corresponde al nmero de nodos que cumplen la condicin.
P6.2.
1. Se tiene el siguiente rbol de bsqueda.
a) Cules son los rdenes posibles en los que llegaron las claves para formar el rbol?.
b) En un listado post-orden quienes figuran antes y despus del valor 6.
c) En un listado post-orden quienes figuran antes y despus del valor 2.
d) Dibujar el rbol, luego de: insertar el nodo con valor 5, y descartar los nodos con valores 4 y
luego el 7. Indicar alternativas de solucin, si las hubiera.

Profesor Leopoldo Silva Bijit

20-01-2010

50

Estructuras de Datos y Algoritmos


7

8
4

1
2

Figura P6.1.
Solucin.
a) Llega primero el 7. Luego pueden llegar el 3 o el 8. Luego del 3 pueden llegar el 1 o el 4. El
2 debe llegar despus del 1; y el 6 despus del 4.
b) 2 1 6 4 3 8 7. El 1 antes del 6, y el 4 luego de ste.
c) El 2 es el primero, luego viene el 1. No hay nada antes del 2, ya que es el primero.
d) Luego de insertar el 5 y descartar el 4, se tienen dos posibles soluciones para descartar el
nodo con valor 7:
7

3
6

1
2

Figura P6.2.
P6.3.
Para un rbol binario de bsqueda, disear una funcin, con el siguiente prototipo:
int trayectoria(pnodo t, int valor);
Retorna 1 si lo encontr, 0 si rbol vaco o no lo encontr.
a) Que imprima la trayectoria desde el nodo con clave igual al argumento valor hasta la raz, si
ste se encuentra en el rbol, y no encontrado en caso contrario.
b) Discuta la forma de diseo, si se desea imprimir los valores de los nodos desde la raz, hasta
el nodo que tiene igual valor de clave que el argumento dado.
Solucin.
Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

51

a) El diseo recursivo almacena en el stack los punteros a los nodos en la ruta de descenso desde
la raz al nodo con el valor buscado, si ste se encuentra en el rbol. Si no se encuentra el valor
buscado, se desciende hasta encontrar un valor nulo. Entonces debe descenderse, pero no
imprimir si se llega a sobrepasar una hoja en el descenso.
Un diseo posible es mediante una variable flag, para indicar si debe o no imprimirse los
valores, luego de los retornos de la funcin recursiva.
static int flag=0;
int imprimetrayectoria(pnodo t, int valor)
{ if (t == NULL)
{ printf("\nArbol vaco o no lo encontr!\n");
flag=0; return(flag);
}
else
if (valor < t->valor)
{ imprimetrayectoria(t->left,valor);
if(flag==1) printf(" %d", t->valor);
}
else
if (valor > t->valor)
{ imprimetrayectoria(t->right,valor);
if(flag==1) printf(" %d", t->valor);
}
else /* lo encontr. */
{ printf("\n%d", t->valor);
flag=1;
}
return(flag);
}
No es necesaria la variable flag, ya que se puede emplear el retorno entero de la funcin, como
puede apreciarse en el siguiente diseo:
int trayectoria2(pnodo t, int valor)
{ if (t == NULL)
{ printf("\nArbol vaco o no lo encontr!\n"); return(0); }
else
if (valor < t->valor)
{ if( trayectoria2(t->left,valor)) printf(" %d", t->valor); }
else
if (valor > t->valor)
{if( trayectoria2(t->right,valor)) printf(" %d", t->valor);}
else /* lo encontr. */
{ printf("\n%d", t->valor); return(1); }
return(1);
}
El stack es lifo.
Profesor Leopoldo Silva Bijit

20-01-2010

52

Estructuras de Datos y Algoritmos

b) La impresin desde la raz hasta el nodo con el valor buscado, puede resolverse empleando
una cola. Se encolan los valores desde la raz, pero considerando que si se llega a un puntero
nulo, no deben imprimirse. Es ms directo en este caso un diseo iterativo.
int ImpIterativo(pnodo t, int valor)
{
creacola();
while ( t != NULL)
{
if ( t->valor == valor )
{ encole(); putchar('\n'); /*lo encontr*/
imprimacola(); return (1);
}
else
{ encole(); //fifo
if (t->valor < valor) t = t->right; else t = t->left;
}
}
/*Al salir del while es rbol vaco o no lo encontr */
if(plista->next==NULL) printf("\nArbol vaco!");
else { printf("\nNo lo encontr!"); liberacola(); }
return (0);
}
Los tipos y macros para manejar la cola:
typedef struct lnode
{ int valor;
struct lnode *next;
} nodol, * pnodol; //tipos de la cola
#define creacola() pnodol pfondo= malloc(sizeof(nodol)); \
pnodol plista=pfondo;
\
plista->next=NULL;
#define encole()

pfondo->next=malloc(sizeof(nodol)); \
pfondo=pfondo->next;
\
pfondo->next=NULL;
\
pfondo->valor=t->valor;

#define imprimacola()

while(plista->next!=NULL) \
{ pfondo=plista; plista=plista->next; \
printf(" %d ",plista->valor); free(pfondo); \
}

Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

53

Cuando el valor no se encuentra, habra que liberar el espacio de la cola.


#define liberacola() while(plista->next!=NULL) \
{ pfondo=plista;plista=plista->next; free(pfondo); \
}
Otra solucin es reemplazar en el cdigo de la parte a), los printf por la accin de empujar los
valores a imprimir a un stack. Luego de terminada la funcin si el stack queda vaco, entonces la
clave no se encontr; si no est vaco, se imprimen desde el tope. De esta forma se imprimen los
valores desde la raz hasta la hoja encontrada.

Ejercicio propuestos.
E6.1.
Desarrollar programa que efecte listado postorden para multirbol descrito por arreglos, con
hijo ms izquierdista y hermano derecho.
E6.2.
Para un rbol binario de bsqueda, determinar procedimiento que escriba slo las hojas.
a) Desde la hoja ms izquierdista hasta la hoja ms derechista.
b) Desde la hoja ms derechista hasta la hoja ms izquierdista.
E6.3.
Se tiene un rbol binario de bsqueda.
typedef struct tnode
{
int valor;
struct tnode *left;
struct tnode *right;
} nodo, * pnodo;
Disear funcin no recursiva que borre la raz de un subrbol, que se pasa como argumento y
retorne un puntero a la nueva raz.

Profesor Leopoldo Silva Bijit

20-01-2010

54

Estructuras de Datos y Algoritmos

ndice general.
CAPTULO 6. .............................................................................................................................................1
RBOLES BINARIOS DE BSQUEDA. ................................................................................................1
6.1. DEFINICIONES. ...................................................................................................................................1
Ejemplos de definiciones. .....................................................................................................................2
6.2. RBOL BINARIO..................................................................................................................................2
Definicin de tipos de datos. ................................................................................................................3
6.3. RBOL BINARIO DE BSQUEDA. .........................................................................................................3
6.4. CLCULOS DE COMPLEJIDAD O ALTURA EN RBOLES. ........................................................................4
6.4.1. rbol completo. ..........................................................................................................................4
6.4.2 rboles incompletos con un nivel de desbalance. .......................................................................6
6.4.3. rboles construidos en forma aleatoria. ....................................................................................7
6.4.4. Nmero de comparaciones promedio en un rbol binario de bsqueda..................................11
6.4.4.1. rbol binario externo ........................................................................................................................ 11
6.4.4.2. Largos de trayectorias interna y externa. ........................................................................................... 13
6.4.4.3. Bsquedas exitosas y no exitosas. ..................................................................................................... 15

6.5. RECORRIDOS EN RBOLES. ...............................................................................................................19


6.5.1. En orden: .............................................................................................................................................. 19
6.5.2. Pre orden: ............................................................................................................................................. 19
6.5.3. Post orden: ........................................................................................................................................... 19
6.5.4. Ejemplo de recorridos. ......................................................................................................................... 19
6.5.5. rboles de expresiones......................................................................................................................... 20
6.5.6. rboles de derivacin. ......................................................................................................................... 20

6.6. OPERACIONES EN RBOLES BINARIOS. .............................................................................................20


6.6.1. Operaciones bsicas ................................................................................................................21
6.6.1.1. Crear rbol vaco. .............................................................................................................................. 21
6.6.1.2. Crea nodo inicializado con un valor de clave. ................................................................................... 21
6.6.1.3. Ejemplo de uso. ................................................................................................................................. 21

6.6.2. Operaciones de recorrido ........................................................................................................21


6.6.2.1. Mostrar en orden ............................................................................................................................... 21
6.6.2.2. Mostrar en post-orden ....................................................................................................................... 23
6.6.2.3. Mostrar en pre-orden ......................................................................................................................... 23

6.6.3. Operaciones de consulta. .........................................................................................................23


6.6.3.1. Seleccionar el nodo con valor mnimo de clave. ............................................................................... 23
6.6.3.2. Seleccionar el nodo con valor mximo de clave................................................................................ 24
6.6.3.3. Nodo descendiente del subrbol derecho con menor valor de clave.................................................. 25
6.6.3.4. Sucesor. ............................................................................................................................................. 26
6.6.3.5. Nodo descendiente del subrbol izquierdo con mayor valor de clave. .............................................. 27
6.6.3.6. Predecesor. ........................................................................................................................................ 27
6.6.3.7. Buscar ............................................................................................................................................... 28
Complejidad de la bsqueda...................................................................................................................... 28

6.6.4. Operaciones de modificacin ...................................................................................................29


6.6.4.1. Insertar nodo ..................................................................................................................................... 29
Diseo iterativo. ........................................................................................................................................ 29
Diseo recursivo........................................................................................................................................ 32

Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

55

Trayectoria en el descenso. ....................................................................................................................... 32


6.6.4.2. Descartar nodo .................................................................................................................................. 35
Descarte recursivo..................................................................................................................................... 35
Descarte iterativo. ..................................................................................................................................... 37
6.6.4.3. Descartar rbol .................................................................................................................................. 39

6.6.5. Otras operaciones ................................................................................................................... 39


6.6.5.1. Profundidad del rbol. ....................................................................................................................... 39
6.6.5.2. Altura del rbol. ................................................................................................................................ 39
6.6.5.3. Contar hojas ...................................................................................................................................... 40
6.6.5.4. Contar nodos del rbol. ..................................................................................................................... 40
6.6.5.5. Contar nodos internos. ...................................................................................................................... 40
6.6.5.6. Contar nodos con valores menores que un valor dado. ..................................................................... 40
6.6.5.7. Partir rbol. ....................................................................................................................................... 40
6.6.5.8. Insertar nueva raz. ............................................................................................................................ 41
6.6.5.9. Unir dos rboles. ............................................................................................................................... 41
6.6.5.10. Rotaciones....................................................................................................................................... 43
6.6.5.11. Insercin en la raz. ......................................................................................................................... 46
6.6.5.12. Imprimir la forma del rbol. ............................................................................................................ 47

PROBLEMAS RESUELTOS. ........................................................................................................................ 48


P6.1. .................................................................................................................................................. 48
P6.2. .................................................................................................................................................. 49
P6.3. .................................................................................................................................................. 50
EJERCICIO PROPUESTOS. ......................................................................................................................... 53
E6.1. .................................................................................................................................................. 53
E6.2. .................................................................................................................................................. 53
E6.3. .................................................................................................................................................. 53
NDICE GENERAL. ................................................................................................................................... 54
NDICE DE FIGURAS................................................................................................................................. 56

Profesor Leopoldo Silva Bijit

20-01-2010

56

Estructuras de Datos y Algoritmos

ndice de figuras.
FIGURA 6.1. RBOLES. ..................................................................................................................................2
FIGURA 6.2. RBOL BINARIO. ........................................................................................................................2
FIGURA 6.3. RBOL BINARIO DE BSQUEDA. .................................................................................................3
FIGURA 6.4. NO ES RBOL BINARIO DE BSQUEDA. .......................................................................................4
FIGURA 6.5. VARIOS RBOLES BINARIOS DE BSQUEDA CON DISTINTA FORMA. ............................................4
FIGURA 6.6. RBOL COMPLETO DE NIVEL 1. ..................................................................................................5
FIGURA 6.7. RBOL COMPLETO DE NIVEL 2. ..................................................................................................5
FIGURA 6.8. RBOL COMPLETO DE NIVEL 3. ..................................................................................................5
FIGURA 6.9. RBOLES INCOMPLETOS DE NIVEL 2. .........................................................................................6
FIGURA 6.10. RAZ CON VALOR I. ..................................................................................................................7
FIGURA 6.11. ALTURA DE RBOL GENERADO ALEATORIAMENTE. ...............................................................10
FIGURA 6.12. ALARGUE DE ALTURA DE RBOL GENERADO ALEATORIAMENTE. ..........................................11
FIGURA 6.13. NODOS INTERNOS Y EXTERNOS. .............................................................................................11
FIGURA 6.14. P(1): NE = NI + 1 ......................................................................................................................12
FIGURA 6.15. P(2): NE = NI + 1 ......................................................................................................................12
FIGURA 6.16. PRIMER CASO DE P(N+1): NE = NI + 1 ......................................................................................13
FIGURA 6.17. SEGUNDO CASO DE P(N): NE = NI + 1 .......................................................................................13
FIGURA 6.18. P(1): E(N) = I(N) + (2 N + 1) .................................................................................................13
FIGURA 6.19. P(2): E(N) = I(N) + (2 N + 1) ..................................................................................................14
FIGURA 6.20. PRIMER CASO DE P(N): E(N) = I(N) + (2 N + 1) .......................................................................14
FIGURA 6.21. SEGUNDO CASO DE P(N): E(N) = I(N) + (2 N + 1) ...................................................................15
FIGURA 6.22. EVALUACIN DE U(0). ..........................................................................................................16
FIGURA 6.23. S(N) ES (LOG2(N)). ..............................................................................................................18
FIGURA 6.24. RBOL CON CLAVES {N0, N1, N2, N3, N4, N5}. ......................................................................20
FIGURA 6.25. RBOL QUE REPRESENTA A: ( A * B) / (C + D) .........................................................................20
FIGURA 6.26. RBOL DE DERIVACIN. ........................................................................................................20
FIGURA 6.27. VARIABLES EN BUSCARMINIMOITERATIVO...........................................................................24
FIGURA 6.28. CONDICIONES EN BUSCAMINIMO ..........................................................................................24
FIGURA 6.29. MENOR DESCENDIENTE SUBRBOL DERECHO. .......................................................................25
FIGURA 6.30. CASOS EN BSQUEDA DEL MENOR DESCENDIENTE.................................................................26
FIGURA 6.31. SUCESORES DE DISTINTOS NODOS. .........................................................................................27
FIGURA 6.31.A. VARIABLES AL SALIR DEL WHILE........................................................................................30
FIGURA 6.31.B. VARIABLES AL SALIR DEL WHILE. .......................................................................................31
FIGURA 6.32. TRAYECTORIAS EN LLAMADOS RECURSIVOS..........................................................................32
FIGURA 6.33. STACK DESPUS DE INSERTARRECURSIVO(RAIZ, 7). ..............................................................33
FIGURA 6.34. STACK DESPUS DE INSERTARRECURSIVO(T1, 7). .................................................................33
FIGURA 6.35. STACK DESPUS DE INSERTARRECURSIVO(T3, 7). .................................................................33
FIGURA 6.36. STACK DESPUS DE INSERTARRECURSIVO(T3->RIGHT, 7). ....................................................33
FIGURA 6.37. STACK DESPUS DEL RETORNO DEL CUARTO LLAMADO.........................................................34
FIGURA 6.38. STACK DESPUS DEL TERCER RETORNO. ................................................................................34
FIGURA 6.39. STACK DESPUS DEL RETORNO DEL SEGUNDO LLAMADO.......................................................34
FIGURA 6.40. DESCARTAR HOJA ..................................................................................................................35
FIGURA 6.41. DESCARTAR NODO CON UN SUBRBOL ..................................................................................36
FIGURA 6.42. DESCARTAR NODO CON DOS HIJOS. ........................................................................................36
FIGURA 6.43. PUNTERO A PUNTERO A NODO................................................................................................37

Profesor Leopoldo Silva Bijit

20-01-2010

rboles binarios de bsqueda

57

FIGURA 6.44. MEMORIZACIN DE TRAYECTORIA DE DESCENSO. ................................................................ 37


FIGURA 6.45. VARIABLES EN UNIR DOS SUBRBOLES. ................................................................................ 41
FIGURA 6.46. PARTE DEL IF DENTRO DEL WHILE. ........................................................................................ 42
FIGURA 6.47. PARTE DEL ELSE DENTRO DEL WHILE. ................................................................................... 42
FIGURA 6.48. UNIN DE LOS RBOLES. ....................................................................................................... 42
FIGURA 6.49. ROTACIN IZQUIERDA........................................................................................................... 44
FIGURA 6.50. ROTACIN DERECHA. ............................................................................................................ 45
FIGURA 6.51. EJEMPLO DE ROTACIN DERECHA DE NODOS 4-6. ................................................................. 45
FIGURA 6.52. INSERCIN DE NODO CON CLAVE 5 EN LA RAZ...................................................................... 46
FIGURA 6.53. IMPRESIN DE LA FORMA DE UN RBOL. ............................................................................... 47
FIGURA P6.1. .............................................................................................................................................. 50
FIGURA P6.2. .............................................................................................................................................. 50

Profesor Leopoldo Silva Bijit

20-01-2010

También podría gustarte