Está en la página 1de 24

9.

´Arboles

Una estructura de datos con una relaci´on es una ´arbol si y s´olo:

La relaci´on es conexa, es decir, existe una composici´on de relaciones entre cualquier par de

nodos en el ´arbol.

No admite ciclos.

Definici´on: Un ´arbol T es un conjunto finito de uno o m´as nodos tal que: (i) hay un nodo
especialmente llamado raı´z R; (ii) los dem´as nodos est´an particionados en n ! 0 conjuntos
desconectados

T1 . . . Tn, donde cada uno de estos conjuntos es un ´arbol, ası´ llamados sub´arboles de la
ra´ız. As´ı:

T = {R} " T1 . . . " Tn

Ti # Tn = $ (2)

Padre: El nodo inmediatamente antecesor

Hijos: nodos inmediatamente sucesor

Grado: nu´mero de hijos de un nodo

Nivel: distancia a la ra´ız de un nodo

Profundidad: nivel m´aximo de un ´arbol

Bosque: ´arboles desconectados

Formas de visualizar un ´arbol son:

Gr´afico:

B CD

EFGHIJ

K LM

Listas:

(A(B(E(K,L),F),C(G),D(H(M),I,J)))

50Data

link1 linkn

0 A111
0 B10 F

0 C0 G0 D1

0 I0 J

0 H0 M

0 E0 K0 L

La representaci´on es esencialmente por listas encadenadas

Teoremas:

El ´arbol es conexo pero al eliminar un arco, se convierte en no conexo

El ´arbol no tiene ciclos y es conexo, arcos = nodos % 1

Al agregar un arco a un ´arbol se crea un ciclo.

10. ´Arbol Binario

Definici´on: Un ´arbol binario es un n´umero finito de nodos que es vac´ıo o consiste de una
ra´ız con

dos ´arboles binarios desconectados llamados sub´arbol izquierdo y derecho. Se llaman los
nodos que

no tienen hijos, nodos hojas o terminales. Nodos con uno o dos hijos son llamados nodos
internos.

51structureBTREE(ITEM)

declare

NEW() & btree

MAKEBT REE(btree, item, btree) & btree

LCHILD(btree) & btree

RCHILD(btree) & btree


DAT A(btree) & item

IS IN(btree, item) & boolean

IS EMP T Y (btree) & boolean

for all bt1, bt2 ' BT REE, i, i1, i2 ' item let

DAT A(NEW()) ::= error

DAT A(MAKEBT REE(bt1, i, bt2)) ::= i

IS EMP T Y (NEW()) ::= true

IS EMP T Y (MAKEBT REE(bt1, i, bt2)) ::= f alse

IS IN(NEW(), i) ::= f alse

IS IN(MAKEBT REE(bt1, i1, bt2), i2) ::= if i1 = i2 then true

else IS IN(bt1, i2) ( IS IN(bt2, i2)

LCHILD(NEW()) ::= NEW()

LCHILD(MAKEBT REE(bt1, i, bt2)) ::= bt1

RCHILD(NEW()) ::= NEW()

RCHILD(MAKEBT REE(bt1, i, bt2)) ::= bt2

Lema: El m´aximo nu´mero de nodos en un nivel i de un ´arbol binario es 2

, i ! 0; y el m´aximo

nu´mero de nodos en un ´arbol binario de profundidad k es 2

k+1

% 1, k ! 0.

Prueba Por inducci´on

Base inducci´on: La ra´ız es el u´nico nodo en el nivel 0. Por lo tanto, el m´aximo nu´mero de
nodos

en el nivel i = 0 es 2

=2

i
.

Hip´otesis de inducci´on: Para todo j, 0 ) j ) i, el m´aximo nu´mero de nodos en el nivel j es 2

Paso de inducci´on: El m´aximo n´umero de nodos en el nivel i % 1 es 2

i!1

, por la hip´otesis de

inducci´on. Debido a que cada nodo del ´arbol tiene como m´aximo grado 2, el n´umero de
nodos

m´aximos en el nivel i es 2 veces el m´aximo nu´mero de nodos en el nivel i % 1 o 2

El m´aximo .

nu´mero de nodos n en un ´arbol binario de profundidad k es la sumatoria del m´aximo


nu´mero de

nodos en cada nivel:

n=

