Sie sind auf Seite 1von 11

Autor: Jos Manuel Arteaga Choz Arboles Definicin Un rbol es una estructura no lineal en la que cada nodo puede

apuntar a uno o varios nodos. Tambin se suele dar una definicin recursiva: un rbol es una estructura en compuesta por un dato y varios rboles.

Definiremos varios conceptos. En relacin con otros nodos: Nodo hijo: Cualquiera de los nodos apuntados por uno de los nodos del rbol. En el ejemplo, 'L' y 'M' son hijos de 'G'. Nodo padre: Nodo que contiene un puntero al nodo actual. En el ejemplo, el nodo 'A' es padre de 'B', 'C' y 'D'.

Los rboles tienen otra caracterstica importante: cada nodo slo puede ser apuntado por otro nodo, es decir, cada nodo slo tendr un padre. Esto hace que estos rboles estn fuertemente jerarquizados, y es lo que en realidad les da la apariencia de rboles. En cuanto a la posicin dentro del rbol: Nodo raz: Nodo que no tiene padre. Este es el nodo que usaremos para referirnos al rbol. En el ejemplo, ese nodo es el 'A'. Nodo hoja: Nodo que no tiene hijos. En el ejemplo hay varios: 'F', 'H', 'I', 'K', 'L', 'M', 'N' y 'O'. Nodo rama: Aunque esta definicin apenas la usaremos, estos son los nodos que no pertenecen a ninguna de las dos categoras anteriores. En el ejemplo: 'B', 'C', 'D', 'E', 'G' y 'J'.

Autor: Jos Manuel Arteaga Choz Otra caracterstica que normalmente tendrn nuestros rboles es que todos los nodos contengan el mismo nmero de punteros, es decir, usaremos la misma estructura para todos los nodos del rbol. Esto hace que la estructura sea ms sencilla, y por lo tanto tambin los programas para trabajar con ellos. Tampoco es necesario que todos los nodos hijos de un nodo concreto existan. Es decir, que pueden usarse todos, algunos o ninguno de los punteros de cada nodo. Un rbol en el que en cada nodo o bien todos o ninguno de los hijos existe, se llama rbol completo. Otros conceptos que definen las caractersticas del rbol, en relacin a su tamao: Orden: es el nmero potencial de hijos que puede tener cada elemento de rbol. De este modo, diremos que un rbol en el que cada nodo puede apuntar a otros dos es de orden dos, si puede apuntar a tres ser de orden tres, etc. Grado: El nmero de hijos que tiene el elemento con ms hijos dentro del rbol. En el rbol del ejemplo, el grado es tres, ya que tanto 'A' como 'D' tienen tres hijos, y no existen elementos con ms de tres hijos. Nivel: Se define para cada elemento del rbol como la distancia a la raz, medida en nodos. El nivel de la raz es cero y el de sus hijos uno. As sucesivamente. En el ejemplo, el nodo 'D' tiene nivel 1, el nodo 'G' tiene nivel 2, y el nodo 'N', nivel 3. Altura: La altura de un rbol se define como el nivel del nodo de mayor nivel. Como cada nodo de un rbol puede considerarse a su vez como la raz de un rbol, tambin podemos hablar de altura de ramas. El rbol del ejemplo tiene altura 3, la rama 'B' tiene altura 2, la rama 'G' tiene altura 1, la 'H' cero, etc.

Los rboles de orden 2 son bastante especiales. Estos rboles se conocen tambin como rboles binarios. Frecuentemente, aunque tampoco es estrictamente necesario, para hacer ms fcil moverse a travs del rbol, aadiremos un puntero a cada nodo que apunte al nodo padre. De este modo podremos avanzar en direccin a la raz, y no slo hacia las hojas. Es importante conservar siempre el nodo raz ya que es el nodo a partir del cual se desarrolla el rbol, si perdemos este nodo, perderemos el acceso a todo el rbol.

Autor: Jos Manuel Arteaga Choz Operaciones bsicas con rboles Las inserciones sern siempre en punteros de nodos hoja o en punteros libres de nodos rama. Con estas estructuras no es tan fcil generalizar, ya que existen muchas variedades de rboles. Tenemos las mismas que las listas: Aadir o insertar elementos. Buscar o localizar elementos. Borrar elementos. Moverse a travs del rbol. Recorrer el rbol completo.

