Sie sind auf Seite 1von 17

[+] Introduccion Las estructuras de datos grafos son llamadas estructuras de ramificacion,ya que un elemento, en comparacion con las

estructuras lineales,puede tener mas de un siguiente elemento. En esta tutorial vamos a hablar de un caso especial de grafos, denominado ARBOL o TREE.

[+] Definicion de Arbol Un arbol es un conjunto finito de 0 o mas nodos v1,v2,...,vn tales que: 1- existe un nodo el cual se distingue de los demas, al mismo lo vamos llamar raiz 2- los demas elementos del conjuntos quedan particionados en m>=0 conjuntos disjuntos T1,T2,...,TN los cuales son arboles.

los elementos T1,T2,...,TN son llamados subarboles. Vemos aqui la naturaleza recursiva de la estructura arbol, puesto que definimos arbol en termino de arboles.

-El grado interior del nodo raiz es nulo, esto quiere decir que no existen ramificaciones de entrada hacia el. -Los nodos que tienen grado exterior=0 se dicen que son nodos hojas de un arbol. -Se dice que un arbolesta en niveles, los cuales estan determinados por la longuitud de la trayectoria desde la raiz hacia dicho nodo.

-El peso de un arbolesta determinado por el numero de nodos hojas -La altura de un arbol es 1 maselel mayor nivel de nodos -Un conjunto de arboles enraizados se dice que forman un bosque.

[+] Arboles Binarios Un arbol binario es un caso especial de arboles generales. Es un conjunto finito de 0 nodos, o mas que tienen un subconjunto disjunto de 2 nodos, uno denominado subarbol derecho y otro subarbol izquierdo.

[+] convertir Arboles Generales a Arboles binarios Esto se realiza obviamente porque es masfacil representar arboles binarios que arboles generales, debido a que la cantidad de apuntadores predecibles son 2: subarbol derecho y subarbol izquierdo. El algoritmo que permite realizar esta operacion de conversion, o transformacion es el siguiente: 1- insertar aristas uniendo los nodos hermanos y eliminar aquellas aristas que unen a los nodos hijos con su padre, excepto el de mas a la izquierda. 2- girar este arbol aproximadamente unos 45 para distinguir los subarboles derecho e izquierdo.

[+] Representacion de un arbol Un arbol se lo puede representar mediante la implementaciondinamica de memoria, esto es utilizando listas encadenadas o ligadas. cada nodo va a tener la siguiente configuacion: |PI|INFO|PD| donde PI: apunta hacia el nodo izquierdo (subarbol izquierdo) de ese nodo INFO: es el campo donde se almacena la informacion PD: apunta hacia el nodo derecho (subarbol derecho)de ese nodo.

[+] Arboles en JAVA... Vamos a realizar una pequea aplicacion en java que nos permita entender el concepto de arbol, el programa realizara inserciones, eliminaciones e imprimira los elementos del arbol generado. Clases: Nodo Arbol ArbolAplicacion Principal ####################################################### Clase NODO #######################################################

publicclass Nodo { private Nodo pd; privateObject dato; private Nodo pi; public Nodo(Object dato){ this.dato=dato; pd=null; pi=null; } publicObjectgetDato() {return dato;} publicvoidsetDato(Object dato) {this.dato = dato;} public Nodo getPd() {returnpd;} publicvoidsetPd(Nodo pd) {this.pd = pd;} public Nodo getPi() {return pi;} publicvoidsetPi(Nodo pi) {this.pi = pi;} } #######################################################

####################################################### CLASE ARBOL ####################################################### publicclassArbol { private Nodo Raiz; publicArbol(){ Raiz=null;} // insertar(Raiz, Raiz, x)

publicbooleanarbolVacio(){returnRaiz == null;}

