Está en la página 1de 9

Estructuras de Datos II

(I.T. Informtica de Gestin y Sistemas)

Boletn n 2 TAD lineales: Pila, Cola y Lista

Nota. Para poder probar las soluciones que propongis a los problemas de los bloques I, III y V podis utilizar los contenedores stack, queue y list de la STL. Tambin podis implementar vuestros propios tipos a partir del material de teora.

I. Utilizacin de los TAD Pila y Cola


1. Escribe un algoritmo que indique si en una expresin matemtica los parntesis estn equilibrados, es decir, a cada parntesis abierto le corresponde uno cerrado del mismo tipo, estando bien anidados. La expresin puede contener cualquiera de los siguientes parntesis: (), [] y {}. Supn que la expresin viene dada en forma de cadena de caracteres. 2. Escribe un algoritmo que convierta una expresin en notacin infija a notacin postfija (tambin llamada notacin polaca inversa, RPN). 3. Escribe un algoritmo que evale la expresin en notacin postfija obtenida en el ejercicio anterior. 4. El lenguaje M abc mirror, es un lenguaje especial de strings formado por las letras [a,b,c,m] donde cada string es de la forma LmR, siendo L un string de uno o ms abcs, m una marca intermedia y R el inverso del string L. Escribe un algoritmo capaz de reconocer secuencias del lenguaje M.
bool CompruebaM(const string& cad) var char letra int i = 0 Pila<char> pila bool parteL = verdadero fvar inicio si cad.length() < 3 entonces // el string no tiene al menos 3 letras devuelve falso fsi

Estructuras de Datos II

Curso 2005/06

hacer letra = cad[i] si parteL entonces si (letra == 'a') (letra == 'b') (letra == 'c') entonces pila.apilar(letra) sino si (letra == 'm') entonces parteL = falso sino devuelve falso fsi sino si (pila.esVacia()) (letra == pila.cima()) entonces pila.desapilar() sino devuelve falso fsi fsi i++ mientras i < cad.length() devuelve pila.esVacia() fin

5. Escribe un algoritmo que devuelva cierto si todos los elementos de una pila son positivos, suponiendo que la pila almacena valores del tipo Integer. 6. Los datos se almacenan en la memoria de la computadora utilizando una representacin binaria. Esto significa que la representacin de los enteros en base 10 que se utiliza en los programas debe convertirse a la representacin en base 2. Uno de los algoritmos que realiza esta conversin consiste en dividir repetidamente el entero entre 2, siendo los restos de dichas divisiones los dgitos del nmero en la representacin en base 2. Escribe un algoritmo que convierta un entero positivo en base 10 a base 2 y muestre el resultado. 7. En Correos un funcionario ha cerrado una ventanilla y la gente de la cola tiene que juntarse con la gente en la cola de otra ventanilla. Esta situacin motiva la introduccin de dos nuevas operaciones para colas: void concatenar(Cola& q1, const Cola& q2) { aade q2 al final de q1 } const Cola& barajar(const Cola& q1, const Cola& q2) { mezcla los elementos de q1 con los elementos de q2, de manera que los elementos de q2 ocupen posiciones impares y los elementos de q1 ocupen las posiciones pares }

II. Implementacin del TAD Cola


8. El TAD Cola admite una implementacin eficiente mediante un tabla circular. Usa esta estructura de datos para implementar las operaciones del tipo vistas en clase.

Universidad de Huelva

Pgina 2

Estructuras de Datos II

Curso 2005/06