k!

i=0

=2

k+1

%1

Lema: Por cada ´arbol binario no vac´ıo T , si n es el n´umero de nodos terminales (hojas) y m
es el

nu´mero de nodos de grado 2, entonces n = m + 1.

Prueba: Sea l el n´umero de nodos de grado uno, entonces el nu´mero total de nodos N en el
´arbol

es N = n + m + l.
Todos los nodos en el ´arbol excepto por la raı´z tienen un arco de llegada. Entonces, N es igual
al

nu´mero de arcos B + 1. Tambie´n, todo arco emana de un nodo de grado uno o de grado dos.
As´ı:

B = l + 2m. Por lo tanto N = 1 + l + 2m.

Substrayendo N = 1 + l + 2m de N = n + m + l nos queda que n = m + 1.

5210.1. Representaci´on por arreglos

Un ´arbol binario se representa en un arreglo del siguiente modo: si un nodo ocupa la posici´on
i,

entonces su hijo izquierdo ocupa la posici´on 2i y su hijo derecho la posici´on 2i + 1.

Si un ´arbol es completo con n nodos, por cada nodo i , 1 ) i ) n, tenemos:

PARENT(i) est´a localizado en *i/2+ si i =, 1. Cuando i = 1, i es la ra´ız y no tiene padre.

LCHILD(i) est´a en 2i si 2i ) n. Si 2i > n entonces no tiene hijo izquierdo.

RCHILD(i) est´a en 2i + 1 si 2i + 1 ) n. Si 2i + 1 > n, entonces no tiene hijo derecho.

Esta forma de representaci´on no es muy usada por problemas de p´erdida de espacio.

10.2. Representaci´on por punteros

Usando punteros, cada nodo es un registro con tres campos: el dato, el puntero al hijo
izquierdo y

el puntero al hijo derecho.

Caminamiento en un ´arboles binario T :

Procedure INORDER(T )

if T =, nil do [

call INORDER(LCHILD(T ))

print(DATA(T))

call INORDER(RCHILD(T )) ]

end INORDER

Procedure P REORDER(T )

if T =, nil do [

print(DATA(T))
call P REORDER(LCHILD(T ))

call P REORDER(RCHILD(T )) ]

end P REORDER

Procedure P OST ORDER(T )

if T =, nil do [

call P OST ORDER(LCHILD(T ))

call P OST ORDER(RCHILD(T ))

print(DATA(T)) ]

end P OST ORDER

Si T es un ´arbol binario con ra´ız de n nodos, el caminamiento en el ´arbol toma !(n). Sea T (n)
el

tiempo que toma el recorrido de un ´arbol binario de n nodos. El menor tiempo posible es el
de un

´arbol vacı´o T (0) = c para alguna constante positiva c. Para n > 0, suponga que la llamada al
recorrido ocurri´o en un nodo x raı´z con k nodos en el sub´arbol izquierdo y n%k%1 hijos en el
sub´arbol

derecho. El tiempo de recorrido es T (n) = T (k)+T (n%k%1)+dparaalgunaconstantepositivad que

refleja el tiempo de ejecuci´on en el nodo ra´ız (o sea, el tiempo de las llamadas recursivas
esencialmente). Provemos que T (n) = (c+d)n+c. Para n = 0, nosotros tenemos que (c+d)0+c = c
= T (0).

53Para n > 0 tenemos que:

T (n) = T (k) + T (n % k % 1) + d

= ((c + d)k + c) + ((c + d)(n % k % 1) + c) + d

= (c + d)n + c % (c + d) + c + d

= (c + d)n + c (3)

Esto demuestra que T (n) = (c + d)n + c y esto es !(n).

10.3. ´Arboles Binarios de B´usqueda

Un ´arbol binario de bu´squeda es un ´arbol binario donde la ra´ız es siempre mayor que los
nodos del

sub´arbol izquierdo y menor que todos los nodos del sub´arbol derecho.
structureBBTREE(ITEM)

declare

NEW() & bbtree

MBT REE(bbtree, item, bbtree) & btree

INSERT (item, bbtree) & bbtree

IS EMP T Y (btree) & boolean

IS IN(bbtree, item) & boolean

MINIMUM(bbtree) & item

MAXIMUM(bbtree) & item

for all bt1, bt2 ' BT REE, i, i1, i2 ' item let

