Anda di halaman 1dari 23

Unidad 5

Listas Enlazadas
Bibliografa: Algoritmos y Estructuras de datos de Aguilar y Martinez. Unidad 9
Autor: Ing Rolando Simon Titiosky.

Fundamentos Tericos
Si en tiempo de Diseo del Algoritmo:
Se conoce la cantidad de elementos a EnListar.
Podemos usar Organizacin Esttica de Memoria: Arrays.
Obliga en tiempo de Compilacin a reservar la memoria a usar.
Implementaciones mas rpidas: Ya se Gestion la Memoria.
Uso Ineficiente de Memoria: Una posicin que no se utiliza no
puede ser usada por nadie mas.

Si no se conoce la cantidad de elementos a EnListar


Debemos usar Organizacin Dinmica: Listas Enlazadas.
Coleccin de Nodos lgicamente uno detrs de otro.
C/Nodo y se compone al menos de 2 campos
La informacin propiamente dicha
Un puntero al prximo elemento de la lista.

CAB
Ptro

Info

Ptro

Info

Ptro

Info

Ptro

Info

Null

Clasificacin de Listas Enlazadas


Simplemente Doblement
Enlazada
e Enlazada

Circular
Simpleme
nte
Enlazada

Circular
Doblement
e Enlazada

# Enlaces
del Nodo

1 al sucesor

1 al sucesor
1 al sucesor 1 al sucesor
1
al
1
al
predecesor
predecesor

Recorrido
Eficiente

Forward

Forward
Backward

y Forward
Circular

Ultimo
Null
Se pueden implementar
Nodo

Forward
Backward
Circular

Apunta al Primero

con Arrays o Punteros.


Todas tiene Cabeza y Cola.
Una Lista Vaca tiene su Cabeza=Cola=Null

Pueden almacenar cualquier tipo de informacin


Las inserciones se pueden realizar en cualquier punto de la lista
Los elementos se insertan ordenados

Operaciones Tpicas en Listas

Inicializacin o creacin
Insertar elementos en la lista
Al principio, al final
Antes o despus de la posicin i
Antes o despus del elemento con la informacin x.

Eliminar elementos en la lista


La cabeza, el final
El elemento de la posicin i
El elemento con la informacin x.

Buscar elementos en la lista


El elemento de la posicin i
El elemento con la informacin x.

Modificar
El elemento de la posicin i
El elemento con la informacin x.

Recorrer los Nodos de la Lista


Comprobar si la lista esta vaca.
Cantidad de elementos de una lista.
Intercambiar dos elementos de la lista

Especificacin TAD Lista


Simplemente Encadenada (SE)
Se hace una Especificacin bsica de ejemplo. Aunque est siempre
ligada al asunto que se quiera resolver.

TAD Lista
(a1, a2, ai, .., an) siendo n>=0; Si n=0 entonces Lista Vacia

Sintaxis

L Lista, x Lista, p puntero


ListaVacia(L): Inicializa la Lista L vaca.
EsVacia(L): Determina si L es vaca
Insertar(L, x, p): Inserta en la Lista L un nodo con el campo dato x,
delante del nodo de direccin p
Localizar(L, x): Localiza en L, el nodo con campo de informacin x.
Suprimir(L, x): Elimina en L, el nodo con campo de informacin x.
Anterior(L,x): Devuelve el Nodo anterior al nodo con campo de
informacin x.
.

Ejemplo Simple de Listas SE


#include <stdio.h>
#include <stdlib.h>
#define MX 99

Cargar una lista simplemente enlazada con


nmeros aleatorios hasta encontrar el
nmero 0.
Luego se muestran por pantalla solo
aquellos que sean nmeros pares.

typedef int Item;


typedef struct Elemento
{ Item dato;
struct Elemento* siguiente;
} Nodo;
void inserPrimero(Nodo** cabeza, Item entrada);
Nodo* crearNodo(Item x);

Ejemplo Simple de Listas SE


void main()
{ Item d;
Nodo *cabeza, *ptr;
int k;
cabeza = NULL; /* lista vaca */
randomize();
for (d = random(MX); d; )/* Bucle termina cuando se genera el nmero 0 */
{
inserPrimero(&cabeza, d);
d = random(MX);
}
for (k = 0, ptr = cabeza; ptr!=NULL; ptr = ptr -> siguiente)
if (ptr -> dato%2 == 0) /* se recorre la lista para escribir los pares */
{
printf("%d ", ptr -> dato);
k++;
printf("%c",(k%12 ? ' ' : '\n'));
/* 12 datos por lnea */
}
printf("\n\n");
}

Ejemplo Simple de Listas SE


