You are on page 1of 68

Captulo 5.

rboles
5 rboles 5.1 Descripcin y terminologa fundamental. 5.2 Especificacin del TDA rbol. 5.3 Ejemplos de uso del TDA rbol. 5.4 Implementaciones del TDA rbol. 5.5 Especificacin del TDA rbol Binario. 5.6 Ejemplos de uso del TDA rbol Binario. 5.7 Implementaciones del TDA rbol Binario. 5.8 rboles Parcialmente Ordenados: Colas de Prioridad. 5.9 rboles Binarios de Bsqueda.

5.1 Descripcin y terminologa fundamental


t

t t t

Un rbol es una coleccin de elementos entre los cuales existe una estructura jerrquica definida mediante una relacin de paternidad entre los elementos. Entre los elementos, que llamaremos nodos, se distingue uno que es el nodo raz. Matemticamente, un rbol es un grafo no orientado, conexo y acclico en el que existe un vrtice destacado llamado raz. Un rbol A n-ario (en adelante slo rbol), siendo n 1, es un conjunto de elementos del mismo tipo tal que:
t t

O bien es el conjunto vaco, en cuyo caso se le denomina rbol vaco. O bien no es vaco, en cuyo caso existe un elemento distinguido llamado raz, y el resto de los elementos se distribuyen en en m subconjuntos disjuntos A1 ,..., Am, con 0 m n, cada uno de los cuales es un rbol nario, llamados subrboles del rbol original.

5.1 Descripcin y terminologa fundamental

Cuando el orden de los subrboles importa, el rbol se dice ordenado. Se dice que la raz del rbol A es padre de la raz de los subrboles A1 ,..., Am y que las raices de los subrboles A1 ,..., Am son hijos de la raz de A. Un rbol binario A es un conjunto de elementos del mismo tipo tal que:
t t

O bien es el conjunto vaco, en cuyo caso se le denomina rbol vaco. O bien no es vaco, en cuyo caso existe un elemento distinguido llamado raz, y el resto de los elementos se distribuyen en dos subconjuntos disjuntos A1, A2, cada uno de los cuales es un rbol binario, llamados respectivamente subrboles izquierdo y derecho del rbol original.

5.1 Descripcin y terminologa fundamental


t

No es lo mismo un rbol 2-ario que un rbol binario, ya que en el rbol binario se distingue entre sbrboles izquierdo y derecho. Los trminos padre e hijo descritos para rboles n-arios son tambin utilizados para rboles binarios. Otros trminos comunes son los siguientes:
t

t t t

Camino: Si existe una secuencia de nodos nl ,..., nk tal que ni es padre de ni+1 , para 1 i k, entonces la secuencia se denomina camino del nodo nl al nodo nk. La longitud de un camino es el nmero de nodos del camino menos 1. Existe un camino de longitud 0 de todo nodo a s mismo. Ascendiente/Descendiente: Un nodo a es ascendiente de un nodo b (y b descendiente de a), si existe un camino del nodo a al nodo b. Por tanto todo nodo es ascendiente (y descendiente) de s mismo. Los ascendientes (y descendientes) de un nodo, excluido el propio nodo, se denominan ascendientes (y descendientes) propios. Hoja: Nodo sin descendientes propios. Altura: La altura de un nodo en un rbol es la longitud del camino ms largo de ese nodo a una hoja. La altura de un rbol es la altura de la raz. Profundidad: La profundidad de un nodo es la longitud del camino nico desde ese nodo a la raz.

5.2 Especificacin del TDA rbol


Especificacin informal del TDA
t

Arbol = TDA con operaciones crea,vacio, raiz,padre, hijoIzquierdo, hermanoDerecho,info, insertaHijo, insertaHermano, suprimeHijo, suprimeHermano,modifica,nodoNulo.

DESCRIPCIN:
t

Los valores del TDA Arbol son arboles n-arios donde cada nodo contiene un dato del tipo Elemento. Las posiciones de los nodos en el rbol son del tipo Posicion. Los rboles son mutables: insertaHijo, insertaHermano, suprimeHijo, suprimeHermano y modifica aaden, eliminan y modifican respectivamente elementos de un rbol.

OPERACIONES:
t

crea()devuelve(A:Arbol)
t efecto: Devuelve el rbol vaco A.

5.2 Especificacin del TDA rbol


t

vacio(A:Arbol)devuelve(booleano)
t efecto: Devuelve cierto si A es el rbol vaco, y falso en caso contrario.

raiz(A:Arbol)devuelve(Posicion)
t efecto: Devuelve la posicin del nodo raz en el rbol A. Si el rbol A est vaco, devuelve nulo.

padre(A:Arbol;P:Posicion)devuelve(Posicion)
t requerimientos: El rbol A es no vaco y P no es nodo nulo t efecto: Devuelve la posicin del nodo padre del nodo P en el rbol A. Si P es la raiz devuelve nulo

hijoIzquierdo(A:Arbol;P:Posicion)devuelve(Posicion)
t requerimientos: El rbol A es no vaco y P no es nodo nulo. t efecto: Devuelve la posicin del nodo hijo ms a la izquierda del nodo P en el rbol A. Si el nodo P no tiene hijos, devuelve nulo

5.2 Especificacin del TDA rbol


t

hermanoDerecho(A:Arbol;P:Posicion)devuelve(Posicion)
t requerimientos: El rbol A es no vaco. P no es nodo nulo. t efecto: Devuelve la posicin del nodo hermano derecho del nodo P en el rbol A. Si el nodo P no tiene hermano derecho, devuelve nulo