INSERT (i, NEW()) ::= MBT REE(NEW(), i, NEW())

INSERT (i, MBT REE(bbt1, i, bbt2)) ::= MBT REE(bbt1, i, bbt2)

INSERT (i, MBT REE(bbt1, i2, NEW())) ::=

if i > i2 then MBT REE(bbt1, i2, MBT REE(NEW(), i, NEW()))

else MBT REE(INSERT (i, bbt1), i2, NEW())

INSERT (i, MBT REE(NEW(), i2, bbt2)) ::=

if i < i2 then MBT REE(MBT REE(NEW(), i, NEW()), i2, bbt2)

else MBT REE(NEW(), i2, INSERT (i, bbt1))

INSERT (i, MBT REE(bbt1, i2, bbt2)) ::=

if i < i2 then MBT REE(INSERT (i, bbt1), i2, bbt2)

else MBT REE(bbt1, i2, INSERT (i, bbt1))

IS EMP T Y (NEW()) ::= true

IS EMP T Y (MBT REE(bbt1, i, bbt2)) ::= f alse

IS IN(NEW(), i) ::= f alse

IS IN(MBT REE(bbt1, i1, bbt2), i2) ::= if i1 = i2 then true

else if i2 < i1 then IS IN(bt1, i2) else IS IN(bt2, i2)

MINIMUM(NEW()) ::= error


MINIMUM(MBT REE(NEW(), i, bbt2)) ::= i

MINIMUM(MBT REE(bbt1, i, bbt2)) ::= MINIMUM(bbt1)

MAXIMUM(NEW()) ::= error

MAXIMUM(MBT REE(bbt1, i, NEW())) ::= i

MAXIMUM(MBT REE(bbt1, i, bbt2)) ::= MAXIMUM(bbt2)

54Los algoritmos de ´arboles binarios de b´usqeuda son:

B´usqueda:

Procedure BUSCAR(N, T )

// N es el valor buscado

// T es la ra´ız del ´arbol binario de b´usqueda

if T =, nil do [

if N = DAT A(T ) then return T

else if N < DAT A(T ) then return BUSCAR(N, LCHILD(T ))

else BUSCAR(N, RCHILD(T )) ]

else return ”no se encontr´o”

end BUSCAR

Procedure BUSCAR(N, T ) // no recursivo

// N es el valor buscado

// T es la ra´ız del ´arbol binario de b´usqueda

p := T

while p =, nil do [

if N = DAT A(p) then return p

else if N < DAT A(p) then p := LCHILD(p)

else p := RCHILD(p) ]

return ”no se encontr´o”

end BUSCAR

En el peor caso, la bu´squeda llega hasta la hoja de un´arbol pasando por un camino desde la
raı´z hata la hoja, es decir, es un camino de largo h, con h siendo la profundidad.

M´ınimo y M´aximo:

Procedure MINIMUM(x)

// x nodo del ´arbol binario de b´usqueda

while LCHILD(x) =, nil do [

x := LCHILD(x) ]

return x

end MINIMUM

Procedure MAXIMUM(x)

// x es un nodo del ´arbol binario de bu´squeda

while RCHILD(x) =, nil do [

x := RCHILD(x) ]

return x

end MAXIMUM

Ambos Algoritmos tienen complejidad O(h) ya que ambos siguen el camino desde la ra´ız a la

hoja m´as izquierda o derecha del ´arbol.

Sucesor y Predecesor:

55Procedure SUCESSOR(x)

// x es un nodo en el ´arbol

//P ARENT (x) obtiene el padre de x

if RCHILD(x) =, nil then return MINIMUM(RCHILD(x))

y := P ARENT (x)

while y =, nil and x = RCHILD(y) do [

x := y

y := P ARENT (y) ]

return y

end SUCESSOR
Si un nodo x tiene un sub´arbol derecho, el sucesor y es el mı´nimo valor del sub´arbol
derecho.

Si un nodo no tiene sub´arbol derecho y tiene sucesor y, entonces, el sucesor y es el menor

ancestor de x cuyo hijo izquierdo es tambi´en un ancestor de x.

La complejidad del algoritmo es O(h) porque sigue el camino hacia una hoja del sub´arbol

derecho o sigue hacia arriba el camino hasta la ra´ız

