Estructuras de Datos 53 Capítulo 5. LISTAS. 5.1 Listas y listas vinculadas. Una lista es una colección lineal de elementos. Las listas pueden ser almacenadas en arreglos (¿de qué manera?), pero las listas enlazadas proporcionan varias ventajas. #define NUM_NODES 100 struct nodeType{ int info; int next; }; strcuct nodeType nodes[NUM_NODES]; Ricardo Ruiz Rodríguez Estructuras de Datos 54 Una lista enlazada es una colección lineal de estructuras auto referenciadas (nodos), conectadas por enlaces de apuntador. Se tiene acceso a una lista enlazada vía un apuntador al primer nodo de la lista. Se puede tener acceso a los nodos subsecuentes vía el apuntador de enlace almacenado en cada nodo. Por regla convencional, para marcar el fin de la lista, el apuntador de enlace en el último nodo de la lista se define a NULL. Una lista enlazada es apropiada cuando no es predecible de inmediato o antemano, el número de elementos de datos a representarse o almacenar en la estructura. Ricardo Ruiz Rodríguez Estructuras de Datos 55 Las listas enlazadas son dinámicas, por lo que conforme sea necesario puede aumentar o disminuir la longitud de una lista. Las listas enlazadas pueden mantenerse en orden, insertando cada elemento nuevo en el punto apropiado dentro de la lista. Normalmente, los nodos de las listas enlazadas no están almacenados en forma contigua en la memoria; sin embargo, lógicamente los nodos aparecen como contiguos. 5.2 Inserción y eliminación de nodos de una lista. Los nodos pueden ser insertados en cualquier parte de la lista, se pueden insertar al principio o al final o en medio de la lista, el Ricardo Ruiz Rodríguez Estructuras de Datos 56 mecanismo de inserción estará en función directa de las necesidades particulares de la implementación de la lista. Si se desea mantener una lista ordenada de elementos por ejemplo, se deberá ir recorriendo la lista de manera secuencial hasta encontrar el lugar apropiado para su inserción. La eliminación de un nodo particular consiste primero en localizar dicho nodo dentro de la lista, si el nodo existe entonces se procede a su eliminación, si no existe debería indicar que el elemento que se está intentando eliminar no existe dentro de la lista. Ricardo Ruiz Rodríguez Estructuras de Datos 57 5.3 Simulación. Una de las aplicaciones más útiles de las colas, las colas de prioridad y de las listas vinculadas es la simulación. Un programa de simulación intenta modelar una situación del mundo real para aprender algo de ella. Cada objeto y acción del mundo tiene su contraparte en el programa. Si la simulación es precisa, el resultado del programa reflejará el resultado de las acciones que se simulan, por lo que será posible comprender lo que ocurre en una situación del mundo real sin realmente observar su ocurrencia. Ricardo Ruiz Rodríguez Estructuras de Datos 58 Ejemplos en los que es posible aplicar la simulación utilizando las estructuras de datos anteriormente mencionadas: • Bancos. • Líneas aéreas. • Casetas de cobro de autopistas. • Terminal de autobuses. 5.4 Listas circulares. Algunos de los problemas que se tienen con una lista simplemente ligada son: Ricardo Ruiz Rodríguez Estructuras de Datos 59 • Dado un apuntador ptr para un nodo en una lista lineal, no se puede llegar a ninguno de los nodos que preceden a ptr. • Si se recorre la lista, el apuntador externo a la lista debe preservarse para que se pueda hacer referencia a la lista otra vez. Suponga que se hace un pequeño cambio a la estructura de una lista lineal: • El campo next en el último nodo contenga un apuntador de regreso al primer nodo y no un apuntador nulo. Ricardo Ruiz Rodríguez Estructuras de Datos 60 Al tipo de lista que adopta este cambio se le denomina lista circular. Ilustración 1. Lista Circular. En una lista circular es posible llegar a cualquier otro punto de ella partiendo de un nodo determinado. Ricardo Ruiz Rodríguez Estructuras de Datos 61 Debe observarse que una lista circular no tiene un “primer” o “último” nodo natural, por lo que se debe establecer un primer y último nodo por convención. Otra convención útil, es permitir que el apuntador externo a la lista circular apunte al último nodo y permitir que el siguiente nodo sea el primero de la lista, tal y como lo muestra la Ilustración 1. También se establece la convención de que un apuntador nulo representa una lista circular vacía. Ejercicio: ¿Cuáles son las consideraciones necesarias para que una lista circular funcione? ¿Cómo es que deben hacerse las Ricardo Ruiz Rodríguez Estructuras de Datos 62 inserciones? ¿Cómo deben hacerse las eliminaciones? ¿Cuáles serían las funciones primitivas? ¿Qué otras operaciones se podrían definir? 5.4.1 El problema de Josephus. El siguiente problema clásico, puede ser solucionado utilizando listas circulares: Un grupo de soldados se encuentran rodeados por una abrumadora fuerza enemiga. No hay esperanza de victoria sin refuerzos, pero sólo hay un caballo disponible para escapar. Los soldados hacen un pacto de sangre para determinar cuál de ellos va Ricardo Ruiz Rodríguez Estructuras de Datos 63 a escapar y pedir ayuda. Para ello, forman un círculo y van eligiendo un número de un sombrero. También se elige uno de sus nombres de otro sombrero. Iniciando con el soldado cuyo nombre se eligió, se empieza a contar en el sentido de las manecillas del reloj alrededor del círculo. Cuando la cuenta llega a n, este soldado se retira del círculo y la cuenta vuelve a empezar con el soldado siguiente. El proceso continúa análogamente hasta que sólo quede un soldado, el cuál será el que va a tomar el caballo y escapar. Ricardo Ruiz Rodríguez Estructuras de Datos 64 En resumen el problema es, dado un número n, el ordenamiento de los soldados en el círculo, y el soldado a partir del que comienza la cuenta, determinar: • El orden en el cual se eliminan los soldados del círculo. • Cuál soldado escapa. Ejercicio: Utilice una implementación de una lista circular para resolver el problema de Josephus. 5.5 Listas doblemente enlazadas. Aunque una lista circular tiene ventajas sobre una lista lineal, todavía tiene algunas desventajas: Ricardo Ruiz Rodríguez Estructuras de Datos 65 • No es posible recorrer la lista hacia atrás. • No es posible eliminar un nodo, dado un apuntador para este nodo (¿Por qué?). Una estructura de datos conveniente para subsanar estas desventajas es precisamente una lista doblemente enlazada. En una lista doblemente enlazada, cada nodo tiene dos apuntadores: uno a su “sucesor” y el otro a su “antecesor”. Las listas doblemente enlazadas pueden ser lineales o circulares. Ricardo Ruiz Rodríguez Estructuras de Datos 66 En su esquema más simple, una lista doblemente enlazada tiene tres campos. Ejercicio: Defina los lineamientos principales que utilizaría, para definir una implementación de una lista doblemente enlazada. Ejercicio: ¿Cuáles son las consideraciones necesarias para que una lista doblemente enlazada funcione? ¿Cómo es que deben hacerse las inserciones? ¿Cómo deben hacerse las eliminaciones? ¿Cuáles serían las funciones primitivas? ¿Qué otras operaciones se podrían definir? ¿Qué cambios habría que realizar para una lista doblemente enlazada circular? Ricardo Ruiz Rodríguez