HelpFeedback
Algoritmos y estructuras datos
Centro de información
Tabla de contenido
Prefacio
Capítulo de muestra
Resumen


Centro de estudiante
Algoritmos y estructuras de datos: Una perspectiva en C

Luis Joyanes Aguilar
Ignacio Zahonero Martínez

ISBN: 844814077x
Copyright year: 2004

Prefacio



Dos de las disciplinas clásicas en todas las carreras relacionadas con la Informática y las Ciencias de la Computación son Estructuras de datos y Algoritmos o bien una sola disciplina, si ambas se estudian integradas, Algoritmos y estructuras de datos. El estudio de estructuras de datos y de algoritmos es tan antiguo como el nacimiento de la programación y se ha convertido en estudio obligatorio en todos los currículos desde finales de los años setenta y sobre todo en la década de los setenta cuando apareció el lenguaje Pascal de la mano del profesor Niklaus Wirtz, y posteriormente en la década de los ochenta con la aparición de su obra —ya clásica— Algorithms and Data Structures, en 1986.

¿Por qué C y no C++/Java o Visual Basic/C#? Muchas facultades y escuelas de Ingeniería, así como institutos tecnológicos, comienzan sus cursos de estructuras de datos con el soporte de C y muchas otras con el soporte de C++ o Java, fundamentalmente; de hecho, en nuestra propia universidad, algunas asignaturas relacionadas con esta disciplina se aprende a diseñar y construir estructuras de datos utilizando C++ o Java. ¿Existe una solución ideal? Evidentemente, consideramos que no y cada una de ellas tiene sus ventajas, y es decisión del profesor, quien debe elegir aquella que considera más recomendable para sus alumnos teniendo en cuenta el entorno y contexto donde se desarrolla su labor, al ser él quien llevará la dirección y responsabilidad de la formación de sus alumnos y pensará en su mejor futuro y encuadre dentro del currículo específico de su carrera.

Sin embargo, hay muchas razones por las cuales pensamos que C es más apropiado que C++ o Java, para la introducción y formación a nivel medio, incluso avanzado, en estructuras de datos, siempre que se recurra al paradigma estructurado, con soporte en tipos abstractos de datos y no al puro enfoque orientado a objetos, en cuyo caso C++ o Java tienen, sin duda, todas las ventajas y sería necesario utilizar uno u otro lenguaje, y también como antes el profesor tendría siempre la última palabra. Una de estas razones es evidente y se deduce del propio nombre de los lenguajes. C++ es un C más, es decir, un C más amplio y potente que se construyó para manejar complejidad a gran escala. Iguales razones, incluso aumentadas, se puede decir de Java, al ser un lenguaje más moderno, con mejores funcionalidades, orientada a la programación en Web, etc.

El primer problema que se suele presentar al estudiante de estructura de datos que, probablemente, procederá de un curso a nivel básico, medio o avanzado de introducción o fundamentos de programación o bien de iniciación de algoritmos, es precisamente el modo de afrontar información compleja desde el principio. Aunque es verdad que C++ (1) tiene muchas ventajas sobre C, muchas de estas ventajas no se hacen evidentes hasta que un programa se «vuelve» o «hace» más complejo y, si me apuran, más complejo. En este caso el paradigma orientado a objetos es una herramienta de programación y organizativa muy poderosa, con grandes ventajas para la enseñanza y posterior tarea profesional.

Por otra parte, la mayoría de los estudiantes de informática, ciencias de la computación, ingeniería de sistemas o de telecomunicaciones, requieren conocer bien el flujo C-C++ y viceversa. Por consiguiente, parece más natural enseñar primero las estructuras de datos en C y una vez conocidas y mejor dominadas las técnicas de diseño y construcción de estructuras de datos en C, y cuando se tenga constancia de que el alumno dispone de conocimientos, al menos, básicos de POO, entonces intentar pasar a C++ o Java.Por otra parte, aunque a primera vista por su enfoque orientado a objetos, C++ podría ser más interesante, en el caso del análisis y diseño de algoritmos y estructuras de datos esta propiedad añade una complejidad inherente, ya que pensamos la idea conceptual de algoritmo encaja mejor en el paradigma estructurado, aunque luego la implementación en clases y objetos, puede darle una nueva potencialidad. Pensando en esta transición, es la razón por la cual se ha incluido un capítulo dedicado a conceptos teórico-prácticos de orientación a objetos. En cualquier caso, el curso está soportando la comprensión del tipo abstracto de datos (TAD) de modo que, aunque, se enseñan las estructuras de datos bajo la metodología estructurada, el estilo de programación empleado en el texto se basa en el estudio de tipos abstractos de datos como base para la formación en orientación a objetos.