info(A:Arbol;P:Posicion)devuelve(E:Elemento)
t requerimientos: El rbol A es no vaco. P no es nodo nulo. t efecto: Devuelve en E} el contenido del nodo P en el rbol A.

insertaHijo(A:Arbol;P:Posicion;E:Elemento)
t requerimientos: Si el rbol A es no vaco, entonces P no es nodo nulo. t modifica: A. t efecto: Aade un nodo, con contenido E, como hijo ms a la izquierda del nodo P en el rbol A. Si el rbol A es vaco, entonces aade un nodo con contenido E como raz del rbol A.

5.2 Especificacin del TDA rbol


t

insertaHermano(A:Arbol;P:Posicion;E:Elemento)
t requerimientos: El rbol A es no vaco. P no es nodo nulo. P no es la raiz. t modifica: A. t efecto: Aade un nodo, con contenido E, como hermano derecho del nodo P en el rbol A.

suprimeHijo(A:Arbol;P:Posicion)
t requerimientos: El rbol A es no vaco. El nodo P no es nulo. t modifica: A. t efecto: Suprime el hijo ms a la izquierda del nodo P en el rbol A y todos sus descendientes.

suprimeHermano(A:Arbol;P:Posicion)
t requerimientos: El rbol A es no vaco. El nodo P no es nulo. t modifica: A. t efecto: Suprime el hermano derecho del nodo P en el rbol A y todos sus descendientes.

5.2 Especificacin del TDA rbol

modifica(A:Arbol;P:Posicion;E:Elemento)
t requerimientos: El rbol A es no vaco. El nodo P no es nodo nulo. t modifica: A. t efecto: Modifica el contenido del nodo P en el rbol A, cambindolo por el nuevo contenido E.

nodoNulo(P:Posicion)devuelve(booleano)
t efecto: Devuelve cierto si P es nulo, y falso en caso contrario.

5.2 Especificacin del TDA rbol


La interface Java del TDA rbol de acuerdo a esta especificacin, y sus excepciones, es la siguiente:
packagearbolInterface; importarbolException.*; publicinterfaceArbol{ publicbooleanvacio(); publicObjectraiz(); publicObjectpadre(Objectposicion)throwsArbolVacioException, NodoNuloException; publicObjecthijoIzquierdo(Objectposicion)throwsArbolVacioException, NodoNuloException; publicObjecthermanoDerecho(Objectposicion)throwsArbolVacioException, NodoNuloException; publicObjectinfo(Objectposicion)throwsArbolVacioException, NodoNuloException; publicvoidinsertaHijo(Objectposicion,Objectelemento)throws NodoNuloException; publicvoidinsertaHermano(Objectposicion,Objectelemento)throws ArbolVacioException,NodoNuloException,RaizException;

5.2 Especificacin del TDA rbol


publicvoidsuprimeHijo(Objectposicion)throwsArbolVacioException, NodoNuloException; publicvoidsuprimeHermano(Objectposicion)throwsArbolVacioException, NodoNuloException; publicvoidmodifica(Objectposicion,Objectelemento)throws ArbolVacioException,NodoNuloException; publicbooleannodoNulo(Objectposicion); }//fininterfaceArbol packagearbolException; publicclassArbolExceptionextendsException{ publicArbolException(){super();}; publicArbolException(Strings){super(s);}; } packagearbolException; publicclassArbolVacioExceptionextendsArbolException{ publicArbolVacioException(){super();}; publicArbolVacioException(Strings){super(s);}; }

5.2 Especificacin del TDA rbol


packagearbolException; publicclassNodoNuloExceptionextendsArbolException{ publicNodoNuloException(){super();}; publicNodoNuloException(Strings){super(s);}; } packagearbolException; publicclassRaizExceptionextendsArbolException{ publicRaizException(){super();}; publicRaizException(Strings){super(s);}; } packagearbolException; publicclassNodoNoNuloExceptionextendsArbolException{ publicNodoNoNuloException(){super();}; publicNodoNoNuloException(Strings){super(s);}; }

5.3 Ejemplos de uso del TDA rbol


t

Veremos en esta seccin algunos ejemplos de uso del TDA rbol. Uno de los aspectos fundamentales en rboles son los esquemas de recorrido. Aprovecharemos esta seccin para describir las distintas formas de recorrido en rboles haciendo uso de las operaciones del TDA, es decir, los procedimientos de recorrido se mostrarn como operaciones a un nivel de abstraccin mayor, y por tanto sern independientes de la implementacin del TDA. Los tres esquemas fundamentales de recorrido en rboles se denominan:
t t t

orden previo o preorden, orden simtrico o inorden, orden posterior o postorden.

Orden previo o Preorden


t Si el rbol es vaco, entonces la lista vaca es el listado de los nodos del rbol en preorden. t Si el rbol no es vaco, el listado en preorden de sus nodos est formado, primero, por la raz del rbol, seguido por los nodos del primer subrbol en preorden, luego por los nodos del segundo subrbol en preorden, y as sucesivamente hasta los nodos del ltimo subrbol en preorden.

5.3 Ejemplos de uso del TDA rbol


t

Orden simtrico o Inorden


t Si el rbol es vaco, entonces la lista vaca es el listado de los nodos del rbol en inorden. t Si el rbol no es vaco, el listado en inorden de sus nodos est formado, primero, por los nodos del primer subrbol en inorden, seguido por la raz del rbol, luego por los nodos del segundo subrbol en inorden, y as sucesivamente hasta los nodos del ltimo subrbol en inorden.

