La Web del Programador: Comunidad de Programadores
 
    Pregunta:  3380 - LISTAS ENLAZADAS
Autor:  ALDAIR PIRRINHA DE LOS SANTOS
urgente!! soy estudiante de la UTC en Quintana Roo, Mexico, y tengo una dificultad para poder construir listas en lazadas en Tc++, desde crear el primer elemento, recorrer la lista, insertar...etc. si alguien pudiera ayudarme a construir la lista, y enviarme una breve explicacion, de verdad!!! se lo agradeceria...!!! Muchas gracias!!

  Respuesta:  Endos
/*******************************************************
* Demostracion del uso de listas doblemente enlazadas *
* (c)2000 Endos, [email protected] *
* - Dominio publico - *
*******************************************************/

#include <stdio.h>

struct ListaDoble
{
int UnDato; // Colocar los datos que sean necesarios
// ...

ListaDoble *Siguiente; // Puntero a la siguiente lista
ListaDoble *Anterior; // Puntero a la anterior lista
}inicioListaDoble;


// Devuelve un puntero a la lista que sigue a ´ListaActual´
ListaDoble *SiguienteLista(ListaDoble *ListaActual)
{
return ListaActual->Siguiente;
}

// Devuelve un puntero a la lista anterior a ´ListaActual´
ListaDoble *AnteriorLista(ListaDoble *ListaActual)
{
return ListaActual->Anterior;
}

// Inserta una nueva lista justo detras de ´ListaActual´
ListaDoble *InsertarLista(ListaDoble *ListaActual)
{
// Crear una nueva
ListaDoble *NuevaLista= new ListaDoble;

// Actualizar punteros anterior y siguiente

NuevaLista->Anterior=ListaActual;
NuevaLista->Siguiente=SiguienteLista(ListaActual);

if(NuevaLista->Siguiente) // Solo si no es NULL
NuevaLista->Siguiente->Anterior=NuevaLista;

ListaActual->Siguiente=NuevaLista;

return NuevaLista; // Retornar la nueva lista creada
}

// Elimina la lista ´ListaActual´ y devuelve un puntero a la siguiente lista
ListaDoble *EliminarLista(ListaDoble *ListaActual)
{
ListaDoble *Siguiente;

// Actualizar los punteros de las listas anterior y siguiente a la actual

Siguiente=SiguienteLista(ListaActual); // Aprovechar para guardar el siguiente
ListaActual->Anterior->Siguiente=Siguiente;

if(ListaActual->Siguiente) // Solo si no es NULL
ListaActual->Siguiente->Anterior=AnteriorLista(ListaActual);

// Ahora que ya tenemos resueltos los punteros podemos eliminar la lista
delete ListaActual;

return Siguiente;
}

// Test simple
// NOTA: !!La lista 0 no se creo con ´new´ asi que no puede eliminarse!!
int main(void)
{
ListaDoble *Primera=&inicioListaDoble; // Puntero a la primera lista
ListaDoble *OtraLista;
ListaDoble *Ultima;

// Indicar que no hay nada antes y despues
Primera->Anterior=NULL;
Primera->Siguiente=NULL;
Primera->UnDato=0; // Colocar un dato (lo haremos coincidir con su posicion)

OtraLista=InsertarLista(Primera); // Insertar una nueva lista
OtraLista->UnDato=1;

for(int bucle=2; bucle<17; bucle++) // Insertar 15 listas mas
{
OtraLista=InsertarLista(OtraLista);
OtraLista->UnDato=bucle;
}

// Listar los datos (Hay 17 listas - de 0 a 16 -)
OtraLista=Primera; // Del principio al final

printf("Aqui estan todas las listas creadas\n\n");

// Aprovecharemos tambien para borrar una lista
while(OtraLista) // Repetir hasta alcanzar el NULL
{
printf("%u - ",OtraLista->UnDato);

if(OtraLista->UnDato==8) // Si es la 8 borrarla
OtraLista=EliminarLista(OtraLista);
else
OtraLista=SiguienteLista(OtraLista);
}

// Ahora volveremos a listar para ver si se eliminio la entrada novena (8)
// a la par que insertamos una nueva entrada en medio de la lista
// Las anteriores inserciones fueron al final de esta
// Tambien eliminamos una entrada para que se vea que es posible insertar
// y eliminar en cualquier parte sin problemas

OtraLista=Primera; // Del principio al final

printf("\n\nListando de nuevo, ahora no debe salir el 8"
" que borramos antes\n pero si el 17 que insertamos ahora"
" detras del 12\n\n");

while(OtraLista) // Hasta alcanzar el NULL que indica el final
{
Ultima=OtraLista; // Guardar la ultima

printf("%u - ",OtraLista->UnDato);

if(OtraLista->UnDato==2) // Si es la 2 borrarla
OtraLista=EliminarLista(OtraLista);
else
if(OtraLista->UnDato==12) // Si es la 12 insertar una nueva (Nº17)
{
OtraLista=InsertarLista(OtraLista);
OtraLista->UnDato=17; // Colocar aqui un 12 causaria un bucle infinito
}
else
OtraLista=SiguienteLista(OtraLista);
}

// Ahora solo nos falta recorrer la lista al reves

printf("\n\nListando de nuevo, ahora del ultimo al primero."
" El 2 fue eliminado antes\n\n");

OtraLista=Ultima; // Ahora del ultimo al primero

while(OtraLista)
{
printf("%u - ",OtraLista->UnDato);
OtraLista=AnteriorLista(OtraLista);
}

// Ya hemos terminado y debemos liberar la memoria ocupada por las listas

printf("\n\nBorrando todas las listas para liberar la memoria\n");

// RECUERDA:
OtraLista=SiguienteLista(Primera); // La primera lista no se creo con ´new´
// asi que borrar a partir de la segunda

printf("\nEliminando Listas ");
while(OtraLista) // Repetir hasta que sea la ultima (NULL)
{
printf("%u, ",OtraLista->UnDato);
OtraLista=EliminarLista(OtraLista);
}

// La memoria esta libre, insertamos, eliminamos y listamos en ambos sentidos

printf("\n\nTest finalizado OK\n");

return 0;
}

  Respuesta:  Eduard Garcia
Puedes realizar la lista de dos maneras. La puedes realizar simplemente apuntada o doblemente apuntada.
El metodo más adequado y que utilizo siempre es la lista doblemente apuntada, es mas compleja en su realización pero es mucho más fácil de recorrer.

Por la largada de la respuesta, esta en el archivo resp3380.txt