You are on page 1of 12

TEMA 11 EDAs de bsqueda y su jerarqua Java rbol Binario de Bsqueda: implementacin de Cola de Prioridad y Diccionario

EJERCICIOS RESUELTOS

Ejercicio 1.- Escribe la versin iterativa del mtodo recuperar Solucin:


public E recuperar(E x) throws ElementoNoEncontrado { return recuperar(x, this.raiz).dato; } protected NodoABB<E> recuperar(E x, NodoABB<E> actual) throws ElementoNoEncontrado { boolean encontrado = false; while (actual != null && !encontrado) { int resC = actual.dato.compareTo(x); if (resC < 0) actual = actual.der; else if (resC > 0) actual = actual.izq; else encontrado = true; } if (!encontrado) throw new ElementoNoEncontrado(Al buscar: + x + no est); return actual; }

Ejercicio 2.- Disea los siguientes mtodos, tanto recursiva como iterativamente:
public E recuperarMin(); public E recuperarMax();

Solucin: a) Versin recursiva:


// SII: !esVacio() public E recuperarMin() { return recuperarMin(this.raiz).dato; } protected NodoABB<E> recuperarMin(NodoABB<E> actual) { if (actual.izq == null) return actual; return recuperarMin(actual.izq); }

// SII: !esVacio() public E recuperarMax() { return recuperarMax(this.raiz).dato; } protected NodoABB<E> recuperarMax(NodoABB<E> actual) { if (actual.der == null) return actual; return recuperarMax(actual.der); }

b) Versin iterativa:
// SII: !esVacio() public E recuperarMin() { return recuperarMin(this.raiz).dato; } protected NodoABB<E> recuperarMin(NodoABB<E> actual) { while (actual.izq != null) actual = actual.izq; return actual; } // SII: !esVacio() public E recuperarMax() { return recuperarMax(this.raiz).dato; } protected NodoABB<E> recuperarMax(NodoABB<E> actual) { while (actual.der != null) actual = actual.der; return actual; }

Ejercicio 3.- Disear un mtodo que devuelva el dato que est en el nodo padre de un elemento dado. Indica el coste temporal del mtodo. Solucin:
public E padre(E x) throws ElementoNoEncontrado { if (raiz != null && raiz.dato.compareTo(x) == 0) return null; return padre(raiz, x).dato; } protected NodoABB<E> padre(NodoABB<E> n, E x) throws ElementoNoEncontrado { if (n == null) throw new ElementoNoEncontrado(x + no est); if (n.izq != null && n.izq.dato.compareTo(x)==0) return n; if (n.der != null && n.der.dato.compareTo(x)==0) return n; int resC = n.dato.compareTo(x); if (resC < 0) return padre(n.der, x); else return padre(n.izq, x); }

Talla: N = tamao del nodo n (tamao del rbol en la llamada ms alta)

Instancias significativas: Mejor caso: el padre es el nodo raz. Peor caso: el dato x no est en el rbol Ecuaciones de recurrencia: TpadreM(N) = k1 TpadreP(N = 0) = k2 P TpadreP(N > 0) = 1 * TpadreP(N/2) + k3, si el rbol est equilibrado 1 * Tpadre (N-1) + k3, para un rbol desequilibrado Coste asinttico: Tpadre(N) (1) Tpadre(N) O(log2N), si el rbol est equilibrado si el rbol est desequilibrado Tpadre(N) O(N),

Ejercicio 4.- Disea un mtodo que devuelva el nivel del nodo que contiene el dato x (se supone que no hay datos duplicados) Solucin:
public int buscarNivel(E x) throws ElementoNoEncontrado { return buscarNivel(raiz, x); } protected int buscarNivel(NodoABB<E> n, E x) throws ElementoNoEncontrado { if (n == null) throw new ElementoNoEncontrado(x + no est); int resC = n.dato.compareTo(x); if (resC < 0) return 1 + buscarNivel(n.der, x); else if (resC > 0) return 1 + buscarNivel(n.izq, x); else return 0; }

Ejercicio 5.- Si se busca el nmero 363 en un ABB que contiene nmeros del 1 al 1000 Cul de las siguientes secuencias de nodos no puede ser la secuencia de nodos examinada? a) 2, 252, 401, 398, 330, 344, 397, 363 b) 924, 220, 911, 244, 898, 258, 362, 363 c) 925, 202, 911, 240, 912, 245, 363 d) 2, 399, 387, 219, 266, 382, 381, 278, 363 e) 935, 278, 347, 621, 299, 392, 358, 363