Orden posterior o Postorden


t Si el rbol es vaco, entonces la lista vaca es el listado de los nodos del rbol en postorden. t Si el rbol no es vaco, el listado en postorden de sus nodos est formado, primero, por los nodos del primer subrbol en postorden, luego por los nodos del segundo subrbol en postorden, y as sucesivamente hasta los nodos del ltimo subrbol en postorden, y finalmente, por la raz del rbol.

5.3 Ejemplos de uso del TDA rbol


importarbolInterface.*; importarbolException.*; importjava.io.*; classArbolUtil{ staticpublicvoidpreOrden(Arbolarbol,Objectp){ try{ if(arbol.nodoNulo(p))return; Objecte=arbol.info(p); System.out.println(e); Objectq=arbol.hijoIzquierdo(p); while(!arbol.nodoNulo(q)){ preOrden(arbol,q); q=arbol.hermanoDerecho(q); } }catch(ArbolExceptione){ System.err.println("ErrorenelusodelArbol:e"); } }//finpreOrden

5.3 Ejemplos de uso del TDA rbol


staticpublicvoidinOrden(Arbolarbol,Objectp){ try{ if(arbol.nodoNulo(p))return; Objectq=arbol.hijoIzquierdo(p); inOrden(arbol,q); Objecte=arbol.info(p); System.out.println(e); while(!arbol.nodoNulo(q)){ q=arbol.hermanoDerecho(q); inOrden(arbol,q); } }catch(ArbolExceptione){ System.err.println("ErrorenelusodelArbol:e"); } }//fininOrden

5.3 Ejemplos de uso del TDA rbol


staticpublicvoidpostOrden(Arbolarbol,Objectp){ try{ if(arbol.nodoNulo(p))return; Objectq=arbol.hijoIzquierdo(p); while(!arbol.nodoNulo(q)){ postOrden(arbol,q); q=arbol.hermanoDerecho(q); } Objecte=arbol.info(p); System.out.println(e); }catch(ArbolExceptione){ System.err.println("ErrorenelusodelArbol:e"); } }//finpostOrden }//finclassArbolUtil

5.4 Implementaciones del TDA rbol


Las clases Arbol y Posicion bsicamente de la siguiente forma:
classPosicion{ protectedObjectinfo; protectedPosicionhijoIzquierdo; protectedPosicionpadre; protectedPosicionhermanoDerecho; } classArbol{ Posicionarbol; }

pueden

escribirse

5.4 Implementaciones del TDA rbol


packagearbol; classPosicion{ protectedObjectinfo; protectedPosicionhijoIzquierdo; protectedPosicionpadre; protectedPosicionhermanoDerecho; publicbooleanequals(Objecto){ if(o==null)returnfalse; Posicionp=(Posicion)o; return(this==p); } }//finclassPosicion

5.4 Implementaciones del TDA rbol


packagearbol; importarbolException.*; publicclassArbolimplementsarbolInterface.Arbol{ Posicionarbol; publicArbol(){ arbol=null; } publicbooleanvacio(){ return(nodoNulo(arbol)); } publicObjectraiz(){ returnarbol; } publicObjectpadre(Objectposicion)throwsArbolVacioException, NodoNuloException{ Posicionp=(Posicion)posicion; if(vacio())thrownewArbolVacioException(); if(nodoNulo(p))thrownewNodoNuloException(); returnp.padre; }

5.4 Implementaciones del TDA rbol


publicObjecthijoIzquierdo(Objectposicion)throwsArbolVacioException, NodoNuloException{ Posicionp=(Posicion)posicion; if(vacio())thrownewArbolVacioException(); if(nodoNulo(p))thrownewNodoNuloException(); returnp.hijoIzquierdo; } publicObjecthermanoDerecho(Objectposicion)throwsArbolVacioException, NodoNuloException{ Posicionp=(Posicion)posicion; if(vacio())thrownewArbolVacioException(); if(nodoNulo(p))thrownewNodoNuloException(); returnp.hermanoDerecho; } publicObjectinfo(Objectposicion)throwsArbolVacioException, NodoNuloException{ Posicionp=(Posicion)posicion; if(vacio())thrownewArbolVacioException(); if(nodoNulo(p))thrownewNodoNuloException(); returnp.info; }

5.4 Implementaciones del TDA rbol


publicvoidinsertaHijo(Objectposicion,Objectelemento)throws NodoNuloException{ Posicionp=(Posicion)posicion; if((!vacio())&&(nodoNulo(p)))thrownewNodoNuloException(); Posicionaux=newPosicion(); aux.info=elemento; aux.hijoIzquierdo=null; if(vacio()){ aux.padre=null; aux.hermanoDerecho=null; arbol=aux; } else{ aux.padre=p; aux.hermanoDerecho=p.hijoIzquierdo; p.hijoIzquierdo=aux; } }

5.4 Implementaciones del TDA rbol

publicvoidinsertaHermano(Objectposicion,Objectelemento)throws ArbolVacioException,NodoNuloException,RaizException{ Posicionp=(Posicion)posicion; if(vacio())thrownewArbolVacioException(); if(nodoNulo(p))thrownewNodoNuloException(); if(p==raiz())thrownewRaizException(); Posicionaux=newPosicion(); aux.info=elemento; aux.hijoIzquierdo=null; aux.hermanoDerecho=p.hermanoDerecho; p.hermanoDerecho=aux; aux.padre=p.padre; }

5.4 Implementaciones del TDA rbol

publicvoidsuprimeHijo(Objectposicion)throwsArbolVacioException, NodoNuloException{ Posicionp=(Posicion)posicion; if(vacio())newArbolVacioException(); if(nodoNulo(p))thrownewNodoNuloException(); Posicionaux=(Posicion)hijoIzquierdo(p); if(!nodoNulo(aux)){ while(!nodoNulo(hijoIzquierdo(aux))) suprimeHijo(aux); p.hijoIzquierdo=aux.hermanoDerecho; } }

5.4 Implementaciones del TDA rbol

publicvoidsuprimeHermano(Objectposicion)throwsArbolVacioException, NodoNuloException{ Posicionp=(Posicion)posicion; if(vacio())newArbolVacioException(); if(nodoNulo(p))thrownewNodoNuloException(); Posicionaux=(Posicion)hermanoDerecho(p); if(!nodoNulo(aux)){ while(!nodoNulo(hijoIzquierdo(aux))) suprimeHijo(aux); p.hermanoDerecho=aux.hermanoDerecho; } }

5.4 Implementaciones del TDA rbol

publicvoidmodifica(Objectposicion,Objectelemento)throws ArbolVacioException,NodoNuloException{ Posicionp=(Posicion)posicion; if(vacio())newArbolVacioException(); if(nodoNulo(p))thrownewNodoNuloException(); p.info=elemento; } publicbooleannodoNulo(Objectposicion){ return(posicion==null); } }//finclassArbol

5.5 Especificacin del TDA rbol Binario

Para el TDA rbol Binario consideramos un conjunto de operaciones muy similar al que hemos descrito para el TDA rbol, con la diferencia de que las operaciones de posicionamiento, insercin y eliminacin van dirigidas hacia el hijo izquierdo y hacia el hijo derecho de un nodo dado, en lugar de hacia el hijo izquierdo y hacia el hermano como se definan en el TDA rbol. Es importante notar la diferencia entre rboles n-arios y rboles binarios, ya que son TDA's distintos. En el rbol binario, los subrboles se contituyen desde su creacin como subrboles izquierdos o derechos mientras que en un rbol, un subrbol puede ser creado como subrbol de ms la izquierda y despus dejar de serlo.

5.5 Especificacin del TDA rbol Binario


Especificacin informal del TDA rbol Binario
t

ArbolBinario = TDA con operaciones crea,vacio, raiz, padre, hijoIzquierdo, hijoDerecho,info, insertaIzquierdo, insertaDerecho, suprimeIzquierdo, suprimeDerecho, modifica,nodoNulo.

DESCRIPCIN:
t

Los valores del TDA ArbolBinario son arboles binarios donde cada nodo contiene un dato del tipo Elemento. Las posiciones de los nodos en el rbol son del tipo Posicion. Los rboles son mutables: insertaIzquierdo, insertaDerecho, suprimeIzqquierdo, suprimeDerecho} y modifica aaden, eliminan y modifican respectivamente elementos de un rbol.

