apunte_modulos_basicos

download apunte_modulos_basicos

of 28

Transcript of apunte_modulos_basicos

  • Apunte de Mdulos Bsicos (v. 0.2)

    Algoritmos y Estructuras de Datos II, DC, UBA.

    2do cuatrimestre de 2013 (compilado 08/10/2013)

    ndice1. Introduccin 2

    2. TADs para especificar iteradores 22.1. TAD Iterador Unidireccional() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22.2. TAD Iterador Unidireccional Modificable() . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22.3. Iterador Bidireccional() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

    3. Invariantes de aliasing 4

    4. Mdulo Lista Enlazada() 5

    5. Mdulo Pila() 9

    6. Mdulo Cola() 11

    7. Mdulo Vector() 13

    8. Mdulo Diccionario Lineal(, ) 16

    9. Mdulo Conjunto Lineal() 21

    10.Mdulo Conjunto acotado de naturales 24

    1

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    1. IntroduccinEl presente documento describe varios mdulos que se pueden utilizar para realizar el TP de diseo. Adems,

    sirve como ejemplo de qu se espera del TP de diseo, y muestra algunas tcnicas que podran ser tiles a la hora dedesarrollar nuevos mdulos.

    Antes de introducir los mdulos, se especifican los tipos de iteradores que se van a utilizar. Esta especificacines auxiliar, para simplificar las precondiciones y postcondiciones de los algoritmos que utilizan iteradores. Luego, sepresentan todos los mdulos, con su interfaz, representacin y clculos de complejidad.

    NOTA: Este apunte no est terminado. Adems de ser incompleto (faltan los algoritmos y los clculosde complejidad de todos los mdulos), puede tener (mejor dicho, tiene) errores y podra sufrir cambiosen cualquier momento.

    2. TADs para especificar iteradoresEn esta seccin se describen los TADs que utilizamos en la materia para especificar los iteradores. Los mismos no

    son ms que un conjunto de funciones auxiliares que sirven para especificar las precondiciones y postcondiciones delas funciones que involucran iteradores. La forma de especificar estos iteradores es envolviendo una estructura querepresenta el concepto de ordenamiento de los valores contenidos. En este sentido, la especificacin de los iteradorescon TADs podra evitarse, pero lo incluimos para simplificar la especificacin de los mdulos.

    2.1. TAD Iterador Unidireccional()El iterador unidireccional permite recorrer los elementos una nica vez, avanzando continuamente. Es el tipo de

    iterador ms simple que se puede especificar y no permite modificar la estructura iterada. Como la idea es convertircualquier estructura en una secuencia, es razonable que este iterador tome una secuencia en la parte de especificacin.La idea final es que esta secuencia describa el orden en el que se recorrern los elementos de la estructura, i.e., estasecuencia es una permutacin de la estructura iterada.

    TAD Iterador Unidireccional()

    parmetros formalesgneros

    gneros itUni()

    igualdad observacional(it1, it2 : it()) (it1 =obs it2 (Siguientes(it1) =obs Siguientes(it2)))

    observadores bsicosSiguientes : itUni() secu()

    generadoresCrearItUni : secu() itUni()

    otras operacionesHayMas? : itUni() boolActual : itUni() it {HayMas?(it)}Avanzar : itUni() it itUni() {HayMas?(it)}

    axiomasSiguientes(CrearItUni(i)) iHayMas?(it) Vacia?(Siguientes(it))Actual(it) Prim(Siguientes(it))Avanzar(it) CrearItUni(Fin(Siguientes(it)))

    Fin TAD

    2.2. TAD Iterador Unidireccional Modificable()El iterador unidireccional modificable es una extensin del iterador unidireccional que permite realizar algunas

    operaciones de modificacin sobre los elementos de la estructura recorrida. Para poder especificar las modificaciones ala estructura iterada, se guarda la secuencia de los elementos que ya fueron recorridos. Observar que para especificar

    2/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    los efectos secundarios que tienen estas modificaciones en el tipo iterado, hay que aclarar cmo es el aliasing entre eliterador y el tipo iterado en el mdulo correspondiente.

    TAD Iterador Unidireccional Modificable()

    parmetros formalesgneros

    gneros itMod()

    igualdad observacional

    (it1, it2 : itMod())(it1 =obs it2

    (Anteriores(it1) =obs Anteriores(it2) Siguientes(it1) =obs Siguientes(it2)

    ))observadores bsicosAnteriores : itMod() secu()Siguientes : itMod() secu()

    generadoresCrearItMod : secu() secu() itMod()

    otras operacionesSecuSuby : itMod() secu()HayMas? : itMod() boolActual : itMod() it {HayMas?(it)}Avanzar : itMod() it itMod() {HayMas?(it)}Eliminar : itMod() it itMod() {HayMas?(it)}Agregar : itMod() itMod()

    axiomasAnteriores(CrearItMod(i, d)) iSiguientes(CrearItMod(i, d)) dSecuSuby(it) Anteriores(it) & Siguientes(it)HayMas?(it) Vacia?(Siguientes(it))Actual(it) Prim(Siguientes(it))Avanzar(it) CrearItMod(Anteriores(it) Actual(it), Fin(Siguientes(it)))Eliminar(it) CrearItMod(Anteriores(it), Fin(Siguientes(it)))Agregar(it, a) CrearItMod(Anteriores(it) a, Siguientes(it))

    Fin TAD

    2.3. Iterador Bidireccional()El iterador bidireccional es una generalizacin del iterador unidireccional modificable. El mismo permite recorrer los

    elementos avanzando y retrocediendo. Si bien se podra hacer una versin de iterador bidireccional no modificable, laespecificacin de ambas es similar. Cuando se utilice en un mdulo que no permita algunas modificaciones, simplementese puede omitir el diseo de las funciones que realizan estas modificaciones (ver e.g., mdulo Conjunto Lineal). Poreste motivo, optamos slo por la versin modificable.

    Para que el iterador bidireccional sea lo mas simtrico posible, cambiamos la operacin actual por dos: anterior ysiguiente. La idea conceptual es pensar que el iterador est posicionado en el medio de dos posiciones, y puede accedertanto a la anterior como a la siguiente. Obviamente, la implementacin puede diferir de esta visin conceptual.

    TAD Iterador Bidireccional()

    parmetros formalesgneros

    gneros itBi()

    igualdad observacional

    (it1, it2 : itBi())(it1 =obs it2

    (Anteriores(it1) =obs Anteriores(it2) Siguientes(it1) =obs Siguientes(it2)

    ))observadores bsicosAnteriores : itBi() secu()Siguientes : itBi() secu()

    generadores

    3/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    CrearItBi : secu() secu() itBi()otras operacionesSecuSuby : itBi() secu()HayAnterior? : itBi() boolAnterior : itBi() it {HayAnterior?(it)}Retroceder : itBi() it itBi() {HayAnterior?(it)}HaySiguiente? : itBi() boolSiguiente : itBi() it {HaySiguiente?(it)}Avanzar : itBi() it itBi() {HaySiguiente?(it)}EliminarSiguiente : itBi() it itBi() {HaySiguiente?(it)}EliminarAnterior : itBi() it itBi() {HayAnterior?(it)}AgregarComoAnterior : itBi() itBi()AgregarComoSiguiente : itBi() itBi()

    axiomasAnteriores(CrearItBi(i, d)) iSiguientes(CrearItBi(i, d)) dSecuSuby(it) Anteriores(i) & Siguientes(d)HayAnterior?(it) Vacia?(Anteriores(it))Anterior(it) Ult(Anteriores(it))Retroceder(it) CrearItBi(Com(Anteriores(it)), Anterior(it) Siguientes(it))HaySiguiente?(it) Vacia?(Siguientes(it))Siguiente(it) Prim(Siguientes(it))Avanzar(it) CrearItBi(Anteriores(it) Siguiente(it), Fin(Siguientes(it)))EliminarSiguiente(it) CrearItBi(Anteriores(it), Fin(Siguientes(it)))EliminarAnterior(it) CrearItBi(Com(Anteriores(it)), Siguientes(it))AgregarComoAnterior(it, a) CrearItBi(Anteriores(it) a, Siguientes(it))AgregarComoSiguiente(it, a) CrearItBi(Anteriores(it), a Siguientes(it))SecuSuby(it) Anteriores(it) & Siguientes(it)

    Fin TAD

    3. Invariantes de aliasingPara simplificar la descripcin del aliasing entre dos variables, vamos a definir un metapredicado. Este metapre-

    dicado, llamado alias, lo vamos a utilizar para describir aquellas variables que comparten memoria en la ejecucin delprograma. Si bien el metapredicado alias no es parte del lenguaje de TADs y no lo describimos en lgica de primerorden, lo vamos a utilizar en las precondiciones y postcondiciones de las funciones. En esta seccin vamos a describirsu semntica en castellano.

    Alias es un metapredicado con un nico parmetro que puede ser una expresin booleana del lenguaje de TADso un predicado en lgica de primer orden. Este paramtro involucrar un conjunto V con dos o ms variables delprograma. El significado es que las variables de V satisfacen durante la ejecucin del resto del programa, siemprey cuando dichas variables no sean asignadas con otro valor. En particular, el invariante puede dejar de satisfacersecuando una variable de V se indefine. Una variable se indefine, cuando el valor al que hace referencia deja de ser valido.Esto ocurre principalmente cuando se elimina un elemento que est siendo iterado.

    Por ejemplo, supongamos que s y t son dos variables de tipo . Si escribimos

    alias(s = t),

    lo que significa informalmente es que s y t comparten la misma posicin de memoria. Un poco ms rigurosamente, loque significa es que cualquier modificacin que se realice a s afecta a t y viceversa, de forma tal que s = t, mientras as y a t no se les asigne otro valor.

    El ejemplo anterior es un poco bsico. Supongamos ahora que tenemos dos variables s y c de tipos secu() yconj(), respectivamente. Si escribimos

    alias(esPermutacion(s, c)),

    estamos diciendo que s y c comparten la misma memoria de forma tal que cualquier modificacin sobre s afecta a c yviceversa, de forma tal que se satisface esPermutacion(s, c). En particular, si se agrega un elemento a a c, se obtieneque la secuencia s se modifica de forma tal que resulta una permutacin de c {a}. Notemos que, en particular, s

    4/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    podra cambiar a cualquier permutacin, salvo que se indique lo contrario. De la misma forma, si se eliminara unelemento a de s, entonces c tambien se vera afectado de forma tal que s sea una permutacin de c. En particular, cpasara a ser c \ {a}.

    Debemos observar que este invariante no es magico, sino que es una declaracin como cualquier otra, y el progra-mado debe asegurarse que este invariante se cumpla. En particular, en el ejemplo anterior, no deberiamos permitir lainsercin de elementos repetido en s, ya que dejara de ser una posible permutacin de un conjunto.

    4. Mdulo Lista Enlazada()El mdulo Lista Enlazada provee una secuencia que permite la insercin, modificacin, borrado y acceso eficiente

    del primer y ltimo elemento. En cambio, el acceso a un elemento aleatorio tiene un costo lineal. En forma concisa,este mdulo implementa lo que se conoce como una lista doblemente enlazada, con punteros al inicio y al fin.

    En cuanto al recorrido de los elementos, se provee un iterador bidireccional que permite eliminar y agregar elemen-tos. De esta forma, se pueden aplicar filtros recorriendo una nica vez la estructura. El iterador se puede inicializartanto apuntando al inicio, en cuyo caso el siguiente del iterador es el primer elemento de la lista, como apuntando alfin, en cuyo caso el anterior del iterador es el ltimo elemento de la lista. En consecuencia, se puede recorrer el reversode la lista en forma eficiente.

    Para describir la complejidad de las operaciones, vamos a llamar copy(a) al costo de copiar el elemento a (i.e.,copy es una funcin de en N).1

    Interfazparmetros formales

    gneros funcin Copiar(in a : ) res :

    Pre {true}Post {res =obs a}Complejidad: (copy(a))Descripcin: funcin de copia de s

    se explica con: Secuencia(), Iterador Bidireccional().

    gneros: lista(), itLista().

    Operaciones bsicas de lista

    Vaca() res : lista()Pre {true}Post {res =obs}Complejidad: (1)Descripcin: genera una lista vaca.

    AgregarAdelante(in/out l : lista(), in a : ) res : itLista(Pre {l =obs l0}Post {l =obs a l0 res = CrearItBi(, l) alias(SecuSuby(res) = l)}Complejidad: (copy(a))Descripcin: agrega el elemento a como primer elemento de la lista. Retorna un iterador a l, de forma tal queSiguiente devuelva a.Aliasing: el elemento a agrega por copia. El iterador se invalida si y slo si se elimina el elemento siguiente deliterador sin utilizar la funcin EliminarSiguiente.

    AgregarAtras(in/out l : lista(), in a : ) res : itLista()Pre {l =obs l0}Post {l =obs l0 a res = CrearItBi(l0, a) alias(SecuSuby(res) = l)}Complejidad: (copy(a))Descripcin: agrega el elemento a como ltimo elemento de la lista. Retorna un iterador a l, de forma tal queSiguiente devuelva a.

    1Ntese que este es un abuso de notacin, ya que no estamos describiendo copy en funcin del tamao de a. A la hora de usarlo, habrque realizar la traduccin.

    5/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    Aliasing: el elemento a se agrega por copia. El iterador se invalida si y slo si se elimina el elemento siguiente deliterador sin utilizar la funcin EliminarSiguiente.

    EsVaca?(in l : lista()) res : boolPre {true}Post {res =obs vacia?(l)}Complejidad: (1)Descripcin: devuelve true si y slo si l no contiene elementos

    Fin(in/out l : lista())Pre {l =obs l0 vaca?(l)}Post {l =obs fin(l0)}Complejidad: (1)Descripcin: elimina el primer elemento de l

    Comienzo(in/out l : lista())Pre {l =obs l0 vaca?(l)}Post {l =obs com(l0)}Complejidad: (1)Descripcin: elimina el ltimo elemento de l

    Primero(in l : lista()) res : Pre {vaca?(l)}Post {alias(res =obs prim(l))}Complejidad: (1)Descripcin: devuelve el primer elemento de la lista.Aliasing: res es modificable si y slo si l es modificable.

    Ultimo(in l : lista()) res : Pre {vaca?(l)}Post {alias(res =obs ult(l))}Complejidad: (1)Descripcin: devuelve el ltimo elemento de la lista.Aliasing: res es modificable si y slo si l es modificable.

    Longitud(in l : lista()) res : natPre {true}Post {res =obs long(l)}Complejidad: (1)Descripcin: devuelve la cantidad de elementos que tiene la lista.

    [](in l : lista(), in i : nat) res : Pre {i < long(l)}Post {alias(res =obs iesimo(l, i))}Complejidad: (i)Descripcin: devuelve el elemento que se encuentra en la i-sima posicin de la lista en base 0. Es decir, l[i]devuelve el elemento que se encuentra en la posicin i+ 1.Aliasing: res es modificable si y slo si l es modificable.

    Copiar(in l : lista()) res : lista()Pre {true}Post {res =obs l}

    Complejidad:

    (`i=1

    copy(l[i])

    ), donde ` = long(l).

    Descripcin: genera una copia nueva de la lista.

    = (in l1 : lista(), in l2 : lista()) res : boolPre {true}Post {res =obs l1 = l2}

    6/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    Complejidad:

    (`i=1

    equal(l1[i], l2[i])

    ), donde ` = mn{long(l1), long(l2)}.

    Descripcin: compara l1 y l2 por igualdad, cuando posee operacin de igualdad.Requiere: = (in a1 : , in a2 : ) res : bool

    Pre {true}Post {res =obs (a1 = a2)}Complejidad: (equal(a1, a2))Descripcin: funcin de igualdad de s

    Operaciones del iterador

    El iterador que presentamos permite modificar la lista recorrida. Sin embargo, cuando la lista es no modificable,no se pueden utilizar las funciones que la modificaran, teniendo en cuenta el aliasing existente entre el iterador y lalista iterada. Cuando la lista es modificable, vamos a decir que el iterador generado es modificable.

    CrearIt(in l : lista()) res : itLista()Pre {true}Post {res =obs crearItBi(, l) alias(SecuSuby(it) = l)}Complejidad: (1)Descripcin: crea un iterador bidireccional de la lista, de forma tal que al pedir Siguiente se obtenga el primerelemento de l.Aliasing: el iterador se invalida si y slo si se elimina el elemento siguiente del iterador sin utilizar la funcinEliminarSiguiente.

    CrearItUlt(in l : lista()) res : itLista()Pre {true}Post {res =obs crearItBi(l, ) alias(SecuSuby(it) = l)}Complejidad: (1)Descripcin: crea un iterador bidireccional de la lista, de forma tal que al pedir Anterior se obtenga el ltimoelemento de l.Aliasing: el iterador se invalida si y slo si se elimina el elemento siguiente del iterador sin utilizar la funcinEliminarSiguiente.

    HaySiguiente(in it : itLista()) res : boolPre {true}Post {res =obs haySiguiente?(it)}Complejidad: (1)Descripcin: devuelve true si y slo si en el iterador todava quedan elementos para avanzar.

    HayAnterior(in it : itLista()) res : boolPre {true}Post {res =obs hayAnterior?(it)}Complejidad: (1)Descripcin: devuelve true si y slo si en el iterador todava quedan elementos para retroceder.

    Siguiente(in it : itLista()) res : Pre {HaySiguiente?(it)}Post {alias(res =obs Siguiente(it))}Complejidad: (1)Descripcin: devuelve el elemento siguiente a la posicin del iterador.Aliasing: res es modificable si y slo si it es modificable.

    Anterior(in it : itLista()) res : Pre {HayAnterior?(it)}Post {alias(res =obs Anterior(it))}Complejidad: (1)Descripcin: devuelve el elemento anterior del iterador.Aliasing: res es modificable si y slo si it es modificable.

    Avanzar(in/out it : itLista())

    7/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    Pre {it = it0 HaySiguiente?(it)}Post {it =obs Avanzar(it0)}Complejidad: (1)Descripcin: avanza el iterador a la posicin siguiente.

    Retroceder(in/out it : itLista())Pre {it = it0 HayAnterior?(it)}Post {it =obs Retroceder(it0)}Complejidad: (1)Descripcin: retrocede el iterador a la posicin anterior.

    EliminarSiguiente(in/out it : itLista())Pre {it = it0 HaySiguiente?(it)}Post {it =obs EliminarSiguiente(it0)}Complejidad: (1)Descripcin: elimina de la lista iterada el valor que se encuentra en la posicin siguiente del iterador.

    EliminarAnterior(in/out it : itLista())Pre {it = it0 HayAnterior?(it)}Post {it =obs EliminarAnterior(it0)}Complejidad: (1)Descripcin: elimina de la lista iterada el valor que se encuentra en la posicin anterior del iterador.

    AgregarComoSiguiente(in/out it : itLista(), in a : )Pre {it = it0}Post {it =obs AgregarComoSiguiente(it0, a)}Complejidad: (copy(a))Descripcin: agrega el elemento a a la lista iterada, entre las posiciones anterior y siguiente del iterador, dejandoal iterador posicionado de forma tal que al llamar a Siguiente se obtenga a.Aliasing: el elemento a se agrega por copia.

    AgregarComoAnterior(in/out it : itLista(), in a : )Pre {it = it0}Post {it =obs AgregarComoAnterior(it0, a)}Complejidad: (copy(a))Descripcin: agrega el elemento a a la lista iterada, entre las posiciones anterior y siguiente del iterador, dejandoal iterador posicionado de forma tal que al llamar a Anterior se obtenga a.Aliasing: el elemento a se agrega por copia.

    Representacin

    Representacin de la listaEl objetivo de este mdulo es implementar una lista doblemente enlazada con punteros al principio y al fin. Para

    simplificar un poco el manejo de la estructura, vamos a reemplazarla por una lista circular, donde el siguiente delltimo apunta al primero y el anterior del primero apunta al ltimo. La estructura de representacin, su invariante derepresentacin y su funcin de abstraccin son las siguientes.

    lista() se representa con lst

    donde lst es tupla(primero: puntero(nodo), longitud : nat)donde nodo es tupla(dato: , anterior : puntero(nodo), siguiente: puntero(nodo))

    Rep : lst boolRep(l) true (l.primero = NULL) = (l.longitud = 0) L (l.longitud 6= 0 L

    Nodo(l, l.longitud) = l.primero (i: nat)(Nodo(l,i)siguiente = Nodo(l,i+ 1)anterior) (i: nat)(1 i < l.longitud Nodo(l,i) 6= l.primero)

    Nodo : lst l nat puntero(nodo) {l.primero 6= NULL}Nodo(l,i) if i = 0 then l.primero else Nodo(FinLst(l), i 1) fi

    8/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    FinLst : lst lstFinLst(l) Lst(l.primerosiguiente, l.longitud mn{l.longitud, 1})

    Lst : puntero(nodo) nat lstLst(p, n) p, n

    Abs : lst l secu() {Rep(l)}Abs(l) if l.longitud = 0 then else l.primerodato Abs(FinLst(l)) fi

    Representacin del iteradorEl iterador es simplemente un puntero al nodo siguiente. Este puntero apunta a NULL en el caso en que se lleg

    al final de la lista. Por otra parte, el nodo anterior se obtiene accediendo al nodo siguiente y retrocediendo (salvo queel nodo siguiente sea el primer nodo). Para poder modificar la lista, tambien hay que guardar una referencia a la listaque est siendo iterada. Adems, de esta forma podemos saber si el iterador apunta al primero o no.

    itLista() se representa con iter

    donde iter es tupla(siguiente: puntero(nodo), lista: puntero(lst))

    Rep : iter boolRep(it) true Rep((it.lista)) L (it.siguiente = NULL L (i: nat)(Nodo(it.lista, i) = it.siguiente)

    Abs : iter it itBi() {Rep(it)}Abs(it) =obs b: itBi() | Siguientes(b) = Abs(Sig(it.lista, it.siguiente))

    Anteriores(b) = Abs(Ant(it.lista, it.siguiente))

    Sig : puntero(lst) l puntero(nodo) p lst {Rep(l, p)}Sig(i, p) Lst(p, llongitud Pos(l, p))

    Ant : puntero(lst) l puntero(nodo) p lst {Rep(l, p)}Ant(i, p) Lst(if p = lprimero then NULL else lprimero fi, Pos(l, p))

    Nota: cuando p = NULL, Pos devuelve la longitud de la lista, lo cual est bien, porque significa que el iterador no tienesiguiente.

    Pos : lst l puntero(nodo) p puntero(nodo) {Rep(l, p)}Pos(l,p) if l.primero = p l.longitud = 0 then 0 else 1 + Pos(FinLst(l), p) fi

    Algoritmos

    5. Mdulo Pila()El mdulo Pila provee una pila en la que slo se puede acceder al tope de la misma. Por este motivo, no incluye

    iteradores.Para describir la complejidad de las operaciones, vamos a llamar copy(a) al costo de copiar el elemento a (i.e.,

    copy es una funcin de en N).2

    Interfazparmetros formales

    gneros funcin Copiar(in a : ) res :

    Pre {true}Post {res =obs a}Complejidad: (copy(a))Descripcin: funcin de copia de s

    se explica con: Pila().2Ntese que este es un abuso de notacin, ya que no estamos describiendo copy en funcin del tamao de a. A la hora de usarlo, habr

    que realizar la traduccin

    9/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    gneros: pila().

    Vaca() res : pila()Pre {}Post {res =obs vaca}Complejidad: (1)Descripcin: genera una pila vaca.

    Apilar(in/out p : pila(), in a : )Pre {p =obs p0}Post {p =obs apilar(p, a)}Complejidad: (copy(a))Descripcin: apila a en pAliasing: el elemento a se apila por copia.

    EsVacia?(in p : pila()) res : boolPre {true}Post {res =obs vacia?(p)}Complejidad: (1)Descripcin: devuelve true si y slo si la pila no contiene elementos

    Tope(in p : pila()) res : Pre {vaca?(p)}Post {alias(res =obs tope(p))}Complejidad: (1)Descripcin: devuelve el tope de la pila.Aliasing: res es modificable si y slo si p es modificable.

    Desapilar(in/out p : pila())Pre {p =obs p0 vaca?(p)}Post {p =obs desapilar(p0) res =obs tope(p)}Complejidad: (1)Descripcin: desapila el tope de p.

    Tamao(in p : pila()) res : natPre {true}Post {res =obs tamao(p)}Complejidad: (1)Descripcin: devuelve la cantidad de elementos apilados en p.

    Copiar(in p : pila()) res : pila()Pre {true}Post {res =obs p}Complejidad:

    (t

    i=1

    copy(p[i])

    )= O

    (t

    t

    maxi=1

    copy(p[i])

    ), donde t = tamao(p).

    Descripcin: genera una copia nueva de la pila

    = (in p1 : pila(), in p2 : pila()) res : boolPre {true}Post {res =obs p1 = p2}Complejidad:

    (t

    i=1

    equal(p1[i], p2[i])

    ), donde t = mn{tamao(p1), tamao(p2)}.

    Descripcin: compara p1 y p2 por igualdad, cuando posee operacin de igualdad.

    10/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    Requiere: = (in a1 : , in a2 : ) res : boolPre {true}Post {res =obs (a1 = a2)}Complejidad: (equal(a1, a2))Descripcin: funcin de igualdad de s

    Especificacin de las operaciones auxiliares utilizadas en la interfaz

    TAD Pila Extendida()

    extiende Pila()

    otras operaciones (no exportadas)[] : pila() p nat i {i < tamao(p)}

    axiomasp[i] if i = 0 then tope(p) else desapilar(p)[i 1] fi

    Fin TAD

    RepresentacinEl objetivo de este mdulo es implementar una pila lo ms eficientemente posible, y eso se puede obtener utilizando

    una lista enlazada. Claramente, cualquier lista representa una pila, donde el tope se encuentra o en el primer o en elltimo elemento. En este caso, elegimos que el tope se encuentre en el primer elemento.

    pila() se representa con lista()

    Rep : lista() boolRep(l) true

    Abs : lista() l pila() {Rep(l)}Abs(l) if vacia?(l) then vaca else apilar(prim(l), Abs(fin(l))) fi

    Algoritmos

    6. Mdulo Cola()El mdulo Cola provee una cola en la que slo se puede acceder al proximo de la misma. Por este motivo, no incluye

    iteradores.Para describir la complejidad de las operaciones, vamos a llamar copy(a) al costo de copiar el elemento a (i.e.,

    copy es una funcin de en N).3

    Interfazparmetros formales

    gneros funcin Copiar(in a : ) res :

    Pre {true}Post {res =obs a}Complejidad: (copy(a))Descripcin: funcin de copia de s

    se explica con: Cola().

    gneros: cola().

    Vaca() res : cola()Pre {true}

    3Ntese que este es un abuso de notacin, ya que no estamos describiendo copy en funcin del tamao de a. A la hora de usarlo, habrque realizar la traduccin

    11/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    Post {res =obs vaca}Complejidad: (1)Descripcin: genera una cola vaca.

    Encolar(in/out c : cola(), in a : )Pre {c =obs c0}Post {p =obs encolar(c, a)}Complejidad: (copy(a))Descripcin: encola a a cAliasing: el elemento a se encola por copia.

    EsVacia?(in c : cola()) res : boolPre {true}Post {res =obs vacia?(c)}Complejidad: (1)Descripcin: devuelve true si y slo si la cola es vaca.

    Proximo(in c : cola()) res : Pre { 6vaca?(c)}Post {alias(res =obs proximo(c))}Complejidad: (1)Descripcin: devuelve el proximo de la cola.Aliasing: res es modificable si y slo si p es modificable.

    Desencolar(in/out c : cola())Pre {c =obs c0 vaca?(c)}Post {c =obs desacolar(c0)}Complejidad: (1)Descripcin: desencola el proximo de c.

    Tamao(in c : cola()) res : natPre {true}Post {res =obs tamao(c)}Complejidad: (1)Descripcin: devuelve la cantidad de elementos encolados en c.

    Copiar(in c : cola()) res : cola()Pre {true}Post {res =obs c}Complejidad:

    (t

    i=1

    copy(c[i])

    ), donde t = tamao(c)

    Descripcin: genera una copia nueva de la cola

    = (in c1 : cola(), in c2 : cola()) res : boolPre {true}Post {res =obs c1 = c2}Complejidad:

    (t

    i=1

    equal(c1[i], c2[i])

    ), donde t = mn{tamao(c1), tamao(c2)}.

    Descripcin: compara c1 y c2 por igualdad, cuando posee operacin de igualdad.

    12/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    Requiere: = (in a1 : , in a2 : ) res : boolPre {true}Post {res =obs (a1 = a2)}Complejidad: (equal(a1, a2))Descripcin: funcin de igualdad de s

    Especificacin de las operaciones auxiliares utilizadas en la interfaz

    TAD Cola Extendida()

    extiende Cola()

    otras operaciones (no exportadas)[] : cola() p nat i {i < tamao(p)}

    axiomasc[i] if i = 0 then proximo(c) else desencolar(c)[i 1] fi

    Fin TAD

    RepresentacinEl objetivo de este mdulo es implementar una cola lo ms eficientemente posible, y eso se puede obtener utilizando

    una lista enlazada. Claramente, cualquier lista representa una cola, donde el proximo se encuentra o en el primer o enel ltimo elemento. En este caso, elegimos que el proximo se encuentre en el primer elemento.

    cola() se representa con lista()

    Rep : lista() boolRep(l) true

    Abs : lista() l cola() {Rep(l)}Abs(l) if vacia?(l) then vaca else encolar(ult(l), Abs(com(l))) fi

    Algoritmos

    7. Mdulo Vector()El mdulo Vector provee una secuencia que permite obtener el i-simo elemento de forma eficiente. La insercin

    de elementos es eficiente cuando se realiza al final de la misma, si se utiliza un anlisis amortizado (i.e., n insercionesconsecutivas cuestan O(n)), aunque puede tener un costo lineal en peor caso. La insercin en otras posiciones no estan eficiente, ya que requiere varias copias de elementos. El borrado de los ltimos elementos es eficiente, no as elborrado de los elementos intermedios.

    Una consideracin a tener en cuenta, es que el espacio utilizado por la estructura es el mximo espacio utilizadoen cualquier momento del programa. Es decir, si se realizan n inserciones seguidas de n borrados, el espacio utilizadoes O(n) por el espacio de cada . Si fuera necesario borrar esta memoria, se puede crear una copia del vector con loselementos sobrevivientes, borrando la copia vieja.

    En cuanto al recorrido de los elementos, como los mismos se pueden recorrer con un ndice, no se proveen iteradores.Para describir la complejidad de las operaciones, vamos a llamar copy(a) al costo de copiar el elemento a (i.e.,

    copy es una funcin de en N), y vamos a utilizar

    f(n) =

    {n si n = 2k para algn k1 en caso contrario

    para describir el costo de insercin de un elemento. Vale la pena notar queni=1

    f(j + i)

    n 1 cuando n , para

    todo j N. En otras palabras, la insercin consecutiva de n elementos costar O(1) copias por elemento, en trminosasintticos.

    Interfaz

    13/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    parmetros formalesgneros funcin Copiar(in a : ) res :

    Pre {true}Post {res =obs a}Complejidad: (copy(a))Descripcin: funcin de copia de s.

    se explica con: Secu().

    gneros: vector().

    Vaca() res : vector()Pre {true}Post {res =obs}Complejidad: (1)Descripcin: genera un vector vaco.

    AgregarAtras(in/out v : vector(), in a : )Pre {v =obs v0}Post {v =obs v0 a}Complejidad: (f(long(v)) + copy(a))Descripcin: agrega el elemento a como ltimo elemento del vector.Aliasing: el elemento a se agrega por copia. Cualquier referencia que se tuviera al vector queda invalidada cuandolong(v) es potencia de 2.

    EsVaco?(in v : vector()) res : boolPre {true}Post {res =obs vacia?(v)}Complejidad: (1)Descripcin: devuelve true si y slo si v esta vaco

    Comienzo(in/out v : vector())Pre {v =obs v0 vaca?(v)}Post {v =obs com(v0)}Complejidad: (1)Descripcin: elimina el ltimo elemento de v.

    TomarPrimeros(in/out v : vector(), in n : nat)Pre {v =obs v0}Post {v =obs Tomar(v0, n)}Complejidad: (1)Descripcin: elimina los ltimos max{long(v) - n, 0} elementos del vector, i.e., se queda con los primeros nelementos del vector.

    TirarUltimos(in/out v : vector(), in n : nat)Pre {v =obs v0}Post {v =obs Tomar(v0, long(v0) - n)}Complejidad: (1)Descripcin: elimina los ltimos max{long(v), n} elementos del vector.

    Ultimo(in v : vector()) res : Pre {vaca?(v)}Post {alias(res =obs ult(v))}Complejidad: (1)Descripcin: devuelve el ltimo elemento del vector.Aliasing: res es modificable si y slo si v es modificable.

    Longitud(in l : vector()) res : natPre {true}Post {res =obs long(v)}

    14/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    Complejidad: (1)Descripcin: devuelve la cantidad de elementos que contiene el vector.

    [](in v : vector(), in i : nat) res : Pre {i < long(v)}Post {alias(res =obs iesimo(v, i))}Complejidad: (1)Descripcin: devuelve el elemento que se encuentra en la i-sima posicin del vector en base 0. Es decir, v[i]devuelve el elemento que se encuentra en la posicin i+ 1.Aliasing: res es modificable si y slo si v es modificable.

    Agregar(in/out v : vector(), in i : nat, in a : )Pre {v =obs v0 i long(v)}Post {v =obs Agregar(v, i, a)}Complejidad: (f(long(v)) + long(v) i + copy(a))Descripcin: agrega el elemento a a v, de forma tal que ocupe la posicin i.Aliasing: el elemento a se agrega por copia. Cualquier referencia que se tuviera al vector queda invalidada cuandolong(v) es potencia de 2.

    Eliminar(in/out v : vector(), in i : nat)Pre {v =obs v0 i < long(v)}Post {v =obs Eliminar(v, i)}Complejidad: (long(v) i)Descripcin: elimina el elemento que ocupa la posicin i de v.

    Copiar(in v : vector()) res : vector()Pre {true}Post {res =obs v}

    Complejidad:

    (`i=1

    copy(v[i])

    ), donde ` = long(v).

    Descripcin: genera una copia nueva del vector.

    = (in v1 : vector(), in v2 : vector()) res : boolPre {true}Post {res =obs v1 = v2}

    Complejidad:

    (`i=1

    equal(v1[i], v2[i])

    ), donde ` = mn{long(v1), long(v2)}.

    Descripcin: compara v1 y v2 por igualdad, cuando posee operacin de igualdad.Requiere: = (in a1 : , in a2 : ) res : bool

    Pre {true}Post {res =obs (a1 = a2)}Complejidad: (equal(a1, a2))Descripcin: funcin de igualdad de s

    Especificacin de las operaciones auxiliares utilizadas en la interfaz

    TAD Secuencia Extendida()

    extiende Secuencia()

    otras operaciones (exportadas)Agregar : secu() s nat i a secu() {i long(s)}Eliminar : secu() s nat i secu() {i < long(s)}Tomar : secu() nat secu()

    otras operaciones (no exportadas)Tirar : secu() nat secu()

    axiomasAgregar(s, i, a) (Tomar(n, i) a) & Tirar(n, i)Eliminar(s, i, a) (Tomar(n, i 1) & Tirar(n, i)

    15/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    Tomar(s, n) if n = 0 vacia?(s) then else prim(s) Tomar(fin(s), n 1) fiTirar(s, n) if n = 0 vacia?(s) then s else Tirar(fin(s), n 1) fi

    Fin TAD

    RepresentacinLa idea de este mdulo es tener una lista donde el i-simo se puede obtener en tiempo O(1). Para esto, necesitamos

    usar algn tipo de acceso aleatorio a los elementos, que se consigue utilizando un arreglo. Ademas, necesitamos queel agregado de elementos tome O(1) copias cuando analizamos el tiempo amortizado, i.e., O(f(n)) copias. Para lograresto, podemos duplicar el tamao del arreglo cuando este se llena.

    vector() se representa con vec

    donde vec es tupla(elementos: arreglo_dimensionable de puntero(), longitud : nat)

    Rep : vec boolRep(v) true (k: nat)(tam(v.elementos) = 2k v.longitud tam(v.elementos)

    (i: nat)(0 i < v.longitud L def?(v.elementos, i)) (i, j: nat)(0 i < j < v.longitud L v.elementos[i] 6= v.elementos[j]))

    Abs : vec v secu() {Rep(v)}Abs(v) if v.longitud = 0 then

    else

    Abs(v.elementos, v.longitud 1) (v.elementos[v.longitud 1])fi

    Algoritmos

    8. Mdulo Diccionario Lineal(, )El mdulo Diccionario Lineal provee un diccionario bsico en el que se puede definir, borrar, y testear si una clave

    est definida en tiempo lineal. Cuando ya se sabe que la clave a definir no esta definida en el diccionario, la definicinse puede hacer en tiempo O(1).

    En cuanto al recorrido de los elementos, se provee un iterador bidireccional que permite recorrer y eliminar loselementos de d como si fuera una secuencia de pares , .

    Para describir la complejidad de las operaciones, vamos a llamar copy(k) al costo de copiar el elemento k y equal(k1, k2) al costo de evaluar si dos elementos k1, k2 son iguales (i.e., copy y equal son funciones de y en N, respectivamente).4

    Interfazparmetros formales

    gneros , funcin = (in k1 : , in k2 : ) res : bool

    Pre {true}Post {res =obs (k1 = k2)}Complejidad: (equal(k1, k2))Descripcin: funcin de igualdad de s

    funcin Copiar(in k : ) res : Pre {true}Post {res =obs k}Complejidad: (copy(k))Descripcin: funcin de copia de s

    funcin Copiar(in s : ) res : Pre {true}Post {res =obs s}Complejidad: (copy(s))Descripcin: funcin de copia de s

    se explica con: Diccionario(, ), Iterador Bidireccional(tupla(, )).4Ntese que este es un abuso de notacin, ya que no estamos describiendo copy y equal en funcin del tamao de k. A la hora de usarlo,

    habr que realizar la traduccin.

    16/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    gneros: dicc(, ), itDicc(, ).

    Operaciones bsicas de diccionario

    Vaco() res : dicc(, )Pre {true}Post {res =obs vacio}Complejidad: (1)Descripcin: genera un diccionario vaco.

    Definir(in/out d : dicc(, ), in k : , in s : ) res : itDicc(, )Pre {d =obs d0}Post {d=obs definir(d, k, s) haySiguiente(res) L Siguiente(res) = k, s alias(esPermutacin(SecuSuby(res),d))}

    Complejidad:

    (kK

    equal(k, k) + copy(k) + copy(s)

    ), donde K = claves(d)

    Descripcin: define la clave k con el significado s en el diccionario. Retorna un iterador al elemento recin agre-gado.Aliasing: los elementos k y s se definen por copia. El iterador se invalida si y slo si se elimina el elemento siguientedel iterador sin utilizar la funcin EliminarSiguiente. Adems, anteriores(res) y siguientes(res) podran cambiarcompletamente ante cualquier operacin que modifique el d sin utilizar las funciones del iterador.

    DefinirRapido(in/out d : dicc(, ), in k : , in s : ) res : itDicc(, )Pre {d =obs d0 definido?(d, k)}Post {d =obs definir(d, k, s) haySiguiente(res) L Siguiente(res) = k, s esPermutacin(SecuSuby(res),d)}Complejidad: (copy(k) + copy(s))Descripcin: define la clave k 6 claves(d) con el significado s en el diccionario. Retorna un iterador al elementorecin agregado.Aliasing: los elementos k y s se definen por copia. El iterador se invalida si y slo si se elimina el elemento siguientedel iterador sin utilizar la funcin EliminarSiguiente. Adems, anteriores(res) y siguientes(res) podran cambiarcompletamente ante cualquier operacin que modifique el d sin utilizar las funciones del iterador.

    Definido?(in d : dicc(, ), in k : ) res : boolPre {true}Post {res =obs def?(d, k)}Complejidad: (

    kK equal(k, k

    )), donde K = claves(d)Descripcin: devuelve true si y slo k est definido en el diccionario.

    Significado(in d : dicc(, ), in k : ) res : Pre {def?(d, k)}Post {alias(res =obs Significado(d, k))}Complejidad: (

    kK equal(k, k

    )), donde K = claves(d)Descripcin: devuelve el significado de la clave k en d.Aliasing: res es modificable si y slo si d es modificable.

    Borrar(in/out d : dicc(, ), in k : )Pre {d = d0 def?(d, k)}Post {d =obs borrar(d0, k)}Complejidad: (

    kK equal(k, k

    )), donde K = claves(d)Descripcin: elimina la clave k y su significado de d.

    #Claves(in d : dicc(, )) res : natPre {true}Post {res =obs #claves(d)}Complejidad: (1)Descripcin: devuelve la cantidad de claves del diccionario.

    Copiar(in d : dicc(, )) res : dicc(, )Pre {true}

    17/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    Post {res =obs d}Complejidad:

    (kK

    (copy(k) + copy(significado(k, d)))

    ), donde K = claves(d)

    Descripcin: genera una copia nueva del diccionario.

    = (in d1 : dicc(, ), in d2 : dicc(, )) res : boolPre {true}Post {res =obs c1 = c2}

    Complejidad: O

    k1K1k2K2

    equal(k1, s1, k2, s2)

    , donde Ki = claves(di) y si = significado(di, ki), i {1, 2}.Descripcin: compara d1 y d2 por igualdad, cuando posee operacin de igualdad.Requiere: = (in s1 : , in s2 : ) res : bool

    Pre {true}Post {res =obs (s1 = s2)}Complejidad: (equal(s1, s2))Descripcin: funcin de igualdad de s

    Operaciones del iterador

    El iterador que presentamos permite modificar el diccionario recorrido, eliminando elementos. Sin embargo, cuandoel diccionario es no modificable, no se pueden utilizar las funciones de eliminacin. Adems, las claves de los elementositerados no pueden modificarse nunca, por cuestiones de implementacin. Cuando d es modificable, decimos que it esmodificable.

    Para simplificar la notacin, vamos a utilizar clave y significado en lugar de 1 y 2 cuando utilicemos unatupla(, ).

    CrearIt(in d : dicc(, )) res : itDicc(, )Pre {true}Post {alias(esPermutacin(SecuSuby(res), d)) vacia?(Anteriores(res))}Complejidad: (1)Descripcin: crea un iterador bidireccional del diccionario, de forma tal que HayAnterior evale a false (i.e.,que se pueda recorrer los elementos aplicando iterativamente Siguiente).Aliasing: El iterador se invalida si y slo si se elimina el elemento siguiente del iterador sin utilizar la funcinEliminarSiguiente. Adems, anteriores(res) y siguientes(res) podran cambiar completamente ante cualquieroperacin que modifique d sin utilizar las funciones del iterador.

    HaySiguiente(in it : itDicc(, )) res : boolPre {true}Post {res =obs haySiguiente?(it)}Complejidad: (1)Descripcin: devuelve true si y slo si en el iterador todava quedan elementos para avanzar.

    HayAnterior(in it : itDicc(, )) res : boolPre {true}Post {res =obs hayAnterior?(it)}Complejidad: (1)Descripcin: devuelve true si y slo si en el iterador todava quedan elementos para retroceder.

    Siguiente(in it : itDicc(, )) res : tupla(, )Pre {HaySiguiente?(it)}Post {alias(res =obs Siguiente(it))}Complejidad: (1)Descripcin: devuelve el elemento siguiente del iterador.Aliasing: res.significado es modificable si y slo si it es modificable. En cambio, res.clave no es modificable.

    SiguienteClave(in it : itDicc(, )) res : Pre {HaySiguiente?(it)}

    18/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    Post {alias(res =obs Siguiente(it).clave)}Complejidad: (1)Descripcin: devuelve la clave del elemento siguiente del iterador.Aliasing: res no es modficable.

    SiguienteSignificado(in it : itDicc(, )) res : Pre {HaySiguiente?(it)}Post {alias(res =obs Siguiente(it).significado)}Complejidad: (1)Descripcin: devuelve el significado del elemento siguiente del iterador.Aliasing: res es modificable si y slo si it es modficable.

    Anterior(in it : itDicc(, )) res : tupla(clave: , significado: )Pre {HayAnterior?(it)}Post {alias(res =obs Anterior(it))}Complejidad: (1)Descripcin: devuelve el elemento anterior del iterador.Aliasing: res.significado es modificable si y slo si it es modificable. En cambio, res.clave no es modificable.

    AnteriorClave(in it : itDicc(, )) res : Pre {HayAnterior?(it)}Post {alias(res =obs Anterior(it).clave)}Complejidad: (1)Descripcin: devuelve la clave del elemento anterior del iterador.Aliasing: res no es modficable.

    AnteriorSignificado(in it : itDicc(, )) res : Pre {HayAnterior?(it)}Post {alias(res =obs Anterior(it).significado)}Complejidad: (1)Descripcin: devuelve el significado del elemento anterior del iterador.Aliasing: res es modificable si y slo si it es modficable.

    Avanzar(in/out it : itDicc(, ))Pre {it = it0 HaySiguiente?(it)}Post {it =obs Avanzar(it0)}Complejidad: (1)Descripcin: avanza a la posicin siguiente del iterador.

    Retroceder(in/out it : itDicc(, ))Pre {it = it0 HayAnterior?(it)}Post {it =obs Retroceder(it0)}Complejidad: (1)Descripcin: retrocede a la posicin anterior del iterador.

    EliminarSiguiente(in/out it : itDicc(, ))Pre {it = it0 HaySiguiente?(it)}Post {it =obs EliminarSiguiente(it0)}Complejidad: (1)Descripcin: elimina del diccionario la clave del elemento que se encuentra en la posicin siguiente.

    EliminarAnterior(in/out it : itDicc(, ))Pre {it = it0 HayAnterior?(it)}Post {it =obs EliminarAnterior(it0)}Complejidad: (1)

    19/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    Descripcin: elimina del diccionario la clave del elemento que se encuentra en la posicin anterior.

    Especificacin de las operaciones auxiliares utilizadas en la interfaz

    TAD Diccionario Extendido(, )

    extiende Conjunto(, )

    otras operaciones (no exportadas)esPermutacion? : secu(tupla(, )) dicc(, ) boolsecuADicc : secu(tupla(, )) dicc(, )

    axiomasesPermutacion?(s, d) d = secuADicc(s) #claves(d) = long(s)secuADicc(s) if vacia?(s) then vacio else definir(1(prim(s)), 2(prim(s)), secuADict(fin(s))) fi

    Fin TAD

    Representacin

    Representacin del diccionarioHay dos opciones bsicas para representar el diccionario lineal, con sus pros y sus contras. La que parece ms natural,

    es representarlo como un conjunto de tuplas sobre secuencia (ver Seccion 9). La ventaja de esta representacin es queel invariante de representacin y la funcin de abstraccin resultan un poco ms naturales. La desventaja es que, comoen un conjunto no se pueden modificar los valores, no podramos modificar el significado de una clave dada. Esto escontrario a lo que queremos. Una opcin alternativa por este camino, es definir el diccionario como un conjunto declaves y conjunto de significados, donde cada clave guarda un iterador o puntero a un significado. Esta opcin puederesultar viable, pero es un poco molesta.

    La representacin que optamos consiste en definir al diccionario como dos listas, una de claves y otra de significados.La lista de claves no puede tener repetidos, mientras que la de significados si puede. Ademas, la i-sima clave de lalista se asocia al i-simo significado. En cierto sentido, estamos definiendo al diccionario como un conjunto de clavesy una secuencia de significados. Para no repetir la representacin y el codigo del diccionario en el conjunto, vamos arepresentar al conjunto como un diccionario (ver Seccin 9). Si bien esto no parece ser una solucin natural, tampocoes tan rara, y nos permite resolver el problema reutilizando la mayora del codigo.

    dicc(, ) se representa con dic

    donde dic es tupla(claves: lista(), significados: lista()

    Rep : dic boolRep(d) true #claves(secuADicc(d.claves)) = long(d.claves) long(d.claves) = long(d.significados)

    Abs : dicc d dicc(, ) {Rep(d)}Abs(d) if vaca?(d.claves) then vaco else definir(prim(d).claves, prim(d).significado, Abs(fin(d))) fi

    Representacin del iteradorEl iterador del diccionario es simplemente un par de iteradores a las listas correspondientes. Lo nico que hay que

    pedir es que se satisfaga el Rep de este par de listas.

    itDicc(, ) se representa con itDic

    donde itDic es tupla(claves: itLista(), significados: itLista())

    Rep : itDic boolRep(it) true Rep(SecuSuby(it.claves), SecuSuby(it.significados))

    Abs : itDic it itBi(tupla(, )) {Rep(it)}Abs(it) CrearItBi(Join(Anteriores(it.claves), Anteriores(it.significados)),

    Join(Siguientes(it.claves), Siguientes(it.significados)))

    Join : secu() a secu() b secu(tupla(, )) {long(a) = long(b)}

    20/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    Join(a, b) if vacia?(a) then else prim(a), prim(b) Join(Fin(a), Fin(b)) fi

    Algoritmos

    9. Mdulo Conjunto Lineal()El mdulo Conjunto Lineal provee un conjunto bsico en el que se puede insertar, eliminar, y testear pertenencia

    en tiempo lineal (de comparaciones y/o copias). Cuando ya se sabe que el elemento a insertar no pertenece al conjunto,la insercin se puede hacer con complejidad de O(1) copias.

    En cuanto al recorrido de los elementos, se provee un iterador bidireccional que permite eliminar los elementositerados.

    Para describir la complejidad de las operaciones, vamos a llamar copy(a) al costo de copiar el elemento a yequal(a1, a2) al costo de evaluar si dos elementos a1, a2 son iguales (i.e., copy y equal son funciones de y en N, respectivamente).5

    Interfazparmetros formales

    gneros funcin = (in a1 : , in a2 : ) res : bool

    Pre {true}Post {res =obs (a1 = a2)}Complejidad: (equal(a1, a2))Descripcin: funcin de igualdad de s

    funcin Copiar(in a : ) res : Pre {true}Post {res =obs a}Complejidad: (copy(a))Descripcin: funcin de copia de s

    se explica con: Conj(), Iterador Bidireccional Modificable().

    gneros: conj(), itConj().

    Operaciones bsicas de conjunto

    Vaco() res : conj()Pre {true}Post {res =obs }Complejidad: (1)Descripcin: genera un conjunto vaco.

    Agregar(in/out c : conj(), in a : ) res : itConj()Pre {c =obs c0}Post {c =obs Ag(a, c0) HaySiguiente(res) L Siguiente(res) = a alias(esPermutacion?(SecuSuby(res), c))}Complejidad:

    (ac

    equal(a, a)

    )Descripcin: agrega el elemento a al conjunto. Para poder acceder al elemento a en O(1), se devuelve un iteradora la posicin de a dentro de c.Aliasing: el elemento a se agrega por copia. El iterador se invalida si y slo si se elimina el elemento siguiente deliterador sin utilizar la funcin EliminarSiguiente. Adems, anteriores(res) y siguientes(res) podran cambiarcompletamente ante cualquier operacin que modifique c sin utilizar las funciones del iterador.

    AgregarRapido(in/out c : conj(), in a : ) res : itConj()Pre {c =obs c0 a 6 c}Post {c =obs Ag(a, c0) HaySiguiente(res) L Siguiente(res) = a alias(esPermutacion?(SecuSuby(res), c))}Complejidad: (copy(a))Descripcin: agrega el elemento a 6 c al conjunto. Para poder acceder al elemento a en O(1), se devuelve uniterador a la posicin de a dentro de c.Aliasing: el elemento a se agrega por copia. El iterador se invalida si y slo si se elimina el elemento siguiente deliterador sin utilizar la funcin EliminarSiguiente. Adems, anteriores(res) y siguientes(res) podran cambiar

    5Ntese que este es un abuso de notacin, ya que no estamos describiendo copy y equal en funcin del tamao de a. A la hora de usarlo,habr que realizar la traduccin.

    21/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    completamente ante cualquier operacin que modifique c sin utilizar las funciones del iterador.

    EsVaco?(in c : conj()) res : boolPre {true}Post {res =obs ?(c)}Complejidad: (1)Descripcin: devuelve true si y slo si c esta vaco.

    Pertenece?(in c : conj(), in a : ) res : boolPre {true}Post {res =obs a c)}Complejidad:

    (ac

    equal(a, a)

    )Descripcin: devuelve true si y slo a pertenece al conjunto.

    Eliminar(in c : conj(), in a : )Pre {true}Post {res =obs c \ {a})}Complejidad:

    (ac

    equal(a, a)

    )Descripcin: elimina a de c, si es que estaba.

    Cardinal(in c : conj()) res : natPre {true}Post {res =obs #c)}Complejidad: (1)Descripcin: devuelve la cantidad de elementos del conjunto.

    Copiar(in c : conj()) res : conj()Pre {true}Post {res =obs c}Complejidad:

    (ac

    copy(a)

    )Descripcin: genera una copia nueva del conjunto.

    = (in c1 : conj(), in c2 : conj()) res : boolPre {true}Post {res =obs c1 = c2}Complejidad: O

    (a1c1

    a2c2

    equal(a1, a2)

    ).

    Descripcin: compara c1 y c2 por igualdad.

    Operaciones del iterador

    El iterador que presentamos permite modificar el conjunto recorrido, eliminando elementos. Sin embargo, cuandoel conjunto es no modificable, no se pueden utilizar las funciones de eliminacin. Adems, los elementos iterados nopueden modificarse, por cuestiones de implementacin.

    CrearIt(in c : conj()) res : itConj()Pre {true}Post {alias(esPermutacion?(SecuSuby(res), c)) vacia?(Anteriores(res))}Complejidad: (1)Descripcin: crea un iterador bidireccional del conjunto, de forma tal que HayAnterior evale a false (i.e.,que se pueda recorrer los elementos aplicando iterativamente Siguiente).Aliasing: El iterador se invalida si y slo si se elimina el elemento siguiente del iterador sin utilizar la funcinEliminarSiguiente. Adems, anteriores(res) y siguientes(res) podran cambiar completamente ante cualquieroperacin que modifique c sin utilizar las funciones del iterador.

    HaySiguiente(in it : itConj()) res : bool

    22/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    Pre {true}Post {res =obs haySiguiente?(it)}Complejidad: (1)Descripcin: devuelve true si y slo si en el iterador todava quedan elementos para avanzar.

    HayAnterior(in it : itConj()) res : boolPre {true}Post {res =obs hayAnterior?(it)}Complejidad: (1)Descripcin: devuelve true si y slo si en el iterador todava quedan elementos para retroceder.

    Siguiente(in it : itConj()) res : Pre {HaySiguiente?(it)}Post {alias(res =obs Siguiente(it))}Complejidad: (1)Descripcin: devuelve el elemento siguiente a la posicin del iterador.Aliasing: res no es modificable.

    Anterior(in it : itConj()) res : Pre {HayAnterior?(it)}Post {alias(res =obs Anterior(it))}Complejidad: (1)Descripcin: devuelve el elemento anterior a la posicin del iterador.Aliasing: res no es modificable.

    Avanzar(in/out it : itConj())Pre {it = it0 HaySiguiente?(it)}Post {it =obs Avanzar(it0)}Complejidad: (1)Descripcin: Avanza a la posicin siguiente del iterador.

    Retroceder(in/out it : itConj())Pre {it = it0 HayAnterior?(it)}Post {it =obs Retroceder(it0)}Complejidad: (1)Descripcin: Retrocede a la posicin anterior del iterador.

    EliminarSiguiente(in/out it : itConj())Pre {it = it0 HaySiguiente?(it)}Post {it =obs EliminarSiguiente(it0)}Complejidad: (1)Descripcin: Elimina de la lista iterada el valor que se encuentra en la posicin siguiente del iterador.

    EliminarAnterior(in/out it : itConj())Pre {it = it0 HayAnterior?(it)}Post {it =obs EliminarAnterior(it0)}Complejidad: (1)Descripcin: Elimina de la lista iterada el valor que se encuentra en la posicin anterior del iterador.

    Especificacin de las operaciones auxiliares utilizadas en la interfaz

    TAD Conjunto Extendido()

    extiende Conjunto()

    otras operaciones (no exportadas)esPermutacion? : secu() conj() boolsecuAConj : secu() conj()

    axiomasesPermutacion?(s, c) c = secuAConj(s) #c = long(s)

    23/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    secuAConj(s) if vacia?(s) then else Ag(prim(s), secuAConj(fin(s))) fiFin TAD

    Representacin

    Representacin del ConjuntoEn este mdulo vamos a utilizar un diccionario lineal para representar el conjunto. La idea es que el conjunto de

    claves del diccionario represente el conjunto lineal. Si bien esta representacin no es la ms natural, permite resolverunas cuantas cuestiones sin duplicar codigo. La desventaja aparente es que gastamos memoria para guardar datosintiles. Sin embargo, los lenguajes de programacin actuales permiten resolver este problema de forma ms o menoselegante. A nosotros no nos va a importar.

    conj() se representa con dicc(, bool)

    Rep : dicc(,bool) boolRep(d) true

    Abs : dicc(,bool) d conj() {Rep(d)}Abs(d) claves(d)

    Representacin del iteradorEl iterador del conjunto es simplemente un iterador del diccionario representante.

    itConj() se representa con itDicc(, bool)

    Rep : itDicc(, bool) boolRep(it) true

    Abs : itDicc(, bool) it itBi() {Rep(it)}Abs(it) =obs b: itBi() | Anteriores(b) = 1(Anteriores(it)) Siguientes(b) = 1(Siguientes(it))

    1 : secu(tupla(, )) secu()1(s) if vacia?(s) then else 1(prim(s)) 1(Fin(s)) fi

    Algoritmos

    10. Mdulo Conjunto acotado de naturalesEl mdulo conjunto acotado de naturales provee un conjunto en el que se pueden insertar nicamente los elementos

    que se encuentran en un rango [`, r] de naturales. La insercin, eliminacin y testeo de pertenencia de un elemento sepueden resolver en tiempo constante. El principal costo se paga cuando se crea la estructura, dado que cuesta tiempolineal en r `.

    En cuanto al recorrido de los elementos, se provee un iterador bidireccional que tambin permite eliminar loselementos iterados.

    EspecificacinTAD Conjunto acotado

    gneros conjAcotado

    igualdad observacional

    (c1, c2 : conjAcotado)(c1 =obs c2

    (Infimo(c1) =obs Infimo(c2) Supremo(c1) =obs Supremo(c2) ConjSuby(c1) =obs ConjSuby(c2)

    ))observadores bsicosInfimo : conjAcotado natSupremo : conjAcotado natConjSuby : conjAcotado conj(nat)

    generadores

    24/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    : nat ` nat r conjAcotado {` r}Ag : nat e conjAcotado c conjAcotado {Infimo(c) e Supremo(c)}

    otras operacionesRango : conjAcotado tupla(nat, nat)

    axiomasInfimo((`, r)) `Infimo(Ag(e, c)) Infimo(c)Supremo((`, r)) rSupremo(Ag(e, c)) Supremo(c)ConjSuby((`, r)) ConjSuby(Ag(e, c)) Ag(e, ConjSuby(c))Rango(c) Infimo(c), Supremo(c)

    Fin TAD

    Interfazse explica con: Conjunto acotado, Iterador Bidireccional(nat).

    gneros: conjAcotado, itConjAcotado.

    Operaciones bsicas de conjunto

    Vaco(in ` : nat, in r : nat) res : conjAcotadoPre {` r}Post {res =obs (`, r)}Complejidad: (r `)Descripcin: genera un conjunto vaco con el rango [`, r.]

    Agregar(in/out c : conjAcotado, in e : nat)Pre {c =obs c0 Infimo(c) e Supremo(c)}Post {c =obs Ag(e, c0)}Complejidad: (1)Descripcin: agrega el elemento e al conjunto.

    Infimo(in c : conjAcotado) res : natPre {true}Post {res =obs Infimo(c)}Complejidad: (1)Descripcin: devuelve el valor mnimo que se puede agregar al conjunto.

    Supremo(in c : conjAcotado) res : natPre {true}Post {res =obs Supremo(c)}Complejidad: (1)Descripcin: devuelve el valor mximo que se puede agregar al conjunto.

    EsVaco?(in c : conjAcotado) res : boolPre {true}Post {res =obs ?(ConjSuby(c))}Complejidad: (1)Descripcin: devuelve true si y slo si c esta vaco.

    Pertenece?(in c : conjAcotado, in e : nat) res : boolPre {true}Post {res =obs e ConjSuby(c)}Complejidad: (1)Descripcin: devuelve true si y slo e pertenece al conjunto. Notar que no es requerido que e pertenezca al rangode c.

    Eliminar(in/out c : conjAcotado, in e : nat)

    25/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    Pre {c = c0}Post {ConjSuby(c) =obs ConjSuby(c0) \ {e} Rango(c) =obs Rango(c0)}Complejidad: (1)Descripcin: Elimina a de c, si es que estaba. Observar que no es requerido que e pertenezca al rango de c.

    Cardinal(in c : conjAcotado) res : natPre {true}Post {res =obs #ConjSuby(c)}Complejidad: (1)Descripcin: Devuelve la cantidad de elementos del conjunto.

    Copiar(in c : conjAcotado) res : conjAcotadoPre {true}Post {res =obs c}Complejidad: (Supremo(c) - Infimo(c))Descripcin: genera una copia nueva del conjunto.

    = (in c1 : conjAcotado, in c2 : conjAcotado) res : boolPre {true}Post {res =obs c1 = c2}Complejidad: (mn{#c1,#c2}).Descripcin: compara c1 y c2 por igualdad.

    Operaciones del iterador

    El iterador que presentamos permite modificar el conjunto recorrido, eliminando elementos. Sin embargo, cuandoel conjunto es no modificable, no se pueden utilizar las funciones de eliminacin. Todos los naturales del conjunto soniterados por copia.

    CrearIt(in c : conjAcotado) res : itConjAcotadoPre {true}Post {alias(esPermutacin?(SecuSuby(res), ConjSuby(c))) vacia?(Anteriores(res))}Complejidad: (1)Descripcin: crea un iterador bidireccional del conjunto, de forma tal que HayAnterior evale a false (i.e.,que se pueda recorrer los elementos aplicando iterativamente Siguiente).Aliasing: El iterador se invalida si y slo si se elimina el elemento siguiente del iterador sin utilizar la funcinEliminarSiguiente. Adems, anteriores(res) y siguientes(res) podran cambiar completamente ante cualquieroperacin que modifique c sin utilizar las funciones del iterador.

    HaySiguiente(in it : itConjAcotado) res : boolPre {true}Post {res =obs haySiguiente?(it)}Complejidad: (1)Descripcin: devuelve true si y slo si en el iterador todava quedan elementos para avanzar.

    HayAnterior(in it : itConjAcotado) res : boolPre {true}Post {res =obs hayAnterior?(it)}Complejidad: (1)Descripcin: devuelve true si y slo si en el iterador todava quedan elementos para retroceder.

    Siguiente(in it : itConjAcotado) res : natPre {HaySiguiente?(it)}Post {res =obs Siguiente(it)}Complejidad: (1)Descripcin: devuelve el elemento siguiente a la posicin del iterador.Aliasing: res se devuelve por copia.

    Anterior(in it : itConjAcotado) res : natPre {HayAnterior?(it)}Post {res =obs Anterior(it)}

    26/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    Complejidad: (1)Descripcin: devuelve el elemento anterior a la posicin del iterador.Aliasing: res se devuelve por copia.

    Avanzar(in/out it : itConjAcotado)Pre {it = it0 HaySiguiente?(it)}Post {it =obs Avanzar(it0)}Complejidad: (1)Descripcin: Avanza a la posicin siguiente del iterador.

    Retroceder(in/out it : itConjAcotado)Pre {it = it0 HayAnterior?(it)}Post {it =obs Retroceder(it0)}Complejidad: (1)Descripcin: Retrocede a la posicin anterior del iterador.

    EliminarSiguiente(in/out it : itConjAcotado)Pre {it = it0 HaySiguiente?(it)}Post {it =obs EliminarSiguiente(it0)}Complejidad: (1)Descripcin: Elimina del conjunto el elemento que se encuentra en la posicin siguiente.

    EliminarAnterior(in/out it : itConjAcotado)Pre {it = it0 HayAnterior?(it)}Post {it =obs EliminarAnterior(it0)}Complejidad: (1)Descripcin: Elimina del conjunto el elemento que se encuentra en la posicin anterior.

    Representacin

    Representacin del ConjuntoLa idea de este mdulo es aprovechar que los elementos que se pueden llegar a agregar son naturales en un rango

    que se conoce desde el inicio, de forma tal de poder acceder a ellos en tiempo O(1). Para esto, podemos tener unarreglo a de booleanos de tamao r`+1 de forma tal que ` e r pertenezca al conjunto si y slo si a[e`] = true.El inconveniente de esta representacin es que no permite iterar todos los elementos en tiempo lineal en la cantidad deelementos del conjunto. En efecto, si el conjunto tiene un nico elemento e, igual tenemos que recorrer todo el rangor ` (que no es constante) para encontrar e. Para subsanar este inconveniente, vamos a guardar un conjunto lineal ccon los elementos que pertenecen al conjunto acotado. Para poder eliminar el elemento e, debemos poner en false elvalor de a[e `], a la vez que tenemos que eliminar a c del conjunto. Esto se puede hacer en tiempo O(1) si podemosobtener eficientemente un puntero a e dentro de c. Este puntero podra ser un iterador. Luego, en a vamos a tener,ademas del booleano, un iterador al conjunto c que nos permita acceder en O(1) a e dentro de c. Una mejora a estaestructura es eliminar el booleano de a, y considerar que e pertenece al conjunto acotado si y slo si el iterador dea[e `] tiene un elemento siguiente. Este elemento siguiente contiene a e en c.

    conjAcotado se representa con ca

    donde ca es tupla(pertenencia: arreglo_dimensionable de iterConj(nat),elementos: conj(nat), infimo: nat)

    Rep : ca boolRep(c) true (e: nat)(e c.elementos e c.infimo e < c.infimo + tam(c.pertenencia) L

    HaySiguiente?(c.pertenencia[e c.infimo])) L(e: nat)(e c.elementos L Siguiente(c.pertenencia[e c.infimo]) = e)

    Abs : ca e conjAcotado {Rep(e)}Abs(e) =obs c: conjAcotado | Infimo(c) = e.infimo Supremo(c) = e.infimo + tam(e.pertenencia) 1

    ConjSuby(c) = e.elementos

    Representacin del iteradorEl iterador del conjunto acotado es simplemente un iterador del conjunto elementos, ya que con ste recorremos

    27/28

  • Algoritmos y Estructuras de Datos II 2do cuatrimestre de 2013 (compilado 08/10/2013)

    todos los elementos, ms un puntero a la estructura del conjunto, para poder borrar al eliminar el iterador.

    itConjAcotado se representa con itCA

    donde itCA es tupla(iter : itConj(nat), conj : puntero(ca))

    Rep : itCA boolRep(it) true Rep(it.conj) EsPermutacion(SecuSuby(it.iter), it.conjelementos)

    Abs : itCA it itBi(nat) {Rep(it)}Abs(it) it.elementos

    Algoritmos

    28/28

    IntroduccinTADs para especificar iteradoresTAD Iterador Unidireccional()TAD Iterador Unidireccional Modificable()Iterador Bidireccional()

    Invariantes de aliasingMdulo Lista Enlazada()Mdulo Pila()Mdulo Cola()Mdulo Vector()Mdulo Diccionario Lineal(, )Mdulo Conjunto Lineal()Mdulo Conjunto acotado de naturales