Solucin: La c) y la e) no son posibles:

c)

925

e)

935

202 911

278 347

240 912 299

621

Error: 912 es mayor que 911

Error: 299 es menor que 347

Ejercicio 6.- Disea de forma iterativa el mtodo:


public void insertarConDuplicados(E x);

Solucin:
public void insertarConDuplicados(E x) { this.raiz = insertarConDuplicados(x, this.raiz); } protected NodoABB<E> insertarConDuplicados(E x, NodoABB<E> actual) { NodoABB<E> res = actual, padre = null, nuevo = new NodoABB<E>(x); int resC = 0; while (actual != null) { resC = actual.dato.compareTo(x); padre = actual; actual.tamanyo++; numTotalComparaciones++; if (resC > 0) actual = actual.izq; else actual = actual.der; } if (padre == null) res = nuevo; else if (resC < 0) padre.der = nuevo; else padre.izq = nuevo; numTotalComparaciones++; return res; }

Ejercicio 7.- Disea el mtodo public void actualizar(E x)de forma iterativa Solucin:
public void actualizar(E x) { this.raiz = actualizar(x, this.raiz); } protected NodoABB<E> actualizar(E x, NodoABB<E> actual) { NodoABB<E> res = actual, padre = null, nuevo = new NodoABB<E>(x); int resC = 0; while (actual != null && (resC = actual.dato.compareTo(x)) != 0) { padre = actual; actual.tamanyo++; numTotalComparaciones++; if (resC > 0) actual = actual.izq; else actual = actual.der; } if (actual != null) { // Actualizacin actual = res; while (actual != null && (resC = actual.dato.compareTo(x)) != 0) { actual.tamanyo--; numTotalComparaciones--; if (resC > 0) actual = actual.izq; else actual=actual.der; } actual.dato = x; } else { // Insercin if (padre == null) res = nuevo; else if (resC < 0) padre.der = nuevo; else padre.izq = nuevo; numTotalComparaciones++; } return res; }

Ejercicio 8.- Disea un nuevo mtodo para la clase ABB que, partiendo de un ABB vaco, inserte los datos de un vector de forma que el ABB resultante quede equilibrado. Solucin:
public void insertarEquilibrado(E v[]) { Ordenacion.quickSort(v); insertarEquilibrado(v, 0, v.length 1); } protected void insertarEquilibrado(E v[], int izq, int der) { if (izq <= der) { int med = (izq + der) / 2; raiz = insertarConDuplicados(v[med], raiz); insertarEquilibrado(v, izq, med 1); insertarEquilibrado(v, med + 1, der); } }

Ejercicio 9.- Escribir la versin iterativa del mtodo eliminar Solucin:


public void eliminar(E x) throws ElementoNoEncontrado { this.raiz = eliminar(x, this.raiz); } protected NodoABB<E> eliminar(E x, NodoABB<E> actual) throws ElementoNoEncontrado { NodoABB<E> res = actual, padre = null; int resC = 0; while (actual != null && (resC = actual.dato.compareTo(x)) != 0) { padre = actual; actual.tamanyo--; numTotalComparaciones--; if (resC > 0) actual = actual.izq; else actual = actual.der; } if (actual == null) { // Hemos de deshacer el cambio de tamanyo de los nodos de la rama actual = res; while (actual != null) { actual.tamanyo++; numTotalComparaciones++; if (actual.dato.compareTo(x) > 0) actual = actual.izq; else actual = actual.der; } throw new ElementoNoEncontrado("Al eliminar: " + x + " no est"); } actual.tamanyo--; numTotalComparaciones--; if (actual.izq != null && actual.der != null) { actual.dato = recuperarMin(actual.der).dato; actual.der = eliminarMin(actual.der); } else { NodoABB<E> aux = (actual.izq != null) ? actual.izq : actual.der; if (aux != null) numTotalComparaciones -= aux.tamanyo; if (padre == null) return aux; else if (padre.izq == actual) padre.izq = aux; else padre.der = aux; } return res; }

Ejercicio 10.- Disear un mtodo en un ABB para eliminar todos los elementos menores que uno dado. Solucin:
public void eliminarMenores(E x) { this.raiz = eliminarMenores(this.raiz, x); }

protected NodoABB<E> eliminarMenores(NodoABB<E> actual, E x) { if (actual == null) return null; NodoABB<E> res = actual; int resC = actual.dato.compareTo(x); if (resC < 0) res = eliminarMenores(actual.der, x); else if (actual.izq != null) { actual.tamanyo -= actual.izq.tamanyo; actual.izq = eliminarMenores(actual.izq, x); if (actual.izq != null) actual.tamanyo += actual.izq.tamanyo; } return res; }

Ejercicio 11.- Disea un mtodo en la clase ABB para que borre todas sus hojas. Ejemplo:

Solucin:
public void borrarHojas() { if (this.raiz != null) this.raiz = borrarHojas(this.raiz); } protected NodoABB<E> borrarHojas(NodoABB<E> actual) { if (actual.izq == null && actual.der == null) return null; if (actual.izq != null) actual.izq = borrarHojas(actual.izq); if (actual.der != null) actual.der = borrarHojas(actual.der); return actual; }

Ejercicio 12.- Disear los siguientes mtodos en la clase ABB: Obtener el nmero total de hojas del rbol Visualizar los datos de los nodos del nivel k del rbol Calcular la altura del rbol Solucin: a) Obtener el nmero total de hojas del rbol
public int numHojas() { return numHojas(this.raiz); }

protected int numHojas(NodoABB<E> n) { if (n == null) return 0; else if (n.izq == null && n.der == null) return 1; else return numHojas(n.izq) + numHojas(n.der); }

b) Visualizar los datos de los nodos del nivel k del rbol


public void verNivel(int nivel) { String res = verNivel(this.raiz, nivel); System.out.println(res); } protected String verNivel(NodoABB<E> n, int nivel) { String res; if (n == null) res = ; else { if (nivel == 0) res = n.dato.toString() + \n; else res = verNivel(n.izq, nivel1) + verNivel(n.der, nivel1); } return res; }

c) Calcular la altura del rbol


public int altura() { return altura(this.raiz); } protected int altura(NodoABB<E> actual) { if (actual == null) return -1; return 1 + Math.max(altura(actual.izq), altura(actual.der)); }

Ejercicio 13.- Disea el mtodo eMCOptimo en la clase ABB que devuelve el eMC que tendra un rbol completo del mismo tamao que el actual Solucin:
// SII !esVacio() public double eMCOptimo() { int numNodos = tamanyo(), alturaOptima = (int) Math.floor(Math.log(numNodos)/Math.log(2)), nodosPorNivel = 1, contNodos = 0, numComparaciones = 0; for (int nivel = 0; nivel < alturaOptima; nivel++) { contNodos += nodosPorNivel; numComparaciones += nodosPorNivel * (1 + nivel); nodosPorNivel *= 2; } numComparaciones += (numNodos - contNodos) * (alturaOptima + 1); return numComparaciones / (double)numNodos; }

Ejercicio 14.- Escribir la versin iterativa del mtodo toStringPreOrden. Solucin:


public String toStringPreOrdenIterativo() { if (this.raiz == null) return ; else return toStringPreOrdenIterativo(this.raiz); } protected String toStringPreOrdenIterativo(NodoABB<E> n) { Pila<NodoABB<E>> p = new ArrayPila<NodoABB<E>> (); p.apilar(n); String res = ; while (!p.esVacia()) { n = p.desapilar(); res += n.dato.toString() + \n; if (n.der != null) p.apilar(n.der); if (n.izq != null) p.apilar(n.izq); } return res; }

Ejercicio 15.- Disea la clase ABBInteger como un ABB que trabaja con datos de tipo Integer, y aade los siguientes mtodos: Un mtodo que obtenga la suma de todos los elementos que sean mayores o iguales a un valor entero dado Un mtodo que cambie el signo de todos los datos del rbol. El ABB debe seguir manteniendo la propiedad de orden. Solucin:
public class ABBInteger extends ABB<Integer> { public int sumaMayoresOIguales(int x) { return sumaMayoresOIguales(new Integer(x), this.raiz); } protected int sumaMayoresOIguales(Integer x, NodoABB<Integer> n) { if (n == null) return 0; int res = sumaMayoresOIguales(x, n.der); if (n.dato.compareTo(x) >= 0) res = n.dato.intValue() + sumaMayoresOIguales(x, n.izq); return res; } public void cambiarSigno() { this.raiz = cambiarSigno(this.raiz); } protected NodoABB<Integer> cambiarSigno(NodoABB<Integer> n) { if (n != null) { n.dato = new Integer(-n.dato.intValue()); n.izq = cambiarSigno(n.der); n.der = cambiarSigno(n.izq); } return n; } }

Ejercicio 16.- Sea un par de datos x, y que definen un intervalo no vaco [x,y]. Define una nueva funcin sobre un ABB que devuelva el nmero de elementos que no pertenecen a dicho intervalo

Solucin:
public int contarFueraRango(E x, E y) { return contarFueraRango(x, y, this.raiz); } protected int contarFueraRango(E x, E y, NodoABB<E> actual) { if (actual == null) return 0; int res = 0, resC = actual.dato.compareTo(x); if (resC < 0) { // actual < x if (actual.izq != null) res = actual.izq.tamanyo; res += contarFueraRango(x, y, actual.der); } else { // actual >= x res = contarFueraRango(x, y, actual.izq); resC = actual.dato.compareTo(y); if (resC <= 0) res += contarFueraRango(x, y, actual.der); else if (actual.der != null) res += actual.der.tamanyo; } return res; }

Ejercicio 17.- Disea un mtodo en un ABB, contarMayores(E x), que devuelva el nmero de elementos mayores que x

Solucin:
public int contarMayores(E x) { return contarMayores(x, this.raiz); } protected int contarMayores(E x, NodoABB<E> actual) { if (actual == null) return 0; int res, resC = actual.dato.compareTo(x); if (resC > 0) { // actual > x res = 1 + contarMayores(actual.izq); if (actual.der != null) res += actual.der.tamanyo; } else // actual <= x res = contarMayores(x, actual.der); return res; }

Ejercicio 18.- Disear un mtodo esMediana que compruebe si un cierto dato x dado es el elemento mediana de un ABB: x es la mediana si el nmero de elementos mayores que x en el ABB es igual al de menores que x x puede no ser un elemento del ABB y se asume que no hay elementos duplicados

Solucin:
public boolean esMediana(E x) { NodoABB<E> actual = this.raiz; int mayores = 0, menores = 0; boolean fin = false; while (actual != null && !fin) { int resC = actual.dato.compareTo(x); if (resC < 0) { menores++; if (actual.izq != null) menores += actual = actual.der; } else if (resC > 0) { mayores++; if (actual.der != null) mayores += actual = actual.izq; } else { if (actual.izq != null) menores += if (actual.der != null) mayores += fin = true; } } return (mayores == menores); }

actual.izq.tamanyo;

actual.der.tamanyo;

actual.izq.tamanyo; actual.der.tamanyo;

Ejercicio 15.- Disea en la clase ABB los mtodos para obtener el sucesor y el antecesor de un dato x dado

Solucin:

a) Clculo del sucesor:


public E sucesor(E x) throws ElementoNoEncontrado { NodoABB<E> suc = sucesor(x, this.raiz, null); if (suc == null) return null; else return suc.dato; }

protected NodoABB<E> sucesor(E x, NodoABB<E> actual, NodoABB<E> ascDer) throws ElementoNoEncontrado { if (actual == null) throw new ElementoNoEncontrado(x + no est); int resC = actual.dato.compareTo(x); if (resC == 0) { if (actual.der != null) return buscarMin(actual.der); else return ascDer; } else if (resC < 0) return sucesor(x, actual.der, ascDer); else return sucesor(x, actual.izq, actual); }

b) Clculo del antecesor El antecesor de un nodo es: el mayor de su subrbol izquierdo (si tiene) o, en caso contrario, el antecesor izquierdo ms inmediato.
public E antecesor(E x) throws ElementoNoEncontrado { NodoeABB<E> ant = antecesor(x, actual, null); if (ant == null) return null; else return ant.dato; } protected NodoABB<E> antecesor(E x, NodoABB<E> actual, NodoABB<E> ascenIzq) throws ElementoNoEncontrado { if (actual == null) throw new ElementoNoEncontrado(x + no est); int resC = actual.dato.compareTo(x); if (resC == 0) { if (actual.izq != null) return buscarMax(actual.izq); else return ascenIzq; } else if (resC < 0) return antecesor(x, actual.der, actual); else return antecesor(x, actual.izq, ascenIzq); } protected NodoABB<E> buscarMax(NodoABB<E> actual) { while (actual.der != null) actual = actual.der; return actual; }

You might also like