void inserPrimero(Nodo** cabeza, Item entrada)
{ Nodo *nuevo ;
nuevo = crearNodo(entrada);
nuevo -> siguiente = *cabeza;
*cabeza = nuevo;
}
Nodo* crearNodo(Item x)
{ Nodo *a ;
a = (Nodo*)malloc(sizeof(Nodo)); /* asigna nuevo nodo */
a -> dato = x;
a -> siguiente = NULL;
return a;
}

Grafica de Punteros Lista SE


3

CAB

Ptro
Nuevo=crearNodo(5)

Ptro
5

Nuevo

10

Null

Ptro

Null

Ptro

CAB
Ptro

Ptro

Nuevo>Siguiente=*Cabeza

10

Null

Ptro

Nuevo
Ptro

CAB

*Cabeza=Nuevo

Ptro

Ptro

Nuevo
Ptro

10

6
Ptro

Null

Insercin al Final de la Lista SE


Es menos eficiente pues hay que recorrer toda la lista.
Void inserFinal(Nodo** cabeza, tem entrada)
{ Nodo *ultimo;
ultimo=*cabeza;
if(ultimo==NULL) /*lista vaca*/
*cabeza=crearNodo(entrada);
else{
for(;ultimo>siguiente;)
ultimo=ultimo>siguiente;
ultimo>siguiente=crearNodo(entrada);
}
}

Algoritmo de Insercin de un
Nodo entre 2 existentes SE
1.

Asignar un nuevo nodo apuntado por el ptr nuevo

2.

Si la lista est vaca se lo inserta como primer Nodo.

Buscar la posicin del nodo Despus, que contiene el


campo dato de referencia.

3.
4.

Si no existe (posicin o referencia) No se Inserta.

Hacer que el nuevo>siguiente apunte al nodo


Despues>siguiente, o Null si es el ltimo.
Hacer que despues>siguiente apunte al nuevo
Nuevo
Despues

4
CAB

Ptro

Ptro

Ptro

Ptro

10

Null

Insercin de un Nodo entre 2 existentes


void insertan(Nodo** cabeza, tem testigo, Item entrada)
{ Nodo *nuevo, *despus;
nuevo = crearNodo(entrada);
if (*cabeza == NULL) *cabeza = nuevo;
else
{
int esta=0;
despus=*cabeza;
while ((despues->siguiente != NULL) && !esta)
{
if (despus>dato !=testigo) despues=despues>siguiente;
else esta=1;
}
if (esta) /* Se enlasa el nuevo nodo */
{
nuevo -> siguiente = despues -> siguiente;
despues -> siguiente = nuevo;
Nuevo
}
}
Despues
}
4
CAB

Ptro

Ptro

Ptro

Ptro

10

Null

Bsqueda Por Contenido

Parmetros:
cabeza: cabeza de lista
destino: valor de referencia que se est buscando.

Localiza un elemento por referencia del contenido.


Si lo encuentra devuelve su ptro. Sino devuelve NULL

Nodo * localizar(Nodo*cabeza, tem destino)


{ Nodo *indice;
for(indice=cabeza; indice!=NULL;indice=indice>siguiente)
if(destino==indice>dato) return indice;
return NULL;
}

Bsqueda por Posicin

Parmetros:
cabeza: cabeza de lista
posicin: posicin de referencia que se esta buscando.

Localiza un elemento por referencia a su posicin dentro de la lista.


Si lo encuentra devuelve su ptro. Sino devuelve NULL

Nodo * buscarPosicion(Nodo*cabeza, int posicin)


{ Nodo *indice;
int i;
indice=cabeza;
for(i=1; (i<posicin) && (indice!=NULL);i++)
indice=indice>siguiente;
return indice;
}

Eliminar un Nodo de la Lista SE

Se enlazar el nodo anterior con el siguiente al que se debe eliminar.

void eliminar (Nodo** cabeza, Item entrada)


{ Nodo* actual = *cabeza;
Nodo *anterior = NULL;
int encontrado = 0;
while ((actual!=NULL) && (!encontrado)) /* bsqueda del nodo y del anterior */
{
encontrado = (actual -> dato == entrada);
if (!encontrado)
{
anterior = actual;
actual = actual -> siguiente;
}
}
if (actual != NULL) /* Enlace nodo anterior con siguiente. Si es NULL No existe elemento */
{
if (actual == *cabeza)
/* distingue entre el nodo cabecera o el resto de la lista */
*cabeza = actual -> siguiente;
else
anterior -> siguiente = actual -> siguiente;
free(actual);
}
}

Listas Doblemente Enlazadas (DE)


Cada elemento contiene 2 ptro: hacia atrs y hacia
delante en la Lista
Las Operaciones son las mismas que para las
Simplemente Enlazadas, pero aqu se pueden dar en
ambas direcciones.
El Borrado supone realizar los enlaces entre el ptr del
nodo anterior con siguiente al que se desea eliminar.

