Documentos de Académico
Documentos de Profesional
Documentos de Cultura
ÁRBOL
DEFINICION.
En ciencias de la informática, un árbol es una estructura de datos ampliamente usada que
imita la forma de un árbol (un conjunto de nodos conectados).
Un nodo es la unidad sobre la que se construye el árbol y puede tener cero o más nodos
hijos conectados a él. Se dice que un nodo a es padre de un nodo b si existe un enlace desde
a hasta b (en ese caso, también decimos que b es hijo de a).
Sólo puede haber un único nodo sin padres, que llamaremos raíz. Un nodo que no tiene hijos
se conoce como hoja. Los demás nodos (tienen padre y uno o varios hijos) se les conoce
como rama.
Representar cada nodo como una variable en el heap, con punteros a sus hijos y a su
padre.
Representar el árbol con un array donde cada elemento es un nodo y las relaciones
padre-hijo vienen dadas por la posición del nodo en el array.
TIPOS DE ARBOLES
ÁRBOL BINARIO.
un árbol binario es una estructura de datos en la cual cada nodo siempre tiene un hijo
izquierdo y un hijo derecho. No pueden tener más de dos hijos (de ahí el nombre "binario").
Si algún hijo tiene como referencia a null, es decir que no almacena ningún dato, entonces
este es llamado un nodo externo. En el caso contrario el hijo es llamado un nodo interno.
Usos comunes de los árboles binarios son los árboles binarios de búsqueda, los montículos
binarios y Codificación de Huffman.
En teoría de grafos, se usa la siguiente definición: «Un árbol binario es un grafo conexo,
acíclico y no dirigido tal que el grado de cada vértice no es mayor a 3». De esta forma sólo
existe un camino entre un par de nodos.
Un árbol binario con enraizado es como un grafo que tiene uno de sus vértices, llamado raíz,
de grado no mayor a 2.
Con la raíz escogida, cada vértice tendrá un único padre, y nunca más de dos hijos. Si
rehusamos el requerimiento de la conectividad, permitiendo múltiples componentes
conectados en el grafo, llamaremos a esta última estructura un bosque.
TIPOS DE ÁRBOL BINARIO.
Un árbol binario es un árbol con raíz en el que cada nodo tiene como máximo dos
hijos.
Un árbol binario lleno es un árbol en el que cada nodo tiene cero o dos hijos.
Un árbol binario perfecto es un árbol binario lleno en el que todas las hojas (vértices
con cero hijos) están a la misma profundidad (distancia desde la raíz, también
llamada altura).
A veces un árbol binario perfecto es denominado árbol binario completo. Otros
definen un árbol binario completo como un árbol binario lleno en el que todas las
hojas están a profundidad n o n-1, para alguna n.
ALMACENAMIENTO.
Los árboles binarios pueden ser construidos a partir de lenguajes de programación de varias
formas. En un lenguaje con registros y referencias, los árboles binarios son construidos
típicamente con una estructura de nodos y punteros en la cual se almacenan datos, cada
uno de estos nodos tiene una referencia o puntero a un nodo izquierdo y a un nodo derecho
denominados hijos.
En ocasiones, también contiene un puntero a un único nodo. Si un nodo tiene menos de dos
hijos, algunos de los punteros de los hijos pueden ser definidos como nulos para indicar que
no dispone de dicho nodo. En la figura adjunta se puede observar la estructura de dicha
implementación.
ÁRBOL AVL
Árbol AVL es un tipo especial de árbol binario ideado por los matemáticos rusos Adelson-
Velskii y Landis. Fue el primer árbol de búsqueda binario auto- balanceable que se ideó
El árbol AVL toma su nombre de las iniciales de los apellidos de sus inventores, Adelson-
Velskii y Landis. Lo dieron a conocer en la publicación de un artículo en 1962: "An algorithm
for the organization of information" ("Un algoritmo para la organización de la información").
Los árboles AVL están siempre equilibrados de tal modo que, para todos los nodos, la altura
de la rama izquierda no difiere en más de una unidad de la altura de la rama derecha.
Gracias a esta forma de equilibrio (o balanceo), la complejidad de una búsqueda en uno de
estos árboles se mantiene siempre en orden de complejidad O (log n). El factor de equilibrio
puede ser almacenado directamente en cada nodo o ser computado a partir de las alturas de
los subárboles.
Para conseguir esta propiedad de equilibrio, la inserción y el borrado de los nodos se ha de
realizar de una forma especial. Si al realizar una operación de inserción o borrado se rompe
la condición de equilibrio, hay que realizar una serie de rotaciones de los nodos.
FACTOR DE EQUILIBRIO
Cada nodo, además de la información que se pretende almacenar, debe tener los dos
punteros a los árboles derecho e izquierdo, igual que los árboles binarios de búsqueda (ABB),
y además el dato que controla el factor de equilibrio.
El factor de equilibrio es la diferencia entre las alturas del árbol derecho y el
izquierdo:
FE = altura subárbol derecho - altura subárbol izquierdo; Por definición, para un árbol AVL,
este valor debe ser -1, 0 ó 1. Si el factor de equilibrio de un nodo es:
0 -> el nodo está equilibrado y sus subárboles tienen exactamente la misma altura. 1
-> el nodo está equilibrado y su subárbol derecho es un nivel más alto. -1 -> el nodo
está equilibrado y su subárbol izquierdo es un nivel más alto. Si el factor de equilibrio
Fe>2 o Fe<-2 es necesario reequilibrar.
OPERACIONES.
De un árbol de raíz (r) y de hijos izquierdo (i) y derecho (d), consiste en formar un
nuevo árbol cuya raíz sea la raíz del hijo derecho, como hijo derecho colocamos el
hijo derecho de d (nuestro d') y como hijo izquierdo construimos un nuevo árbol que
tendrá como raíz la raíz del árbol (r), el hijo izquierdo de d será el hijo derecho (i') y el
hijo izquierdo será el hijo izquierdo del árbol (i).
Precondición: Tiene que tener hijo derecho no vacío.
ROTACIÓN DOBLE A LA DERECHA.
ARBOL -B.
B-árbol es un árbol de búsqueda que puede estar vacío o aquel cuyos nodos pueden tener
varios hijos, existiendo una relación de orden entre ellos, tal como muestra el dibujo.
Un árbol-B de orden M (el máximo número de hijos que puede tener cada nodo) es un árbol
que satisface las siguientes propiedades:
Cada nodo tiene como máximo M hijos.
Cada nodo (excepto raíz y hojas) tiene como mínimo M/2 hijos.
La raíz tiene al menos 2 hijos si no es un nodo hoja.
Todos los nodos hoja aparecen al mismo nivel.
Un nodo no hoja con k hijos contiene k-1 elementos almacenados.
Los hijos que cuelgan de la raíz (ri, •••, rm) tienen que cumplir ciertas condiciones:
El primero tiene valor menor que ri.
El segundo tiene valor mayor que ri y menor que r2, etc.
El último hijo tiene valor mayor que
LIBRERÍAS EN PYTHON
Programa 1
class ArbolBinarioBusqueda:
def __init__(self):
self.raiz = None
self.tamano = 0
def longitud(self):
return self.tamano
def __len__(self):
return self.tamano
def __iter__(self):
return self.raiz.__iter__()
Programa 2
class NodoArbol:
def __init__(self,clave,valor,izquierdo=None,derecho=None, padre=None):
self.clave = clave
self.cargaUtil = valor
self.hijoIzquierdo = izquierdo
self.hijoDerecho = derecho
self.padre = padre
def tieneHijoIzquierdo(self):
return self.hijoIzquierdo
def tieneHijoDerecho(self):
return self.hijoDerecho
def esHijoIzquierdo(self):
return self.padre and self.padre.hijoIzquierdo == self
def esHijoDerecho(self):
return self.padre and self.padre.hijoDerecho == self
def esRaiz(self):
return not self.padre
def esHoja(self):
return not (self.hijoDerecho or self.hijoIzquierdo)
def tieneAlgunHijo(self):
return self.hijoDerecho or self.hijoIzquierdo
def tieneAmbosHijos(self):
return self.hijoDerecho and self.hijoIzquierdo
def reemplazarDatoDeNodo(self,clave,valor,hizq,hder):
self.clave = clave
self.cargaUtil = valor
self.hijoIzquierdo = hizq
self.hijoDerecho = hder
if self.tieneHijoIzquierdo():
self.hijoIzquierdo.padre = self
if self.tieneHijoDerecho():
self.hijoDerecho.padre = self
Programa 3
def agregar(self,clave,valor):
if self.raiz:
self._agregar(clave,valor,self.raiz)
else:
self.raiz = NodoArbol(clave,valor)
self.tamano = self.tamano + 1
def _agregar(self,clave,valor,nodoActual):
if clave < nodoActual.clave:
if nodoActual.tieneHijoIzquierdo():
self._agregar(clave,valor,nodoActual.hijoIzquierdo)
else:
nodoActual.hijoIzquierdo = NodoArbol(clave,valor,padre=nodoActual)
else:
if nodoActual.tieneHijoDerecho():
self._agregar(clave,valor,nodoActual.hijoDerecho)
else:
nodoActual.hijoDerecho = NodoArbol(clave,valor,padre=nodoActual)
Programa 4
def __setitem__(self,c,v):
self.agregar(c,v)
Programa 5
def obtener(self,clave):
if self.raiz:
res = self._obtener(clave,self.raiz)
if res:
return res.cargaUtil
else:
return None
else:
return None
def _obtener(self,clave,nodoActual):
if not nodoActual:
return None
elif nodoActual.clave == clave:
return nodoActual
elif clave < nodoActual.clave:
return self._obtener(clave,nodoActual.hijoIzquierdo)
else:
return self._obtener(clave,nodoActual.hijoDerecho)
def __getitem__(self,clave):
return self.obtener(clave)
Programa 6
def __contains__(self,clave):
if self._obtener(clave,self.raiz):
return True
else:
return False
Programa 7
def eliminar(self,clave):
if self.tamano > 1:
nodoAEliminar = self._obtener(clave,self.raiz)
if nodoAEliminar:
self.remover(nodoAEliminar)
self.tamano = self.tamano-1
else:
raise KeyError('Error, la clave no está en el árbol')
elif self.tamano == 1 and self.raiz.clave == clave:
self.raiz = None
self.tamano = self.tamano - 1
else:
raise KeyError('Error, la clave no está en el árbol')
def __delitem__(self,clave):
self.eliminar(clave)
Programa 8
if nodoActual.esHoja():
if nodoActual == nodoActual.padre.hijoIzquierdo:
nodoActual.padre.hijoIzquierdo = None
else:
nodoActual.padre.hijoDerecho = None
Programa 9
Programa 10
Programa 11
def encontrarSucesor(self):
suc = None
if self.tieneHijoDerecho():
suc = self.hijoDerecho.encontrarMin()
else:
if self.padre:
if self.esHijoIzquierdo():
suc = self.padre
else:
self.padre.hijoDerecho = None
suc = self.padre.encontrarSucesor()
self.padre.hijoDerecho = self
return suc
def encontrarMin(self):
actual = self
while actual.tieneHijoIzquierdo():
actual = actual.hijoIzquierdo
return actual
def empalmar(self):
if self.esHoja():
if self.esHijoIzquierdo():
self.padre.hijoIzquierdo = None
else:
self.padre.hijoDerecho = None
elif self.tieneAlgunHijo():
if self.tieneHijoIzquierdo():
if self.esHijoIzquierdo():
self.padre.hijoIzquierdo = self.hijoIzquierdo
else:
self.padre.hijoDerecho = self.hijoIzquierdo
self.hijoIzquierdo.padre = self.padre
else:
if self.esHijoIzquierdo():
self.padre.hijoIzquierdo = self.hijoDerecho
else:
self.padre.hijoDerecho = self.hijoDerecho
self.hijoDerecho.padre = self.padre