III. Utilizacin del TAD Lista (usa iteradores para resolver estos problemas)
9. Escribe una funcin que dadas dos listas, L1 = (x1, x2, , xn) y L2 = (y1, y2, ..., ym), obtenga una lista Z mezcla de ambas. Esto es, Z = (x1, y1, x2, y2, ..., xm, ym, xm+1, xm+2, ..., xn) si m n o Z = (x1, y1, x2, y2, ... , xn, yn, yn+1, yn+2, ..., ym) si m > n. 10. Escribe un algoritmo que, dadas dos listas ordenadas de menor a mayor, devuelva otra lista con todos los elementos de las dos listas originales y ordenada tambin de menor a mayor. 11. Escribe un algoritmo que dada una lista L devuelva otra lista R conteniendo los elementos repetidos de L. Por ejemplo, si L almacena los valores 5, 2, 7, 2, 5, 5, 1, debe construirse una lista R con los valores 5, 2. Si en L no hay elementos repetidos, R ser la lista vaca. 12. Escribe una funcin que dada una lista L devuelva otra lista I, inversa de L. 13. Escribe un algoritmo que dada una lista L y un valor devuelva dos listas, cada una de ellas conteniendo, respectivamente, los elementos de L mayores y menores al valor proporcionado. 14. Escribe una funcin que dada una lista L, mueva un elemento de posicin i, n lugares hacia delante, si es posible, o al final de L, en caso contrario.
Pseudocdigo template <typename T> void mover(Lista<T>& L, int pos, int lugares) var int i; Lista<T>::Iterador it1, it2; fvar; inicio i=1; it1 = L.ponerIterador(pos); it2 = it1; mientras i < lugares+2 it1 L.final() hacer it1.avanzar(L); i++; fmientras; L.insertar(it1, L.observar(it2)); L.eliminar(it2); fin; C++ (usando el TAD Lista proporcionado en clase) template <typename T> void mover(Lista<T>& L, int pos, int lugares) { typename Lista<T>::Iterador it1 = L.ponerIterador(pos); typename Lista<T>::Iterador it2 = it1; for (int i=1; i < lugares+2 && it1 != L.final(); i++) it1.avanzar(L); L.insertar(it1, L.observar(it2)); L.eliminar(it2); }

Universidad de Huelva

Pgina 3

Estructuras de Datos II

Curso 2005/06

C++ (usando el TAD list de la STL) template <typename T> void mover_STL(list<T>& L, int pos, int lugares) { typename list<T>::iterator it1 = L.begin(); for (int i=1; i<pos; i++) it1++; typename list<T>::iterator it2 = it1; for (int i=1; i < lugares+2 && it1 != L.end(); i++) it1++; L.insert(it1, *it2); L.erase(it2); }

15. Las listas SelfOrganizing se caracterizan porque cada uno de sus nodos contiene un campo frecuencia, que indica el nmero de veces que el nodo ha sido recuperado. Adems, la lista se mantiene en orden descendente segn el valor de este campo frecuencia. Despus de cada consulta, el nodo modifica su posicin en la lista colocndose delante de los que tienen un nmero de accesos inferior a l. Los nuevos elementos aadidos a la lista se colocan al final con frecuencia 1. Implementa la operacin de consulta observa que devuelve el elemento de la posicin i de una lista SelfOrganizing.

IV. Implementacin del TAD Lista


16. Escribe un mtodo que aada un elemento al final de una lista suponiendo las siguientes implementaciones de la misma: a) Lista lineal simplemente enlazada con referencia al primer elemento de la misma.
CLASE NODO template <typename T> class Nodo { typedef Nodo<T>* PtrNodo; public: Nodo(const T& objeto); Nodo(const T& objeto, PtrNodo psig); Nodo(const Nodo& n); const T& getObj() const; PtrNodo getSig() const; void setObj(const T& objeto); void setSig(PtrNodo psig); private: T obj; PtrNodo sig; } CLASE LISTA template <typename T> class Lista { typedef Nodo<T>* PtrNodo; public: void aadirFinal(const T& objeto); // operaciones del TAD private: PtrNodo primero; int num; }

Universidad de Huelva

Pgina 4

Estructuras de Datos II

Curso 2005/06

void aadirFinal(const T& objeto); var PtrNodo aux n; fvar; inicio n = nuevo Nodo(objeto); si esVacia() entonces primero = n; sino aux = primero; mientras aux ->getSig() NULO hacer aux = aux->getSig(); fmientras; aux->setSig(n); fsi; num++; fin;

b) Lista circular simplemente enlazada. c) Lista doblemente enlazada con referencias al primer y ltimo elemento de la misma. Define las clases que utilices en cada caso. 17. Escribe un mtodo que elimine el ltimo elemento de una lista suponiendo las siguientes implementaciones de la misma: a) Lista lineal enlazada con referencias al primer y ultimo elemento de la misma. b) Lista lineal enlazada con referencia al primer elemento de la misma y nodo cabecera. Define las clases que utilices en cada caso. 18. Dados dos elementos adyacentes (consecutivos) apuntados por p y q, intercmbialos ajustando slo los punteros y no los datos. Hazlo suponiendo las siguientes situaciones: a) Una lista enlazada de modo simple con un puntero al primer elemento. b) Una lista doblemente enlazada con un puntero al primer elemento. 19. Tenemos una coleccin de datos de alumnos que nos interesa ordenar por dos campos: Nombre y Nmero de Matrcula. La solucin escogida ha sido utilizar una lista enlazada donde cada nodo tiene dos campos de enlace: uno para ordenar ascendentemente los nodos segn su nombre y otro para ordenar descendentemente los nodos segn el nmero de matrcula del alumno. Define los tipos de datos necesarios y escribe un mtodo que inserte un nuevo elemento en la estructura. Este tipo de listas ordenadas por ms de un criterio se denominan multilistas.