OPERACIONES:
t

crea()devuelve(A:ArbolBinario)
t efecto: Devuelve el rbol vaco A.

5.5 Especificacin del TDA rbol Binario


t

vacio(A:ArbolBinario)devuelve(booleano)
t efecto: Devuelve cierto si A es el rbol vaco, y falso en caso contrario.

raiz(A:ArbolBinario)devuelve(Posicion)
t efecto: Devuelve la posicin del nodo raz en el rbol A. Si el rbol A est vaco, devuelve nulo

padre(A:ArbolBinario;P:Posicion)devuelve(Posicion)
t requerimientos: El rbol A es no vaco. El nodo P es no nulo. t efecto: Devuelve la posicin del nodo padre del nodo P en el rbol A. Si P es la raiz, devuelve nulo.

hijoIzquierdo(A:ArbolBinario; (Posicion)}

P:Posicion)

devuelve

t requerimientos: El rbol A es no vaco. El nodo P es no nulo. t efecto: Devuelve la posicin del nodo hijo izquierdo del nodo P en el rbol A. Si el nodo P no tiene hijo izquierdo, devuelve nulo.

5.5 Especificacin del TDA rbol Binario


t

hijoDerecho(A:ArbolBinario;P:Posicion)devuelve(Posicion)
t requerimientos: El rbol A es no vaco. El nodo P es no nulo. t efecto: Devuelve la posicin del nodo hijo derecho del nodo P en el rbol A. Si el nodo P no tiene hijo derecho, devuelve nulo

info(A:ArbolBinario;P:Posicion)devuelve(E:Elemento)
t requerimientos: El rbol A es no vaco. El nodo P es no nulo. t efecto: Devuelve en E el contenido (etiqueta) del nodo P en el rbol A.

insertaIzquierdo(A:ArbolBinario;P:Posicion;E:Elemento)
t requerimientos: Si el rbol A es no vaco, entonces el nodo P es no nulo y el nodo hijo izquierdo de P es nulo t modifica: A. t efecto: Aade un nodo, con contenido E, como hijo izquierdo del nodo P en el rbol A. Si el rbol A es vaco, entonces aade un nodo con contenido E como raz del rbol A.

5.5 Especificacin del TDA rbol Binario


t

insertaDerecho(A:ArbolBinario;P:Posicion;E:Elemento)
t requerimientos: El rbol A es no vaco. El nodo P es no nulo. El nodo hijo derecho de P es nulo t modifica: A. t efecto: Aade un nodo, con contenido E, como hijo derecho del nodo P en el rbol A.