Además de estas ventajas, existen otras, que si bien se pueden considerar menores, no por ello son menos importantes ni dejan de tener gran incidencia en la formación en esta materia. Por ejemplo, algunas de las funciones de Entrada/Salida (tan importantes en programación) son más fáciles en C++ que en C (véase el caso de números enteros); otros tipos de datos tales como cadenas y números reales se pueden formatear más fácilmente en C. Otro factor importante para los principiantes es el conjunto de mensajes de error y advertencias proporcionadas por un compilador durante el desarrollo del programa.

Este libro no es un libro clásico de programación (2) sino más bien la continuación natural de estos estudios introductorios. Se estudian estructuras de datos con un objetivo fundamental: aprender a escribir programas más eficientes. También cabe aquí hacerse la pregunta de por qué se necesitan programas más eficientes cuando las nuevas computadoras son más rápidas cada año (en el momento de escribir este prólogo, las frecuencias de trabajo de las computadoras personales domésticas son de 3 GHz o superiores, y las memorias centrales de 512MB, son prácticamente usuales en la mayoría de las PC y, claro está, son el nivel de partida en profesionales). La razón tal vez resida en el hecho de que nuestras metas no se amplían a medida que se aumentan las características de las computadoras. La potencia de cálculo y las capacidades de almacenamiento aumentan la eficacia y ello conlleva un aumento de los resultados de las máquinas y de los programas desarrollados para ellas.

La búsqueda de la eficiencia de un programa no debe chocar con un buen diseño y una codificación clara y legible. La creación de programas eficientes tienen poco que ver con «trucos de programación», sino al contrario se basan en una buena organización de la información y buenos algoritmos. Un programador que no domine los principios básicos de diseños claros y limpios probablemente no escribirá programas eficientes. A la inversas, programas claros requieren organizaciones de datos claras y algoritmos claros, precisos y transparentes.

La mayoría de los departamentos informáticos reconocen que las destrezas de buena programación requieren un fuerte énfasis en los principios básicos de ingeniería de software. Por consiguiente, una vez que un programador ha aprendido los principios para diseñar e implementar programas claros y precisos, el paso siguiente es estudiar los efectos de las organizaciones de datos y los algoritmos en la eficiencia de un programa.

El enfoque del libro
En esta obra se muestran muchas técnicas de representación de datos. El contexto las mismas se engloba en los siguientes principios:

• 1. Cada estructura de datos tiene sus costes y sus beneficios. Los programadores y diseñadores necesitan una comprensión rigurosa y completa de cómo evaluar los costes y beneficios para adaptarse los nuevos retos que afronta la construcción de la aplicación. Estas propiedades requieren un conocimiento o comprensión de los principios del análisis de algoritmos y también una consideración práctica de los efectos significativos del medio físico empleado (p. ej., datos almacenados en un disco frente a memoria principal).
• 2. Los temas relativos a costes y beneficios se consideran dentro del concepto de elemento de compensación. Por ejemplo, es bastante frecuente reducir los requisitos de tiempo en beneficio de un incremento de requisitos de espacio en memoria o viceversa.
• 3. Los programadores no deben reinventar la rueda continuamente. Por consiguiente, los estudiantes necesitan aprender las estructuras de datos utilizadas junto con los algoritmos correspondientes.
• 4. Los datos estructurados siguen a las necesidades. Los estudiantes deben aprender a evaluar primero las necesidades de la aplicación, a continuación, encontrar una estructura de datos en correspondencia con sus funcionalidades.