Los algoritmos de insercin y borrado dependen en gran medida del tipo de rbol que estemos implementando, de modo que por ahora los pasaremos por alto y nos centraremos ms en el modo de recorrer rboles. Recorridos por Arboles El modo evidente de moverse a travs de las ramas de un rbol es siguiendo los punteros, del mismo modo en que nos movemos a travs de las listas. Esos recorridos dependen en gran medida del tipo y propsito del rbol, pero hay ciertos recorridos que usaremos frecuentemente. Se trata de aquellos recorridos que incluyen todo el rbol. Hay tres formas de recorrer un rbol completo, y las tres se suelen implementar mediante recursividad. En los tres casos se sigue siempre a partir de cada nodo todas las ramas una por una. Supongamos que tenemos un rbol de orden tres, y queremos recorrerlo por completo. Partiremos del nodo raz:
RecorrerArbol(raiz);

La funcin RecorrerArbol, aplicando recursividad, ser tan sencilla como invocar de nuevo a la funcin RecorrerArbol para cada una de las ramas:
void RecorrerArbol(Arbol a) \{ if(a == NULL) return; RecorrerArbol(a->rama[0]); RecorrerArbol(a->rama[1]); RecorrerArbol(a->rama[2]); }

Autor: Jos Manuel Arteaga Choz Los tres tipos para recorrer son: Pre-orden En este tipo de recorrido, el valor del nodo se procesa antes de recorrer las ramas:
void PreOrden(Arbol a) \{ if(a == NULL) return; Procesar(dato); RecorrerArbol(a->rama[0]); RecorrerArbol(a->rama[1]); RecorrerArbol(a->rama[2]); }

Si seguimos el rbol del ejemplo en pre-orden, y el proceso de los datos es sencillamente mostrarlos por pantalla, obtendremos algo as: ABEKFCGLMDHIJNO In-orden En este tipo de recorrido, el valor del nodo se procesa despus de recorrer la primera rama y antes de recorrer la ltima. Esto tiene ms sentido en el caso de rboles binarios, y tambin cuando existen ORDEN-1 datos, en cuyo caso procesaremos cada dato entre el recorrido de cada dos ramas (este es el caso de los rboles-b):
void InOrden(Arbol a) \{ if(a == NULL) return; RecorrerArbol(a->rama[0]); Procesar(dato); RecorrerArbol(a->rama[1]); RecorrerArbol(a->rama[2]); }

Si seguimos el rbol del ejemplo en in-orden, y el proceso de los datos es sencillamente mostrarlos por pantalla, obtendremos algo as: KEBFALGMCHDINJO

Autor: Jos Manuel Arteaga Choz Post-orden En este tipo de recorrido, el valor del nodo se procesa despus de recorrer todas las ramas:
void PostOrden(Arbol a) { if(a == NULL) return; RecorrerArbol(a->rama[0]); RecorrerArbol(a->rama[1]); RecorrerArbol(a->rama[2]); Procesar(dato); }

Si seguimos el rbol del ejemplo en post-orden, y el proceso de los datos es sencillamente mostrarlos por pantalla, obtendremos algo as: K E F B L M G C H I N O J D A. Eliminar nodos en un rbol El proceso general es muy sencillo en este caso, pero con una importante limitacin, slo podemos borrar nodos hoja: El proceso sera el siguiente: 1. Buscar el nodo padre del que queremos eliminar. 2. Buscar el puntero del nodo padre que apunta al nodo que queremos borrar. 3. Liberar el nodo. 4. padre->nodo[i] = NULL; Cuando el nodo a borrar no sea un nodo hoja, diremos que hacemos una "poda", y en ese caso eliminaremos el rbol cuya raz es el nodo a borrar. Se trata de un procedimiento recursivo, aplicamos el recorrido PostOrden, y el proceso ser borrar el nodo. El procedimiento es similar al de borrado de un nodo: 1. Buscar el nodo padre del que queremos eliminar. 2. Buscar el puntero del nodo padre que apunta al nodo que queremos borrar. 3. Podar el rbol cuyo padre es nodo. 4. padre->nodo[i] = NULL; En el rbol del ejemplo, para podar la rama 'B', recorreremos el subrbol 'B' en postorden, eliminando cada nodo cuando se procese, de este modo no