El algoritmo P redecessor(x) es sime´trico y con el mismas complejidad.

Insertar y Borrar:

Procedure INSERT AR(P, T )

// P es el nodo a insertar

// T es la ra´ız del ´arbol binario de b´usqueda

if DAT A(T ) = DAT A(P ) then return existe

else if DAT A(P ) < DAT A(T ) then [

if LCHILD(T ) = nil then [

LCHILD(T):= P

return ]

else

INSERT AR(P, LCHILD(T ))]

else

if RCHILD(T ) = nil then[

RCHILD(T):= P

return ]

else

INSERT AR(P, RCHILD(T ))

end INSERT AR

En el peor caso, la inserci´on en un ´arbol se hace en un nodo hoja, lo que queda dado por la

profundidad del ´arbol O(h)antes de insertar. Ojo, al insertar, esta profundidad puede variar.

56Procedure DELET E(P, T )


// P es el nodo a eliminar

// T es la ra´ız del ´arbol binario de b´usqueda

if LCHILD(P ) = nil and RCHILD(P ) = nil then

y := P

else y := SUCCESSOR(P )

if LCHILD(y) =, nil then

x := LCHILD(y)

else x := RCHILD(y)

if x =, nil then [

P ARENT (x) := P ARENT (y)

if P ARENT (y) = nil then

T := x

else if y = LCHILD(P ARENT (y)) then

LCHILD(P ARENT (y)) := x

else RCHILD(P ARENT (y)) := x

if y =, x then

DATA(P) := DATA(y)

copia de informaci´on de punteros

return y

end DELET E

Para borrar se consideran 3 casos. Si P no tiene hijos, modifique el padre de P para reemplazar

P por nil como su hijo.

H T

B LRU

A D K M P

I
J

H T

B LRU

H T

B LRU

A D K

57Si P tiene s´olo un hijo, se divide P haciendo un nuevo enlace entre su hijo y su padre.

H T

B LRU

A D K M P

H T

B LRU

A D I M P

Finalmente, si el nodo tiene dos hijos, se divide el sucesor de P , y, el cual no tiene hijo

izquierdo y se reemplaza la clave de P y sus punteros con la clave de y y sus informaci´on de


punteros.

H T

B LRU

A D K M P

I T

B LRU

A D K M P

Problema: La eficiencia de un m´etodo depende de que el ´arbol de b´usqueda este´


balanceado. Entonces, ¿ c´omo mantener el ´arbol balanceado?

Definici´on: en un ´arbol de b´usqueda balanceado (AVL) la profundidad del sub´arbol


izquierdo es

igual a la profundidad del sub´arbol derecho ±1. A su vez, esta profundidad es satisfecha
recursivamente por los sub´arboles. Por ejemplo:

58H T

B JRU

A D P

Supongamos que tenemos un ´arbol binario de b´usqueda balanceado y le insertamos un


nuevo nodo.

El caso simple es cuando el ´arbol continua siendo balanceado.

AC

B
El problema sucede cuando al insertar el nodo, se desbalancea el ´arbol. Eso sucede en dos
caso

posibles:

La soluci´on es rotar el ´arbol una vez insertado el nodo. En el primer caso, la rotaci´on es
simple y

se hace en el sentido contrario al desbalanceo. El segundo caso, es necesario hacer dos


rotaciones

ya que el desbalanceo se produce en el sentido contrario a la inserci´on:

59D

BD

AC

En ambos casos, los ´arboles resultantes mantienen la profundidad inicial.

Otra situaci´on a considerar es al borrar un nodo de un ´arbol que est´a balanceado y que se
desbalancea.

AC
D

AD

Al igual que para inserci´on se deben realizar rotaciones. A diferencia de cuando se inserta, sin
embargo, los ´arboles resultantes pueden cambiar su profundidad y por lo tanto, no se puede
garantizar

que el balanceo del sub´arbol mantenga el rbol que lo contenga balanceado.

En resumen:

Al insertar:

1. usar b´usqueda binaria para ver donde insertar, e insertar el nodo

2. desde allı´ hacia arriba, chequear donde ocurre el desbalanceo.

3. hacer la rotaci´on adecuada.

Al eliminar:

1. borrar el nodo

2. ubicar punto de desbalanceo (´unico si existe)

3. hacer la rotacti´on correspondiente

604. si cambi´o profundidad volver al punto 2

Por ejemplo, en la siguiente figura, al ingresar la clave 20 se producen dos desbalances. La


rotaci´on

sobre el nodo con valor 11 soluciona s´olo un debalance.

4 11

3 6 9 18

2 8 14 19

12 17 22

20

4 18
3 6 11 19

2 8 14 22

9 12 17 20

rotación izquierda

Sin embargo, al tomar el desbalance mas profundo (m´as cercano a la hoja donde se inserta el

elemento) y su balanceo, el ´arbol vuelve a estar balanceado.

617

4 11

3 6 9 18

2 8 14 19

12 17 22

20

4 18

3 6 11 20

2 8 14 19 22

9 12 17

rotación doble

Algoritmos de rotaci´on: Asume que X tiene hijo derecho.

αβ

γα

βγ

right rotation(T,y)
left rotation(T,y)

62Procedure LEF T ROT AT ION(T, x)

// x nodo de rotatci´on

// T es la ra´ız del ´arbol binario de b´usqueda

y := RCHILD(x)

RCHILD(x) := LCHILD(y)

if LCHILD(y) =, nil then

P ARENT (LCHILD(y)) := x

P ARENT (y) := P ARENT (x)

if P ARENT (x) = nil then

T := y

else if x = LCHILD(P ARENT (x)) then

LCHILD(P ARENT (x)) := y

else RCHILD(P ARENT (x)) := y

LCHILD(y) := x

PARENT(x) := y

end LEF T ROT AT ION(T, x)

63Ejercicios de ´arboles binarios y a´rboles binarios de b´usqueda

1. Combinando preorden con inorder. Dado una secuencia de un ´arbol binario en preorden y

otra en inorden, es posible definir el ´unico ´arbol que las define.

Suponga la siguiente secuencia en preorden: A B C D E F G H I y la secuencia en inorden:

B C A E D G H F I, se puede construir el ´arbol binario haciendo que la primera letra en

preorden sea la ra´ız y al consider la definici´on en inorden de que todos los antecesores de A

sean los hijos izquierdo y los restantes en el lado derecho. Eso nos queda:

B,C D,E,F,G,H,I

Movie´ndose a continuaci´on de la secuencia en preorden est´a B como la pr´oxima ra´ız y por


la
secuencia en inorden se tiene que B no tiene hijo izquierdo y un sub´arbol derecho con C.

B D,E,F,G,H,I

Continuando de esta manera, se llega a:

B D

C E F

G J

Se puede decir que cada ´arbol binario tiene un u´nico par de secuencias pre-orden-inorden.

2. Contando a´rboles binarios.

Para 0 o 1 nodo , se tiene 1 posible ´arbol binario.

64Para 2 nodos, se tiene 2 posibles ´arboles binarios.

Para 3 nodos, se tienen 5..

Para ¿n?

Si los nodos de un ´arbol son enumerados en una secuencia de preorden de 1 . . . n, entonces


por el ejercicio anterior, distintos ´arbol binarios definen distintas secuencias en inorden

(permutaciones en inorden).

Usando el concepto de permutaci´on en inorden, es posible mostrar que el nu´mero total de

distintas permutaciones pasando los 1 . . . n nodes a trav´es de una pila y borr´andolas en


todas

las formas posibles es igual al n´umero total de ´arboles binarios con n nodos.

Comenzemos con 3 nodos (1 . . . 3), las posibles secuencias son:

1,2,3;3,2,1;2,1,3;2,3,1;3,2,1

Cada una de estas permutaciones corresponde a uno de los 5 ´arboles posibles:

2
3

23

En forma m´as general, queremos una expresi´on bn de los nu´meros de ´arboles binarios
distintos

con n nodos. Se puede deducir que bn es la suma de todos los posibles ´arboles binarios de la

siguiente forma, una ra´ız y dos subrboles bi

, bn!i!1:

bn =

0"i"n!1

bibn!i!1, n ! 1 - b0 = 1

Con recurrencia

B(x) =

i#0

bix

con
B(0) = b0 = 1

B(x) =

1%

1 % 4x

2x

Por teorema binomial

B(x) =

m#0

"

1/2

m+1

(%1)m

2m+1

xm

65Comparando las ecuaciones anteriores, bn es el coeficiente de x

en B(x):

bn) =

