Professional Documents
Culture Documents
EJERCICIOS RESUELTOS
Ejercicio 2.- Disea los siguientes mtodos, tanto recursiva como iterativamente:
public E recuperarMin(); public E recuperarMax();
// 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); }
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
c)
925
e)
935
202 911
278 347
621
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 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); }
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 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:
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; }