Esta edición, fundamentalmente, describe estructuras de datos, métodos de organización de grandes cantidades de datos y algoritmos junto con el análisis de los mismos, en esencia estimación del tiempo de ejecución de algoritmos. A medida que las computadoras se vuelven más y más rápidas, la necesidad de programas que puedan manejar grandes cantidades de entradas se vuelve más crítica y su eficiencia aumenta a medida que estos programas puedan manipular más y mejores organizaciones de datos. Analizando un algoritmo antes de que se codifique realmente, los estudiantes pueden decidir si una determinada solución será factible y rigurosa. Por ejemplo, se pueden ver cómo diseños e implementaciones cuidadas pueden reducir los costes en tiempo y memoria de algoritmos. Por esta razón, se dedican dos capítulos, en exclusiva a tratar los conceptos fundamentales de análisis de algoritmos, y en un gran número de algoritmos se incluyen explicaciones de tiempos de ejecución para poder medir la complejidad y eficiencia de los mismos.

El método didáctico que sigue nuestro libro ya lo hemos seguido en otras obras nuestras y busca preferentemente enseñar al lector a pensar en la resolución de un problema siguiendo un determinado método ya conocido o bien creado por el propio lector; una vez esbozado el método, se estudia el algoritmo correspondiente junto con las etapas que pueden resolver el problema. A continuación se escribe el algoritmo, en ocasiones en pseudocódigo, que al ser en español facilitará el aprendizaje al lector, y en la mayoría de las veces en lenguaje C; para que el lector pueda verificar su programa antes de introducirlo en la computadora, se incluyen a veces la salida en pantalla resultante de la ejecución correspondiente en la máquina.

Uno de los objetivos fundamentales del libro es enseñar al estudiante, simultáneamente, buenas reglas de programación y análisis de algoritmos de modo que puedan desarrollar los programas con la mayor eficiencia posible.

El libro como texto de referencia universitaria y profesional
El estudio de Algoritmos y de Estructuras de datos son disciplinas académicas que se incorporan a todos los planes de estudios universitarios de Ingeniería e Ingeniería Técnica en Informática, Ingeniería de Sistemas Computacionales y Licenciaturas en Informática, así como a los planes de estudio de Informática en Formación Profesional y en institutos politécnicos. Suele considerarse también a estas disciplinas como ampliaciones de las asignaturas de Programación, en cualquiera de sus niveles.

En el caso de España, los actuales planes de estudios y los futuros, contemplados en la Declaración de Bolonia, de Ingeniería Técnica en Informática e Ingeniería Informática, contemplan materias troncales relativas tanto a Algoritmos como a Estructuras de datos. Igual sucede en los países iberoamericanos, donde también es común incluir estas disciplinas en los currículos de carreras de Ingeniería de Sistemas y Licenciaturas en Informática. ACM, la organización profesional norteamericana más prestigiosa del mundo, incluye en las recomendaciones de sus diferentes currículos de carreras relacionadas con informática el estudio de materias de algoritmos y estructuras de datos. En el conocido Computing Curricula de 1992 se incluyen descriptores recomendados de Programación y Estructura de Datos, y en el último currículo publicado, Computing Curricula 2001, se incluyen en el área PF de Fundamentos de Programación (Programming Fundamentals, PF1 a PF4), AL de Algoritmos y Complejidad (Algorithms and Complexity, AL1 a AL3). En este libro se ha incluido los descriptores más importantes tales como Algoritmos y Resolución de Problemas, Estructuras de datos fundamentales, Recursión, Análisis de algoritmos básicos y estrategias de algoritmos. Además se incluyen un estudio de algoritmos de estructuras discretas tan importantes como Árboles y Grafos.

Organización del libro
Este libro, pese a su amplitud, está concebido como libro de texto y no como una enciclopedia o libro de consulta, aunque dado el carácter didáctico que hemos pretendido y por nuestra experiencia en este campo, podría servir para estas últimas tareas pero una vez terminado el aprendizaje y formación básica en estructuras de datos, objetivo fundamental de la obra, bien en cursos avanzados o bien en la actividad profesional de programación.