publicvoid insertar(Nodo ant, Nodo p, Nodo x){

if (p != null){ if (Integer.parseInt(x.getDato().toString()) > Integer.parseInt(p.getDato().toString())) { insertar(p, p.getPd(), x); }else{ insertar(p, p.getPi(), x); }

- Estructuras dinmicas: Implementacin en Java de un rbol binario ordenado


Problema 1:
A continuacin desarrollamos una clase para la administracin de un rbol binario ordenado. Programa:
publicclassArbolBinarioOrdenado { class Nodo { intinfo; Nodo izq, der; } Nodo raiz; publicArbolBinarioOrdenado() { raiz=null; } public void insertar (int info) { Nodo nuevo; nuevo = new Nodo (); nuevo.info = info; nuevo.izq = null; nuevo.der = null; if (raiz == null) raiz = nuevo; else { Nodo anterior = null, reco; reco = raiz; while (reco != null) { anterior = reco; if (info< reco.info) reco = reco.izq; else reco = reco.der; } if (info< anterior.info) anterior.izq = nuevo; else anterior.der = nuevo; } }

privatevoidimprimirPre (Nodo reco)

{ if (reco != null) { System.out.print(reco.info + " "); imprimirPre (reco.izq); imprimirPre (reco.der); } } public void imprimirPre () { imprimirPre (raiz); System.out.println(); } private void imprimirEntre (Nodoreco) { if (reco != null) { imprimirEntre (reco.izq); System.out.print(reco.info + " "); imprimirEntre (reco.der); } } public void imprimirEntre () { imprimirEntre (raiz); System.out.println(); }

private void imprimirPost (Nodoreco) { if (reco != null) { imprimirPost (reco.izq); imprimirPost (reco.der); System.out.print(reco.info + " "); } }

public void imprimirPost () { imprimirPost (raiz); System.out.println(); } public static void main (String [] ar) { ArbolBinarioOrdenadoabo = new ArbolBinarioOrdenado (); abo.insertar (100); abo.insertar (50); abo.insertar (25); abo.insertar (75); abo.insertar (150);

System.out.println ("Impresionpreorden: "); abo.imprimirPre (); System.out.println ("Impresionentreorden: "); abo.imprimirEntre (); System.out.println ("Impresionpostorden: "); abo.imprimirPost (); } }

public void insertar (int info) { Nodo nuevo; nuevo = new Nodo (); nuevo.info = info; nuevo.izq = null; nuevo.der = null; if (raiz == null) raiz = nuevo; else { Nodo anterior = null, reco; reco = raiz; while (reco != null) { anterior = reco; if (info< reco.info) reco = reco.izq; else reco = reco.der; } if (info< anterior.info) anterior.izq = nuevo; else anterior.der = nuevo; } }

Creamos un nodo y disponemos los punteros izq y der a null, guardamos la informacin que llega al mtodo en el nodo. Si el rbol est vaco, apuntamos raz al nodo creado; en caso de no estar vaco, dentro de una estructura repetitiva vamos comparando info con la informacin del nodo, si info es mayor a la del nodo descendemos por el subrbol derecho en caso contrario descendemos por el subrbol izquierdo. Cuando se encuentra un subrbol vaco insertar el nodo en dicho subrbol. Para esto llevamos un puntero anterior dentro del while.
privatevoidimprimirPre (Nodo reco) { if (reco != null) { System.out.print(reco.info + " "); imprimirPre (reco.izq); imprimirPre (reco.der);

} } public void imprimirPre () { imprimirPre (raiz); System.out.println(); }

El mtodo imprimirPre(), es decir el no recursivo se encarga de llamar al mtodo recursivo pasando la direccin del nodo raiz. El mtodo recursivo voidimprimirPre (Nodo reco) lo primero que verifica con un if si reco est apuntando a un nodo (esto es verdad si reco es distinto a null), en caso afirmativo ingresa al bloque del if y realiza:
- Visitar la raiz. - Recorrer el subrbol izquierdo en pre-orden. - Recorrer el subrbol derecho en pre-orden.

La visita en este caso es la impresin de la informacin del nodo y los recorridos son las llamadas recursivas pasando las direcciones de los subrboles izquierdo y derecho. Los algoritmos de los recorridos en entreorden y postorden son similares. La diferencia es que la visita la realizamos entre las llamadas recursivas en el recorrido en entre orden:
privatevoidimprimirEntre (Nodo reco) { if (reco != null) { imprimirEntre (reco.izq); System.out.print(reco.info + " "); imprimirEntre (reco.der); } }

y por ltimo en el recorrido en postorden la visita la realizamos luego de las dos llamadas recursivas:
private void imprimirPost (Nodoreco) { if (reco != null) { imprimirPost (reco.izq); imprimirPost (reco.der); System.out.print(reco.info + " "); } }

Problema 2:

Confeccionar una clase que permita insertar un entero en un rbol binario ordenado verificando que no se encuentre previamente dicho nmero. Desarrollar los siguientes mtodos: 1 - Retornar la cantidad de nodos del rbol. 2 - Retornar la cantidad de nodos hoja del rbol. 3 - Imprimir en entre orden. 4 - Imprimir en entre orden junto al nivel donde se encuentra dicho nodo. 5 - Retornar la altura del rbol. 6 - Imprimir el mayor valor del rbol. 7 - Borrar el nodo menor del rbol.
publicclassArbolBinarioOrdenado { class Nodo { intinfo; Nodo izq, der; } Nodoraiz; intcant; intaltura; publicArbolBinarioOrdenado() { raiz=null; } publicvoid insertar (intinfo) { if (!existe(info)) { Nodo nuevo; nuevo = new Nodo (); nuevo.info = info; nuevo.izq = null; nuevo.der = null; if (raiz == null) raiz = nuevo; else { Nodo anterior = null, reco; reco = raiz; while (reco != null) { anterior = reco; if (info< reco.info) reco = reco.izq; else reco = reco.der; } if (info< anterior.info) anterior.izq = nuevo; else anterior.der = nuevo; } } } publicbooleanexiste(int info) { Nodo reco=raiz;

while (reco!=null) { if (info==reco.info) return true; else if (info>reco.info) reco=reco.der; else reco=reco.izq; } return false; } private void imprimirEntre (Nodoreco) if (reco != null) { imprimirEntre (reco.izq); System.out.print(reco.info + " "); imprimirEntre (reco.der); } } public void imprimirEntre () { imprimirEntre (raiz); System.out.println(); } {

private void cantidad(Nodoreco) { if (reco!=null) { cant++; cantidad(reco.izq); cantidad(reco.der); } } publicintcantidad() { cant=0; cantidad(raiz); return cant; } privatevoidcantidadNodosHoja(Nodo reco) { if (reco!=null) { if (reco.izq==null &&reco.der==null) cant++; cantidadNodosHoja(reco.izq); cantidadNodosHoja(reco.der); } } publicintcantidadNodosHoja() { cant=0; cantidadNodosHoja(raiz); return cant; } privatevoidimprimirEntreConNivel (Nodo reco,int nivel) if (reco != null) { {

imprimirEntreConNivel (reco.izq,nivel+1); System.out.print(reco.info + " ("+nivel+") - "); imprimirEntreConNivel (reco.der,nivel+1); } } publicvoidimprimirEntreConNivel () { imprimirEntreConNivel (raiz,1); System.out.println(); } privatevoidretornarAltura (Nodo reco,int nivel) if (reco != null) { retornarAltura (reco.izq,nivel+1); if (nivel>altura) altura=nivel; retornarAltura (reco.der,nivel+1); } } publicintretornarAltura () { altura=0; retornarAltura (raiz,1); return altura; } public void mayorValorl() { if (raiz!=null) { Nodo reco=raiz; while (reco.der!=null) reco=reco.der; System.out.println("Mayor valor del rbol:"+reco.info); } } public void borrarMenor() { if (raiz!=null) { if (raiz.izq==null) raiz=raiz.der; else { Nodo atras=raiz; Nodo reco=raiz.izq; while (reco.izq!=null) { atras=reco; reco=reco.izq; } atras.izq=reco.der; } } } public static void main (String [] ar) { ArbolBinarioOrdenadoabo = new ArbolBinarioOrdenado (); abo.insertar (100); abo.insertar (50); abo.insertar (25); {

abo.insertar (75); abo.insertar (150); System.out.println ("Impresionentreorden: "); abo.imprimirEntre (); System.out.println ("Cantidad de nodos del rbol:"+abo.cantidad()); System.out.println ("Cantidad de nodos hoja:"+abo.cantidadNodosHoja()); System.out.println ("Impresion en entre orden junto al nivel del nodo."); abo.imprimirEntreConNivel(); System.out.print ("Artura del arbol:"); System.out.println(abo.retornarAltura()); abo.mayorValorl(); abo.borrarMenor(); System.out.println("Luego de borrar el menor:"); abo.imprimirEntre (); } }

Para verificar si existe un elemento de informacin en el rbol disponemos un puntero reco en el nodo apuntado por raiz. Dentro de un while verificamos si la informacin del parmetro coincide con la informacin del nodo apuntado por reco, en caso afirmativo salimos del mtodo retornando true, en caso contrario si la informacin a buscar es mayor a la del nodo procedemos a avanzar reco con la direccin del subrbol derecho:
publicbooleanexiste(int info) { Nodo reco=raiz; while (reco!=null) { if (info==reco.info) return true; else if (info>reco.info) reco=reco.der; else reco=reco.izq; } return false; }

Para retornar la cantidad de nodos del rbol procedemos a inicializar un atributo de la clase llamado cant con cero. Llamamos al mtodo recursivo y en cada visita al nodo incrementamos el atributo cant en uno:
privatevoid cantidad(Nodo reco) { if (reco!=null) { cant++; cantidad(reco.izq); cantidad(reco.der); } } publicintcantidad() { cant=0; cantidad(raiz); return cant; }

Para imprimir todos los nodos en entre orden junto al nivel donde se encuentra planteamos un mtodo recursivo que llegue la referencia del nodo a imprimir junto al nivel de dicho nodo. Desde el mtodo no recursivo pasamos la referencia a raiz y un uno (ya que raiz se encuentra en el primer nivel) Cada vez que descendemos un nivel le pasamos la referencia del subrbol respectivo junto al nivel que se encuentra dicho nodo:
privatevoidimprimirEntreConNivel (Nodo reco,int nivel) if (reco != null) { imprimirEntreConNivel (reco.izq,nivel+1); System.out.print(reco.info + " ("+nivel+") - "); imprimirEntreConNivel (reco.der,nivel+1); } } publicvoidimprimirEntreConNivel () { imprimirEntreConNivel (raiz,1); System.out.println(); } {

Para obtener la altura del rbol procedemos en el mtodo no recursivo a inicializar el atributo altura con el valor cero. Luego llamamos al mtodo recursivo con la referencia a raiz que se encuentra en el nivel uno. Cada vez que visitamos un nodo procedemos a verificar si el parmetro nivel supera al atributo altura, en dicho caso actualizamos el atributo altura con dicho nivel.
privatevoidretornarAltura (Nodo reco,int nivel) if (reco != null) { retornarAltura (reco.izq,nivel+1); if (nivel>altura) altura=nivel; retornarAltura (reco.der,nivel+1); } } publicintretornarAltura () { altura=0; retornarAltura (raiz,1); return altura; } {

Para imprimir el mayor valor del rbol debemos recorrer siempre por derecha hasta encontrar un nodo que almacene null en der:
public void mayorValorl() { if (raiz!=null) { Nodo reco=raiz; while (reco.der!=null) reco=reco.der; System.out.println("Mayor valor del rbol:"+reco.info); } }

Para borrar el menor valor del rbol lo primero que comprobamos es si el subrbol izquierdo es nulo luego el menor del rbol es el nodo apuntado por raiz. Luego si el subrbol izquierdo no est vaco procedemos a descender siempre por la izquierda llevando un puntero en el nodo anterior. Cuando llegamos al nodo que debemos borrar procedemos a enlazar el puntero izq del nodo que se encuentra en el nivel anterior con la referencia del subrbol derecho del nodo a borrar:
public void borrarMenor() { if (raiz!=null) { if (raiz.izq==null) raiz=raiz.der; else { Nodo atras=raiz; Nodo reco=raiz.izq; while (reco.izq!=null) { atras=reco; reco=reco.izq; } atras.izq=reco.der; } } }

Hola estoy estudiando para un xamen y no soy capaz de hacer este ejercicio. A ver si me puedes dar alguna ayuda. Gracias Implementar un mtodo arbolSuma que reciba como parmetro de entrada un rbol binario de nmeros enteros y devuelva otro rbol binario de nmeros enteros en el que cada uno de sus nodos contenga la suma de l mismo junto con todos sus nodos descendientes. Hola, para la solucion necesitas 2 clases la clase NodoArbolBinario y ArbolBinario y en la clase ArbolBinario se encuentra los metodosarbolSuma uno publico y otro privado, el que debes llamar desde la clase donde esta el main es el publico es decir el que recibe el ArbolBinario por parametro, estas son: //************************************ // clase NodoArbolBinario //************************************ publicclassNodoArbolBinario { privateintinfo = 0; privateNodoArbolBinario derecho = null; privateNodoArbolBinario izquierdo = null; publicNodoArbolBinario ( int x ) { this.info = x; this.derecho = null; this.izquierdo = null; } publicNodoArbolBinariogetDerecho(){ returnthis.derecho; } publicvoidsetDerecho(NodoArbolBinario derecho){ this.derecho = derecho; }

publicintgetInfo(){ return this.info; } publicvoidsetInfo(intinfo){

this.info = info; }

publicNodoArbolBinariogetIzquierdo(){ returnthis.izquierdo; } publicvoidsetIzquierdo(NodoArbolBinario izquierdo){ this.izquierdo = izquierdo; } } //************************************ // clase ArbolBinario //************************************ publicclassArbolBinario { privateNodoArbolBinarioraiz = null; privateNodoArbolBinario padre = null; privateboolean centinela = false, sw = false; publicArbolBinario () { } publicNodoArbolBinario adicionar( int x ) { NodoArbolBinario p = new NodoArbolBinario ( x ), r = null; if ( this.raiz == null ) { this.raiz = p; } else { NodoArbolBinario q = raiz; while ( q != null ) { r = q; if ( x >= q.getInfo() ) { q = q.getDerecho(); } else { q = q.getIzquierdo(); } } }

if ( x >= r.getInfo() ) { r.setDerecho( p ); } else { r.setIzquierdo( p ); } return p; } publicArbolBinarioarbolSuma(ArbolBinariotree){ ArbolBinario res = new ArbolBinario(); arbolSuma(res,tree.raiz); return res; } privateintarbolSuma(ArbolBinario res, NodoArbolBinario p){ if ( p == null ){ return 0; } else { int sum = p.getInfo(); NodoArbolBinarioaux = res.adicionar(sum); sum += arbolSuma(res, p.getIzquierdo() ); sum += arbolSuma(res, p.getDerecho() ); aux.setInfo(sum); return sum; } } }

Das könnte Ihnen auch gefallen