Sie sind auf Seite 1von 4

Listas doblemente enlazadas

Son listas que tienen un enlace con el elemento siguiente y con el anterior. Una ventaja que tienen es que pueden recorrerse en ambos sentidos, ya sea para efectuar una operacin con cada elemento o para insertar/actualizar y borrar. La otra ventaja es que las bsquedas son algo ms rpidas puesto que no hace falta hacer referencia al elemento anterior. Su inconveniente es que ocupan ms memoria por nodo que una lista simple. Se realizar una implementacin de lista ordenada con doble enlace que aproveche el uso de la cabecera y el centinela. A continuacin se muestra un grfico que muestra una lista doblemente enlazada con cabecera y centinela, para lo que se utiliza un nico nodo que haga las veces de cabecera y centinela.

- Declaracin: struct listaDE { int clave; struct listaDE *ant, *sig; };

- Procedimiento de creacin: void crearDE(struct listaDE **LDE) { *LDE = (struct listaDE *) malloc(sizeof(struct listaDE)); (*LDE)->sig = (*LDE)->ant = *LDE; }

- Procedimiento de insercin: void insertarDE(struct listaDE *LDE, int elem) { struct listaDE *actual, *nuevo; /* busca */ actual = LDE->sig; LDE->clave = elem;

while (actual->clave < elem) actual = actual->sig; /* crea */ nuevo = (struct listaDE *) malloc(sizeof(struct listaDE)); nuevo->clave = elem; /* enlaza */ actual->ant->sig = nuevo; nuevo->ant = actual->ant; nuevo->sig = actual; actual->ant = nuevo; }

- Procedimiento de borrado: void borrarDE(struct listaDE *LDE, int elem) { struct listaDE *actual; /* busca */ actual = LDE->sig; LDE->clave = elem; while (actual->clave < elem) actual = actual->sig; /* borra */ if (actual != LDE && actual->clave == elem) { actual->sig->ant = actual->ant; actual->ant->sig = actual->sig; free(actual); } }

Para probarlo se pueden usar las siguientes instrucciones: struct listaDE *LDE; ... crearDE(&LDE); insertarDE(LDE, 1); borrarDE(LDE, 1);

Listas circulares
Las listas circulares son aquellas en las que el ltimo elemento tiene un enlace con el primero. Su uso suele estar relacionado con las colas, y por tanto su desarrollo se realizar en el tema de colas. Por supuesto, se invita al lector a desarrollarlo por su cuenta.

Algoritmos de ordenacin de listas

* Un algoritmo muy sencillo: Se dispone de una lista enlazada de cualquier tipo cuyos elementos son todos comparables entre s, es decir, que se puede establecer un orden, como por ejemplo nmeros enteros. Basta con crear una lista de tipo ordenada e ir insertando en ella los elementos que se quieren ordenar al tiempo que se van borrando de la lista original sus elementos. De esta manera se obtiene una lista ordenada con todos los elementos de la lista original. Este algoritmo se llama Insercin Directa; ver Algoritmos de Ordenacin. La complejidad para ordenar una lista de n elementos es: cuadrtica en el peor caso (n * n) -que se da cuando la lista inicial ya est ordenada- y lineal en el mejor (n) -que se da cuanda la lista inicial est ordenada de forma inversa. Para hacer algo ms rpido el algoritmo se puede implementar modificando los enlaces entre los elementos de la lista en lugar de aplicar la idea propuesta anteriormente, que requiere crear una nueva lista y borrar la lista no ordenada. El algoritmo anterior es muy rpido y sencillo de implementar, pues ya estn creadas las estructuras de listas ordenadas necesarias para su uso. Eso s, en general es ineficaz y no debe emplearse para ordenar listas grandes. Para ello se emplea la ordenacin por fusin de listas. * Un algoritmo muy eficiente: ordenacin por fusin o intercalacin (ver Ordenacin por fusin).

Problemas propuestos: - La ordenacin por fusin no recursiva: consiste en desarrollar un algoritmo para fusionar dos listas pero que no sea recursivo. No se trata de desarrollar una implementacin iterativa del programa anterior, sino de realizar una ordenacin por fusin ascendente. Se explica mediante un ejemplo: 3 -> 2 -> 1 -> 6 -> 9 -> 0 -> 7 -> 4 -> 3 -> 8 se fusiona el primer elemento con el segundo, el tercero con el cuarto, etctera: [(3) -> (2)] -> [(1) -> (6)] -> [(9) -> (0)] -> [(7) -> (4)] -> [(3) -> (8)] queda: 2 -> 3 -> 1 -> 6 -> 0 -> 9 -> 4 -> 7 -> 3 -> 8 se fusionan los dos primeros (primera sublista) con los dos siguientes (segunda sublista), la tercera y cuarta sublista, etctera. Observar que la quinta sublista se fusiona con una lista vaca, lo cual no supone ningn inconveniente para el algoritmo de fusin. [(2 -> 3) -> (1 -> 6)] -> [(0 -> 9) -> (4 -> 7)] -> [(3 -> 8)] queda: 1 -> 2 -> 3 -> 6 -> 0 -> 4 -> 7 -> 9 -> 3 -> 8 se fusionan los cuatro primeros con los cuatro siguientes, y aparte quedan los dos ltimos: [(1 -> 2 -> 3 -> 6) -> (0 -> 4 -> 7 -> 9)] -> [(3 -> 8)] queda: 0 -> 1 -> 2 -> 3 -> 4 -> 6 -> 7 -> 9 -> 3 -> 8 se fusionan los ocho primeros con los dos ltimos, y el resultado final es una lista totalmente ordenada: 0 -> 1 -> 2 -> 3 -> 3 -> 4 -> 6 -> 7 -> 8 -> 9

Para una lista de N elementos, ordena en el mejor y en el peor caso en un tiempo proporcional a: NlogN. Observar que para ordenar una lista de 2 elementos requiere un paso de ordenacin, una lista de 4 elementos requiere dos pasos de ordenacin, una lista de 8 elementos requiere tres pasos de ordenacin, una lista de 16 requiere cuatro pasos, etctera. Es decir: log 2 = 1 log 4 = 2 log 8 = 3 log 16 = 4 log 32 = 5 De ah el logaritmo en base 2. N aparece porque en cada paso se requiere recorrer toda la lista, luego el tiempo es proporcional a NlogN. Se pide: codificar el algoritmo de ordenacin por fusin ascendente.

Conclusin
Las listas enlazadas son muy verstiles. Adems, pueden definirse estructuras ms complejas a partir de las listas, como por ejemplo arrays de listas, etc. En algunas ocasiones los grafos se definen como listas de adyacencia (ver seccin de grafos). Tambin se utilizan para las tablas de hash (dispersin) como arrays de listas. Son eficaces igualmente para disear colas de prioridad, pilas y colas sin prioridad, y en general cualquier estructura cuyo acceso a sus elementos se realice de manera secuencial.

Das könnte Ihnen auch gefallen