la lista enlazada simple

Upload: erick-zuniga-vazquez

Post on 10-Jan-2016

214 views

Category:

Documents


0 download

DESCRIPTION

informacion respecto a una lista enlazada

TRANSCRIPT

La lista enlazada simple

Prerrequisitos Introduccin Definicin Construccin del modelo de un elemento de la lista Operaciones sobre las listas enlazadas Inicializacin Insercin de un elemento en la lista Insercin en una lista vaca Insercin al inicio de la lista Insercin al final de la lista Insercin en otra parte de la lista Eliminacin de un elemento de la lista Eliminacin al inicio de la lista Eliminacin en otra parte de la lista Visualizacin de la lista Destruccin de la lista Ejemplo completo lista.h Consulta tambin:Listas enlazadas c

PrerrequisitosLos prerrequisitos son los tipos de datos, las estructuras, el uso detypedef, los punteros y las funciones usuario.

IntroduccinEl objetivo de este artculo es el de comprender el uso de las listas enlazadas simples.Las listas enlazadas pueden ser utilizadas cuando se necesitan hacer varias operaciones de insercin y eliminacin de elementos.

DefinicinLas listas enlazadas son estructuras de datos semejantes a losarraysalvo que el acceso a un elemento no se hace mediante un indice sino mediante un puntero.La asignacin de memoria es hecha durante la ejecucin.

En una lista los elementos son contiguos en lo que concierne al enlazado.

En cambio, mientras que en unarraylos elementos estn contiguos en la memoria, en una lista los elementos estn dispersos. El enlace entre los elementos se hace mediante un puntero. En realidad, en la memoria la representacin es aleatoria en funcin del espacio asignado.

El punterosiguientedel ltimo elemento tiene que apuntar hacia NULL (el fin de la lista).

Para acceder a un elemento, la lista es recorrida comenzando por el inicio, el punteroSiguientepermite el cambio hacia el prximo elemento.El desplazamiento se hace en una sola direccin, del primer al ltimo elemento.Si deseas desplazarte en las dos direcciones (hacia delante y hacia atrs) debers utilizar las listas doblemente enlazadas.

Construccin del modelo de un elemento de la listaPara establecer un elemento de la lista, ser utilizado el tipostruct. El elemento de la lista tendr un campodatoy un punterosiguiente.El punterosiguientetiene que ser del mismo tipo que el elemento, si no, no podr apuntar hacia el elemento. El punterosiguientepermitir el acceso al prximo elemento.

typedef struct ElementoLista { char *dato; struct ElementoLista *siguiente;}Elemento;

Para tener el control de la lista es preferible guardar determindos elementos: el primer elemento, el ltimo elemento, el nmero de elementos. Para ello ser empleado otra estructura (no es obligatorio, pueden ser utilizadas variables).

typedef struct ListaIdentificar { Elemento *inicio; Elemento *fin; int tamao;}Lista;

El punteroiniciotendr la direccin del primer elemento de la lista. El punterofinalbergar la direccin del ltimo elemento de la lista. La variabletamaocontiene el nmero de elementos.

Cualquiera sea la posicin en la lista, los punterosinicioyfinapuntan siempre al primer y ltimo elemento. El campotamaocontendr al numero de elementos de la lista cualquiera sea la operacin efectuada sobre la lista.

Operaciones sobre las listas enlazadasPara la insercin y la eliminacin, una nica funcin bastar si est bien concebida de acuerdo a lo que se necesite. Debo recordar que este artculo es puramente didctico.Por lo tanto, he escrito una funcin para cada operacin de insercin y eliminacin.

InicializacinModelo de la funcin:

void inicializacion (Lista *lista);

Esta operacin debe ser hecha antes de otra operacin sobre la lista.Esta comienza el punteroinicioy el punterofincon el puntero NULL, y eltamaocon el valor 0.

La funcin

void inicializacion (Lista *lista){ lista->inicio = NULL; lista->fin = NULL; tamao = 0;}

Insercin de un elemento en la listaA continuacin el algoritmo de insercin y el registro de los elementos: declaracin del elemento que se va a insertar, asignacin de la memoria para el nuevo elemento, llena el contenido del campo de datos, actualizacin de los punteros hacia el primer y ltimo elemento si es necesario. Caso particular: en una lista con un nico elemento, el primero es al mismo tiempo el ltimo. Actualizar el tamao de la listaPara aadir un elemento a la lista hay varios casos: insercin en una lista vaca, insercin al inicio de la lista, insercin al final de la lista e insercin en otra parte de la lista.

