Anda di halaman 1dari 8

7.

2 Listas doblemente enlazadas

Las listas simplemente enlazadas tienen un gran inconveniente, que limita su utilización
extensiva: la lista no se puede recorrer en sentido inverso. Por esta razón se utilizan
generalmente las listas doblemente enlazadas.

Las listas doblemente enlazadas consisten en elementos que contienen datos y dos
enlaces, uno al siguiente elemento y el otro al elemento procedente. Una lista que tiene
dos enlaces en lugar de uno solo, tiene dos grandes ventajas:

1.- La lista se puede se leer en cualquier dirección, esto no solo simplifica la ordenación
de la lista, si no también, en el caso de una base de datos, permite a un usuario explorar
la lista en cualquier dirección.

2.- Ya sea que con el enlace hacia delante o con el enlace hacia atrás se puede leer la
lista completa, si un enlace se pierde o no es válido, la lista se puede reconstruir usando
el otro enlace. Esto tiene sentido solo en caso de una falla de equipo.

En la siguiente figura se muestra como se encuentran colocados estos enlaces en una


lista doblemente enlazada.

Construcción de una lista doblemente enlazada

Construir una lista doblemente enlazada es similar a construir una lista simplemente
enlazada, excepto que la estructura tiene que tener un sitio para albergar enlaces.

Al construir una lista doblemente enlazada, se pueden realizar tres operaciones


primarias:

1. Insertar un primer nuevo elemento.


2. Insertar un nuevo elemento en medio de dos.
3. Insertar un nuevo elemento al final.
Estas tres operaciones se muestran en la siguiente figura.

1.- Copiar primero en nuevo sig


2.- nuevo ant= null
3.- primero ant= nuevo
4.- primero=nuevo

1. copiar último en nuevo ant.


2. nuevo sig= null
3. ultimo sig = nuevo
4. ultimo = nuevo
Borrado de elementos de una lista doblemente enlazada.

La operación de borrado de un nodo en una lista doblemente ligada, al igual que en el


caso de las listas simplemente enlazadas, consiste en eliminar un elemento de la lista y
restablecer las ligas que correspondan.

Hay tres casos a considerar cuando se borra un elemento de una lista doblemente
enlazada:

1. Borrar el primer elemento.


2. Borrar un elemento en medio de dos.
3. Borrar el último elemento.

En las siguientes figuras se muestra como se reordena los enlaces para cada caso:

1. índice = primero
2. primero = primero -> sig
3. índice sig= null
4. principio ant= null

1. índice = primero
2. buscar en índice sig el elemento a borrar
3. copiar borrado = índice sig
4. indice sig = borrado sig
5. borrado sig ant= índice
6. borrado sig= null,
7. borrado ant=null
8. delete (borrado)
1. Índice = ultimo
2. último = ultimo ant
3. índice ant = null
4. ultimo sig = null
PROGRAMA #17

Programa que sirve para crear y manejar una lista doblemente enlazada de números
enteros.

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <iostream>

using namespace std;

class dato
{

int x;
struct dato *sig;
struct dato *ant;

public:
dato *primero, *nuevo, *indice, *ultimo;

void asigna_memoria(void);
void intro_dato(void);
void lista_datos1(void);
void lista_datos2(void);
dato *busca_dato(void);
void borra_dato(void);
};

void dato::asigna_memoria(void)
{
nuevo= new (class dato);
if(nuevo == NULL)
cout <<"\n No hay espacio de memoria";
else
cout <<"\n Se asigna espacio de memoria para el nuevo elemento";
}

void dato::intro_dato(void)
{
asigna_memoria();
if(nuevo == NULL) return;
if( primero == NULL)
{
primero = indice = ultimo = nuevo;
nuevo->sig = NULL;
nuevo->ant = NULL;
}
else
{ indice = primero;
while(indice ->sig != NULL)
indice = indice ->sig;
indice->sig = nuevo;
nuevo->sig = NULL;
nuevo->ant = indice;
indice = ultimo = nuevo;
}
cout <<"\n Dame el dato (entero):";
cin >> indice->x;
}

void dato::lista_datos1(void)
{
cout <<"\n LISTA LOS DATOS DEL PRINCIPIO AL FINAL ";
if(primero == NULL)
{cout <<"\n LISTA VACIA "; return; }
indice = primero;
do {
cout <<"\nDATO= "<<indice ->x;
indice = indice->sig;
} while (indice != NULL); cout << "\n";
}

void dato::lista_datos2(void)
{
cout <<"\n LISTA LOS DATOS DEL FINAL AL PRINCIPIO";
if(primero == NULL || ultimo == NULL)
{cout <<"\n LISTA VACIA "; return; }
indice = ultimo;
do {
cout <<"\nDATO= "<<indice ->x;
indice = indice->ant;
} while (indice != NULL); cout << "\n";
}

dato *dato::busca_dato(void)
{
int xdato;
cout <<"\n BUSQUEDA DE UN DATO ";
cout <<"\n Dato a buscar : ";
cin >>xdato;
if(primero == NULL)
{cout <<"\n LISTA VACIA "; return(NULL); }
indice = primero;
do {
if(xdato == indice->x)
{ cout <<"\n Si esta el dato "<<indice->x << " en la lista";
return(indice);
}
indice = indice->sig;
}while (indice != NULL);
cout <<"\n NO SE encontro el dato "<< xdato << " en la lista";
return(NULL);
}

void dato::borra_dato(void)
{
dato *y;
cout <<"\n BUSQUEDA DEL DATO A BORRAR ";
y = busca_dato();
if(y == NULL) return;
cout <<"\n Se encontro el dato a borrar : "<< y->x << " y se procede a borrar\n";
indice = y;
if(y == primero)
{
primero = primero->sig; y->sig = NULL;
if(primero != NULL) primero->ant = NULL;
delete(y);
return;}
if(y == ultimo)
{
ultimo = ultimo->ant; y->ant = NULL;
if( ultimo != NULL) ultimo->sig = NULL;
delete(y);
return;}

indice=primero;
while(indice ->sig != y)
indice = indice->sig;
indice -> sig = y->sig;
y->sig->ant = indice;

delete (y);
}

main(void)
{
dato lista;
int opcion;
lista.primero=NULL;
lista.nuevo=NULL;
lista.indice=NULL;
lista.ultimo=NULL;

for(;;)
{
cout <<"\n MANEJO DE UNA LISTA DOBLEMENTE ENLAZADA";
cout <<"\n 1. Introducir un dato a lista";
cout <<"\n 2. Listar la lista del principio al final";
cout <<"\n 3. Listar la lista del final al principio";
cout <<"\n 4. Busqueda de un dato";
cout <<"\n 5. Borrado de un dato";
cout <<"\n 6. Salir";
cout <<"\n opcion : ";
cin >>opcion;
switch(opcion)
{ case 1: lista.intro_dato();
break;
case 2: lista.lista_datos1();
break;
case 3: lista.lista_datos2();
break;
case 4: lista.busca_dato();
break;
case 5: lista.borra_dato();
break;
case 6: cout << "\nFIN";
getch();
exit(0);
}
}
}

Anda mungkin juga menyukai