Sei sulla pagina 1di 14

Programaci on Declarativa Haskell Inform atica Sistemas Curso 2003-2004

Pepe Gallardo Universidad de M alaga


Tema 9.

Arboles
9.1

Arboles binarios
fmap para arboles binarios
Plegado de arboles binarios
9.2

Arboles generales
fmap para arboles generales
Plegado de arboles generales
9.3

Arboles de b usqueda
9.1

Arboles binarios
Tipo para arboles binarios homog eneos con datos en nodos:
data

ArbolB a = VacoB | NodoB
hijo izq

(

ArbolB a)
dato en nodo

a
hijo der

(

ArbolB a)
deriving Show
VacoB es un arbol binario vaco
Las tres componentes de NodoB son
sub arbol izquierdo
dato en nodo
sub arbol derecho
Si falta un sub arbol, se usa VacoB.
Ejemplo:

15

24
^

27

10

18
^

24
^
a : :

ArbolB Integer
a = NodoB aI 10 aD
where
aI = NodoB aII 15 aID
aD = NodoB VacoB 18 aDD
aII = hojaB 24
aID = hojaB 27
aDD = hojaB 24
hojaB : : a

ArbolB a
hojaB x = NodoB VacoB x VacoB
Inform atica Pepe Gallardo Universidad de M alaga 9.1

Arboles binarios (2)


data

ArbolB a = VacoB | NodoB
hijo izq

(

ArbolB a)
dato en nodo

a
hijo der

(

ArbolB a)
deriving Show
Algunas funciones
razB : :

ArbolB a a
razB VacoB = error raz de arbol vaco
razB (NodoB x ) = x
tama noB : :

ArbolB a Integer
tama noB VacoB = 0
tama noB (NodoB i d) = 1 + tama noB i + tama noB d
profundidadB : :

ArbolB a Integer
profundidadB VacoB = 0
profundidadB (NodoB i d) = 1 + max (profundidadB i ) (profundidadB d)
Recorridos de un arbol binario:
enOrdenB : :

ArbolB a [a]
enOrdenB VacoB = [ ]
enOrdenB (NodoB i r d) = enOrdenB i ++ [r] ++ enOrdenB d
preOrdenB : :

ArbolB a [a]
preOrdenB VacoB = [ ]
preOrdenB (NodoB i r d) = [r] ++ preOrdenB i ++ preOrdenB d
postOrdenB : :

ArbolB a [a]
postOrdenB VacoB = [ ]
postOrdenB (NodoB i r d) = postOrdenB i ++ postOrdenB d ++ [r]
Inform atica Pepe Gallardo Universidad de M alaga 9.2
fmap para arboles binarios
La funci on map solo est a denidad para listas
map : : (a b) [a] [b]
map f [ ] = [ ]
map f (x : xs) = f x : map f xs
La clase Functor dene una funci on fmap para estructuras arbitrarias
class Functor t where
fmap : : (a b) t a t b
Las listas son una instancia predenida:
instance Functor [ ] where
fmap = map
Es posible usar tanto map como fmap con listas.
La funci on fmap tambi en tiene sentido para arboles binarios:
instance Functor

ArbolB where
fmap f VacoB = VacoB
fmap f (NodoB i r d) = NodoB (fmap f i ) (f r) (fmap f d)
Ejemplo de uso:
empareja : : Functor t t a t (a, a)
empareja = fmap ( x (x, x))
? empareja [1..3]
[ (1, 1), (2, 2), (3, 3) ] : : [(Integer, Integer)]
? empareja (NodoB VacoB 10 VacoB)
NodoB VacoB (10, 10) VacoB : :

ArbolB (Integer, Integer)
Inform atica Pepe Gallardo Universidad de M alaga 9.3
Plegado de arboles binarios
Muchas funciones sobre el tipo

ArbolB siguen el mismo esquema:
sum

ArbolB : :

ArbolB Integer Integer
sum

ArbolB VacoB = 0
sum

ArbolB (NodoB i r d) = sumar (sum

ArbolB i ) r (sum

ArbolB d)
where
sumar x y z = x +y +z
enOrdenB : :

ArbolB t [t]
enOrdenB VacoB = [ ]
enOrdenB (NodoB i r d) = concatenar (enOrdenB i ) r (enOrdenB d)
where
concatenar x y z = x ++ [y] ++ z
El esquema com un y la funci on de orden superior:
fun : :

ArbolB a b
fun VacoB = z
fun (NodoB i r d) = f (fun i ) r (fun d)
fold

ArbolB : : (b a b b) b (

ArbolB a b)
fold

ArbolB f z = fun
where
fun VacoB = z
fun (NodoB i r d) = f (fun i ) r (fun d)
O equivalentemente (ya que fold

ArbolB f z = fun)
fold

ArbolB : : (babb)b

ArbolB ab
fold

ArbolB f z VacoB = z
fold