suprimeIzquierdo(A:ArbolBinario;P:Posicion)
t requerimientos: El rbol A es no vaco. El nodo P es no nulo. t modifica: A. t efecto: Suprime el hijo izquierdo del nodo P en el rbol A y todos sus descendientes.

suprimeDerecho(A:ArbolBinario;P:Posicion)
t requerimientos: El rbol A es no vaco. El nodo P es no nulo. t modifica: A. t efecto: Suprime el hijo derecho del nodo P en el rbol A y todos sus descendientes.

5.5 Especificacin del TDA rbol Binario

modifica(A:ArbolBinario;P:Posicion;E:Elemento)
t requerimientos: El rbol A es no vaco. El nodo P es no nulo. t modifica: A. t efecto: Modifica el contenido del nodo P en el rbol A, cambindolo por el nuevo contenido E.

nodoNulo(P:Posicion)devuelve(booleano)
t efecto: Devuelve cierto si P es nulo, y falso en caso contrario.

5.5 Especificacin del TDA rbol Binario


La interface Java del TDA rbol de acuerdo a esta especificacin es la siguiente (las excepciones utilizadas son las mismas que las del TDA rbol):
packagearbolBinarioInterface; importarbolException.*; publicinterfaceArbolBinario{ publicbooleanvacio(); publicObjectraiz(); publicObjectpadre(Objectposicion)throwsArbolVacioException, NodoNuloException; publicObjecthijoIzquierdo(Objectposicion)throwsArbolVacioException, NodoNuloException; publicObjecthijoDerecho(Objectposicion)throwsArbolVacioException, NodoNuloException; publicObjectinfo(Objectposicion)throwsArbolVacioException, NodoNuloException;

5.5 Especificacin del TDA rbol Binario

publicvoidinsertaHijoIzquierdo(Objectposicion,Objectelemento)throws NodoNuloException,NodoNoNuloException; publicvoidinsertaHijoDerecho(Objectposicion,Objectelemento)throws ArbolVacioException,NodoNuloException,NodoNoNuloException; publicvoidsuprimeHijoIzquierdo(Objectposicion)throws ArbolVacioException,NodoNuloException; publicvoidsuprimeHijoDerecho(Objectposicion)throwsArbolVacioException, NodoNuloException; publicvoidmodifica(Objectposicion,Objectelemento)throws ArbolVacioException,NodoNuloException; publicbooleannodoNulo(Objectposicion); }//finclassArbolBinario

5.6 Ejemplos de uso del TDA rbol Binario


t

Como ejemplos de uso de rboles binarios veremos tambin los esquemas de recorrido para estos, los cuales difieren con respecto a los recorridos para rboles generales ya que ambos tipos de datos y sus conjuntos de opraciones son diferentes. Para rboles binarios, se definen los recorridos en preorden, inorden y postorden de la siguiente forma: Preorden:
t t

Si el rbol binario es vaco, entonces la lista vaca es el listado de los nodos del rbol binario en preorden. Si el rbol binario no es vaco, el listado en preorden de sus nodos est formado, primero, por la raz del rbol, seguido por los nodos del subrbol izquierdo en preorden, y finalmente, por los nodos del subrbol derecho en preorden.

5.6 Ejemplos de uso del TDA rbol Binario


t

Inorden:
t t

Si el rbol binario es vaco, entonces la lista vaca es el listado de los nodos del rbol binario en inorden. Si el rbol binario no es vaco, el listado en inorden de sus nodos est formado, primero, por los nodos del subrbol izquierdo en inorden, seguido por la raz del rbol, y finalmente, por los nodos del subrbol derecho en inorden.

Postorden:
t t

Si el rbol binario es vaco, entonces la lista vaca es el listado de los nodos del rbol binario en postorden. Si el rbol binario no es vaco, el listado en postorden de sus nodos est formado, primero, por los nodos del subrbol izquierdo en postorden, luego por los nodos del subrbol derecho en postorden, y finalmente, por la raz del rbol.

5.6 Ejemplos de uso del TDA rbol Binario