n+1

"

2n

n
#

bn = O(

n3/2

3. Extensi´on de la definici´on algebraica de un ´arbol binario. Defina las funciones:

P REORDER(btree) & queue

INORDER(btree) & queue

P OST ORDER(btree) & queue

usando la definici´on AP P END(queue, queue) & queue

Defina, adem´as, una funci´on que realice el SWAP BT REE(btree) & btree que invierte los

hijos izquierdos y derechos en forma recursiva y la funci´on que entrega el nu´mero de nodos

hojas de un btree NUM LEAV ES(btree) & int.

P REORDER(CREAT E) ::= EMP T Y QUEUE

P REORDER(MAKEBT (l, d, r)) ::=

AP P END(AP P END(ADDQ(EMP T Y QUEUE, d), (P REORDER(l))), (P REORDER(r)))

INORDER(CREAT E) ::= EMP T Y QUEUE

INORDER(MAKEBT (l, d, r)) ::=

AP P END(AP P END((INORDER(l)), ADDQ(EMP T Y QUEUE, d)), (INORDER(l)))

P OST ORDER(CREAT E) ::= EMP T Y QUEUE

P OST ORDER(MAKEBT (l, d, r)) ::=

AP P END(AP P END((P OST ORDER(l)), (P OST ORDER(l))), ADDQ(EMP T Y QUEUE, d))

SWAP BT REE(CREAT E) ::= CREAT E

SWAP BT REE(MAKEBT (l, d, r)) ::= MAKEBT (SWAP BT REE(r), d, SWAP BT REE(l))

NUM LEAV ES(CREAT E) ::= 0

NUM LEAV ES(MAKEBT (l, d, r)) ::=


if ISEMT BT (l) and ISEMT BT (r) then 1

else NUM LEAV ES(l) + NUM LEAV ES(r)

4. ´Arboles Completos: Un ´arbol con altura h es completo si tiene todos los niveles llenos
hasta

el nivel h (ojo, se asume aquı´ que a la altura h, el nivel es h + 1) . El nivel h + 1 est´a lleno de

izquierda a derecha y a partir de un punto en adelante est´a vacı´o. Escriba un algoritmo que

indique si el ´arbol est´a o no lleno.

5. ´Arboles atados:

´Arboles atados son aquellos donde los nodos nulos de un ´arbol binario

tradicional son usados para asociar el nodo al nodo sucesor o antecesor en el recorrido del

´arbol en un determinado orden (INORDER, POSTORDER, PREORDER). En la siguiente

figura se muestra un ´arbol atado para un recorrido en inorder que apoya los algoritmos de

sucesor o predecesor.

Algunos algoritmos para estos ´arboles son:

66I 0

AH

punteros adicional

punteros originales

Figura 20:

´Arboles Atados

Encontrar el sucesor en inorder de un nodo N en un ´arbol atado.

Procedure SUCESSOR(var NodeN)


//Sea N el nodo en un ´arbol atado en inorder para el cual se desea encontrar el sucesor.

// N retornar´a el valor del sucesor

N := RLINK(N)

if N es un puntero de atadura o N = nil then termina

while LLINK(N) no sea un puntero de atadura do N := LCHILD(N)

endSUCESSOR

Recorrer en inorder un ´arbo atado en inorder

Procedure WALK(NodeR)

//Sea R la ra´ız del ´arbol atado

N := R

while LLINK(N) =, nil do N := LCHILD(N)

Visite N

N := SUCCESOR(N)

while N =, nil do [

visite N

N := SUCCESOR(N)]

endWALK

Insertar un sub´arbol atado T1 como sub´arbol derecho de un nodo N en otro sub´arbol

atado T2.

Procedure INSERT AR(var nodeN, nodeRT1)

// RT1 es la ra´ız de T1

R := RT1

S := N

repeat S := RCHILD(S) until S es una atadura o S = nil

RLINK(N) := R

Q := R

while RLINK(Q) no sea una atadura y RLINK(Q) =, nil do Q := RLINK(Q)


RLINK(Q) := S

Q := R

while LLINK(Q) no sea una atadura y LLINK(Q) =, nil do Q := LLINK(Q)

LLINK(Q) := N

endINSERT AR

67