ArbolB f z (NodoB i r d) = f (fold

ArbolB f z i ) r (fold

ArbolB f z d)
Las funciones originales como concreci on de fold

ArbolB:
sum

ArbolB : :

ArbolB Integer Integer
sum

ArbolB = fold

ArbolB ( x y z x +y +z ) 0
enOrdenB : :

ArbolB t [t]
enOrdenB = fold

ArbolB ( x y z x ++ [y] ++ z ) [ ]
Inform atica Pepe Gallardo Universidad de M alaga 9.4
Plegado de arboles binarios (2)
fold

ArbolB : : (b a b b) b (

ArbolB a b)
fold

ArbolB f z = fun
where
fun VacoB = z
fun (NodoB i r d) = f (fun i ) r (fun d)
Para denir una funci on usando fold

ArbolB:
Proporcionar el resultado para el arbol vaco (z ) .
Proporcionar funci on (f ) que calcule el resultado a partir del resultado para
el sub arbol izquierdo, la raz y el resultado para el sub arbol derecho.
Ejemplos
tama no de un arbol (n umero de elementos almacenados)
tama noB : :

ArbolB a Integer
tama noB = fold

ArbolB ( ti r td 1 + ti + td) 0
profundidad de un arbol
profundidadB : :

ArbolB a Integer
profundidadB = fold

ArbolB ( pi r pd 1 + max pi pd) 0


recorrido en pre orden
preOrdenB : :

ArbolB a [a]
preOrdenB = fold

ArbolB ( pi r pd [r] ++ pi ++ pd) []


Inform atica Pepe Gallardo Universidad de M alaga 9.5
9.2

Arboles generales
Un arbol es una estructura no lineal acclica
Un arbol es una colecci on de valores {v
1
, v
2
, . . . v
n
} tales que
Si n = 0, el arbol se dice vaco
En otro caso, existe un valor destacado (la raz) y los dem as elementos for-
man parte de colecciones disjuntas que a su vez son arboles (sub arboles del
raz)

10

22

35

52
+ ? j

15

12

33
N ?
data

Arbol a = Vaco | Nodo a

raz
[

Arbol a]

hijos
deriving Show
a1 : :

Arbol Integer
a1 = Nodo 10 [a11, a12, a13]
where
a11 = Nodo 22 [hoja 15, hoja 12]
a12 = hoja 35
a13 = Nodo 52 [hoja 33]
hoja : : a

Arbol a
hoja x = Nodo x [ ]
raz : :

Arbol a a
raz Vaco = error raz de arbol vaco
raz (Nodo x ) = x
subarboles : :

Arbol a [

Arbol a]
subarboles Vaco = error subarboles de arbol vaco
subarboles (Nodo xs) = xs
Inform atica Pepe Gallardo Universidad de M alaga 9.6

Arboles generales (2)


data

Arbol a = Vaco | Nodo a

raz
[

Arbol a]

hijos
deriving Show
Algunas funciones
tama no : :

Arbol a Integer
tama no Vaco = 0
tama no (Nodo xs) = 1 + sum (map tama no xs)
profundidad : :

Arbol a Integer
profundidad Vaco = 0
profundidad (Nodo [ ]) = 1
profundidad (Nodo xs) = 1 + maximum (map profundidad xs)
pertenece : : Eq a a

Arbol a Bool
pertenece Vaco = False
pertenece x (Nodo r xs) = x == r | | or (map (pertence x) xs)
Recorridos de un arbol general:
preOrden : :

Arbol a [a]
preOrden Vaco = [ ]
preOrden (Nodo r xs) = [r] ++ concat (map preOrden xs)
postOrden : :

Arbol a [a]
postOrden Vaco = [ ]
postOrden (Nodo r xs) = concat (map postOrden xs) ++ [r]
Inform atica Pepe Gallardo Universidad de M alaga 9.7
fmap para arboles generales
La funci on fmap tambi en tiene sentido para un arbol general
instance Functor

Arbol where
fmap f Vaco = Vaco
fmap f (Nodo r xs) = Nodo (f r) [ fmap f x | x xs ]
o usando map
instance Functor

Arbol where
fmap f Vaco = Vaco
fmap f (Nodo r xs) = Nodo (f r) (map (fmap f ) xs)
Ahora la funci on empareja puede usarse con arboles generales
empareja : : Functor t t a t (a, a)
empareja = fmap ( x (x, x))
? empareja (Nodo 10 [Nodo 20 [ ]])
Nodo (10, 10) [Nodo (20, 20) [ ]] : :

Arbol (Integer, Integer)
? fmap (+1) (Nodo 10 [Nodo 20 [ ]])
Nodo 11 [Nodo 21 [ ]] : :

Arbol Integer
Inform atica Pepe Gallardo Universidad de M alaga 9.8
Plegado de arboles generales
Muchas funciones siguen el mismo esquema
sum