importarbolBinarioInterface.*; importarbolException.*; importjava.io.*; classArbolBinarioUtil{ staticpublicvoidpreOrden(ArbolBinarioarbol,Objectp){ try{ if(arbol.nodoNulo(p))return; Objecte=arbol.info(p); System.out.println(e); preOrden(arbol,arbol.hijoIzquierdo(p)); preOrden(arbol,arbol.hijoDerecho(p)); }catch(ArbolExceptione){ System.err.println("ErrorenelusodelArbol:e"); } }//finpreOrden

5.6 Ejemplos de uso del TDA rbol Binario

staticpublicvoidinOrden(ArbolBinarioarbol,Objectp){ try{ if(arbol.nodoNulo(p))return; inOrden(arbol,arbol.hijoIzquierdo(p)); Objecte=arbol.info(p); System.out.println(e); inOrden(arbol,arbol.hijoDerecho(p)); }catch(ArbolExceptione){ System.err.println("ErrorenelusodelArbol:e"); } }//fininOrden

5.6 Ejemplos de uso del TDA rbol Binario


staticpublicvoidpostOrden(ArbolBinarioarbol,Objectp){ try{ if(arbol.nodoNulo(p))return; postOrden(arbol,arbol.hijoIzquierdo(p)); postOrden(arbol,arbol.hijoDerecho(p)); Objecte=arbol.info(p); System.out.println(e); }catch(ArbolExceptione){ System.err.println("ErrorenelusodelArbol:e"); } }//finpostOrden }//finclassArbolBinarioUtil

5.7 Implementaciones del TDA rbol Binario


Las clases ArbolBinario y Posicion pueden escribirse bsicamente de la siguiente forma:
classPosicion{ protectedObjectinfo; protectedPosicionhijoIzquierdo; protectedPosicionpadre; protectedPosicionhijoDerecho; } classArbolBinario{ Posicionarbol; }

5.7 Implementaciones del TDA rbol Binario


packagearbolBinario; classPosicion{ protectedObjectinfo; protectedPosicionhijoIzquierdo; protectedPosicionpadre; protectedPosicionhijoDerecho; publicbooleanequals(Objecto){ if(o==null)returnfalse; Posicionp=(Posicion)o; return(this==p); } }//finclassPosicion

5.7 Implementaciones del TDA rbol Binario


packagearbolBinario; importarbolException.*; publicclassArbolBinarioimplementsarbolBinarioInterface.ArbolBinario{ Posicionarbol; publicArbolBinario(){ arbol=null; } publicbooleanvacio(){ return(nodoNulo(arbol)); } publicObjectraiz(){ returnarbol; } publicObjectpadre(Objectposicion)throwsArbolVacioException, NodoNuloException{ Posicionp=(Posicion)posicion; if(vacio())thrownewArbolVacioException(); if(nodoNulo(p))thrownewNodoNuloException(); returnp.padre; }

5.7 Implementaciones del TDA rbol Binario


publicObjecthijoIzquierdo(Objectposicion)throwsArbolVacioException, NodoNuloException{ Posicionp=(Posicion)posicion; if(vacio())thrownewArbolVacioException(); if(nodoNulo(p))thrownewNodoNuloException(); returnp.hijoIzquierdo; } publicObjecthijoDerecho(Objectposicion)throwsArbolVacioException, NodoNuloException{ Posicionp=(Posicion)posicion; if(vacio())thrownewArbolVacioException(); if(nodoNulo(p))thrownewNodoNuloException(); returnp.hijoDerecho; } publicObjectinfo(Objectposicion)throwsArbolVacioException, NodoNuloException{ Posicionp=(Posicion)posicion; if(vacio())thrownewArbolVacioException(); if(nodoNulo(p))thrownewNodoNuloException(); returnp.info; }

5.7 Implementaciones del TDA rbol Binario


publicvoidinsertaHijoIzquierdo(Objectposicion,Objectelemento)throws NodoNuloException,NodoNoNuloException{ Posicionp=(Posicion)posicion; if(!vacio()){ if(nodoNulo(p))thrownewNodoNuloException(); if(!nodoNulo(hijoIzquierdo(p)))thrownew NodoNoNuloException(); } Posicionaux=newPosicion(); aux.info=elemento; aux.hijoIzquierdo=null; aux.hijoDerecho=null; if(vacio()){aux.padre=null;arbol=aux;} else{aux.padre=p;p.hijoIzquierdo=aux;} }

5.7 Implementaciones del TDA rbol Binario

publicvoidinsertaHijoDerecho(Objectposicion,Objectelemento)throws ArbolVacioException,NodoNuloException,NodoNoNuloException{ Posicionp=(Posicion)posicion; if(vacio())thrownewArbolVacioException(); if(nodoNulo(p))thrownewNodoNuloException(); if(!nodoNulo(hijoDerecho(p)))thrownewNodoNoNuloException(); Posicionaux=newPosicion(); aux.info=elemento; aux.hijoIzquierdo=null; aux.hijoDerecho=null; aux.padre=p; p.hijoDerecho=aux; }

5.7 Implementaciones del TDA rbol Binario

publicvoidsuprimeHijoIzquierdo(Objectposicion)throws ArbolVacioException,NodoNuloException{ Posicionp=(Posicion)posicion; if(vacio())newArbolVacioException(); if(nodoNulo(p))thrownewNodoNuloException(); Posicionaux=(Posicion)hijoIzquierdo(p); if(!nodoNulo(aux)){ suprimeHijoIzquierdo(aux); suprimeHijoDerecho(aux); p.hijoIzquierdo=null; } }

5.7 Implementaciones del TDA rbol Binario

publicvoidsuprimeHijoDerecho(Objectposicion)throwsArbolVacioException, NodoNuloException{ Posicionp=(Posicion)posicion; if(vacio())newArbolVacioException(); if(nodoNulo(p))thrownewNodoNuloException(); Posicionaux=(Posicion)hijoDerecho(p); if(!nodoNulo(aux)){ suprimeHijoIzquierdo(aux); suprimeHijoDerecho(aux); p.hijoDerecho=null; } }

5.7 Implementaciones del TDA rbol Binario

publicvoidmodifica(Objectposicion,Objectelemento)throws ArbolVacioException,NodoNuloException{ Posicionp=(Posicion)posicion; if(vacio())newArbolVacioException(); if(nodoNulo(p))thrownewNodoNuloException(); p.info=elemento; } publicbooleannodoNulo(Objectposicion){ return(posicion==null); } }//finclassArbolBinario

5.8 rboles Parcialmente Ordenados: Colas de prioridad

En un captulo anterior vimos una implementacin de colas de prioridad mediante estructuras de datos lineales, en concreto, mediante representacin enlazada con apuntadores. En esa implementacin, la operacin inserta gastaba un tiempo de ejecucin O(n) en el peor caso, si bien la operacin suprime se realiza en un tiempo de ejecucin constante O(1). La implementacin que veremos en esta seccin para colas de prioridad requiere un tiempo de ejecucin O(logn) para ambas operaciones, lo que supone una mejora sustancial para valores grandes de n.

5.8 rboles Parcialmente Ordenados: Colas de prioridad

En esta implementacin, los elementos de la cola de prioridad se organizan en un rbol binario que est lo ms balanceado posible. En el nivel ms bajo, en el cual pueden faltar algunas nodos (lo cual no puede producirse en niveles superiores), se exige adems que los nodos que falten sean los de ms a la derecha posible. El rbol binario es parcialmente ordenado, es decir, la prioridad de un nodo no es menor que la de sus hijos, por lo que en la raz estar siempre el elemento con mayor prioridad

5.8 rboles Parcialmente Ordenados: Colas de prioridad


10

7 6 3 1 4 7 6 5 7

9 8

rbol binario parcialmente ordenado balanceado

5.8 rboles Parcialmente Ordenados: Colas de prioridad


Podemos usar como representacin un vector A en el cual:

si hay n nodos en el rbol, se usan las n primeras posiciones del vector, A[1] contiene el elemento situado en la raz del arbol, el hijo izquierdo del nodo A[i] est, si existe, est en A[2i], el hijo derecho de A[i] est, si existe, est en A[2i+1] el padre del elemento representado en A[i] est en A[idiv2], para i>1.

Esta representacin de rboles parcialmente ordenados se denomina comnmente representacin por montculos. La ventaja est en que se aprovecha la posibilidad de operar aritmticamente con los ndices del vector para obtener, con tiempos de ejecucin constantes, las posiciones de los padres e hijos izquierdo y derecho. La desventaja es que se requiere determinar a priori el nmero mximo de elementos en el rbol.

5.8 rboles Parcialmente Ordenados: Colas de prioridad


La interface del TDA Cola de Prioridad se corresponde con el que presentamos en el captulo de colas para colas de prioridad. No obstante, la especificacin del TDA Cola de Prioridad que estamos considerando en esta seccin es diferente a la que consideramos anteriormente. La diferencia radica en que ahora no se tiene en cuenta la propiedad FIFO para elementos de igual prioridad. Por tanto, no suponemos ahora ningn orden en el procesamiento de dos elementos con igual prioridad (si queremos imponer un orden ser necesario dar mayor prioridad a uno de ellos)

5.8 rboles Parcialmente Ordenados: Colas de prioridad


La implementacin completa en Java es la siguiente:
packagecolaPrioridadBasadaArbol; importcolaException.*; publicclassColaPrioridadimplementscolaPrioridadInterface.ColaPrioridad{ privatestaticintmax=100; privateObjectelementos[]; privateintprioridades[]; privateintultimo; publicColaPrioridad(){ elementos=newObject[max+1]; prioridades=newint[max+1]; ultimo=0; }

5.8 rboles Parcialmente Ordenados: Colas de prioridad


publicbooleanvacia(){ return(ultimo==0); } publicObjectprimero()throwsColaVaciaException{ if(vacia())thrownewColaVaciaException(); returnelementos[1]; } publicintprimero_prioridad()throwsColaVaciaException{ if(vacia())thrownewColaVaciaException(); returnprioridades[1]; }

5.8 rboles Parcialmente Ordenados: Colas de prioridad


publicvoidinserta(Objectelemento,intprioridad){ ultimo++; inti=ultimo; booleanencontrado=false; while((i>1)&&(!encontrado)){ intpadre=i/2; if(prioridad<=prioridades[padre]) encontrado=true; else{ elementos[i]=elementos[padre]; prioridades[i]=prioridades[padre]; i=padre; } } elementos[i]=elemento; prioridades[i]=prioridad; }

5.8 rboles Parcialmente Ordenados: Colas de prioridad


publicvoidsuprime()throwsColaVaciaException{ publicvoidsuprime()throwsColaVaciaException{ if(vacia())thrownewColaVaciaException(); if(vacia())thrownewColaVaciaException(); Objectelemento=elementos[ultimo]; Objectelemento=elementos[ultimo]; intprioridad=prioridades[ultimo]; intprioridad=prioridades[ultimo]; ultimo--; ultimo--; inti=1;intj=2*i; inti=1;intj=2*i; booleanencontrado=false; booleanencontrado=false; while((j<=ultimo)&&(!encontrado)){ while((j<=ultimo)&&(!encontrado)){ if((j<ultimo)&&(prioridades[j]<prioridades[j+1]))j++; if((j<ultimo)&&(prioridades[j]<prioridades[j+1]))j++; if(prioridad>=prioridades[j])encontrado=true; if(prioridad>=prioridades[j])encontrado=true; else{elementos[i]=elementos[j]; else{elementos[i]=elementos[j]; prioridades[i]=prioridades[j]; prioridades[i]=prioridades[j]; i=j;j=2*i; i=j;j=2*i; } } } } elementos[i]=elemento; elementos[i]=elemento; prioridades[i]=prioridad; prioridades[i]=prioridad; } } }//finclassColaPrioridad

5.9 rboles Binarios de Bsqueda

Un rbol binario de bsqueda es un rbol binario formado por elementos en los cuales se asume un orden lineal, y stos se organizan en el rbol de la forma:

todos los elementos almacenados en el subrbol izquierdo de cualquier nodo son menores que el elemento almacenado en dicho nodo todos los elementos almacenados en el subrbol derecho de cualquier nodo son mayores que el elemento almacenado en ese nodo

Los rboles binarios de bsqueda se utilizan tpicamente como estructura de datos para la representacin de conjuntos con operaciones:

inserta,para insertar un elemento dado en un conjunto suprime,para suprimir un elemento determinado de un conjunto miembro, para saber si un elemento dado pertenece o no a un conjunto.

Todas estas operaciones pueden realizarse en un tiempo de ejecucin promedio O(logn) para un conjunto de n elementos.

5.9 rboles Binarios de Bsqueda

Otras posibles operaciones que puede realizarse con el mismo tiempo de ejecucin promedio usando rboles binarios de bsqueda son:

min, que devuelve el elemento mnimo de un rbol suprime_min, que elimina el elemento mnimo de un rbol max, que devuelve el elemento mximo de un rbol suprime_max, que elimina el elemento mximo de un rbol

Podramos usar tambin rboles binarios de bsqueda para representar colas de prioridad (en este caso permitiramos almacenar elementos repetidos en el rbol, asumiendo, por ejemplo, que los elementos almacenados en el subrbol derecho de cualquier nodo son mayores o iguales que el elemento almacenado en ese nodo).

5.9 rboles Binarios de Bsqueda


Especificacin Informal

ArbolBinarioBusqueda= TDA con operaciones crea,destruye,vacio, inserta,suprime,miembro.

DESCRIPCIN:

Los valores del TDA ArbolBinarioBusqueda son rboles binarios de bsqueda de elementos del tipo Elemento. Los rboles binarios de bsqueda son mutables: inserta} y suprime aaden y eliminan elementos en el rbol respectivamente.