Se pretende enseñar los principios requeridos para seleccionar o diseñar las estructuras de datos que ayudarán a resolver mejor los problemas que no a memorizar una gran cantidad de implementaciones. Por consiguiente, hemos diseñado esta obra como un libro de texto, para cursos reglados o pensando en autodidactas que ya tienen formación básica de programación, y por ello contempla la mayoría de los algoritmos y estructuras de datos más notables y sobresalientes, a la par que los más utilizados. Los lectores deben tener conocimientos a nivel de iniciación o nivel medio en programación. Es deseable haber cursado al menos un curso de un semestre de introducción a los algoritmos y a la programación, con ayuda de alguna herramienta de programación, preferentemente pseudocódigo; y se sacará el mayor rendimiento si además se tiene conocimiento de un lenguaje estructurado tal como Pascal o C. De cualquier forma y pensando en los lectores que puedan tener conocimientos básicos de estas materias, se incluyen los anexos, una guía de sintaxis de un lenguaje algorítmico (UPSAM 2.0) basado en pseudocódigo, junto con una guía de sintaxis del lenguaje C y una guía de palabras reservadas en C/C++, de modo que pueda servir al lector para consulta o como referencia.

El libro contiene gran número de ejercicios y problemas resueltos, implementados en pseudocódigo (lenguaje algorítmico en «español» de sintaxis similar a C) aunque en su gran mayoría todos están posteriormente implementados en lenguaje C. Normalmente los programas contienen una o varias líneas de comentarios que pretenden ayudar al entendimiento y seguimiento de los mismos.

La estructura de cada capítulo contiene una lista de palabras clave (reservadas) relativas al tema central del capítulo, una propuesta de ejercicios junto con la otra propuesta de problemas. La diferencia, en general, reside en el nivel de complejidad de la cuestión propuesta a resolver. Se pretende que el lector practique y adquiera destrezas en el diseño y programación de algoritmos y estructuras de datos preferentemente implementando problemas correspondientes a situaciones reales dadas.

El libro está pensado para un curso completo anual o bien dos semestres y una carga lectiva de 4/6 horas semanales, incluyendo teoría, prácticas en cuaderno y en computadora con compiladores en C. Se ha estructurado el contenido en cuatro partes para facilitar al profesor/maestro la selección que considere más oportuna y a los alumnos/lectores tener disponibles los algoritmos y estructuras de datos básicos y avanzados más empleados en el mundo de la programación y en el de base de datos e ingeniería de software. La estructuración del libro permite al lector seguir cualquier capítulo una vez que ha leído y comprendido los cuatro primeros capítulos, siempre que disponga de una formación básica en programación y en C. Caso de no tener estos conocimientos o bien desea refrescar los que ya tiene, le recomendamos comience leyendo los Apéndices A y B, donde incluimos unos cursos básicos a modo de guía de sintaxis tanto del lenguaje algorítmico UPSAM 2.0 como de C y palabras reservadas en C.

Contenido
El contenido del libro sigue los programas clásicos de las disciplinas Estructura de Datos y/o Estructuras de Datos y de la Información respetando las directrices emanadas de los currículos de 1991 y las actualizadas del 2001 de ACM/IEEE, así como de los planes de estudio de Ingeniero Informático e Ingenieros Técnicos en Informática de España y los de Ingenieros de Sistemas y Licenciados en Informática de muchas universidades latinoamericanas.

La Parte I: Análisis de algoritmos y estructuras de datos básicas describe el importante concepto de análisis de un algoritmo y las diferentes formas de medir su complejidad y eficiencia; así mismo se describen las estructuras de datos más simples tales como arrays, cadenas o estructuras. La Parte II: Diseño de algoritmos (recursividad, ordenación y búsqueda) examina los algoritmos más utilizados en la construcción de cualquier programa tales como los relativos a búsqueda y ordenación, así como las potentes técnicas de manipulación de la recursividad. La Parte III: Estructuras de datos lineales (abstracción de datos, listas, pilas, colas y tablas hash) constituyen una de las partes avanzadas del libro y que suele formar parte de cursos de nivel medio/alto en organización de datos. Por último, la Parte IV: Estructuras de datos avanzadas (árboles y grafos) constituyen también una de las partes avanzadas del libro; su conocimiento y manipulación permitirán al programador obtener el máximo aprovechamiento en el diseño y construcción de sus programas. La descripción más detallada de los capítulos correspondientes se reseñan a continuación.

Capítulo 1. Algoritmos, estructuras de datos y programas. Los tipos de datos y necesidad de su organización en estructuras de datos es la parte central de este capítulo. El tratamiento de la abstracción de datos, junto con el reforzamiento de los conceptos de algoritmos y programas, y su herramienta de representación más característica, el pseudocódigo, completan el capítulo.