Arbol : :

Arbol Integer Integer
sum

Arbol Vaco = 0
sum

Arbol (Nodo r xs) = sumar r (map sum

Arbol xs)
where
sumar y ys = y + sum ys
preOrden : :

ArbolB t [t]
preOrden Vaco = [ ]
preOrden (Nodo r xs) = unir r (map preOrden xs)
where
unir y ys = [y] ++ concat ys
El esquema com un y la funci on de orden superior
fun : :

Arbol a b
fun Vaco = z
fun (Nodo r xs) = f r (map fun xs)
fold

Arbol : : (a [b] b) b (

Arbol a b)
fold

Arbol f z = fun
where
fun Vaco = z
fun (Nodo r xs) = f r (map fun xs)
Las funciones originales como concreciones de fold

Arbol
sum

Arbol : :

Arbol Integer Integer
sum

Arbol = fold

Arbol ( y ys y + sum ys) 0


preOrden : :

ArbolB t [t]
preOrden = fold

Arbol ( y ys [y] ++ concat ys) [ ]


Inform atica Pepe Gallardo Universidad de M alaga 9.9
Plegado de arboles generales (2)
fold

Arbol : : (a [b] b) b (

Arbol a b)
fold

Arbol f z = fun
where
fun Vaco = z
fun (Nodo r xs) = f r (map fun xs)
Para denir una funci on usando fold

Arbol
Proporcionar el resultado para el arbol vaco (z ) .
Proporcionar funci on (f ) que calcule el resultado a partir de la raz y una lista
con el resultado para cada sub arbol.
Ejemplos
tama no de un arbol
tama no : :

Arbol a Integer
tama no = fold

Arbol ( r ts 1 + sum ts) 0


pertenencia de un dato a un arbol
pertenece : : Eq a a

Arbol a Bool
pertenece x = fold

Arbol ( r ps x == r | | or ps) False


recorrido en post orden
postOrden : :

Arbol a [a]
postOrden = fold

Arbol ( r ps concat ps ++ [r]) [ ]


Inform atica Pepe Gallardo Universidad de M alaga 9.10
9.3

Arboles de b usqueda
Un arbol de b usqueda es un arbol binario tal que
O bien es vaco
O no es vaco y para cualquier nodo se cumple que:
los elementos del sub arbol izquierdo son menores o iguales al almace-
nado en el nodo
y los elementos del sub arbol derecho son estrictamente mayores al al-
macenado en el nodo
Ejemplo

50

30

60
R

30

35

80
R U
La siguiente funci on puede ser utilizada para comprobar si un arbol binario es de
b usqueda:
es

ArbolBB : : Ord a

ArbolB a Bool
es

ArbolBB VacoB = True


es

ArbolBB (NodoB i r d) = todos

ArbolB (<= r) i
&& todos

ArbolB (> r) d
&& es

ArbolBB i
&& es

ArbolBB d
todos

ArbolB : : (a Bool )

ArbolB a Bool
todos

ArbolB p VacoB = True


todos

ArbolB p (NodoB i r d) = p r &&


todos

ArbolB p i && todos

ArbolB p d
Inform atica Pepe Gallardo Universidad de M alaga 9.11

Arboles de b usqueda (2)


Pertenencia a un arbol de b usqueda
perteneceBB : : Ord a a

ArbolB a Bool
perteneceBB x VacoB = False
perteneceBB x (NodoB i r d)
| x == r = True
| x < r = perteneceBB x i
| otherwise = perteneceBB x d
Inserci on en un arbol de b usqueda
insertarBB : : Ord a a

ArbolB a

ArbolB a
insertarBB x VacoB = NodoB VacoB x VacoB
insertarBB x (NodoB i r d)
| x <= r = NodoB (insertarBB x i ) r d
| otherwise = NodoB i r (insertarBB x d)
Construcci on de un arbol de b usqueda a partir de una lista
listaA

ArbolBB : : Ord a [a]



ArbolB a
listaA

ArbolBB = foldr insertarBB VacoB


El recorrido en orden genera una lista ordenada (tree sort)
treeSort : : Ord a [a] [a]
treeSort = enOrdenB . listaA

ArbolBB
? treeSort [4, 7, 1, 2, 9]
[1, 2, 4, 7, 9] : : [Integer]
Inform atica Pepe Gallardo Universidad de M alaga 9.12
Objetivos del tema
El alumno debe:
Conocer las deniciones de tipo para representar arboles en Haskell
Saber denir funciones sobre arboles
Conocer la clase Functor y saber realizar instancias de esta clase
Conocer las funciones de plegado para arboles
Saber denir funciones como concreciones de las funciones de plegado
Conocer la implementaci on de los arboles de b usqueda en Haskell
Inform atica Pepe Gallardo Universidad de M alaga 9.13

Potrebbero piacerti anche