Insercin en una lista vacaEjemplo de la funcin:

int ins_en_lista_vacia (Lista *lista, char *dato);

La funcin retorna 1 en caso de error, si no devuelve 0.

Las etapas son asignar memoria para el nuevo elemento, completa el campo de datos de ese nuevo elemento, el punterosiguientede este nuevo elemento apuntar hacia NULL (ya que la insercin es realizada en una lista vaca, se utiliza la direccin del punteroinicioque vale NULL), los punterosinicioyfinapuntaran hacia el nuevo elemento y el tamao es actualizado

La funcin

/* insercin en una lista vaca */int ins_en_lista_vacia (Lista * lista, char *dato){ Element *nuevo_elemento; if ((nuevo_elemento = (Element *) malloc (sizeof (Element))) == NULL) return -1; if ((nuevo _elemento->dato = (char *) malloc (50 * sizeof (char))) == NULL) return -1; strcpy (nuevo_elemento->dato, dato);

nuevo_elemento->siguiente = NULL; lista->inicio = nuevo_elemento; lista->fin = nuevo_elemento; lista->tamao++; return 0;}

Insercin al inicio de la listaEjemplo de la funcin:

int ins_inicio_lista (Lista *lista,char *dato);

La funcin da-1en caso de error, de lo contrario da0.

Etapas: asignar memoria al nuevo elemento, rellenar el campo de datos de este nuevo elemento, el punterosiguientedel nuevo elemento apunta hacia el primer elemento, el punteroinicioapunta al nuevo elemento, el punterofinno cambia, el tamao es incrementado

La funcin

/* insercin al inicio de la lista */int ins_inicio_lista (Lista * lista, char *dato){ Element *nuevo_elemento; if ((nuevo_elemento = (Element *) malloc (sizeof (Element))) == NULL) return -1; if ((nuevo_elemento->dato = (char *) malloc (50 * sizeof (char))) == NULL) return -1; strcpy (nuevo_elemento->dato, dato);

nuevo_elemento->siguiente = lista->inicio lista->inicio = nuevo_elemento; lista->tamao++; return 0;}

Insercin al final de la listaEjemplo de la funcin:

int ins_fin_lista (Lista *lista, Element *actual, char *dato);

La funcin da-1en caso de error, si no arroja0.

Etapas: proporcionar memoria al nuevo elemento, rellenar el campo de datos del nuevo elemento, el punterosiguientedel ultimo elemento apunta hacia el nuevo elemento, el punterofinapunta al nuevo elemento, el punteroiniciono vara, el tamao es incrementado:

La funcin

/*insercin al final de la lista */int ins_fin_lista (Lista * lista, Element * actual, char *dato){ Element *nuevo_elemento; if ((nuevo_elemento = (Element *) malloc (sizeof (Element))) == NULL) return -1; if ((nuevo_elemento->dato = (char *) malloc (50 * sizeof (char))) == NULL) return -1; strcpy (nuevo_elemento->dato, dato);

actual->siguiente = nuevo_elemento; nuevo_elemento->siguiente = NULL;

lista->fin = nuevo_elemento;

lista->tamao++; return 0;}

Insercin en otra parte de la listaEjemplo de la funcin:

int ins_lista (Lista *lista, char *dato,int pos);

La funcin arroja-1en caso de error, si no da0.

La insercin se efectuar despus de haber pasado a la funcin una posicin como argumento.Si la posicin indicada no tiene que ser el ltimo elemento. En ese caso se debe utilizar la funcin de insercin al final de la lista.

Etapas: asignacin de una cantiad de memoria al nuevo elemento, rellenar el campo de datos del nuevo elemento, escoger una posicin en la lista (la insercin se har luego de haber elegido la posicin), el punterosiguientedel nuevo elemento apunta hacia la direccin a la que apunta el punterosiguientedel elemento actual, el punterosiguientedel elemento actual apunta al nuevo elemento, los punterosinicioyfinno cambian, el tamao se incrementa en una unidad:

La funcin