Universidad de Huelva

Pgina 5

Estructuras de Datos II

Curso 2005/06

20. Supongamos la siguiente estructura para almacenamiento de una secuencia de elementos clasificados en orden ascendente. Cada elemento est enlazado con su anterior y su siguiente. Se mantiene, adems, un puntero a la posicin central de la secuencia. Qu ventajas e inconvenientes tiene esta estructura? Define los tipos de datos ms adecuados para soportar esta estructura. Implementa una operacin que permita insertar un elemento e. Las inserciones se realizan manteniendo el orden de los elementos y el apuntador al elemento central.

21. Sea la siguiente lista circular doblemente enlazada que utiliza nodo cabecera. Define los tipos de datos utilizados e implementa todas las operaciones del TAD Lista.

V. Definicin de TAD usando el TAD Lista


22. Una lista de frecuencias es un TAD que mantiene un listado alfabtico de todas las palabras que aparecen en un conjunto de textos. Por razones de eficiencia, y pensando que se va a utilizar dicho tipo para almacenar frecuencias de palabras de muchos documentos, se ha optado por utilizar varias listas pequeas ordenadas en lugar de una sola lista con todas las palabras. De esta forma, se tendr una lista ordenada de las palabras que comienzan por 'a', otra lista ordenada con las palabras que empiezan por 'b', y as sucesivamente. Por tanto, tendremos un array con ndices 'a'..'z', conteniendo cada una de estas listas. Adems, para cada palabra, necesitamos almacenar el nmero de cada uno de los documentos en los que aparece y con qu frecuencia. Implementa el TAD lista de frecuencias. 23. Se trata de desarrollar un TAD Mercado que modele el comportamiento de un mercado de trabajo simplificado, donde las personas pueden ser contratadas y despedidas por empresas. Para ello se ha pensado utilizar una lista ordenada de empresas (ascendentemente por su nombre), de manera que a cada empresa de la lista se le asocia una lista ordenada de empleados contratados (tambin, ascendentemente por su nombre).

Universidad de Huelva

Pgina 6

Estructuras de Datos II

Curso 2005/06

