You are on page 1of 12

Lab 131 Universidad Mayor de San Andrs Carrera de Informtica Lab 131 II/2013

II/2013

Arboles Binarios y de Busqueda


Definicin. Un rbolbinario es una estructura de datos en la cual cada nodo siempre tiene un hijo izquierdo y
un hijo derecho. No pueden tener ms de dos hijos (de ah el nombre "binario"). Si algn hijo tiene como referencia a null, es decir que no almacena ningn dato, entonces este es llamado un nodo externo o nodo hoja.

Tipos de rboles. Un rbol binario es un rbol con raz en el que cada nodo tiene como mximo 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 (vrtices con cero hijos) estn a la misma profundidad (distancia desde la raz, tambin 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 estn a profundidad n o n-1, para alguna n.

Un rbol binario es un rbol en el que ningn nodo puede tener ms de dos subrboles. En un rbol binario cada nodo puede tener cero, uno o dos hijos (subrboles). Se conoce el nodo de la izquierda como hijo izquierdo y el nodo de la derecha como hijo derecho. Recorrido de arboles Preorden: (raz, izquierdo, derecho). Para recorrer un rbol binario no vaco en preorden, hay que realizar las siguientes operaciones recursivamente en cada nodo, comenzando con el nodo de raz: 1. Visite la raz 2. Atraviese el sub-rbol izquierdo 3. Atraviese el sub-rbol derecho

D'jalmar Gutierrez

Lab 131

II/2013

Inorden: (izquierdo, raz, derecho). Para recorrer un rbol binario no vaco en inorden (simtrico), hay que realizar las siguientes operaciones recursivamente en cada nodo: 1. Atraviese el sub-rbol izquierdo 2. Visite la raz 3. Atraviese el sub-rbol derecho Postorden: (izquierdo, derecho, raz). Para recorrer un rbol binario no vaco en postorden, hay que realizar las siguientes operaciones recursivamente en cada nodo: 1. Atraviese el sub-rbol izquierdo 2. Atraviese el sub-rbol derecho 3. Visite la raz

Implementacion.

Class Nodo

classNodo_A { privateNodo_Aizq; privateintdato; privateNodo_Ader; publicNodo_A () { izq = null; der = null; } publicNodo_AgetIzq() { returnizq; } publicvoidsetIzq(Nodo_Aizq) { this.izq = izq; 2 D'jalmar Gutierrez

Lab 131 } publicintgetDato() { returndato; } publicvoidsetDato(intdato) { this.dato = dato; } publicNodo_AgetDer() { returnder; } publicvoidsetDer(Nodo_A der) { this.der = der; } } ClassArbol importjava.util.Stack; classArbol { privateNodo_AR; publicNodo_AgetR() { returnR; } publicvoidsetR(Nodo_A r) { R = r; } publicArbol () { R = null; } publicbooleanesVacia () { if (R == null) returntrue; returnfalse; } publicvoidr_Niveles () { Stack<Nodo_A> aux=new Stack<Nodo_A>(); Stack<Nodo_A> p=new Stack<Nodo_A>(); Nodo_A x; p.push(R); while (p.size()!=0) { while (p.size()!=0) { 3

II/2013

D'jalmar Gutierrez

Lab 131 x = p.pop(); System.out.print (" " + x.getDato()); if (x.getIzq() != null) aux.push(x.getIzq()); if (x.getDer() != null) aux.push(x.getDer()); } while (aux.size()!=0) { p.push(aux.pop()); } System.out.println (" "); } } publicvoidr_Niveles (Nodo_A x) { Stack<Nodo_A> aux=new Stack<Nodo_A>(); Stack<Nodo_A> p=new Stack<Nodo_A>(); p.push(x); while (p.size()!=0) { while (p.size()!=0) { x = p.pop(); System.out.print (" " + x.getDato()); if (x.getIzq() != null) aux.push(x.getIzq()); if (x.getDer() != null) aux.push(x.getDer()); } while (aux.size()!=0) { p.push(aux.pop()); } System.out.println (" "); } } publicvoidr_preOrden (Nodo_A x) { if (x != null) { System.out.print (x.getDato() + " r_preOrden (x.getIzq()); r_preOrden (x.getDer()); } } publicvoidr_inOrden (Nodo_A x) 4

II/2013

");

D'jalmar Gutierrez

Lab 131 { if (x != null) { r_inOrden (x.getIzq()); System.out.print (x.getDato() + " r_inOrden (x.getDer()); } } publicvoidr_postOrden (Nodo_A x) { if (x != null) { r_postOrden (x.getIzq()); r_postOrden (x.getDer()); System.out.print (x.getDato() + " } } } Class ArbolBinario importjava.util.Scanner; importjava.util.Stack; class AB extendsArbol { public AB () { super (); }

II/2013

");

");

publicvoidcarga () { Nodo_A x, xi = null, xd = null; Nodo_Araiz = newNodo_A (); Stack<Nodo_A> p=new Stack<Nodo_A>(); charresp; System.out.println ("Introduzca el dato de la raiz "); raiz.setDato(Integer.parseInt(new Scanner(System.in).nextLine())); raiz.setIzq(null); raiz.setDer(null); p.push(raiz); while (p.size()!=0) { x = p.pop (); System.out.println ("TieneNodoIzq. " + x.getDato() + "?"); resp = new Scanner(System.in).next().charAt(0); if (resp == 's') 5 D'jalmar Gutierrez

Lab 131 {

II/2013

xi = newNodo_A (); System.out.println ("Nodo Izq. es :"); xi.setDato(new Scanner(System.in).nextInt()); x.setIzq(xi); } else { x.setIzq(null) ; } System.out.println ("Tiene Nodo Der. " + x.getDato() + "?"); resp = new Scanner(System.in).next().charAt(0); if (resp == 's') { xd = newNodo_A (); System.out.println ("Nodo Der. es :"); xd.setDato(new Scanner(System.in).nextInt()); x.setDer(xd); } else { x.setDer(null); } if (x.getDer() != null) p.push (xd); if (x.getIzq() != null) p.push (xi); } setR(raiz); } publicvoidr_Niveles () { super.r_Niveles (); } publicvoidr_Niveles (Nodo_A x) { super.r_Niveles (x); } publicvoidr_inOrden (Nodo_A R) { super.r_inOrden (R); } publicvoidr_postOrden (Nodo_A R) { super.r_postOrden (R); } 6 D'jalmar Gutierrez

Lab 131

II/2013

} AB arbolBinario = newAB(); arbolBinario.carga(); System.out.println("niveles"); arbolBinario.r_Niveles(); System.out.println("orden"); arbolBinario.r_inOrden(arbolBinario.getR()); System.out.println("pre"); arbolBinario.r_preOrden(arbolBinario.getR()); System.out.println("post"); arbolBinario.r_postOrden(arbolBinario.getR()); System.out.println("hojas"); arbolBinario.muestraHoja(arbolBinario.getR()); System.out.println("hojas"); Nodo_A x= arbolBinario.padre(arbolBinario.getR(),4); if(x!=null) System.out.println(x.getDato()); else System.out.println("El nodo no existe o no tiene padres"); Ejercicios Resueltos 1. Mostrar los nodos hoja de un rbol publicvoidmuestraHoja(Nodo_A R) { if(R == null) return; if(R.getIzq() == null&&R.getDer() == null) { System.out.println(R.getDato()); return; } else { muestraHoja(R.getIzq()); muestraHoja(R.getDer()); } } 2. Mostrar el padre de un nodo publicNodo_A padre(Nodo_Anodo,int dato) { if(nodo!=null) { if(nodo.getIzq()!=null) { if(nodo.getIzq().getDato() == dato) returnnodo; else return padre(nodo.getIzq(),dato); } 7 D'jalmar Gutierrez

Lab 131 if(nodo.getDer()!=null) { if(nodo.getDer().getDato()==dato) returnnodo; else return padre(nodo.getDer(),dato); } } returnnull; } EjerciciosPropuestos 1. Dado un rbol binario eliminar un nodo x. 2. Determinar si un rbol es lleno o perfecto. 3. Verificar si dos rboles son simtricamente iguales

II/2013

Arboles Binarios de Bsqueda

D'jalmar Gutierrez

Lab 131

II/2013

Definicion. Un rbol binario de bsqueda tambin llamados BST (acrnimo del ingls BinarySearchTree) es un tipo particular de rbol binario que presenta una estructura de datos ordenada, para as optimizar la bsqueda. Para una fcil comprensin queda resumido en que es un rbol binario que cumple que el subrbol izquierdo de cualquier nodo (si no est vaco) contiene valores menores que el que contiene dicho nodo, y el subrbol derecho (si no est vaco) contiene valores mayores. El inters de los rboles binarios de bsqueda (ABB) radica en que su recorrido en inordenproporciona los elementos ordenados de forma ascendente y en que la bsqueda de algn elemento suele ser muy eficiente.

Implementacion. Class ABB publicclass ABB extendsArbol { public ABB () { super (); } publicvoidcarga (int e) { Nodo_A x = null, y; if (esVacia ()) { x = newNodo_A (); x.setDato(e); 9 D'jalmar Gutierrez

Lab 131 setR( x); } else { x = newNodo_A (); x.setDato(e); y = getR(); intsw = 0; while (sw == 0) { if (e >y.getDato()) { if (y.getDer() != null) y = y.getDer(); else { y.setDer(x); sw = 1; } } else if (y.getIzq() != null) y = y.getIzq(); else { y.setIzq( x); sw = 1; } } } } publicvoidr_inorden (Nodo_A R) { super.r_inOrden (R); } } Ejercicios Resueltos. 1. Sumar los elementos del un ABB publicintsuma(Nodo_Anx) { int s=0; Stack<Nodo_A> p=new Stack<Nodo_A>(); Nodo_A x; p.push (nx); while (p.isEmpty()) { x = p.pop (); s=s+x.getDato(); 10

II/2013

D'jalmar Gutierrez

Lab 131 if (x.getDer() != null) p.push(x.getDer()); if (x.getIzq() != null) p.push(x.getIzq()); } return s; } 2. Realizar el llenado de manera recursiva publicvoidcarga(Nodo_AR,intdato) { if(R != null) { if(dato>R.getDato()) { if(R.getDer()!= null) carga(R.getDer(),dato); else { Nodo_A x=newNodo_A(); x.setDato(dato); R.setDer(x); } } else { if(R.getIzq()!=null) carga(R.getIzq(),dato); else { Nodo_A x=newNodo_A(); x.setDato(dato); R.setIzq(x); } } } else { R=newNodo_A(); R.setDato(dato); } } importjava.util.Scanner; classManejaAbb { publicstaticvoid main (String args []) { ABBarbolBusqueda = newABB(); //cargamos 10 datos 11

II/2013

D'jalmar Gutierrez

Lab 131 Nodo_Araiz=newNodo_A(); raiz.setDato(new Scanner(System.in).nextInt()); arbolBusqueda.setR(raiz); for (int i = 0; i < 10; i++) { arbolBusqueda.carga(arbolBusqueda.getR(), new Scanner(System.in).nextInt()); } arbolBusqueda.r_inorden(arbolBusqueda.getR()); } }

II/2013

Ejercicios Propuestos. 1. Eliminar un nodo sin afectar el orden del ABB 2. Mostrar de forma ordenada descendentemente un ABB

12

D'jalmar Gutierrez