Capítulo 2. Análisis de algoritmos. La medida de la eficiencia de un algoritmo es, sin duda, una de las características fundamentales en cualquier programa. El tiempo de ejecución y los resultados dependerán de que esta medida sea rigurosa y fiable. El estudio de la notación O-grande junto con el primer análisis de algoritmos básicos de ordenación y búsqueda forman este capítulo tan importante para la realización de programas.

Capítulo 3. Arrays (listas y tablas) en C. La estructura de datos básica más empleada en programación es el array (arreglo en Latinoamérica). Una revisión completa de este tipo de datos, clasificación, manipulación y utilización, se describen en el capítulo.

Capítulo 4. Estructuras y uniones. El lenguaje C tiene otras dos estructuras de datos básicas: las uniones y las estructuras. El concepto, acceso a los datos almacenados en ellas y los diferentes tipos de estructuras y uniones conforman el capítulo. También se considera el tipo enumeración, tipos definidos por el usuario typedef y los campos de bits como elementos característicos de ayuda a buenos diseños de programas.

Capítulo 5. Recursividad. Una de las propiedades más importantes en el tratamiento de problemas, especialmente matemáticos y científicos, es la recursividad. Muchas situaciones y problemas de la vida diaria tienen naturaleza recursiva. Su concepto, tratamiento y algoritmos de resolución son una necesidad vital en la formación de un programador. Se consideran en el capítulo los algoritmos más conocidos para resolver problemas de naturaleza recursiva. Entre ellos se destacan: las Torres de Hanoi, Backtraking, Salto del Caballo, las Ocho Reinas o el Problema de la Selección Óptima. Se analizan en detalle los algoritmos y sus correspondientes codificaciones en C. En algún caso se utilizan conceptos que se explicarán con más detalles en los capítulos de grafos y árboles, pero se han utilizado en este capítulo para guardar consistencia con el título de este capítulo y que todos los conceptos importantes se describieran juntos, aunque en algún caso pueden ser necesarios conceptos de otros capítulos, que por otra parte se señalan explícitamente.

Capítulo 6. Algoritmos de ordenación y búsqueda. La ordenación y la búsqueda, como ya se ha comentado anteriormente, son dos de las operaciones más frecuentemente utilizadas en programación. Los algoritmos más reconocidos y más eficientes se analizan y describen con detalle en este capítulo. Así, por ejemplo, se describen e implementan en C, algoritmos de ordenación tan populares como Burbuja, Selección, Inserción, Shell, QuickSort junto con otros más avanzados y no tan populares como MergeSort, RadixSort o BinSort. También se describen los métodos de búsqueda lineal o secuencial y binaria, junto con la búsqueda binaria recursiva.

Capítulo 7. Algoritmos de ordenación de archivos. Los archivos (ficheros) son una de las estructuras de datos más utilizadas en problemas de gestión de la información. Una revisión del tipo de dato y los métodos más usuales de procesamiento de datos situados en archivos externos (discos, cintas, etc.) constituyen este importante capítulo.

Capítulo 8. Tipos abstractos de datos y objetos. El concepto de tipo abstracto de dato como origen del concepto de objeto, base fundamental de la programación moderna, se examina en el capítulo. Además se analizan los conceptos de objetos, reutilización de software y una comparación entre el método tradicional de programación (estructurado) y el método moderno de programación (objetos). La implementación de tipos abstractos de datos en C se explica también en este capítulo.

Capítulo 9. Listas, listas enlazadas. Los conceptos de lista y de lista enlazada son vitales en un diseño avanzado de programas, debido fundamentalmente, a la inmensa cantidad de organizaciones y estructuras de la vida diaria que tienen o se asemejan al concepto de lista. Las operaciones y algoritmos básicos para manipulación de listas se analizan con detalle. Las listas doblemente enlazadas y circulares son variantes de las listas enlazadas, también, muy empleadas en el importante campo de la programación.

Capítulo 10. Pilas y sus aplicaciones. La pila es una estructura de datos simple y cuyo concepto forma parte, en un elevado porcentaje, de la vida diaria de las personas y organizaciones. El TAD Pila se puede implementar con arrays o con punteros, y el Capítulo 10 describe ambos algoritmos y sus correspondientes implementaciones en C.