Autor: Jos Manuel Arteaga Choz perdemos los punteros a las ramas apuntadas por cada nodo, ya que esas ramas se borrarn antes de eliminar el nodo. De modo que el orden en que se borrarn los nodos ser: K E F y B. Heaps Un heap o montculo es un rbol binario completo, y adems parcialmente ordenado. Ya hemos visto el concepto de rbol completo. Un rbol parcialmente ordenado es aqul que tiene todas y cada una de sus ramas, consideradas como listas, totalmente ordenadas, ya sea de forma creciente o decreciente. En relacin al heap, se exige una ordenacin decreciente, lo que puede dar lugar a una definicin ms natural de heap: un heap es un rbol binario completo, tal que el valor de su raz es mayor o igual que las races de sus hijos, siendo tambin heaps ambos hijos. A este concepto le aadiremos ciertas operaciones, lo cual desemboca en el TAD Heap. La siguiente figura ilustra un ejemplo de heap, as como casos de rboles que no lo son: Por no ser parcialmente ordenados, o por no ser completos.

Al igual que para el rbol binario de bsqueda, las operaciones bsicas son las mismas que para el rbol binario simple, y al igual que en aqul, el generador Arbol_binario est oculto al usuario. Necesitamos adems un predicado que nos diga cuando un rbol es un heap:
Es_Heap: ArbolB Lgico

Ecuaciones a: ArbolB

Autor: Jos Manuel Arteaga Choz


Es_Heap(a) == Es_Completo(a) and Es_Parc_Orden(a)

Ya hemos especificado formalmente cuando un rbol es completo. Nuestra definicin de parcialmente ordenado se completa con la siguiente especificacin:

Es_Parc_Orden : ArbolB Lgico Ecuaciones r: Elemento i, d : ArbolB Es_Parc_Orden(Crear) == V Es_Parc_Orden(Arbol_binario(r, i, d)) == (Es_Vacio(i) or r >= Raiz(i)) and (Es_Vacio(d) or r >= Raiz(d)) and Es_Parc_Orden(i) and Es_Parc_Orden(d) }

Vamos a ver ahora unas cuantas operaciones interesantes. La primera de ellas inserta un elemento en un rbol completo, y hace que el resultado siga siendo un rbol completo:
Ins_Completo: Elemento ArbolB ArbolB Ecuaciones e, r: Elemento i, d: ArbolB Ins_Completo(e, Crear) == Arbol_binario(e, Crear, Crear) Ins_Completo(e, Arbol_binario(r, i, d)) == SI ((Altura (i) > Altura (d)) and (not Es_Lleno(i))) or ((Altura (i) = Altura (d)) and Es_Lleno(d)) ENTONCES Arbol_binario(r, Ins_Completo(e, i), d) SI NO Arbol_binario(r, i, Ins_Completo(e, d)) De manera que se verifica: Teorema e: Elemento a: ArbolB Es_Completo(a) 6 Es_Completo(Insertar(e, a))

A partir de esta operacin, podemos convertir cualquier rbol en completo, sin ms que recorrer todos sus nodos, e ir insertndolos en otro rbol que se inicializar a vaco; para ello usaremos una operacin auxiliar:

Autor: Jos Manuel Arteaga Choz


A_Completo: ArbolB ArbolB A_Completo_aux: ArbolB ArbolB ArbolB Ecuaciones r: Elemento a, b, i, d: ArbolB A_Completo(a) == A_Completo_aux(a, Crear) A_Completo_aux(Crear, b) == b A_Completo_aux(Arbol_binario(r, i, d), b) == Ins_Completo(r, A_Completo_aux(i, A_Completo_aux(d, b))) De manera que se verifica: Teorema a: ArbolB Es_Completo(A_Completo(a)) == V

Una vez que hemos convertido cualquier rbol en completo, ya slo nos queda convertirlo en heap, que es lo que hace la operacin Completo_A_Heap, que parte del rbol completo, y aplica recursivamente Arbol_heap a cada raz, y a sus dos hijos ya convertidos es heap:
Completo_A_Heap: ArbolB ArbolB Arbol_heap: Elemento ArbolB ArbolB ArbolB Precondiciones a: ArbolB Completo_A_Heap(a): Es_Completo(a) Ecuaciones r: Elemento i, d : ArbolB Completo_A_Heap(Crear) == Crear Completo_A_Heap(Arbol_binario(r, i, d)) == Arbol_heap(r, Completo_A_Heap(i), Completo_A_Heap(d)) Arbol_heap(r, i, d) == SI Es_Vacio(i) Arbol_binario(r, Crear, Crear) SI NO SI Es_Vacio(d) ENTONCES SI r > Raiz(i) ENTONCES Arbol_binario(r, i, Crear) SI NO

