Está en la página 1de 15

Ti pos abstractos de datos (TAD) Objetivo: Introducir al alumno las estructuras de datos mediante el conce de tipo abstracto de datos.

pto En este captulo s e presenta una primera implementacion del TAD C onj unto y s e ira mejorando a lo largo del mismo incluyendo un analisis de la comple- jidad de los metodos que lo forman. 2.1 Introduccion

Un tipo de datos e s una abstraccion que determina un conjunto de valores que deben tener los datos de cierto tipo. Por ejemplo en los lenguaje s de pro- gramacion s e tienen el tipo entero, real y Booleano. A partir d e e so se puede determinar, por ejempl , que el 5 e s un numero o entero, que tr ue e s un valor Booleano, etc. Ademas, los datos tienen ciertas operaci nes y propiedades,por ejemplo sabemos que para nu o meros se tienen las operaci nes aritmeticas y para booleanos las o operacioneslogicas. Entre las propiedadesde estos datos se cuenta con que los datos forman conjuntos cerrados, por ejemplo una ope- racion entre dos Booleanos devuel un booleano. Al considerar tanto datos ve como operacioness e tiene un tipo abstracto de datos. Un tipo abstracto de datos (TAD) e s un conjunto de datos con sus ope- raciones.Se denom inan TAD porque nada en la definicion indica el como s e impleme ntan las operaciones(por cierto, puede haber ma s de una implemen- tacion), por tanto en Java para definir TAD se recom ienda usar interface s .

Para completar la descripcion de un TAD se debe proporcionar adema s de la interfaz con las operaciones que se pued en realizar, una descri ci p on de las propiedadesque deben tener tales operaciones.Un mecanismo util para describir estos aspectos no-sintacticos e s el uso de pre/post condiciones.Una pre-condicion e s aquella propiedad que debe satisfacerse antes de la ejecuci on de un metodo. Un post-condicion especifica propiedadesque se debe n esperar como consecuencia la ejecuc de ion de un metodo. Por su parte, las estructuras de datos tradicionales son mecanismosu tiles para almacenar y recuperar (en/de memoria) coleccionesde datos. En Java represe ntan una implementacion de un TAD particular. 2.2 El TAD Conjunto