OPERACIONES:

crea() devuelve (A:ArbolBinarioBusqueda)


efecto: Devuelve el rbol binario de bsqueda vaco A.

5.9 rboles Binarios de Bsqueda

vacio(A:ArbolBinarioBusqueda)devuelve(booleano)
efecto: Devuelve cierto si A es el rbol vaco, y falso en caso contrario.

inserta(A:ArbolBinarioBusqueda;E:Elemento)
modifica: A. efecto: Aade el elemento E al rbol binario de bsqueda A.

suprime(A:ArbolBinarioBusqueda;E:Elemento)
modifica: A. efecto: Suprime el elemento E, si existe, del rbol binario de bsqueda A.

miembro(A:ArbolBinarioBusqueda;E:Elemento)devuelve (booleano)
efecto: Devuelve cierto si E es un elemento del rbol binario de bsqueda A, y falso en caso contrario.

5.9 rboles Binarios de Bsqueda


La interface en Java del TDA rbol Binario de Bsqueda es la siguiente:
packagearbolBinarioBusquedaInterface; importComparable; publicinterfaceArbolBinarioBusqueda{ publicbooleanvacio(); publicvoidinserta(Comparableelemento); publicvoidsuprime(Comparableelemento); publicbooleanmiembro(Comparableelemento); }//fininterfaceArbolBinarioBusqueda