Autor: Jos Manuel Arteaga Choz


Arbol_binario(Raiz(i), Arbol_binario(r, Crear, Crear), Crear) SI NO SI (r $ Raiz(i)) and (r $ Raiz(d)) ENTONCES Arbol_binario(r, i, d) SI NO SI (Raiz(i) $ r) and (Raiz(i) $ Raiz(d)) ENTONCES Arbol_binario(Raiz(i), Arbol_heap(r, Hijo_izq(i), Hijo_dch(i)), d) SI NO Arbol_binario(Raiz(d), i, Arbol_heap(r, Hijo_izq(d), Hijo_dch(d))) Teoremas a, i, d: ArbolB r : Elemento Completo(a) 6 Es_Heap(Completo_A_Heap(a)) Es_Completo(Arbol_binario(r, i, d)) and Es_Heap(i) and Es_Heap(d) 6 Es_Heap(Arbol_heap(r, i, d))

No obstante, podemos simplificar estas tareas hasta cierto punto, con una sola operacin que inserte un elemento en un heap, de manera similar a como lo hace el Insertar de los rboles binarios de bsqueda. Ello da lugar a la operacin:
Insertar: Elemento Heap Heap Ecuaciones e, r: Elemento i, d: Heap Insertar (e, Crear) == Arbol_binario(e, Crear, Crear) Insertar (e, Arbol_binario(r, i, d)) == SI e > r ENTONCES SI Es_Vacio(i) ENTONCES Arbol_binario(e, Arbol_binario(r, Crear, Crear), Crear) SI NO SI Es_Vacio(d) ENTONCES Arbol_binario(e, i, Arbol_binario(r, Crear, Crear)) SI NO SI ((Altura (i) > Altura (d)) and (not Es_Lleno(i))) or ((Altura (i) = Altura (d)) and Es_Lleno(d)) ENTONCES Arbol_binario(e, Insertar(r, i), d)

Autor: Jos Manuel Arteaga Choz


SI NO Arbol_binario(e, i, Insertar(r, d)) SI NO SI Es_Vacio(i) ENTONCES Arbol_binario(r, Arbol_binario(e, Crear, Crear), Crear) SI NO SI Es_Vacio(d) ENTONCES Arbol_binario(r, i, Arbol_binario(e, Crear, Crear)) SI NO SI ((Altura (i) > Altura (d)) and (not Es_Lleno(i))) or ((Altura (i) = Altura (d)) and Es_Lleno(d)) ENTONCES Arbol_binario(r, Insertar (e, i), d) SI NO Arbol_binario(r, i, Insertar (e, d))

La especificacin anterior queda ms compacta de la forma:


Insertar: Elemento Heap Heap Auxiliares Min, max : Elemento Elemento Elemento Ecuaciones e, r: Elemento i, d : Heap Min(a, b) == SI a # b ENTONCES a SI NO b max(a, b) == SI a > b ENTONCES a SI NO b Insertar (e, Crear) == Arbol_binario(e, Crear, Crear) Insertar (e, Arbol_binario(r, i, d) == SI ((Altura(i) > Altura(d)) and (not Es_Lleno(i))) or ((Altura(i) = Altura(d)) and Es_Lleno(d)) ENTONCES Arbol_binario(max(r, e), Insertar(min(r, e), i), d) SI NO Arbol_binario(max(r, e), i, Insertar(min(r, e), d))

Autor: Jos Manuel Arteaga Choz Lo cual puede dar una idea de lo importantes que pueden ser las operaciones auxiliares a la hora de esclarecer una especificacin, y que por ello el diseador no debe escatimar su uso.

Referencias Videos Balanceo AVL http://www.youtube.com/watch?v=S6JNSJk1Hv8 Tabla Hash http://www.youtube.com/watch?v=TmSpPHeLlag&feature=related Videos de otro usos de los Arboles http://www.youtube.com/watch?v=m0KibH2fxNQ&feature=related

Das könnte Ihnen auch gefallen