La informacin que interesa disponer de las empresas es su nombre, y la lista de empleados contratados. De los empleados se conoce su nombre. Se ha considerado interesante poder hacer las siguientes operaciones con el mercado: void contrata(const string& nomEmpresa, const string& nomEmpleado) throw (EmpresaInexistenteExcepcion, EmpleadoYaContratadoExcepcion) Modifica el mercado de trabajo, efectuando la contratacin de nomEmpleado como empleado de nomEmpresa. La empresa debe pertenecer al mercado de trabajo, mientras que el trabajador no debe aparecer como empleado de la misma. void despide(const string& nomEmpresa, const string& nomEmpleado) throw (EmpresaInexistenteExcepcion, EmpleadoNoContratadoExcepcion) Modifica el mercado de trabajo, efectuando el despido de nomEmpleado que es empleado de nomEmpresa. void nuevaEmpresa(const string& nomEmpresa) throw (EmpresaYaExisteExcepcion) Aade una nueva empresa al mercado de trabajo. bool esEmpleado(const string& nomEmpresa, const string& nomEmpleado) throw (EmpresaInexistenteExcepcion) Indica si nomEmpleado es empleado de nomEmpresa. bool esPluriempleado(const string& nomEmpleado) throw (EmpleadoNoContratadoExcepcion) Indica si nomEmpleado es empleado de ms de una empresa. Se pide construir una clase que, usando el TAD Lista, implemente el TAD Mercado. 24. Se desea implementar un TAD Consultorio que modele el comportamiento de un consultorio mdico. Para ello se ha pensado utilizar una lista ordenada de mdicos (ascendentemente por su nombre), de manera que a cada mdico de la lista se le asocia su cola de pacientes en espera de ser atendidos. La informacin que nos interesa de los mdicos es su nombre y la cola de pacientes en espera. De los pacientes nos interesa su nombre. Se ha considerado interesante poder hacer las siguientes operaciones con el consultorio: void nuevoMedico(const string& nomMed) throw (MedicoYaExisteExcepcion) Modifica el consultorio, aadiendo un nuevo mdico que antes no figuraba en el consultorio. void pideConsulta(const string& nomMed, const string& nomPac) throw (MedicoInexistenteExcepcion) Modifica el consultorio, haciendo que el paciente de nombre nomPac se ponga a la espera para ser atendido por el mdico nomMed. El mdico debe pertenecer al consultorio. const string& siguientePaciente(const string& nomMed) throw (MedicoInexistenteExcepcion, SinPacientesExcepcion) Devuelve el paciente a quien le toca el prximo turno para ser atendido por el mdico nomMed. ste debe pertenecer al consultorio y tener algn paciente por atender. void atiendeConsulta(const string& nomMed) throw (MedicoInexistenteExcepcion, SinPacientesExcepcion) Modifica la estructura consultorio, eliminando el paciente al que le toca turno para ser atendido por el mdico nomMed. ste debe pertenecer al consultorio y tener algn paciente por atender.

Universidad de Huelva

Pgina 7

Estructuras de Datos II

Curso 2005/06

bool tienePacientes(const string& nomMed) throw (MedicoInexistenteExcepcion) Devuelve si hay o no pacientes a la espera de ser atendidos por un mdico, el cual debe pertenecer al consultorio. Se pide construir una clase que, usando los TAD Lista y Cola, implemente el TAD Consultorio. A continuacin aparece implementada la clase Mdico y el mtodo pideConsulta de la clase Consultorio. El resto de mtodos de esta clase quedan propuestos para el alumno.
CLASE MDICO typedef string Paciente; typedef cola<Paciente> CP; class Medico{ public: Medico(const string& nombre); CP& getPacientes(); const string& getMedico() const; void setPacientes(const CP& c); void setMedico(const string& nombre); private: string nm; CP pacientes; }; Medico(const string& nombre): nm(nombre), pacientes() inicio fin; CP& getPacientes() inicio devolver pacientes; fin; const string& getMedico() const { inicio devolver nm; fin; void setPacientes(const CP& c) { inicio pacientes = c; fin; void setMedico(const string& nombre) { inicio nm = nombre; fin;

Universidad de Huelva

Pgina 8

Estructuras de Datos II

Curso 2005/06

CLASE CONSULTORIO typedef lista<Medico> LM; typedef LM::iterador ILM; class Consultorio { public: Consultorio(); void pideConsulta(const string& nomMed, const string& nomPac) throw (MedicoInexistenteExcepcion); // resto de mtodos private: LM consulta; }; void pideConsulta(const string& nomMed, const string& nomPac) throw (MedicoInexistenteExcepcion){ var ILM it; fvar; inicio it = consulta.pricipio(); mientras it consulta.fin() it->getMedico() < nomMed hacer it .avanzar(consulta); fmientras; si it == consulta.fin() it->getMedico() > nomMed entonces lanzar MedicoInexistenteExcepcion(nomMed); fsi; it->getPacientes().aadir(nomPac); fin;

Universidad de Huelva

Pgina 9