You are on page 1of 8

Listas enlazadas

A.J.M.Checa<ajmoreno@ull.es>
February 5, 2008

IMPORTANTE:
La Prctica planteada en la ltima seccin de estos apuntes supone un 50% de la nota final.
Ser entregada y explicada en una de las dos convocatorias de febrero de 2008.

Introduccin

Las listas enlazadas son elementos del mismo tipo enlazados mediante una direccin a la que
llamaremos nodo. En nuestro caso, los elementos sern estructuras y los nodos punteros al
mismo tipo de estructura. En la figura 1 se representa el primer elemento de una lista, al que

Figure 1: Primer elemento


hemos denominado ini1. c1, c2,...,son los campos del elemento que contendrn informacin y
nodo es un campo especial, ya que ha de contener la direccin del siguiente elemento, al que
hemos denominado act. En la figura 2 se representa una lista enlazada. El acceso a cualquiera
de sus elementos es secuencial, ya que para llegar hasta l hemos de recorrer los que le preceden.
1

Es importante recordar que estos nombre se refieren a direcciones asignadas mediante la funcin malloc a las
estructuras que formarn la lista enlazadas.

Figure 2: Lista enlazada

Generacin de una lista simplemente enlazada

Una lista es simplemente enlazada cuando cada elemento posee un nico nodo que enlaza con
el siguiente elemento.
En primer lugar, antes de enlazar el primero con el segundo, hemos de tener ambos: como

Figure 3: Los dos primeros elementos sin enlazar


se muestra en la figura 3. A continuacin enlazamos el primero con el segundo; aunque esto
mismo lo hubiramos podido hacer sin utilizar act:
2

ini -> sig = (struct *lista) malloc(sizeof(struct lista));

Sin embargo nosotros seguiremos utilizando el puntero act, pues como veremos a continuacin, resulta muy til para generar una lista.

Figure 4: Los dos primeros elementos enlazados


Enlazaremos el segundo con un tercero, previa generacin de un nuevo elemento que llamaremos new;
4
5

new = (struct *lista) malloc(sizeof(struct lista));


act -> sig = new;

pero hacer esto es equivalente a;


4

act -> sig =

(struct *lista) malloc(sizeof(struct lista));

con lo cual no es necesario introducir un nuevo puntero a estructura new. Ya estamos en


condiciones de generar automticamente una lista enlazada de N elementos. No olvidemos que
la lista es de acceso secuencial, lo cual quiere decir que solo es necesario conocer la direccin
del primer elemento de la lista;
for(i=0 , i<N-1, i++)
{
act -> sig = (struct *lista) malloc(sizeof(struct lista));
act = act -> sig;
}

La sentencia
act = act -> sig;

es para actualizar el elemento actual. No se pierde ninguna informacin, ya que los nodos se
van guardando en elementos anteriores. Por otra parte, este bucle se realiza N 1 veces, pues
ya tenemos el primer elemento ini.

El cdigo completo lo resumimos en el siguiente cuadro mediante la declaracin de una determinada estructura con un nico campo;
#include <stdlib.h>
struct lista{
int n;
struct lista *sig;
} *ini,*act;
main(){
int i;
ini = (struct *lista) malloc(sizeof(struct lista));
act=ini;
for(i=0 , i<N-1, i++)
{
act -> sig = (struct *lista) malloc(sizeof(struct lista));
act = act -> sig;
}
act -> sig = NULL;
return 0;
}

El ltimo comando
act -> sig = NULL;

es til para cerrar la lista, o lo que es lo mismo, para saber cual es el ltimo elemento.

2.1

Ejercicio

a. Implemente una funcin que permita eliminar o insertar un determinado elemento en


una lista simplemente enlazada, siempre que no sea el primero o el ltimo.
b. Como en el caso anterior, pero teniendo en cuenta si el elemento es el primero o el
ltimo.

Generacin listas doblemente enlazada

Decimos que una lista est doblemente enlazada cuando cada elemento posee dos nodos, uno
que contiene la direccin del siguiente elemento y otro que contiene la direccin del elemento
anterior.
struct lista{
int n;
struct lista *sig, *ant;
} *ini,*act,*ult;

La estructura anterior puede utilizarse para crear la lista enlazada de la figura 5.En este caso
particular la lista se dice que es circular, pues el ltimo elemento de la lista ult contiene la direccin del primero ini, y a su vez el primero se enlaza con ult, y como es circular, hemos de

Figure 5: Lista circular doblemente enlazada


guardar dos direcciones, ini y ult.
El siguiente programa puede utilizarse para implementar una lista no circular doblemente enlazada.
#include <stdlib.h>
struct lista{
int n;
struct lista *sig, *ant;
} *ini,*act,*new;
int main(){
int i;
ini = (struct *lista) malloc(sizeof(struct lista));

ini -> ant

= NULL;

act=ini;
for(i=0 ;
{
act ->
(act ->
act =
}

i<N-1; i++)
sig
= (struct *lista) malloc(sizeof(struct lista));
sig) -> ant = act;
act -> sig ;

act -> sig = NULL;


return 0;
}

Aadir y eliminar elementos de una lista

Estas notas solo son indicativas respecto a la insercin o extraccin de elementos de una lista
doblemente enlazada. No tiene en cuenta como hacerlo si se trata del primer o ltimo elemento. Esta tarea ha de ser desarrollada por el alumno como parte de la prctica que se detalla
en la introduccin.
la siguiente funcin permite aadir un elemento en una lista ordenada por el campo n,

/* Esta funcin inserta un nuevo elemento (new =malloc(sizeof(struct lista)); )


entre los elementos menor y mayor que Nel.
Nel se compara con el contenido del campo n del elemento actual y con el
contenido del campo n del elemento siguiente mediante la instruccin
if( (Nel > act->n )&&(Nel < (act->sig)->n )).*/
#include <stdlib.h>

struct lista{
int n;
struct lista *sig, *ant;
} *ini,*act,*new;

void aniadirElemento(struct lista *act,int Nel){


while(act!=NULL)
{
if( (Nel > act->n )&&(Nel < (act->sig)->n )){
new =malloc(sizeof(struct lista));
new->n=Nel;
new->sig=act->sig;
new->ant=act;
(act->sig)->ant=new;
act->sig=new;

return;
}
act=act->sig;
}
return;
}
}

La sentencia while(act! = N U LL) es vlida para una lista que no se circular, pues el ltimo
elemento de la lista es el nico con direccin nula.

la siguiente funcin permite aadir un elemento en una lista ordenada por el campo n,

/* Esta funcin elimina el elemento cuyo campo n sea Nel*/

void borrarElemento(struct lista *act,int Nel){


while(act!=NULL)
{
if(act->n==Nel){
(act->ant)->sig=act->sig;
(act->sig)->ant=act->ant;
free(act);
return;
}
act=act->sig;
}
return;
}
}
}

Prctica

Escriba un programa en C para crear un lista circular doblemente enlazada con dos opciones2
a. Eliminar un determinado elemento de la lista.
b. Aadir un nuevo elemento.

Tenga cuidado si se trata del primer o ltimo elemento.

You might also like