/* insercin en la posicin solicitada */int ins_lista (Lista * lista, char *dato, int pos){ if (lista->tamao < 2) return -1; if (pos < 1 || pos >= lista->tamao) return -1;

Element *actual; Element *nuevo_elemento; int i;

if ((nuevo_elemento = (Element *) malloc (sizeof (Element))) == NULL) return -1; if ((nuevo_elemento->dato = (char *) malloc (50 * sizeof (char))) == NULL) return -1;

actual = lista->inicio; for (i = 1; i < pos; ++i) actual = actual->siguiente; if (actual->siguiente == NULL) return -1; strcpy (nuevo_elemento->dato, dato);

nuevo_elemento->siguiente = actual->siguiente; actual->siguiente = nuevo_elemento; lista->tamao++; return 0;

Eliminacin de un elemento de la listaA continuacin un algoritmo para eliminar un elemento de la lista: uso de un puntero temporal para almacenar la direccin de los elementos a borrar, el elemento a eliminar se encuentra despus del elemento actual, apuntar el punterosiguientedel elemento actual en direccin del punterosiguientedel elemento a eliminar, liberar la memoria ocupada por el elemento borrado, actualizar el tamao de la lista.

Para eliminar un elemento de la lista hay varios casos: eliminacin al inicio de la lista y eliminacin en otra parte de la lista.

Eliminacin al inicio de la listaEjemplo de la funcin:

int sup_inicio (Lista *lista);

La funcin devuelve-1en caso de equivocacin, de lo contrario da0.

Etapas: el punterosup_elemcontendr la direccin del 1er elemento, el punteroinicioapuntara hacia el segundo elemento, el tamao de la lista disminuir un elemento:

La funcin

/* eliminacin al inicio de la lista */int sup_inicio (Lista * lista){ if (lista->tamao == 0) return -1; Element *sup_elemento; sup_element = lista->inicio; lista->inicio = lista->inicio->siguiente; if (lista->tamao == 1) lista->fin = NULL; free (sup_elemento->dato); free (sup_elemento); lista->tamao--; return 0;}

Eliminacin en otra parte de la listaEjemplo de la funcin:

int sup_en_lista (Lista *lista, int pos);

La funcin da-1en caso de error, si no devuelve0.

Etapas: el punterosup_elemcontendr la direccin hacia la que apunta el punterosiguientedel elementoactual, el punterosiguientedel elemento actual apuntara hacia el elemento al que apunta el punterosiguientedel elemento que sigue al elementoactualen la lista. Si el elementoactuales el penltimo elemento, el punterofindebe ser actualizado. El tamao de la lista ser disminuido en un elemento:

La funcin

/* eliminar un elemento despus de la posicin solicitada */int sup_en_lista (Lista * lista, int pos){ if (lista->tamao = lista->tamao) return -1; int i; Element *actual; Element *sup_elemento; actual = lista->inicio;

for (i = 1; i < pos; ++i) actual = actual->siguiente;

sup_elemento = actual->siguiente; actual->siguiente = actual->siguiente->siguiente; if(actual->siguiente == NULL) lista->fin = actual; free (sup_elemento->dato); free (sup_elemento); lista->tamao--; return 0;}

Visualizacin de la listaPara mostrar la lista entera hay que posicionarse al inicio de la lista (el punteroiniciolo permitir). Luego usando el punterosiguientede cada elemento la lista es recorrida del primero al ultimo elemento.La condicin para detener es proporcionada por el punterosiguientedel ultimo elemento que vale NULL.

La funcin

/* visualizacin de la lista */void visualizacin (Lista * lista){ Element *actual; actual = lista->inicio; while (actual != NULL){ printf ("%p - %s\n", actual, actual->dato); actual = actual->siguiente; }}

Destruccin de la listaPara destruir la lista entera, he utilizado la eliminacin al inicio de la lista porque el tamao es mayor a cero.La funcin

/* destruir la lista */void destruir (Lista *lista){ while (lista->tamao > 0) sup_inicio (lista);}

Ejemplo completolista.h/* ---------- lista.h ----------- */typedef struct ElementoLista{ char *dato; struct ElementoLista *siguiente;} Elemento;

typedef struct ListaIdentificar{ Elemento *inicio; Elemento *fin; int tamao;} Lista;

/* inicializacin de la lista */void inicializacin (Lista * lista);

/* INSERCION */

/* insercin en une lista vaca */int ins_en_lista_vacia (Lista * lista, char *dato);

/* insercin al inicio de la lista */int ins_inicio_lista (Lista * lista, char *dato);

/* insercin al final de la lista */int ins_fin_lista (Lista * lista, Elemento * actual, char *dato);

/* insercin en otra parte */int ins_lista (Lista * lista, char *dato, int pos);

/* SUPRESION */

int sup_inicio (Lista * lista);int sup_en_lista (Lista * lista, int pos);

int menu (Lista *lista,int *k);void muestra (Lista * lista);void destruir ( Lista * lista);/* -------- FIN lista.h --------- */

===lista _function.h===

/***************************\

lista_function.h *\***************************/voidinicialisacion (Lista * lista){ lista ->inicio = NULL; lista ->fin = NULL; lista ->tamao = 0;}/* insercion en une lista vacia */int ins_en_lista _vacia (Lista * lista, char *dato){ Elemento *nuevo_elemento; if ((nuevo_elemento = (Elemento *) malloc (sizeof (Elemento))) == NULL) return -1; if ((nuevo_elemento->dato = (char *) malloc (50 * sizeof (char))) == NULL) return -1; strcpy (nuevo_elemento->dato, dato); nuevo_elemento->siguiente = NULL; lista ->inicio = nuevo_elemento; lista ->fin = nuevo_elemento; lista ->tamao++; return 0;}/* insercin al inicio de la lista */int ins_inicio_lista (Lista * lista, char *dato){ Elemento *nuevo_elemento; if ((nuevo_elemento = (Elemento *) malloc (sizeof (Elemento))) == NULL) return -1; if ((nuevo_elemento->dato = (char *) malloc (50 * sizeof (char))) == NULL) return -1; strcpy (nuevo_elemento->dato, dato); nuevo_elemento->siguiente = lista->inicio; lista ->inicio = nuevo_elemento; lista ->tamao++; return 0;}/*insercion al final de la lista */int ins_fin_lista (Lista * lista, elemento * actual, char *dato){ Elemento *nuevo_elemento; if ((nuevo_elemento = (Elemento *) malloc (sizeof (Elemento))) == NULL) return -1; if ((nuevo_elemento->dato = (char *) malloc (50 * sizeof (char))) == NULL) return -1; strcpy (nuevo_elemento->dato, dato); actual->siguiente = nuevo_elemento; nuevo_elemento->siguiente = NULL; lista ->fin = nuevo_elemento; lista ->tamao++; return 0;}/* insercion en la posicion solicitada */int ins_ lista (Lista * lista, char *dato, int pos){ if (lista ->tamao < 2) return -1; if (pos < 1 || pos >= lista ->tamao) return -1; Elemento *actual; Elemento *nuevo_elemento; int i; if ((nuevo_elemento = (Elemento *) malloc (sizeof (Elemento))) == NULL) return -1; if ((nuevo_elemento->dato = (char *) malloc (50 * sizeof (char))) == NULL) return -1; actual = lista ->inicio; for (i = 1; i < pos; ++i) actual = actual->siguiente; if (actual->siguiente == NULL) return -1; strcpy (nuevo_elemento->dato, dato); nuevo_elemento->siguiente = actual->siguiente; actual->siguiente = nuevo_elemento; lista ->tamao++; return 0;}/* supresin al inicio de la lista */int sup_inicio (Lista * lista){ if (lista ->tamao == 0) return -1; Elemento *sup_elemento; sup_elemento = lista ->inicio; lista ->inicio = lista ->inicio->siguiente; if (lista ->tamao == 1) lista ->fin = NULL; free (sup_elemento->dato); free (sup_elemento); lista ->tamao--; return 0;}/* suprimir un elemento despus de la posicin solicitada */int sup_en_lista (Lista * lista, int pos){ if (lista ->tamao = lista ->tamao) return -1; int i; Elemento *actual; Elemento *sup_elemento; actual = lista ->inicio; for (i = 1; i < pos; ++i) actual = actual->siguiente; sup_elemento = actual->siguiente; actual->siguiente = actual->siguiente->siguiente; if(actual->siguiente == NULL) lista ->fin = actual; free (sup_elemento->dato); free (sup_elemento); lista ->tamao--; return 0;}/* visualizacin de la Lista */void muestra (Lista * lista){ Elemento *actual; actual = lista ->inicio; while (actual != NULL){ printf ("%p - %s\n", actual, actual->dato); actual = actual->siguiente; }}/* destruir la Lista */void destruir (La lista*La lista){ while (lista ->tamao > 0) sup_inicio (lista);}int menu (Lista *lista,int *k){ int eleccin; printf("********** MENU **********\n"); if (lista ->tamao == 0){ printf ("1. Adicin del1er elemento\n"); printf ("2. Quitar\n"); }else if(lista ->tamao == 1 || *k == 1){ printf ("1. Adicin al inicio de la lista\n"); printf ("2. Adicin al final de la lista\n"); printf ("4. Supresin al inicio de la lista\n"); printf ("6. Destruir la lista\n"); printf ("7. Quitar\n"); }else { printf ("1. Adicin al inicio de la lista\n"); printf ("2. Adicin al final de la lista\n"); printf ("3. Adicin despus de la posicin indicada\n"); printf ("4. Supresin al inicio de la lista\n"); printf ("5. Supresin despus de la posicin indicada\n"); printf ("6. Destruir la lista\n"); printf ("7. Quitar\n"); } printf ("\n\nElegir: "); scanf ("%d", &eleccin); getchar(); if(lista->tamao == 0 && eleccin == 2) eleccin = 7; return eleccin;}/* -------- FIN lista_function.h --------- */===lista.c===/**********************\ * lista.c *\**********************/#include #include #include #include "lista.h"#include "lista _function.h"int main (void){ char eleccin; char *nom; Lista *lista; Elemento *actual; if ((lista = (Lista *) malloc (sizeof (Lista))) == NULL) return -1; if ((nom = (char *) malloc (50)) == NULL) return -1; actual = NULL; eleccin = 'o'; inicialisacion (lista); int pos, k; while (eleccin!= 7){ eleccin = menu (lista, &k); switch (eleccin){ case 1: printf ("Ingresa un elemento: "); scanf ("%s", nom); getchar (); if (lista->tamao == 0) ins_en_lista_vacia (lista, nom); else ins_inicio_lista (lista, nom); printf ("%d elementos:ini=%s,fin=%s\n", lista->tamao, lista->inicio->dato, lista->fin->dato); muestra (lista); break; case 2: printf ("Ingrese un elemento: "); scanf ("%s", nom); getchar (); ins_fin_lista (lista, lista->fin, nom); printf ("%d elementos:ini=%s,fin=%s\n", lista->tamao, lista->inicio->dato, lista->fin->dato); muestra (lista); break; case 3: printf ("Ingrese un elemento: "); scanf ("%s", nom); getchar (); do{ printf ("Ingrese la posicion: "); scanf ("%d", &pos); } while (pos < 1 || pos > lista->tamao); getchar (); if (lista->tamao == 1 || pos == lista->tamao){ k = 1; printf("-----------------------------------------------\n"); printf("/!\\Fracaso la insercion.Utilice el menu {1|2} /!\\\n"); printf("-----------------------------------------------\n"); break; } ins_lista (lista, nom, pos); printf ("%d elementos:ini=%s,fin=%s\n", lista->tamao, lista->inicio->dato, lista->fin->dato); muestra (lista); break; case 4: sup_inicio (lista); if (lista->tamao != 0) printf ("%d elementos:ini=%s,fin=%s\n", lista->tamao, lista->inicio->dato, lista->fin->dato); else printf ("lista vacia\n"); muestra (lista); break; case 5: do{ printf ("Ingrese la posicion : "); scanf ("%d", &pos); } while (pos < 1 || pos > lista->tamao); getchar (); sup_en_lista (lista, pos); if (lista->tamao != 0) printf ("%d elementos:ini=%s,fin=%s\n", lista->tamao, lista->inicio->dato, lista->fin->dato); else printf ("lista vacia\n"); muestra (lista); break; case 6: destruir (lista); printf ("la lista ha sido destruida: %d elementos\n", lista->tamao); break; } } return 0;}https://dmmolina.wordpress.com/listas-enlazadas-y-ejemplos/