Un conjunto puede verse com o un tipo de datos donde se puede almacenar cualquier cantidad de datos sin importar el orden y sin posibilidad de repeticion de valores. Las operaciones basicas con conjuntos son: almacenar un dato en el, eliminar un dato, verificar si contiene algun dato particular, determinar si el conjunto esta vaco o su tamano. Adem as podran e star las operaciones clasicas de interseccion, union y diferencia. Una forma bonita de definir un TAD e s mediante una interfaz, as que para los conjuntos se p ue de tener la siguiente: publ ic interfa ce Conj untable { publ ic void agregarEl e ment o(O bjec t ele m); publ ic void el iminarElem e n to(Obje ct el e m) ; publ ic bool ean contie neElem e o (O bjec t el em); nt publ ic bool ean est aVaco(); publ ic int tama~no() ; .. . //Operaciones clasic as con conju nt os. Quedan com o ejerc c o i i } Propied des que se esperan de un conjunto: a agregarEl e ment o. Si el elemento no existe en el conjunto lo agrega al conjunto, aunque no esta definida la posicion del nuevo elemento. Si el elemento ya s e encuentra en el conjunto se dispa una excepcion. ra En caso de ser exitosa la operacion el tamano del conjunto crece en una unidad.

cont ieneElem e n Regresatr ue si el elemento esta en el conjunto y to. false en otro caso.Este metodo no cambia el estado del conjunto. el iminarElem e n Si el elemento existe en el conjunto lo elimina, en to. caso contrario dispara la excepcion N oS uchElem e ntExceptio n. En caso de que la operacion sea exitosa se reduce el tamano del conjunto en una unidad. estaV acio. Devuel e tr ue si el conjunto esta vaco y false en v otro caso. tam a ~no. Devuel e un entero que indica la cantidad de elem e v ntos en el conjunto. La interfaz es independiente de la implementacion. A continuacion s e presenta una implementacion usando arreglos. /* * * Programa que im p lementa el tipo de datos abst racto conj unto . * @aut hor Am p a Lopez G a o ro na * @versio n A gost o 2007. * / publ ic c ass Conjunto imple ments C onju nt able { l privat e Obj ect [ datos; ] privat e int indi ceFinal ; /** C onstructo r por omis on, crea un conjunto con una capacidad maxima de i * 20 elementos * / publ ic C onj unt o() { datos = n ew O bject [20] ; indi ceFinal = 0; } /* * * Crea un arre gl o con capac dad para un conjunto de un max m o determinado i i * por el usuario o 20 en caso de proporcionar un nu mero nega vo. ti * @para m tam - entero posi t vo que determina el tam a i ~no max m o del i conjunto * /

publ ic C onj unt o(int ta m) { datos = (tam <= 0) ? ne w Obj ect [20] : n ew O bject [ a m] ; t indi ceFinal = 0; } /* * * Metodo que determina s un conjunto no tien e ele m e os. i nt * @ret urn boolean - true si el conjunto esta vaco y fals e en otro caso. * / publ ic bool ean est aVaco(){ return (indice Fi nal == 0); } /* * * Metodo que determina la cantidad de el e ment os en el conjunto * @ret urn int - can dad de el e m e os en el conjun to. ti nt * / publ ic int tama~no(){ return indi ceFinal ; } /* * * Metodo que determina s un elemento dado esta en el conjunto i * @para m el e m - O bje o a buscar t * @ret urn boolean - true si el objeto se encuentra en el conjutno y * false en otr o caso * / publ ic bool ean contie neElem e o (O bjec t el em){ nt i (!est aV aco()) f for (int i = 0; i < indice Fi nal; i++) i (el em.equal s(datos [i]) f ) return tr ue; return false; } /* * * Metodo que permite borra r un el e ment o del conjun to * @para m el e m - O bje o a el minar t i

* / publ ic void el iminarElem e n to(Obje ct el e m){ int i = 0; bool ean borrado = fa se; l w hi e (i < ind iceFina l & & ! borra do) l i (el em.equal s(datos [i]) { / recorr e los elemntos del arreglo f ) / for (int j = i; j < indice Fi nal -1; j++) datos[ j = dat os[ +1]; ] j indi ceFinal - ; borr ado = true; } el se i+ +; } /* * * Metodo que permite agregar un elem e n del conjunto, si aun no to est a * en el * @para m el e m - O bje o a insertar en el conju nto. t * / publ ic void agregarEl e ment o(O bjec t ele m){ if ( cont eneEl e ment o(ele m) & & indice Fi nal < datos.le ngt h) ! i datos[ ind iceFi nal++] = ele m; } 2.2.1 Analisis de algoritmos

En general interesa conocer que tan eficientes son los metodos programados, e s decir estimar el tiempo requerido para ejecutar cada uno. Porque no e s de- seable ejecutar un programa que tarde un ano en su ejecuci on o que requiera mas memoria de la disponible. A primera vista parece sencillo medir la efec tividad de un algoritmo en terminos de tiempo, basta que al ejecutar el program a se tome el tiempo que tarda en correr. Ya sea con un reloj en mano o bien desdeel programa. Esto no e s muy deseable porque depende de la maquina, aun del compilador, en q ue se haya ejecutado el programa. El analisis de algoritmos e s un tecnica que permite caracterizar la ejecu- cion de algoritmos de manera independiente de cualquier plataforma, com-

pilador o lenguaje. En lugar de medir el tiempo de ejecucion de un programa s e mide el del algoritmo, el cual estara programado en uno o mas metodos, as que la medida se basa e n el examendel tiempo de ejecuc ion para la invocaci on de un solo metodo. Al hacer mas rapido un metodo se pu ed e mejorar la velocidad de ejecucion de un programa entero. Generalme nte se calcula el tiempo de ejecucion en el peor caso, porque el mejor caso no aporta nada y el caso promedio refleja el comportamiento tpico. As que con el peor caso se tiene un estimado de ejecuci on con cualquier entrada posible. Si el metodo para calcular el tamano de un conjunto fuera el siguiente: for (int i = 0; i <datos ength ; i++) .l i (datos [i] == nul) f l return i; return datos ength ; .l y el conjunto tuviera 100 elem e ntos, s era necesario hacer 100 asignacionesy si cada una se reali a en un tiempo const nte c, entonces el z a metodo tarda c 100 unidades de tiempo en realizarse. Si el tamano del arreglo cambia a n, s e requiere que se hagan n asignaciones. este caso se En dice que el tiempo de ejecucion del metodo depende de la cantidad de datos de entrada, o mas formalmente que s e tiene un algoritmo de complejidad O(n) (O grande de n). En caso de que el metodo estuviera programado como sigue: publ ic int tama~no(){ return indi ceFinal ; } En este caso con una sola instruccion se pued e determinar el tamano del conjunto. Este algoritmo es mucho mejor que el anterior, porque no depende de la cantidad de datos de entrada, por lo tanto toma un tiempo constante en su ejecucion, as que se dice que es de orden O(1). En el analisis de la complejidad de un algoritmo no s e incluyen constantes, e s decir, no se d ice O(2n2 ) ni O(n2 + n), en ambos casos la forma correcta e s O(n2 ). Por ejemplo, si se d e se a bajar un archivo de n Kbytes que e sta en Internet. Si s e tarda 3 segundosen estab lecer la conexi on, luego la ca rga se realiza a 1.5 Kb/seg, el tiempo requerido se desc ribe como T (n) = n/ 1,5 + 3, por tanto s e tiene una funcion lineal. Si n = 1500 entonces T(n) = 1003 y

T(750) = 503, que es casi la mitad. Luego si s e duplica el tiempo de inicio s e tiene que T(1500) = 1006 y T(750) = 506, es decir sigue siendo casi la mitad sin importar la constante, por tanto s e ignoran las constantes. Funciones comunes Las funciones mas comunes para rango de crecimiento son: Funcion c log n log2 n nn n log n n2 n n n3 nd , d > 3 2n n! nombre Constante Logartmica Log-cuadratica Raz cuadrada Lineal

Cuadratica Cubica Polinomial Exponencial Factorial

Ejercicio: Cual e s el tiempo de ejecucion de una funcion de cada uno de los grados, si s e tiene n = 105 datos de entrada, y se realizan 106 Respuesta: Funcion log n n n log n n2 n3 2n Nombre Tiempo de ejecucion Logartmica 1.2 *105 se g Lineal 0.1 se g 1.2 se g Cuadratica 2.8 horas Cubica 31.7 anos Exponencial mas de un siglo

Que analizar? Si s e tiene el siguiente metodo para calcular la suma de los primeros n nu me- ros al cubo y s e d e s e acalcular su complejidad.

publ ic static int suma;

int su manC ub os(int n) {

su m a = 0; for (int i=1; i < n; i++) su m a += i*i*i; return sum a ; } El tiempo requerido para resolver las declaraci ones no cuenta, las asignaciones toman una unidad de tiempo, el cuerpo del for toma cuatro (dos multiplicaciones, una suma y una asignacion) por n veces que se ejecuta da un total de 4n unidades. El encabezado del for toma una unidad para la inicializacion, n + 1 para las comp araciones y n para el increme nto, lo cual da un total de 2n + 2. Sumado todo nos da un total de 6n + 4, e s decir se tiene un metodo que orden O(n) o se a lineal. Para evitar hacer e so s calculos tan detallados s e tienen las siguientes regl generales: as 1. Asignaciones, declaraciones. Para efec tos de calculos se asum e que todas las operaciones sobre tipos primitivos, las asignaciones, las s e- cuenciasde asign aciones toman un tiempo constante. 2. Proposiciones consecuti vas. Se suman. 3. Condicionales. S e toma el tiempo de la condicion mas el mayor de las dos alternativas. i (a > 0) { f sum a += a; datos++; else a*= (-1 ); 4. Ciclos. El tiempo de ejecuc ion de un ciclo es el tiempo de ejecucion de su cuerpo por el numero de veces que se realiz El caso mas a. sencillo es cuando estan fijos los valores de entrada y de salida y el cuerpo toma un tiempo constante. Ejemplo: for (int i=0; i < n; i++) i (valo es[i] < mn m o f r i ) mni m o = valo es[ ] r i ;

Este ciclo se realiza n ve ce sy el cuerpo toma un tiempo cons tante cada vez, por tanto el tiempo de ejecuci on de este ciclo e s O(n). Cual e s el tiempo de ejecucion del siguiente ciclo? publ ic bool ean esPrimo (int n) { for (int i=2; i*i <= n; i++) i (0 == n %i) ret urn fals e; f return tr ue; }

Aqu el ciclo se hace m ientras la i se a menor o igual a la raz cuadrada de n, e s decir el numero maximo de iteraci ones es n, del ciclo toma un tiempo constante, se tiene que el algoritmo e s O( n). Recordem os estasmedidasrepresentan la ejecucion en el peor caso. que 5. Ciclos anidados. El tiempo de ejecucion de una proposicion dentro de un grupo de ciclos anidados es el tiempo de ejecucion de la propo- sicion multiplicado por el producto de los tamanos de todos los ciclos. Ejemplo: for (int i = 0; i <n ; i++) for (int j=0; j < n ; j++) k++; Este algoritmo es de orden n2 , porque cada ciclo se reali a n ve cesy el z cuer o es de orden uno. p for (int i = 0; i <n ; i++) for (int j=0; j < n ; j++) { c[ i]j ] = 0; [ for (int k=0; k < n ; k++) c[ i [ ] += a ] ]j [i][k * b[ k j ; ][ ] } El tiempo de ejecuci on de este ciclo e s O(n3 ). Cuando los lmites de las iteraciones e stan relacion ados con los ndice s externos, el analisis s e vuelve mas complejo.

for (int i = n-1; i > 0; i--) for (int j = 0; j < i; j++) i (v[ j > v +1]) { f ] [j double tem p = v[ j ; ] v[ j = v[ j+1 ] ]; v[j+1] = temp; } Para determinar el tiempo de ejecucion de e ste algoritmo notamos que la iteracion interna s e realiza n 1 ve ces , la segunda n 2 veces,etc. As el ciclo interno se realiza (n 1) + (n 2) + .. + 1 = ((n 1)n)/2 = (n2 n)/2 por tanto el algoritmo e s O(n2 ). 6. Llamadas a metodos. El tiempo s e calcula como el necesario para realizar tal metodo. publ ic void imprimePrimos(int n) { for (int i =2; i <=n; i++) i (esPri m o i) ) f ( Syst e m.out p nt ln("v al or "+ i + "es pr m o ) ; . ri i ." el se Syst e m.out p nt ln("v al or "+ i + "no es primo." ) . ri ; } El metodo esPrimo tiene un tiempo de ejecucion O( n) (como se vio antes) por tanto imprimePrimo e s de orden O(n n) Cuando se suma complejidad algortmica, el valor mayor e s el que predo- mina y se co nser p ara el resultado. Por ejemplo O(n2 )+O(n) = va O(n2 +n) = O(n2 ). La tabla e s la que da las prioridades. 2.2.2 Iteradores

Es tarea comun, recorrer una colecci on o estructura de datos para obtener todos los elementos de ella, ya se a para imprimirlos o bien realizar una ope- racion sobre todos ellos (por ejemplo, incrementar el salario de todos los em plead dar de alta un conjunto de alumnos en un curso os, particular, etc.) Para ello se usa, en general,un for.

for (int i = 0; i < miArre gl o. tama~no(); i++) { O bject v = miArr eglo obtenerEl e m e o(i ) . nt ; .. . } Solo que esta forma no e s generica pues depende de obtenerEl e ment o y de que se sabe que en la implementacion s e utiliza un arreglo. Otra forma de hacerlo es impleme ntando la interfaz I erat or del paquete t java.utl presentada a continuacion: i publ ic interfa ce Iter at or { publ ic bool ean hasNext( ; ) publ ic O bject next () throws N oSuchElementExcept ion ; publ ic void rem o ve() throws I leg al StateExcept on, l i N oS uchElem e ntExceptio n; } As que normalmente las clases que implementan o tienen colecciones incluyen un metodo que devuel un conjunto de elem e ve ntos de una clase que implementa la interfaz I erador. El objeto cliente no t requiere conocer la organizacion de los datos. En gener l, se define com o a una claseinterna, como s e vera en el siguiente ejemplo. impor java.u i .* ; t t l publ ic c ass Conjunto imple ments C onju nt able { l / Mism a estruct ura y metodos que antes mas los metodos / siguie nt es: publ ic I erator el e m e os () { t nt return ne w dat osIndexados() ; } privat e class datosIndexados imple ment s I erator { t privat e int pos = 0; //Posic on inicial i publ ic datosIn dexados(){} Constr uctor por o mision publ ic bool ean hasN ext() { // D etermi na si aun hay el e m e os nt en return (pos < nElems); / el conjun to /

2.3. ARREGLOS EXPANDIB LES }

12

publ ic O bject next () throws N oSuchElementExcept ion { i (hasNext ()) f / Devuel ve el siguie nt e ele m e / nto en el conju nt o return datos[p os++] ; throw ne w NoS uchEl e m e Except on() nt i ; } publ ic void rem o ve() throws I leg al StateExcept on l i , N oS uchElem e ntExceptio n { throw ne w NoS uchEl e m e Except on() nt i ; } } publ ic static void m a in( Str ing xx) { [] .. . Syst e m.out p nt ln("Voy a imprimi r ") ; . ri : for ( ter at or i = c.el e m e os( ; I t nt ) it.h asN ext () ) Syst e m.out p nt ((In eger) ; . ri t it next() + " . " ); } Definir una clase dentro de otra permite establecer que hay una estrecha relacion entre ambas clases. Una clase interna tiene acceso, sin calificativo, a todos los metodos y estructura del objeto que la encierra (aun los priva- dos). Se recom ienda que la clase interna se a muy sencill . La clase externa proporciona la mayora de la a funcionalidad y la interna, solo funcionalidad asociada a la externa pero subordinada a ella. 2.3 Arreglos expandibles

El arreglo es la unica estructura de datos que proporciona Java. La ventaja de los arreg los es que toma el mismo tiempo acceder a cualquier elemento de el, sin embargo no pueden crecer, es costoso insertar o suprimir elemen- tos de una coleccion almacenada en un arreglo sin dejar huecos. Es decir, aunque son sum ame utiles no son nte apropiados para todos los problemasde almacenamie de datos. nto

2.3. ARREGLOS EXPANDIB LES inter ace Arre gl oExpandib e { f l publ ic bool ean est aVac o i () publ ic int tama~no ( ; ; ) publ ic void agregarEl e ment o(O bjec t val , int pos) ; publ ic O bject obtenerEl e m e o(in pos); nt t publ ic void el iminarElem e n to(int pos); publ ic void ree mpl azarElemento(Object v, int pos); publ ic void aj ustarTam a ~no(int nuevoT a m a~no) ; }

13

La forma de trabajar de los objetos de la clase que implemente la interfaz ArregloExpandible e s la siguiente: estaV acio. Devuel e tr ue si el arreglo no tiene eleme v ntos y false en otro caso. tam a ~no. Devuel e un entero que indica la cantidad de elem e v ntos alma- cenad en el arreglo. os agregarEl e ment o. Agrega un elemento al arreglo en la posicion indica- da (esta debe tener un valor menor o igual al tamano del arreglo). Para insertar un elemento, se h a c e un espacio en el arreglo recorriendo los elementos hacia le final del arreglo. Si el arreglo esta lleno, s e aumenta su capacidad. El tamano del arreglo se incrementa en una unidad. Notar que en este arreglo se tienen dos concept tam a os, ~no que es la can- tidad de elementos en el y capac dad que es la cantidad de i localidades que contiene fsicame el arreglo. Este ultimo dato lo nte descon ce el usuario. o

(datos.length) datos Figura 2.1: Arr eglo expandible

2.3. ARREGLOS EXPANDIB LES

14

obtenerEl e ment o. Devuel e el elemento almacenadoen la posicion v in- dicada, siemprey cu an do se a esta se a valida. Si la posicion e s inv alida s e dispara la excepcion ArrayI ndexOutOfBoundsExcept on. i Este metodo no cambia el estado del objeto. el iminarElem e n Elimina el elemento almacen to. ado en la posicion in- dicada, siempre y cuando sea esta se a valida. Si la posicion e s invalida se dispara la excepcion ArrayI ndexOutOfBoundsExcept on. En caso de que la operacion i sea exitosa se reduce el tamano del arreglo en una unidad. ree mpl azarElemento. Sustituye el eleme nto almacen ado en la posici on indicada por el elemento indicado. Si la posicion e s invalida dispara la excepcion. ArrayI ndexOutOfBoundsExcept on. El m i etodo no cambia el tamano del arreglo. aj ustarTam a ~no. Aumenta la capacidad del arreglo en el numero de unidades indicado. Este metodo no altera la cantidad de elementos almacenadosen el arreglo.

También podría gustarte