Capítulo 11. Colas. Al igual que las pilas, las colas conforman otra estructura que abunda en la vida ordinaria. La implementación del TAD Cola se puede hacer con arrays, listas enlazadas e incluso listas circulares.

Capítulo 12. Colas de prioridades y montículos. Un tipo especial de cola, la cola de prioridades, utilizado en situaciones especiales, para resolución de problemas, junto con el concepto de montículo (heap, en inglés) se analizan detalladamente, junto con un método de ordenación por montículos muy eficientes, sobre todo en situaciones complejas y difíciles.

Capítulo 13. Tablas de dispersión, funciones hash. Las tablas aleatorias hash junto con los problemas de resolución de colisiones y los diferentes tipos de direccionamiento conforman este capítulo.

Capítulo 14. Árboles. Árboles binarios, árboles ordenados. Los árboles son, sin duda, una de las estructuras de datos no lineales, más empleadas en informática, tanto para resolver problemas de hardware como de software. Los árboles de directorios son una de las organizaciones más empleada por cualquier usuario o programador de una computadora. En el capítulo se describen los tipos de árboles más sobresalientes tales como los generales, binarios o binarios de búsqueda.

Capítulo 15. Árboles equilibrados de búsqueda. Un tipo especial de árbol de búsqueda, no por ello menos importante, es el árbol equilibrado de búsqueda. Su eficiencia y las operaciones que se realizan sobre el mismo se describen en detalle junto con sus algoritmos y sus implementaciones en C.

Capítulo 16. Árboles B. Este tipo de árbol responde a la necesidad de representar diferentes tipos de organizaciones que no responden bien a una implementación eficiente. Su definición, representación, creación recorrido y eliminación de claves, junto con las implementaciones respectivas constituyen la base de este capítulo.

Capítulo 17. Grafos I: representación y operaciones. Los grafos son una de las herramientas más empleadas en matemáticas, estadística, investigación operativa y en numerosos campos científicos. El estudio de la teoría de grafos se realiza fundamentalmente como elemento de Matemática discreta o Matemática aplicada. El conocimiento profundo de la teoría de grafos junto con los algoritmos de implementación es fundamental para conseguir el mayor rendimiento de las operaciones con datos, sobre todo si éstos son complejos en su organización. Un programador de alto nivel no puede dejar de conocer en toda su profundidad la teoría de grafos y sus operaciones.

Capítulo 18. Grafos II: algoritmos. Si el campo de los grafos en general, es una necesidad vital en la matemática, en la ingeniería, la toma de decisiones, etc., sus aplicaciones son numerosísimas y complejas. Por estas razones se requiere conocer las aplicaciones estándar más eficientes. Por ello se tratan en este capítulo problemas tales como: ordenación topológica, caminos más cortos, flujos de fluidos, etc., o algoritmos clásicos como Prim, Kruskal o Warshall.

Apéndice A. Lenguaje algorítmico UPSAM 2.0. El estudio de algoritmos y su implementación práctica es usual se realice con un lenguaje algorítmico basado en pseudocódigo. En nuestro caso se describe la guía de sintaxis UPSAM 2.0 (3), es una versión de lenguaje algorítmico cuyo lenguaje de implementación es el pseudocódigo en español. Este lenguaje y su correspondiente compilador ha sido construido en el Departamento de Lenguajes y Sistemas Informáticos e Ingeniería de Software de la Facultad de Informática de la Universidad Pontificia de Salamanca. Sus primeras versiones se publicaron en la segunda mitad de los años ochenta y la versión tratada en esta obra se publicó el año 2003.

Apéndice B. Guía de sintaxis C. Descripción de los elementos básicos, tipos de datos, sentencias, funciones, estructuras de datos básicos, etc., se incluyen en este apéndice. Esta guía busca facilitar el aprendizaje de la programación del lector no iniciado en C y proporcionar reglas y recordatorios de sintaxis para los lectores ya iniciados que les ayude en su tarea de aprendizaje y formación.

Apéndice C. Palabras reservadas de C y C++. El buen uso de la sintaxis de las palabras clave (reservadas) de C es vital en el aprendizaje de la programación y posteriormente en el diseño y construcción de algoritmos y programas.

