You are on page 1of 28

Lenguaje de Programación Estructurada

UNI – FIIS
Glen Rodríguez R.
Árboles

Al igual que las listas enlazadas, los árboles están
hechos de nodos.

Estos nodos se relacionan con otros NO por
relaciones de siguiente o anterior (como en las
listas enlazadas), sino por relaciones padre-hijo.

Hay un solo nodo llamado raíz que no tiene padre.

Cualquier otro nodo tiene exactamente un sólo
padre.
Árbol binario

Se caracterizan por que cada nodo tiene un
máximo de 2 hijos.

Cada nodo contiene un puntero a otros dos
nodos (posiblemente Null = None). Estos
punteros se llaman subárboles izquierdo y
derecho.

Como los nodos de las listas, los nodos de los
árboles también contienen una carga
Árbol binario

El nodo al que apunta tree sería la raíz.

Los otros nodos se llaman ramas y los nodos de
los extremos con referencias nulas se llaman
hojas. Puede parecer extraño que dibujemos el
árbol con la raíz arriba y las hojas abajo, pero esa
es la costumbre.

Arriba de cada flecha está el padre y abajo un hijo.
Hijos del mismo padre se llaman nodos hermanos.

Todos los nodos que están a la misma distancia de
la raíz forman un nivel del árbol.
Árbol binario

Igual que las listas enlazadas, los árboles son
estructuras de datos recursivas porque se
definen recursivamente.

Un árbol es:
– El árbol vacío, representado por None, o
– Un nodo que contiene una referencia a una carga y
dos referencias a árboles.
Creando árboles
class Arbol:
def __init__(self, carga, izquierda=None,
derecha=None):
self.carga = carga
self.izquierda = izquierda
self.derecha = derecha
def __str__(self):
return str(self.carga)
Creando árboles

Una forma de construir un árbol es de abajo hacia
arriba. Asigne primero los nodos hijos:
izquierda = Arbol(2)
derecha = Arbol(3)

Luego cree el nodo padre y vincúlelo a los hijos:
arbol = Arbol(1, izquierda, derecha);

O en forma reducida
arbol = Arbol(1, Arbol(2), Arbol(3))
Recorrer árboles
def total(arbol):
if arbol == None:
return 0
return total(arbol.izquierda) + total(arbol.derecha)
+ arbol.carga
Recorrer árboles

El caso base es el árbol vacío, que no tiene
carga, así que la suma es 0. El paso recursivo
hace dos llamadas recursivas para hallar la
suma de los árboles hijos. Cuando terminan las
llamadas recursivas, sumamos la carga del
padre y devolvemos el total.

Es este caso el orden del recorrido da igual
pues estamos sumando, pero si estuvieramos
ENUMERANDO los nodos, el orden si interesa
Recorrer árboles

Primero en profundidad (raíz, abuelo, padre ,
nieto ,etc. hasta terminar y luego retroceder al
siguiente hijo de raíz)
– Pre-orden: raíz, subárbol izquierdo, subárbol
derecho
– In-orden: izquierdo, raíz, derecho
– Post-orden: izquierdo, derecho, raíz

Primero en anchura: raíz, luego todos los hijos
de raíz, luego todos los hijos de los hijos, etc.
Árboles de expresión

Un árbol es un forma natural de representar la
estructura de una expresión.

Al contrario que otras notaciones, puede
representar el cálculo de forma no ambigua.

Muy usado en COMPILACION DE
PROGRAMAS y en PROGRAMACION
GENETICA.
Árboles de expresión

Los nodos de un árbol de expresión pueden ser
operandos como 1 y 2 u operadores como + y *. Los
operandos son nodos hojas; los nodos operadores
contienen referencias a sus operandos. (Todos
estos operadores son binarios, lo que significa que
tienen exactamente dos operandos)

Así podemos construir este árbol:
arbol = Arbol('+', Arbol(1), Arbol('*', Arbol(2),
Arbol(3)))
Ejemplo
Arbol('*', Arbol('+', Arbol(3), Arbol(7)), Arbol(9))

(3+7)*9
Recorrido prefijo
from __future__ import print_function
def imprimeArbol(arbol):
if arbol == None:
return
print(arbol.carga,end=" ")
imprimeArbol(arbol.izquierda)
imprimeArbol(arbol.derecha)


>>> arbol = Arbol('+', Arbol(1), Arbol('*', Arbol(2), Arbol(3)))

>>> imprimeArbol(arbol)

+1*23
Recorrido postfijo
from __future__ import print_function
def imprimeArbolPostfijo(arbol):
if arbol == None:
return
imprimeArbolPostfijo(arbol.izquierda)
imprimeArbolPostfijo(arbol.derecha)
print(arbol.carga,end=" ")
Recorrido infijo
from __future__ import print_function
def imprimeArbolInfijo(arbol):
if arbol == None:
return
imprimeArbolInfijo(arbol.izquierda)
print(arbol.carga,end=" ")
imprimeArbolInfijo(arbol.derecha)
Imprimiendo el árbol respetando los
niveles
from __future__ import print_function
def imprimeArbolSangrado(arbol, nivel=0):
if arbol == None:
return
imprimeArbolSangrado(arbol.derecha, nivel+1)
print(' '*nivel + str(arbol.carga))
imprimeArbolSangrado(arbol.izquierda, nivel+1)
Construyendo un árbol de expresión
from __future__ import print_function
def tomaToken(listaToken, esperado):
if listaToken[0] == esperado:
listaToken[0:1] = [] # quita el token
return 1
else:
return 0
Construyendo un árbol de expresión
(2)
def obtieneProducto(listaToken) :
a = obtieneNumero(listaToken)
if tomaToken(listaToken, '*') :
b = obtieneProducto(listaToken)
return Arbol('*', a, b)
else :
return a
Construyendo un árbol de expresión
(3)
def obtieneSuma(listaToken) :
a = obtieneProducto(listaToken)
if tomaToken(listaToken, '+') :
b = obtieneSuma(listaToken)
return Arbol('+', a, b)
else :
return a
Construyendo un árbol de expresión
(4)
def obtieneNumero(listaToken):
if tomaToken(listaToken, '(') :
x = obtieneSuma(listaToken) # obtiene
subexpresion
tomaToken(listaToken, ')') # se come el cierre
de parentesis
return x
Construyendo un árbol de expresión
(5)
else :
x = listaToken[0]
if type(x) != type(0) :
return None
listaToken[0:1] = [] # quita el token
return Arbol(x, None, None) # devuelve una hoja
sin el numero

>>> listaToken = [9, '*', '(', 11, '+', 5, ')', '*', 7, 'fin']

>>> arbol = obtieneSuma(listaToken)

>>> imprimeArbolPostfijo(arbol)
Árbol binario de búsqueda

Un árbol binario de búsqueda (abb) se basa en
la propiedad de que las claves que son menores
que el padre se encuentran en el subárbol
izquierdo, y las claves que son mayores que el
padre se encuentran en el subárbol derecho.
Llamaremos esto la propiedad abb.

El árbol de búsqueda de la siguiente figura
representa los nodos que existen después de
haber insertado las siguientes claves en el orden
mostrado: 70,31,93,94,14,23,73.
Ejemplo
Buscando un nodo
def buscar(self, dato, a):
if a == None:
return None
else:
if dato == a.carga:
return a
else:
if dato < a.carga:
return self.buscar(dato, a.izquierda)
else:
return self.buscar(dato, a.derecha)
Insertando un nodo
Borrando un nodo

You might also like