Los elementos deben implementar la interface Comparable porque as lo requiere el TDA rbol Binario de Bsqueda al asumirse un rden lineal entre sus elementos.

5.9 rboles Binarios de Bsqueda


La interface en Java del TDA rbol Binario de Bsqueda es la siguiente:
packagearbolBinarioBusquedaInterface; importComparable; publicinterfaceArbolBinarioBusqueda{ publicbooleanvacio(); publicvoidinserta(Comparableelemento); publicvoidsuprime(Comparableelemento); publicbooleanmiembro(Comparableelemento); }//fininterfaceArbolBinarioBusqueda

Los elementos deben implementar la interface Comparable porque as lo requiere el TDA rbol Binario de Bsqueda al asumirse un rden lineal entre sus elementos.

5.9 rboles Binarios de Bsqueda


packagearbolBinarioBusqueda; importComparable; publicclassArbolBinarioBusquedaimplements arbolBinarioBusquedaInterface.ArbolBinarioBusqueda{ privateComparableinfo; privateArbolBinarioBusquedaizquierdo,derecho; publicArbolBinarioBusqueda(){ info=null; izquierdo=null; derecho=null; } publicbooleanvacio(){ return((info==null)&&(izquierdo==null)&&(derecho==null)); }

5.9 rboles Binarios de Bsqueda


publicvoidinserta(Comparableelemento){ if(vacio()){ info=elemento; izquierdo=newArbolBinarioBusqueda(); derecho=newArbolBinarioBusqueda(); } elseif(elemento.menorQue(info)){ izquierdo.inserta(elemento); } else{ derecho.inserta(elemento); } }

5.9 rboles Binarios de Bsqueda


publicvoidsuprime(Comparableelemento){ if(vacio())return; if(elemento.menorQue(info)){ izquierdo.suprime(elemento); } elseif(elemento.mayorQue(info)){ derecho.suprime(elemento); } elseif((izquierdo.vacio())&&(derecho.vacio())){ info=null; derecho=null; izquierdo=null; } elseif(izquierdo.vacio()){ info=derecho.info; izquierdo=derecho.izquierdo; derecho=derecho.derecho; }

5.9 rboles Binarios de Bsqueda


elseif(derecho.vacio()){ info=izquierdo.info; derecho=izquierdo.derecho; izquierdo=izquierdo.izquierdo; } else{ ArbolBinarioBusquedamin=derecho; while(!min.izquierdo.vacio())min=min.izquierdo; info=min.info; min.info=min.derecho.info; min.izquierdo=min.derecho.izquierdo; min.derecho=min.derecho.derecho; } }

5.9 rboles Binarios de Bsqueda


publicbooleanmiembro(Comparableelemento){ if(vacio())returnfalse; if(elemento.equals(info))returntrue; if(elemento.menorQue(info))returnizquierdo.miembro(elemento); returnderecho.miembro(elemento); } }//finclassArbolBinarioBusqueda