Agregar nodo a lista doblemente enlazada (lenguaje C)

Iniciado por NOB2014, 31 Julio 2016, 18:18 PM

0 Miembros y 1 Visitante están viendo este tema.

NOB2014

Hola, buen día para todos. -
Como me pareció tener claro listas simplemente enlazada http://foro.elhacker.net/programacion_cc/borrar_nodo_en_lista_simplemente_enlazadac-t455556.0.html me metí con lista doblemente enlazada y tengo una parte que no puedo solucionar, me parece que la función crear para el primer nodo funciona, pero cuando agrego 2,3,4 no puede el anterior apuntar a NULL, por más que practique no me sale, por momento parece en mi mente que es una bobada pero cuando lo llevo a la práctica no me resulta. -   
Si le es posible desearía que me digan si la función agregar es correcta. - 

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

struct nodo{
int dato;
struct nodo *anterior, *siguiente;
};

struct lista{
struct nodo *primero, *ultimo;
int elementos;
};

void menu( void );
void limpiar( void );
struct lista *agregar( struct lista *L );
struct nodo *crear( int dato );


int main( void ){

menu();

return 0;
}


void menu( void ){
struct lista *Lista = NULL;
Lista->elementos=0;
int opc, ok, ch;

do{
do{
limpiar();
printf( "\n ========== Menu Principal ==========\n" );
if( Lista != NULL)
printf( "\n Total de datos.....:%d\n", Lista->elementos );
printf(" \n 1 - Agregar\n 2 - buscar\n 3 - Ordenar " );
printf(" \n 4 - Total\n 5 - Finalizar\n\n Ingrese Opcion....: "  );
ok = scanf( "%d", &opc ) == 1 && opc > 0 && opc <= 5;
while ((ch = getchar()) != EOF && ch != '\n');
}while( !ok );

switch ( opc ){
case 1: Lista = agregar( Lista );
break;
case 2: //Lista = buscar( Lista );
break;
case 3: //ordenar( Lista );
break;
case 4: //mostrar( Lista );
break;
case 5:;
free( Lista );
break;
}
}while( opc != 5 );

}

void limpiar( void ){
system("cls||clear");
}

struct lista *agregar( struct lista *L ){
int ok, ch, dto;

do{
limpiar();
printf( "\n Ingrese dato (mayor a 0 y menor a %d)....: ", INT_MAX );
ok = scanf( "%d", &dto ) == 1 && dto >0 && dto <= INT_MAX;
while ((ch = getchar()) != EOF && ch != '\n');
}while( !ok );

if( L != NULL ){
struct nodo *e = crear( dto );
L->ultimo->siguiente = e;
L->ultimo = e;
L->elementos++;
return L;
}else{
struct nodo *e = crear( dto );
struct lista *l = calloc( sizeof( struct lista ), 1 );
l->primero = e;
l->ultimo = e;
l->elementos = 1;
return l;
}

return L;
}

struct nodo *crear( int dato ){
struct nodo *e = calloc( sizeof( struct nodo), 1 );

e->dato = dato;
e->siguiente = NULL;
e->anterior = NULL;

return e;
}


Un abrazo. -
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

AlbertoBSD

#1
Como bien dices la falla esta al agregar los nodos despues del primero.

Lo primero que tienes que definir es

¿En donde Agrego loa nodos nuevos? ¿Al final? ¿Al principio?

Ahora sobre papel irlos agregando "A mano" y ver todo s los cambios que debes  a hacer.

Supongo que agregaras los nodos al final.

Tu codigo actual:

if( L != NULL ){
struct nodo *e = crear( dto );
L->ultimo->siguiente = e;
L->ultimo = e;
L->elementos++;
return L;
}


Cosas que hay que redefinir suponiendo que los nodos nuevos se agregen al ultimo:


  • El ultimo Nodo (Nuevo nodo) en su valor siguiente Debe de apuntar a el primero
  • El primer nodo en su valor anterior debe de apuntar al nodo nuevo