Insercin

Null

Null
INS
DEL

Borrado

Null

Null

Creacin de una Lista DE


typedef struct tipoNodo
{ Item dato;
struct tipoNodo* adelante;
struct tipoNodo* atras;
}Nodo;

Cargar una lista doblemente enlazada


con nmeros capturados por consola
hasta encontrar el nmero 0.

void main()
{ Nodo *cabeza,*ptr;
int n;
cabeza = NULL; /* lista vaca */
while (n!=0)
{
scanf (%i, &n);
inserPrim(&cabeza,n);
}
}

Creacin de una Lista DE


Nodo* crearNodo(Item x)
{ Nodo *a ;
a = (Nodo*)malloc(sizeof(Nodo));
a -> dato = x;
a -> adelante = a -> atras = NULL;
return a;
}

Null

nuevo

void inserPrim(Nodo** cabeza, Item entrada)


{ Nodo* nuevo;
nuevo = crearNodo(entrada);
nuevo -> adelante = *cabeza; /*Apuntar al primer elemento antes de la INS*/
nuevo -> atras = NULL; /*Nuevo apuntar a Cabeza*/
if (*cabeza != NULL)
(*cabeza)-> atras = nuevo; /* cabeza es ptr de ptr: esta referencia es hacia el
ptr atrs del elemento al que apunta cabeza*/

*cabeza = nuevo; /*cabeza apuntar al nuevo primer elemento*/


}

Insertar entre elementos DE


Una vez encontrado el elemento anterior al punto de Insercin, se
llama a esta funcion insertar
Void insertar(Nodo **cabeza, tem entrada, Nodo *anterior)
{ Nodo *nuevo;
if ((*cabeza)==NULL) || anterior==NULL) /*Principio de Lista*/
inserPrim(&cabeza, entrada);
else
{
nuevo=crearNodo(entrada);
nuevo>adelante=anterior>adelante;
if (anterior>delante!=NULL) /*No es fin de lista*/
/*atrs del siguiente apunta al nodo nuevo*/ (anterior>delante)>atrs=nuevo;
anterior>delante=nuevo;
nuevo>atrs=anterior;
}
Null ANTE
RIOR
Null
}
nuevo

Eliminar entre Elementos DE


void eliminar (Nodo** cabeza, tem entrada)
{ Nodo* actual = *cabeza;
int encontrado=0;
while ((actual!=NULL) && (!encontrado) /*Bsqueda del Nodo*/
{
encontrado=(actual>dato==entrada);
if (!encontrado) actual=actual>adelante;
}
if (actual !=NULL) /*enlazar el anterior con el siguiente. */
{
if(actual==*cabeza)
/*1er elemento de la lista */
{*cabeza = actual -> adelante;
if (actual -> adelante != NULL)
(actual -> adelante) -> atras = NULL;
/*El nuevo 1er elemento de la lista debe tener el ptr atrs igual a NULL*/

}
else if (actual -> adelante != NULL) /*Nodo Intermedio*/
{(actual -> atrs) -> adelante = actual -> adelante;
(actual -> adelante) -> atras = actual -> atras;
}
else (actual -> atrs) -> adelante = NULL; /*Es el ultimo Nodo*/
free(actual);
ACT
}
}

Null

Null

Lista Circular
Idealmente No tiene ni principio ni fin.
Sigue existiendo Cabeza, pero es usada solo para
comenzar a recorrer la lista.

El Nodo Cola apunta al primer elemento de la


lista: Cola>siguiente==cabeza.
Aunque esto puede variar pues no tiene primer
elemento de la lista

Las Operaciones posibles son las mismas que


en las otras listas.
CAB
Ptro

Info

Ptro

Info

Ptro

Info

Ptro

Trabajos Prcticos Unidad


COMO MINIMO, REALIZAR:
De la Bibliografa
Del Capitulo 9:
Ejercicios: 9.1, 9.2, 9.4, 9.6, 9.8.
Problemas (En tanto se los realice, finalizar las
especificaciones e implementaciones de los TADs
ListaSE y ListaDE con las Interfaces que se
necesiten): 9.2, 9.9.

Ejercicios Complementarios
1. Con Array, crear una lista doblemente enlazada
que no tenga espacios vacos intermedios.

Adems, implementar las operaciones bsicas: Crear,


Insertar, Borrar, Modificar.

2. Especificar e implementar un TAD string que


permita manipular cadenas de caracteres.
Especifique al menos 10 operaciones.
Implemente al menos 4. Entre ellas, comprobar si
una determinada palabra es Palndromo (la lectura
directa o inversa son iguales. Ej: alila)