Estructuras de datos Estructuras de datos Derivadas del modelo de listas nacieron otras estructuras que intentan solucionar algunas de las deficiencias de las listas simples. El primero de ellos son las listas doblemente ligadas. NULL NULL Ing. Ing.Jorge JorgeA. A.Hernández HernándezP.: P.:Otras Otrasestructuras estructuraslineales lineales Estructuras de datos typedef struct doble{ ELEMENTO x; struct doble *siguiente; struct doble *anterior; }DOBLE; Como puede verse el precio de una mayor versatilidad se paga con mayor espacio en memoria para almacenar el apuntador extra. Ing. Ing.Jorge JorgeA. A.Hernández HernándezP.: P.:Otras Otrasestructuras estructuraslineales lineales La implementación de este tipo de listas es similar a la de listas con apuntadores y para realizarlas cada nodo debe tener un campo extra para un apuntador hacia el nodo anterior ademas del nodo siguiente. La ventaja es una mayor libertad de desplazamiento por la lista, y además facilita la implementación de algunos algoritmos. Ing. Ing.Jorge JorgeA. A.Hernández HernándezP.: P.:Otras Otrasestructuras estructuraslineales lineales Estructuras de datos Otro tipo de lista derivada de las listas simples lo son las listas circulares. Este tipo de listas son utiles para algunos algoritmos que requieren el formar ciclos. Cuando las colas se realizan con arreglos es muy común realizarlos con una lista circular en donde se usa la aritmetica modular (de residuos para unir el final de la lista con el inicio). Ing. Ing.Jorge JorgeA. A.Hernández HernándezP.: P.:Otras Otrasestructuras estructuraslineales lineales 1 Estructuras de datos Es decir, si usamos la siguiente identidad: ( a + b) mod a = b, siempre que b < a. De esta forma es posible unir la última posición del arreglo con la primera teniendo lo siguiente (TAM + final) mod TAM = final de esta forma final formará un ciclo de valores que va de 0 a TAM – 1. Todavía es posible usar la formula de nuevo final como final = (final + 1) % TAM, cuidando que nunca se cumpla que inicio = final, excepto cuando la lista esta vacía. Ing. Ing.Jorge JorgeA. A.Hernández HernándezP.: P.:Otras Otrasestructuras estructuraslineales lineales Estructuras de datos Las listas circulares también pueden realizarse con apuntadores uniendo el extremo final de la lista con el inicio. Y desde luego que esto también puede realizarse de manera trivial con listas doblemente enlazadas. Ing. Ing.Jorge JorgeA. A.Hernández HernándezP.: P.:Otras Otrasestructuras estructuraslineales lineales Estructuras de datos Desde luego que la aritmética modular no es el único problema a la hora de implementar listas circulares con arreglos. El otro problema es el de detectar listas llenas y vacías. En las más de las ocasiones no queda de otra más que llevar cuenta del numero de elementos incluidos en la lista además de guardar la posición de inicio y finalización de la lista. Ing. Ing.Jorge JorgeA. A.Hernández HernándezP.: P.:Otras Otrasestructuras estructuraslineales lineales Estructuras de datos Un uso interesante de las listas circulares lo representa el manejo de numeros grandes. El máximo entero con signo que podemos representar con C es 2,147,483,647. Este numero si bien bastante grande resulta inadecuado para muchas aplicaciones como la criptografia. En su lugar deberan usarse numeros más grandes hasta de 512 bits (16 veces mas grandes). Ing. Ing.Jorge JorgeA. A.Hernández HernándezP.: P.:Otras Otrasestructuras estructuraslineales lineales 2 Estructuras de datos El enfoque consiste en dividir el numero en cifras mas manejables y generar un acarreo cada vez que sea necesario y pasarlo al siguiente elemento en la lista. Un manejo más eficiente aun es considerar una lista de bits de longitud variable y aplicar por software los algoritmos que internamente usa el ALU. Otro problema clásico a resolverse con listas circulares es el Dilema de Josephus. Consultar el capitulo Colas y listas de Tenenbaum. Ing. Ing.Jorge JorgeA. A.Hernández HernándezP.: P.:Otras Otrasestructuras estructuraslineales lineales Estructuras de datos template <class T> class Nodo_:Prior{ public: Nodo_Prior(T x, int p){dato = x; prior = p; sig = NULL;} Nodo_Prior<T> GetSig()[return sig;} void SetSig(NodoPrior<T> *p){sig = p;} T GetDato(){return dato;} int GetPrior(){return prior;} private: T dato; int prior; Nodo_Prior<T> *sig; } Ing. Ing.Jorge JorgeA. A.Hernández HernándezP.: P.:Otras Otrasestructuras estructuraslineales lineales Estructuras de datos Ademas de estas estructuras derivadas de las listas simples, es de hacer notar que existen las llamadas colas de prioridad. Una cola de prioridad tiene un comportamiento parecido al de una cola, pero cada elemento de la cola posee un campo extra que sirve para asignarle una prioridad. Asi los elementos se forman según su prioridad. Ing. Ing.Jorge JorgeA. A.Hernández HernándezP.: P.:Otras Otrasestructuras estructuraslineales lineales Estructuras de datos En una cola de prioridad descendente, se forman primero los elementos con mayor prioridad en el orden en el que van llegando. En una cola ascendente, sucede lo contrario y se forman primero los elementos de menor prioridad. Estas estructuras sirven de base a otras como los monticulos. Ing. Ing.Jorge JorgeA. A.Hernández HernándezP.: P.:Otras Otrasestructuras estructuraslineales lineales 3