Código C disponible
Los códigos en C de todos los programas importantes de este libro están disponibles en la Web (Internet) —en formato Word para que puedan ser utilizados directamente y evitar su «tecleado» en el caso de los programas largos, o bien simplemente, para seleccionar, recortar, modificar, etc., por el lector a su conveniencia, a medida que avanza en su formación—. Estos códigos fuente se encuentran en la página oficial del libro http://www.mhe.es/joyanes

AGRADECIMIENTOS
Muchos profesores y colegas españoles y latinoamericanos nos han alentado a escribir esta obra, continuación/complemento de nuestra antigua y todavía disponible en librería Estructura de datos, cuyo enfoque era en el clásico lenguaje Pascal. A todos ellos queremos mostrarles nuestro agradecimiento y como siempre brindarles nuestra colaboración si así lo desean.

En particular, deseamos agradecer como en otras ocasiones a todos nuestro/as colegas —y sin embargo amigo/as— de nuestro departamento, Lenguajes y Sistemas Informáticos e Ingeniería de Software de la Facultad y Escuela Universitaria de Informática de la Universidad Pontificia de Salamanca en el campus de Madrid, la colaboración que siempre nos prestan en la realización de nuestros libros. A todos ellos y en particular a nuestros colegas de las asignaturas de las áreas de Programación y Estructuras de Datos nuestro reconocimiento y agradecimiento.

A los muchos instructores, maestros y profesores anónimos de universidades e institutos tecnológicos y politécnicos de Latinoamérica que siempre apoyan nuestras obras y a los que desgraciadamente no podemos agradecer individualmente; al menos que conste en este humilde homenaje, nuestro eterno agradecimiento y reconocimiento por ese cariño que siempre prestan a nuestros obras. Como saben aquellos que nos conocen siempre estamos a su disposición en la medida que, físicamente, nos es posible. Gracias a todos, esta obra es posible, en un porcentaje muy alto, por vuestra ayuda y colaboración.

Y como no, a los estudiantes, a los lectores autodidactas y no autodidactas, que siguen nuestras obras. Su apoyo es un gran acicate para seguir nuestra obra. También gracias, queridos lectores. Pero si importantes son en esta obra, nuestros colegas y lectores españoles y latinoamericanos, no podemos dejar de citar al equipo humano que desde la editorial siempre cuida nuestras obras y sobre todo nos dan consejos, sugerencias, propuestas, nos «soportan» nuestros retrasos, nuestros «cambios» en la redacción, etc. A Concepción Fernández (Concha), coordinadora editorial de McGraw-Hill, nuestra gran amiga y editora desde «ha muchos años», a Amelia Nieta de McGraw- Hill, que en esta edición me ha asesorado y aconsejado en todo momento. Simplemente, gracias.

Madrid, febrero de 2004

(1) Véase otras obras del autor, publicadas también enMcGraw-Hill, tales como Programación en C++ o Programación en Java 2.
(2) Los lectores interesados en este nivel tienen a su disposición numerosos y excelentes obras, algunas de las cuales podrá consultar en el apéndice final de bibliografía. En nuestro caso, puede consultar, si lo desea, nuestra obra Fundamentos de programación, 3.a edición (McGraw-Hill, 2003).
(3) La guía de sintaxis fue creada por el profesor Joyanes, pero las últimas versiones han sido obra de un equipo que el citado profesor ha coordinado. Entre los autores de esta guía, además de los autores de este libro se pueden destacar nombres de profesores tales como Luis Rodríguez y Matilde Fernández y muchos otros que han colaborado tales como Víctor Martín, Joaquín Abeger, Antonio Muñoz, etc. (en Fundamentos de programación, 3.a ed. McGraw-Hill, 2003) se enumeran todos los profesores que han contribuido a la creación del lenguaje. En lo relativo al compilador, la profesora María Luisa Díez Plata y el profesor Enrique Torres Fernández del mismo departamento y facultad, lideran el equipo de trabajo que han desarrollado el compilador UPSAM 2.0 utilizado en prácticas de programación y de procesadores de lenguajes.
Algoritmos y estructuras de datos

Para obtener un acceso de instructor a este OLC, pregunte a su representante local. Si usted está pensando en adoptar este libro, solicite una copia de evaluación.