Cambios en comentarios
if( L != NULL ){
struct nodo *e = crear( dto );
L->ultimo->siguiente = e;
L->ultimo = e;
//e->siguiente = L->primero;
//L->primero->anterior = e;
L->elementos++;
return L;
}


Y cuando es el nodo inicial ( En el else) hace falta hacer cosas similares con el anterior y siguiente del primer nodo (nodo e)

Espero y sea suficiente xD

Saludos
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

NOB2014

Hola.
Decime si la imagen es correcta, si tengo un solo nodo el recuadro de la izquierda esta bien, si agrego un nuevo nodo las flechas indicarían las modificaciones que debo hacer. -



CitarEl ultimo Nodo (Nuevo nodo) en su valor siguiente Debe de apuntar a el primero
    El primer nodo en su valor anterior debe de apuntar al nodo nuevo

esto no lo entiendo, para mí está equivocado, perdón...

Saludos.
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

NOB2014

#3
struct lista *agregar( struct lista *L, int *contactos ){
int ok, ch, dto;

do{
limpiar();
printf( "\n Ingrese dato (mayor a 0 y menor a %d)....: ", INT_MAX );
ok = scanf( "%d", &dto ) == 1 && dto >0 && dto <= INT_MAX;
while ((ch = getchar()) != EOF && ch != '\n');
}while( !ok );

if( L != NULL ){
struct nodo *e = crear( dto );
e->anterior = L->ultimo;
L->actual = e;
L->ultimo->siguiente = e;
L->ultimo = e;
*contactos += 1;
return L;
}else{
struct nodo *e = crear( dto );
struct lista *l = calloc( sizeof( struct lista ), 1 );
l->primero = e;
l->ultimo = e;
l->actual = e;
*contactos += 1;
return l;
}

return L;
}

struct nodo *crear( int dato ){
struct nodo *e = calloc( sizeof( struct nodo), 1 );

e->dato = dato;
e->siguiente = NULL;
e->anterior = NULL;

return e;
}

Saludos.
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

ivancea96

Cita de: NOB2014 en 31 Julio 2016, 20:11 PM
esto no lo entiendo, para mí está equivocado, perdón...

Sí bueno, eso es en las listas circulares, no en las doblemente enlazadas.

AlbertoBSD

Una disculpa si me confundi de estrucutra de datos.
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

NOB2014

Hola, gente.
Tal vez fui un tanto duro, pero no entendía porque nadie respondía a mi necesidad, algo que para Uds. debe ser tan simple como respirar(la imagen), de cualquier manera deje mi código ya que lo pude lograr por mí mismo, seguramente se debe poder optimizar pero por lo menos funciona. -
Una cosa que me desconcertó es el emoticón o como se llame(desconozco ese tipo moderno de comunicarse) cag. de risa con los ojos cerrados, no me agrado demasiado. - 
Por último, si para alguien le es molesto mi manera de preguntar casi continuamente, no se obliguen a contestarme no hay ningún problema voy a saber entender que debo cambiar mi insistencia y arreglármelas más a solas al fin me ocasionara un poco de perdida de tiempo, no creo que sea más que eso, por favor no olviden aquello de que tengo 64 años y no encuentro demasiados "amigos" para consultar. -
Lo dejo a su consideración.-

Saludos. 
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

AlbertoBSD

Me aleagra que lograras el cometido por tu cuenta.

Y me confundí por la estructura ya que son muy similares por ejemplo un reproductor de música cuando tiene su "Lista" de canciones solo tiene funciones de anterior y siguiente (Adicioanles al Play) y también tiene una opción que se llama "repetir todas" la cual convierte la lista doblemente ligada en una lista circular  y segun recuerdo la diferencia solo es esa (Los nodos ultimpo y primero apuntan entre si).

De hecho es un buen ejercicio. Convertir una lista Doblemente ligada en una Circular.

Saludos.
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW