Listas doblemente enlazadas

última actualización el 13 de junio de 2009, 03:15 por Carlos-vialfa
Publicado por Carlos-vialfa

Listas doblemente enlazadas




Requisitos


Los tipos de datos
Las estructuras
El uso de typedef
Los punteros
Las funciones usuario
Las listas enlazadas simples

I. Introducción


El objetivo de este artículo es la comprensión de las listas doblemente enlazadas.
Las listas doblemente enlazadas pueden ser utilizadas cuando son necesarias varias operaciones de inserción o eliminación de elementos.

II. Definición


Las listas doblemente enlazadas son estructuras de datos semejantes a las listas enlazadas simples.
La asignación de memoria es hecha al momento de la ejecución.

En cambio, en relación a la listas enlazada simple el enlace entre los elementos se hace gracias a dos punteros (uno que apunta hacia el elemento anterior y otro que apunta hacia el elemento siguiente).



El puntero anterior del primer elemento debe apuntar hacia NULL (el inicio de la lista).
El puntero siguiente del último elemento debe apuntar hacia NULL (el fin de la lista).

Para acceder a un elemento, la lista puede ser recorrida en ambos sentidos:
  • comenzando por el inicio, el puntero siguiente permite el desplazamiento hacia el próximo elemento.
  • comenzando por el final, el puntero anterior permite el desplazamiento hacia el elemento anterior.


Resumiendo, el desplazamiento se hace en ambas direcciones, del primer al ultimo elemento y/o del ultimo al primer elemento.

III. La construcción del modelo de un elemento de la lista


Para definir un elemento de la lista será utilizado el tipo struct.
El elemento de la lista contendrá: un campo dato, un puntero anterior y un puntero siguiente.

Los punteros anterior y siguiente deben ser del mismo tipo que el elemento, en caso contrario no podrán apuntar hacia un elemento de la lista.
El puntero anterior permitirá el acceso hacia el elemento anterior mientras que el puntero siguiente permitirá el acceso hacia el próximo elemento.

 typedef struct dl_ElementoLista {
  char *dato;
  struct dl_ElementoLista *anterior;
  struct dl_ElementoLista *siguiente;
}dl_Elemento;


Para tener el control de la lista es preferible conservar algunos elementos: el primer elemento, el último elemento, el número de elementos.

Para ello, será utilizada otra estructura (no es obligatorio, pueden ser utilizadas variables).

typedef struct dl_ListaIdentificacion {
  dl_Elemento *inicio;
  dl_Elemento *fin;
  int tamaño;
}dl_Lista;


El puntero inicio contendrá la dirección del primer elemento de la lista.
El puntero fin contendrá la dirección del último elemento de la lista.
La variable tamaño contiene el número de elementos.

Cualquiera que sea la posición en la lista, los punteros inicio y fin apuntan siempre al primer y último elemento.
El campo tamaño contendrá el numero de elementos de la lista cualquiera que sea la operación efectuada sobre la lista.

IV. Operaciones sobre la lista doblemente enlazadas


Para la inserción y la eliminación, una solo función bastará si está bien concebida en función de las necesidades.
Sin embargo, debo recordar que este artículo es puramente didáctico.
Por esta razón he escrito una función para cada operación de inserción y eliminación.

A. Inicialización


Modelo de la función:

void inicialización (Lista *lista);


Esta operación debe ser hecha antes de cualquier otra operación sobre la lista.
Esta inicializa el puntero inicio y el puntero fin con el puntero NULL, y el tamaño con el valor 0.

La función

void inicialización (Liste *liste){
  lista->inicio = NULL;
  lista->fin = NULL;
  tamaño = 0;
}

B. Inserción de un elemento en la lista


A continuación el algoritmo de inserción y registro de los elementos:
  • declaración del elemento a insertar
  • asignación de la memoria para el nuevo elemento
  • rellenar el contenido del campo de datos
  • actualizar los punteros hacia el elemento anterior y el elemento siguiente
  • actualizar los punteros hacia el 1er y ultimo elemento si es necesario.
    • Caso particular: en una lista con un solo elemento, el primero es al mismo tiempo el último.
    • Actualizar el tamaño de la lista



Para añadir un elemento a la lista hay varias situaciones:
  • 1. Inserción en una lista vacía
  • 2. Inserción al inicio de la lista
  • 3. Inserción al final de la lista
  • 4. Inserción antes de un elemento
  • 5. Inserción después de un elemento

1. Inserción en una lista vacía


Modelo de la función:

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


La función devuelve -1 en caso de error, si no devuelve 0.

Etapas:
  • asignación de memoria para el nuevo elemento
  • rellenar el campo de datos del nuevo elemento
  • el puntero anterior del nuevo elemento apuntará hacia NULL (ya que la inserción es hecha en una lista vacía utilizamos la dirección del puntero inicio que vale NULL)
  • el puntero siguiente del nuevo elemento apuntará hacia NULL (ya que la inserción es hecha en una lista vacía se utiliza la dirección del puntero fin que vale NULL)
  • los punteros inicio y fin apuntaran hacia el nuevo elemento
  • el tamaño es actualizado



La función

int insercion_en_lista_vacia (dl_Lista * lista, char *dato){
  dl_Elemento *nuevo_elemento;
  if ((nuevo_elemento = alloc (nuevo_elemento)) == NULL)
    return -1;
  strcpy (nuevo_elemento->dato, dato);
  nuevo_elemento->anterior = lista->inicio;
  nuevo_elemento->siguiente = lista->fin;
  lista->inicio = nuevo_elemento;
  lista->fin = nuevo_elemento;
  lista->tamaño++;
  return 0;
}

2. Inserción al inicio de la lista


Modelo de la función:

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


La función devuelve -1 en caso de error, si no devuelve 0.

Etapas:
  • asignación de memoria al nuevo elemento
  • rellenar el campo de datos del nuevo elemento
  • el puntero anterior del nuevo elemento apunta hacia NULL
  • el puntero siguiente del nuevo elemento apunta hacia el 1er elemento
  • el puntero anterior del 1er elemento apunta hacia el nuevo elemento
  • el puntero inicio apunta hacia el nuevo elemento
  • el puntero fin no cambia
  • el tamaño es incrementado




La función

int ins_inicio_lista(dl_Lista * lista, char *dato){
  dl_Elemento *nuevo_elemento;
  if ((nuevo_elemento = alloc (nuevo_elemento)) == NULL)
    return -1;
  strcpy (nuevo_elemento->dato, dato);
  nuevo_elemento->anterior = NULL;
  nuevo_elemento->siguiente = lista->inicio;
  lista->inicio->anterior = nuevo_elemento;
  lista->inicio = nuevo_elemento;
  lista->tamaño++;
  return 0;
}

3. Inserción al final de la lista


Modelo de la función:

int ins_fin_lista(dl_Lista * lista, char *dato);


La función devuelve -1 en caso de error, si no devuelve 0.

Etapas:
  • asignación de memoria al nuevo elemento
  • rellenar el campo de datos del nuevo elemento
  • el puntero siguiente del nuevo elemento apunta hacia NULL
  • el puntero anterior del nuevo elemento apunta hacia el ultimo elemento (es el puntero fin que contiene por ahora su dirección)
  • el puntero siguiente del ultimo elemento apuntará hacia el nuevo elemento
  • el puntero fin apunta hacia el nuevo elemento
  • el puntero inicio no cambia
  • el tamaño es incrementado




La función

int ins_fin_lista(dl_Lista * lista, char *dato){
  dl_Elemento *nuevo_elemento;
  if ((nuevo_elemento = alloc (nuevo_elemento)) == NULL)
    return -1;
  strcpy (nuevo_elemento->dato, dato);
  nuevo_elemento->siguiente = NULL;
  nuevo_elemento->anterior = lista->fin;
  lista->fin->siguiente = nuevo_elemento;
  lista->fin = nuevo_elemento;
  lista->tamaño++;
  return 0;
}

4. Inserción antes de un elemento de la lista


Modelo de la función:

int ins_antes (dl_Lista * lista, char *dato, int pos);


La función devuelve -1 en caso de error, si no devuelve 0.

La inserción se efectuara antes de cierta posición pasado como argumento a la función.
La posición indicada no debe ser ni el primer ni el último elemento. En ese caso hay que utilizar las funciones de inserción al inicio y/o al final de la lista.

Etapas:
  • asignación de memoria al nuevo elemento
  • rellenar el campo de datos del nuevo elemento
  • Elegir una posición en la lista (la inserción se hará después de la posición elegida)
  • el puntero siguiente del nuevo elemento apunta hacia el elemento actual.
  • el puntero anterior del nuevo elemento apunta hacia la dirección hacia la que apunta el puntero anterior del elemento actual.
  • el puntero siguiente del elemento que precede al elemento actual apuntará hacia el nuevo elemento
  • el puntero anterior del elemento actual apunta hacia el nuevo elemento
  • el puntero fin no cambia
  • el puntero inicio cambia si la posición elegida es la posición 1
  • el tamaño se incrementa en una unidad






La función

int ins_antes (dl_Lista * lista, char *dato, int pos){
  int i;
  dl_Elemento *nuevo_elemento, *actual;
  if ((nuevo_elemento = alloc (nuevo_elemento)) == NULL)
    return -1;
  strcpy (nuevo_elemento->dato, dato);
  actual = lista->inicio;
  for (i = 1; i < pos; ++i)
    actual = actual->siguiente;
  nuevo_elemento->siguiente = actual;
  nuevo_elemento-> anterior = actual->anterior;
  if(actual->anterior == NULL)
    lista->inicio = nuevo_elemento;
  else
    actual->anterior->siguiente = nuevo_elemento;
  actual->anterior = nuevo_elemento;
  lista->tamaño++;
  return 0;
}

5. Inserción después de un elemento de la lista


Modelo de la función:

int ins_después (dl_Lista * lista, char *dato, int pos);


La función devuelve -1 en caso de error, si no devuelve 0.

La inserción se efectuará después de cierta posición pasado como argumento a la función.
La posición indicada no debe ser el último elemento. En ese caso hay que utilizar la función de inserción al final de la lista.

Etapas:
  • asignación de memoria al nuevo elemento
  • rellenar el campo de datos del nuevo elemento
  • Elegir una posición en la lista (la inserción se hará después de la posición elegida)
  • el puntero siguiente del nuevo elemento apunta hacia la dirección hacia la que apunta el puntero siguiente del elemento actual (ver la imagen).
  • el puntero anterior del nuevo elemento apunta hacia el elemento actual.
  • el puntero anterior del elemento que va después del elemento actual apuntará hacia el nuevo elemento.
  • el puntero siguiente del elemento actual apunta hacia el nuevo elemento
  • el puntero inicio no cambia
  • el puntero fin cambia si la posición elegida es la posición del ultimo elemento (el tamaño de la lista)
  • el tamaño se incrementa en una unidad





La función

int ins_después (dl_Lista * lista, char *dato, int pos){
  int i;
  dl_Elemento *nuevo_elemento, *actual;
  if ((nuevo_elemento = alloc (nuevo_elemento)) == NULL)
    return -1;
  strcpy (nuevo_elemento->dato, dato);
  actual = lista->inicio;
  for (i = 1; i < pos; ++i)
    actual = actual->siguiente;
  nuevo_elemento->siguiente = actual->siguiente;
  nuevo_elemento->anterior = actual;
  if(actual->siguiente == NULL)
    lista->fin = nuevo_elemento;
  else
    actual->siguiente->anterior = nuevo_elemento;
  actual->siguiente = nuevo_elemento;
  lista->tamaño++;
  return 0;
}

C. Eliminación de un elemento de la lista


A continuación el algoritmo para eliminar un elemento de la lista:
  • uso de un puntero temporal para guardar la dirección de los elementos a eliminar
  • el elemento a eliminar puede encontrase en cualquier posición en la lista.


En relación a la lista enlazada simple en el que la eliminación solo puede ser hecha después que un elemento ha sido designado, las listas doblemente enlazadas son más flexibles gracias a los 2 punteros que permiten guardar el rastro tanto hacia atrás como hacia delante.
  • liberar la memoria ocupada por el elemento eliminado
  • actualizar el tamaño de la lista


Para eliminar un elemento de la lista hay varias situaciones:
  • 1. Eliminación al inicio de la lista
  • 2. Eliminación al final de la lista
  • 3. Eliminación antes de un elemento
  • 4. Eliminación después de un elemento
  • 5 Eliminación de un elemento


Sin embargo, la eliminación al inicio y al final de la lista doblemente enlazada así como antes o después de un elemento equivale a la eliminación en la posición 0 (cero) o en la posición N (N= numero de elementos de la lista) o en otra parte de la lista.

En el caso de listas doblemente enlazadas la eliminación en cualquier posición no presenta ningún problema gracias a los punteros anterior y siguiente, que permiten conservar el enlace entre los elementos de la lista.
Razón por la cual solo vamos a crear una función.
  • si deseamos eliminar el elemento al inicio de la lista elegiremos la posición cero
  • si deseamos eliminar el elemento al final de la lista elegiremos la posición N (el numero de elementos)
  • si deseamos eliminar cualquier elemento entonces elegimos su posición en la lista.

Eliminación en la lista


Modelo de la función:

int supp(dl_Lista *lista, int pos);


La función devuelve -1 en caso de error, si no devuelve 0.

Podemos distinguir varias situaciones:
  • eliminación en la posición 1 en una lista con un solo elemento
  • eliminación en la posición 1 en una lista con varios elementos
  • eliminación en la ultima posición (el ultimo elemento)
  • eliminación en otra parte de la lista en cierta posición


La eliminación en una lista vacía no tiene sentido

Etapas:
  • La posición elegida es 1 (el caso de eliminación del 1er elemento de la lista)
    • el puntero sup_elemento contendrá la dirección del 1er elemento
    • el puntero inicio contendrá la dirección contenida por el puntero siguiente del 1er elemento que deseamos eliminar (si este puntero vale NULL entonces actualizamos el puntero fin ya que estamos en el caso de una lista con un solo elemento, si no hacemos apuntar el puntero anterior del 2do elemento hacia NULL)



  • la posición elegida es igual al numero de elementos de la lista
    • el puntero sup_elemento contendrá la dirección del ultimo elemento
    • hacemos apuntar al puntero siguiente del penúltimo elemento (es el elemento hacia el que apunta el puntero <anterior> del ultimo elemento), hacia NULL
    • actualizamos el puntero fin


  • la posición elegida es aleatoria en la lista
    • el puntero sup_elemento contendrá la dirección del elemento a eliminar
    • el puntero siguiente del elemento que antecede al elemento a eliminar apunta hacia la dirección contenida en el puntero siguiente del elemento a eliminar
    • el puntero anterior del elemento que va después del elemento a eliminar apunta hacia la dirección contenida en el puntero anterior del elemento a eliminar.
    • el tamaño de la lista será disminuida en 1 elemento




La función

int supp(dl_Lista *lista, int pos){
  int i;
  dl_Elemento *sup_elemento,*actual;

  if(lista->tamaño == 0)
    return -1;

  if(pos == 1){ /* eliminación del 1er elemento */
    sup_elemento = lista->inicio;
    lista->inicio = lista->inicio->siguiente;
    if(lista->inicio == NULL)
      lista->fin = NULL;
    else
      lista->inicio->anterior == NULL;
  }else if(pos == lista->tamaño){ /* eliminación del último elemento */
    sup_elemento = lista->fin;
    lista->fin->anterior->siguiente = NULL;
    lista->fin = lista->fin->anterior;
  }else { /* eliminación en otra parte */
    actual = lista->inicio;
      for(i=1;i<pos;++i)
        actual = actual->siguiente;
    sup_elemento = actual;
    actual->anterior->siguiente = actual->siguiente;
    actual->siguiente->anterior = actual->anterior;
  }
  free(sup_elemento->dato);
  free(sup_elemento);
  lista->tamaño--;
  return 0;
}

D. Visualización de la lista


Para mostrar la lista entera podemos posicionarnos al inicio o al final de la lista (el puntero inicio o fin lo permitirá).
Luego utilizando el puntero siguiente o anterior de cada elemento, la lista es recorrida del 1er al ultimo elemento o del ultimo al 1er elemento.
La condición para detener es dada por el puntero siguiente del ultimo elemento que vale NULL en el caso de la lectura del inicio hacia el fin de la lista, o por el puntero anterior del 1er elemento que vale NULL, en el caso de una lectura del final hacia el inicio de la lista.

Las funciones

void affiche(dl_Lista *lista){ /* visualización hacia adelante */
  dl_Elemento *actual;
  actual = lista->inicio; /* punto de inicio el 1er elemento */
  printf("[ ");
  while(actual != NULL){
    printf("%s ",actual->dato);
    actual = actual->siguiente;
  }
  printf("]\n");
}

void mustra_inv(dl_Lista *lista){ /* visualización hacia atrás */
  dl_Elemento *actual;
  actual = lista->fin; /* punto de inicio el ultimo elemento */
  printf("[ ");
  while(actual != NULL){
    printf("%s : ",actual->dato);
    actual = actual->anterior;
  }
  printf("]\n");
}

E. Destrucción de la lista


Para destruir la lista entera, he utilizado la eliminación en la posición 1 ya que el tamaño es mayor a cero.

La función

void destruir(dl_Lista *lista){
  while(lista->tamaño > 0)
    sup(lista,1);
}

V. Ejemplo completo


dlista.h


/* ---------- dlista.h ----------- */
 typedef struct dl_ElementooLista{ 
char *dato; 
struct dl_ElementoLista *anterior;
struct dl_ElementoLista *siguiente; 
} dl_Elemento;

typedef struct dl_ListaIdentificar{
dl_Elemento *inicio;
dl_Elemento *fin;
int tamaño;
} dl_Lista;

 /* inicialización de la liste */
void inicialización (dl_Lista * lista); 
dl_Elemento *alloc (dl_Elemento * nuevo_elemento);

 /* INSERCION */ 
int ins_en_lista_vacia (dl_Lista * lista, char *dato);
int ins_inicio_lista(dl_Lista * lista, char *dato);
int ins_fin_lista(dl_Lista * lista, char *dato);
int ins_después (dl_Lista * lista, char *dato, int pos);
int ins_antes (dl_Lista * lista, char *dato, int pos);


 /*ELIMINACION*/
 int sup(dl_Lista *liste, int pos);
void muestra (dl_Lista * lista);

/**************************/ 
void muestra_inv (dl_Lista * lista);
void destruir (dl_Lista * lista);
/* -------- FIN lista.h --------- */ 

dlista_function.h


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

 *     dlista_function.h    *
\***************************/
void inicialización (dl_Lista * lista){
  lista->inicio = NULL;
  lista->fin = NULL;
  lista->tamaño = 0;
}

int inserción_en_lista_vacia (dl_Lista * lista, char *dato){
  dl_Elemento *nuevo_elemento;
  if ((nuevo_elemento = alloc (nuevo_elemento)) == NULL)
    return -1;
  strcpy (nuevo_elemento->dato, dato);
  nuevo_elemento->anterior = NULL;
  nuevo_elemento->siguiente = NULL;
  lista->inicio = nuevo_elemento;
  lista->fin = nuevo_elemento;
  lista->tamaño++;
  return 0;
}

int ins_inicio_lista(dl_Lista * lista, char *dato){
  dl_Elemento *nuevo_elemento;
  if ((nuevo_elemento = alloc (nuevo_elemento)) == NULL)
    return -1;
  strcpy (nuevo_elemento->dato, dato);
  nuevo_elemento->anterior = NULL;
  nuevo_elemento->siguiente = lista->inicio;
  lista->inicio->anterior = nuevo_elemento;
  lista->inicio = nuevo_elemento;
  lista->tamaño++;
  return 0;
}

int ins_fin_lista(dl_Lista * lista, char *dato){
  dl_Elemento *nuevo_elemento;
  if ((nuevo_elemento = alloc (nuevo_elemento)) == NULL)
    return -1;
  strcpy (nuevo_elemento->dato, dato);
  nuevo_elemento->siguiente = NULL;
  nuevo_elemento->anterior = lista->fin;
  lista->fin->siguiente = nuevo_elemento;
  lista->fin = nuevo_elemento;
  lista->tamaño++;
  return 0;
}

int ins_después (dl_Lista * lista, char *dato, int pos){
  int i;
  dl_Elemento *nuevo_elemento, *actual;
  if ((nuevo_elemento = alloc (nuevo_elemento)) == NULL)
    return -1;
  strcpy (nuevo_elemento->dato, dato);
  actual = lista->inicio;
  for (i = 1; i < pos; <gras>i)
    actual = actual->siguiente;
  nuevo_elemento->siguiente = actual->siguiente;
  nuevo_elemento->anterior = actual;
  if(actual->siguiente == NULL)
    lista->fin = nuevo_elemento;
  else
    actual->siguiente->anterior = nuevo_elemento;
  actual->siguiente = nuevo_elemento;
  lista->tamaño++;
  return 0;
}

int ins_antes (dl_Lista * lista, char *dato, int pos){
  int i;
  dl_Elemento *nuevo_elemento, *actual;
  if ((nuevo_elemento = alloc (nuevo_elemento)) == NULL)
    return -1;
  strcpy (nuevo_elemento->dato, dato);
  actual = lista->inicio;
  for (i = 1; i < pos; <gras>i)
    actual = actual->siguiente;
  nuevo_elemento->siguiente = actual;
  nuevo_elemento-> anterior = actual->anterior;
  if(actual->anterior == NULL)
    lista->inicio = nuevo_elemento;
  else
    actual->anterior->siguiente = nuevo_elemento;
  actual->anterior = nuevo_elemento;
  lista->tamaño++;
  return 0;
}

int sup(dl_Lista *lista, int pos){
  int i;
  dl_Elemento *sup_elemento,*actual;
  
  if(lista->tamaño == 0)
    return -1;

  if(pos == 1){ /* eliminación de 1er elemento */
    sup_elemento = lista->inicio;
    lista->inicio = lista->inicio->siguiente;
    if(lista->inicio == NULL)
      lista->fin = NULL;
    else
      lista->inicio->anterior == NULL;
  }else if(pos == lista->tamaño){ /* eliminacion del ultimo elemento */
    sup_elemento = lista->fin;
    lista->fin->anterior->siguiente = NULL;
    lista->fin = lista->fin->anterior;
  }else { /* eliminacion en otra parte */
    actual = lista->inicio;
    for(i=1;i<pos;<gras>i)
	    actual = actual->siguiente;
    sup_elemento = actual;
    actual->anterior->siguiente = actual->siguiente;
    actual->siguiente->anterior = actual->anterior;
  }
  free(sup_elemento->dato);
  free(sup_elemento);
  lista->tamaño--;
  return 0;
}

void destruir(dl_Lista *lista){
  while(lista->tamaño > 0)
    supp(lista,1);
}

dl_Elemento *alloc (dl_Elemento * nuevo_elemento){
  if ((nuevo_elemento = (dl_Elemento *) malloc (sizeof (dl_Elemento))) == NULL)
    return NULL;
  if ((nuevo_elemento->dato = (char *) malloc (50 * sizeof (char)))
      == NULL)
    return NULL;
  return nuevo_elemento;
}

int menu (dl_Lista *lista){
  int choix;
  if (lista->tamaño == 0){
    printf ("1. Adición del 1er elemento\n");
    printf ("2. Eliminar\n");
  }  else{
    printf ("1. Añadir al inicio de la lista\n");
    printf ("2. Añadir al final de la lista\n");
    printf ("3. Añadir antes de la posición especificada\n");
    printf ("4. Añadir después de la posición especificada\n");
    printf ("5. Eliminacion en la posicion especificada\n");
    printf ("6. Destruir la lista\n");
    printf ("7. Eliminar\n");
  }
  printf ("\n\nElija: ");
  scanf ("%d", &elección);
  getchar();
  if(lista->tamaño == 0 && elección == 2)
    elección = 7;
  return elección;
}
int supp(dl_Lista *lista, int pos);
void muestra(dl_Lista *lista){
	dl_Elemento *actual;
	actual = lista->inicio;
	printf("[ ");
	while(actual != NULL){
		printf("%s ",actual->dato);
		actual = actual->siguiente;
	}
	printf("]\n");
}
void muestra_inv(dl_Lista *lista){
	dl_Elemento *actual;
	actual = lista->fin;
	while(actual != NULL){
		printf("%s : ",actual->dato);
		actual = actual->anterior;
	}
	printf("\n");
}
/* -------- FIN dlista_function.h --------- */

dlista.c


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

 *     dlista.c        *
\**********************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dlista.h"
#include "dlista_function.h"

int main (void)
{

  int elección = 0,pos;
  char *dato;
  dato = malloc(50);
  dl_Lista *lista;
  dl_Elemento *piloto = NULL;
  lista = (dl_Lista *) malloc (sizeof(dl_Lista));

  inicialización(lista);

  while(elección != 7){
    elección = menu(lista);
    switch(elección){
      case 1:
             printf("Ingrese un elemento: ");
	     scanf("%s",dato);
	     getchar();
	     if(lista->tamaño == 0)
               inserción_en_lista_vacia(lista,dato);
	     else
               ins_inicio_lista(lista, dato);
	     printf("%d elementos: deb=%s,fin=%s ",
lista->tamaño,lista->inicio->dato,lista->fin->dato);
	     muestra(lista);
	     break;
      case 2:
	     printf("Ingrese un elemento: ");
	     scanf("%s",dato);
	     getchar();
	     ins_fin_lista(lista, dato);
	     printf("%d elementos: deb=%s,fin=%s ",
		lista->tamaño,lista->inicio->dato,lista->fin->dato);
	     muestra(lista);
	     break;
      case 3:
	     if(lista->tamaño == 1){
           printf("Utilizar la inserción al inicio o al final (Ingrese Menu: 1 ó 2)\n");
	       break;
	     }
	     printf("Ingrese un elemento: ");
	     scanf("%s",dato);
	     getchar();
	     do{
                 printf("Ingrese la posición: ");
		 scanf("%d",&pos);
	     }while (pos < 1 || pos > lista->tamaño);
	     getchar();
	     ins_antes(liste,dato,pos);
	     printf("%d elementos: deb=%s fin=%s ",
		       lista->tamaño,lista->inicio->dato,lista->fin->dato);
	     muestra(lista);
	     break;
      case 4:
	     if(lista->tamaño == 1){
             Printf("Utilizar la inserción al inicio o al final (Ingrese Menu: 1 ó 2)\n");
	     break;
	     }
	     printf("Ingrese un elemento: ");
	     scanf("%s",dato);
	     getchar();
	     do{
                 printf("Ingrese la posicion: ");
		 scanf("%d",&pos);
	     }while (pos < 1 || pos > lista->tamaño);
	     getchar();
	     ins_después(lista,dato,pos);
	     printf("%d elementos: deb=%s,fin=%s ",
	                   lista->tamaño,lista->inicio->dato,lista->fin->dato);
	     muestra(lista);
	     break;
      case 5:
	     do{
                 printf("Ingrese la posición : ");
		 scanf("%d",&pos);
	     }while (pos < 1 || pos > lista->tamaño);
	     getchar();
	     supp(lista,pos);
	     if(lista->tamaño != 0)
               printf("%d elementos: deb=%s,fin=%s ",
		   lista->tamaño,lista->inicio->dato,lista->fin->dato);
	     else
               printf("liste vide : %d elementos",lista->tamaño);
	     muestra(lista);
	     break;
      case 6:
      destruir(lista);
      printf("la lista ha sido destruida: %d elementos\n",lista->tamaño);
      break;
    }
  }
  return 0;
}
/* -------- FIN dlista.c --------- */

VI. Ver también



PD: El artículo original fue escrito por lami20j, contribuidor de CommentCaMarche
Mejores respuestas para « Listas doblemente enlazadas » en :
La lista enlazada simple Ver La lista enlazada simple Pre-requisitos I. Introducción II. Definición III. Construcción del modelo de un elemento de la lista IV. Operaciones sobre las listas enlazadas A. Inicialización B. Inserción de un elemento en la lista 1....
Las listas circulares (Ring Buffer) Verlas listas circulares Requisitos I. Introducción II Definición III. La construcción del modelo de un elemento de la lista IV. Operaciones sobre las listas circulares A. Inicialización B. Inserción de un elemento en la lista 1....
Crear una lista desplegable simple en Excel VerSi deseas que los datos a ingresar de las celdas de tu hoja de cálculo sean elegidos de una lista desplegable. Entonces sigue estos pasos: En una zona de la hoja activa o en otra hoja de tu documento Excel activo, ingresa los datos de la lista en...
Lista de puertos abiertos VerBajo Windows o Linux/Unix, la ejecución del siguiente comando en la consola permite mostrar una lista de puertos abiertos en el PC: netstat -a Para herramientas gráficas más avanzadas, ver ¿Qué puertos están abiertos en nuestra PC? PD: El...
Listas en HTML VerListas Una lista es un párrafo estructurado que contiene una serie de elementos. HTML define tres tipos de listas: Listas ordenadas; Listas no ordenadas; Listas de definiciones. Lista ordenada Contenedor Tipo de lista Efecto...
Listas de correo VerEl concepto de listas de correo La lista de correo es uno de los servicios más usados en Internet, ya que permite que las personas envíen mensajes a uno o más receptores. El correo electrónico fue inventado por Ray Tomlinson en 1972. ...