|
131
|
Programación / Programación C/C++ / Agregar nodo a lista doblemente enlazada (lenguaje C)
|
en: 31 Julio 2016, 18:18 pm
|
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:; break; } }while( opc != 5 ); } void limpiar( void ){ } 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. -
|
|
|
132
|
Programación / Programación C/C++ / Re: Borrar nodo en lista simplemente enlazada[C]
|
en: 28 Julio 2016, 14:22 pm
|
Hola, que tengan un muy buen día. - Alberto, muchas gracias funcionan a la perfección, me queda un consuelo que no estaba tan errado, solo me queda ahora lidiar con que el nodo a borrar no sea ni el primero ni el último. - Un abrazo. ==================== EDITO ====================Bueno al fin lo logre, por lo menos para mí no da ningún error, dejo la función borrar completa por si alguien la quiere consultar o corregir. - struct lista *borrar( struct lista *L, struct nodo *borrar ){ if( L->elementos == 1 ){ //LSE001 L = NULL; } else if( L->primero == borrar ){ //LSE002 L->primero = borrar->siguiente; //LSE003 L->elementos--; } else if( borrar->siguiente == NULL){ //LSE004 struct nodo *aux = L->primero; while( aux->siguiente != borrar ){ aux = aux->siguiente; } //LSE005 L->ultimo = aux; //LSE006 L->elementos--; aux->siguiente = NULL; //LSE007 } else{ //LSE008 struct nodo *aux = L->primero; while( aux->siguiente != borrar ){ //LSE009 aux = aux->siguiente; } aux->siguiente = borrar->siguiente; //LSE010 L->elementos--; //LSE011 } return L; } /* =============================== Ayuda =============================== LSE001 Verificamos si la cantidad de ingresos es un solo dato, de ser así con L = NULL inicializamos toda la lista a cero, pero permanece en memoria para nuevos ingresos. LSE002 En caso de no ser el único ingreso verificamos si es el primer Nodo, LSE003 De ser así igualamos el primer Nodo a borrar->siguiente, de esa manera el que era el segundo pasa a ser el primero Nodo y el primero es borrado. LSE004 A esta altura el nodo a borrar es el último. LSE005 A esta altura el nodo aux es el penultimo. LSE006 El que antes era penúltimo ahora será el último. LSE007 El apuntador siguiente del último Nodo debe de apuntar a NULL. LSE008 Por último, llegamos a este else porque el Nodo a borrar no es el único ni es el primero ni es el último, se encuentra entre estos dos. LSE009 Con este bucle obtenemos la dirección de memoria donde está el nodo anterior al que queremos borrar. LSE010 aux->siguiente ahora ya no apunta al Nodo siguiente que es el que queremos borrar apunta al Nodo siguiente al que borraremos. LSE011 Decrementamos el contador de nodos. LSE012 Liberamos memoria. */
|
|
|
133
|
Programación / Programación C/C++ / Re: Borrar nodo en lista simplemente enlazada[C]
|
en: 28 Julio 2016, 02:37 am
|
Hola. ivancea96 mucha gracia por ocuparte, con respecto a lo primero era para confirmar que estaba en lo cierto, no te olvides que estoy aprendiendo y necesitaba saber si las validaciones eran lo suficiente para hacer que el programa diera resultados correctos. - Bueno ahora tengo inconvenientes desde la línea 230 a la 239, ¿alguien me podría dar una mano con esto? . - El programa no me da ningún error, pero el resultado es incorrecto. - Si el ingreso es 1 3 5 y trato de borrar el último nodo me da como resultado 1 3 0. - El programa lo pongo completo porque tuve que efectuar algunas modificaciones. - #include <stdio.h> #include <stdlib.h> #include <limits.h> struct nodo{ int dato; struct nodo *siguiente; }; struct lista{ struct nodo *primero; struct nodo *ultimo; int elementos; }; void menu( void ); struct lista *menuUno( struct lista *L, struct nodo *N ); void limpiar( void ); struct lista *agregar( struct lista *L ); struct nodo *crear( int dato ); void mostrar( struct lista *L ); void ordenar( struct lista *L ); struct lista *buscar( struct lista *L ); void modificar( struct nodo *pivote ); struct lista *borrar( struct lista *L, struct nodo *borrar ); int main( void ){ menu(); return 0; } void menu( void ){ struct lista *Lista = NULL; 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:; break; } }while( opc != 5 ); } struct lista *menuUno( struct lista *L, struct nodo *N ){ int opc, ok, ch; do{ do{ limpiar(); printf( "\n ========== Menu ==========\n" ); printf(" \n 1 - Modificar\n 2 - Borrar\n 3 - Salir" " \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: modificar( N ); opc=3; break; case 2: L = borrar( L, N ); opc=3; break; case 3: break; } }while( opc != 3 ); return L; } void limpiar( void ){ } 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; } } struct nodo *crear( int dato ){ struct nodo *e = calloc( sizeof( struct nodo ), 1 ); e->dato = dato; e->siguiente = NULL; return e; } void mostrar( struct lista *L ){ struct nodo *auxiliar; int i=0; if( L != NULL ){ auxiliar = L->primero; while( auxiliar != NULL ){ printf( "\n %d", auxiliar ->dato ); auxiliar = auxiliar->siguiente; i++; } }else{ printf( "\n La lista esta vacia..." ); } printf( "\n Pulse una tecla para continuar..." );getchar (); } void ordenar( struct lista *L ){ struct nodo *pivote = NULL, *actual = NULL; int tmp; if( L != NULL ){ pivote = L->primero; while( pivote != L->ultimo ){ actual = pivote->siguiente; while( actual != NULL ){ if( pivote->dato > actual->dato ){ tmp = pivote->dato; pivote->dato = actual->dato; actual->dato = tmp; } actual = actual->siguiente; } pivote = pivote->siguiente; } mostrar( L ); }else{ printf( "\n La lista esta vacia..." ); printf( "\n Pulse una tecla para continuar..." );getchar (); } } struct lista *buscar( struct lista *L ){ int ok, ch, dto, i=0; struct nodo *pivote = NULL; if( L != NULL ){ do{ limpiar(); printf( "\n Ingrese el dato a buscar....: " ); ok = scanf( "%d", &dto ) == 1 && dto >0 && dto <= INT_MAX ; while ((ch = getchar()) != EOF && ch != '\n'); }while( !ok ); pivote = L->primero; while( pivote != NULL ){ if( pivote->dato == dto ){ L = menuUno( L, pivote ); i++; break; } pivote = pivote->siguiente; } if( i == 0 ){ printf( "\n El dato no existe..." ); printf( "\n Pulse una tecla para continuar..." );getchar (); } }else{ printf( "\n La lista esta vacia..." ); printf( "\n Pulse una tecla para continuar..." );getchar (); } return L; } void modificar( struct nodo *pivote ){ int ok, ch, dto; do{ limpiar(); printf( "\n Dato a modificar.....: %d \n Ingrese nuevo dato...: ", pivote ->dato ); ok = scanf( "%d", &dto ) == 1 && dto >0 && dto <= INT_MAX ; while ((ch = getchar()) != EOF && ch != '\n'); }while( !ok ); pivote->dato = dto; } struct lista *borrar( struct lista *L, struct nodo *borrar ){ if( L->elementos == 1 ){ L = NULL; } else if( borrar == L->primero){ L->primero = borrar->siguiente; L->elementos--; } else if( borrar->siguiente == NULL){ struct nodo *aux = L->primero; while( aux->siguiente != NULL ){ aux = aux->siguiente; } L->ultimo = aux; L->elementos--; aux->siguiente = NULL; } else{ printf( "\n Esta entre el primer dato y el ultimo..." ); } return L; }
Saludos y desde ya muchas gracias. -
|
|
|
134
|
Programación / Programación C/C++ / Borrar nodo en lista simplemente enlazada[C]
|
en: 24 Julio 2016, 18:33 pm
|
Hola, que tengan un muy buen día. - Tengo actualmente 2 dudas que se encuentran en las funciones menuUno y borrar. - La primera: necesito alguna validación más o con estas cuatro es suficiente para saber si el nodo es el único y de no ser el único si es el primero o si es el último o está entre ambos. - La restante es: si dentro de if( L->elementos == 1 ) pongo L=NULL, esto es suficiente y si la función llamadora se entera del cambio o tengo que hacer un return. - #include <stdio.h> #include <stdlib.h> #include <limits.h> struct nodo{ int dato; struct nodo *siguiente; }; struct lista{ struct nodo *primero; struct nodo *ultimo; int elementos; }; void menu( void ); void menuUno( struct lista *L, struct nodo *N ); void limpiar( void ); struct lista *agregar( struct lista *L ); struct nodo *crear( int dato ); void mostrar( struct lista *L ); void ordenar( struct lista *L ); void buscar( struct lista *L ); void modificar( struct nodo *pivote ); void borrar( struct lista *L, struct nodo *pivote ); int main( void ){ menu(); return 0; } void menu( void ){ struct lista *Lista = NULL; 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: buscar( Lista ); break; case 3: ordenar( Lista ); break; case 4: mostrar( Lista ); break; case 5:; break; } }while( opc != 5 ); } void menuUno( struct lista *L, struct nodo *N ){ int opc, ok, ch; do{ do{ limpiar(); printf( "\n ========== Menu ==========\n" ); printf(" \n 1 - Modificar\n 2 - Borrar\n 3 - Salir" " \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: modificar( N ); opc=3; break; case 2: borrar( L, N ); opc=3; break; case 3: break; } }while( opc != 3 ); } void limpiar( void ){ } 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; } } struct nodo *crear( int dato ){ struct nodo *e = calloc( sizeof( struct nodo ), 1 ); e->dato = dato; e->siguiente = NULL; return e; } void mostrar( struct lista *L ){ struct nodo *auxiliar; int i=0; if( L != NULL ){ auxiliar = L->primero; while( auxiliar != NULL ){ printf( "\n %d", auxiliar ->dato ); auxiliar = auxiliar->siguiente; i++; } }else{ printf( "\n La lista esta vacia..." ); } printf( "\n Pulse una tecla para continuar..." );getchar (); } void ordenar( struct lista *L ){ struct nodo *pivote = NULL, *actual = NULL; int tmp; if( L != NULL ){ pivote = L->primero; while( pivote != L->ultimo ){ actual = pivote->siguiente; while( actual != NULL ){ if( pivote->dato > actual->dato ){ tmp = pivote->dato; pivote->dato = actual->dato; actual->dato = tmp; } actual = actual->siguiente; } pivote = pivote->siguiente; } mostrar( L ); }else{ printf( "\n La lista esta vacia..." ); printf( "\n Pulse una tecla para continuar..." );getchar (); } } void buscar( struct lista *L ){ int ok, ch, dto, i=0; struct nodo *pivote = NULL; if( L != NULL ){ do{ limpiar(); printf( "\n Ingrese el dato a buscar....: " ); ok = scanf( "%d", &dto ) == 1 && dto >0 && dto <= INT_MAX ; while ((ch = getchar()) != EOF && ch != '\n'); }while( !ok ); pivote = L->primero; while( pivote != NULL ){ if( pivote->dato == dto ){ menuUno( L, pivote ); i++; break; } pivote = pivote->siguiente; } if( i == 0 ){ printf( "\n El dato no existe..." ); printf( "\n Pulse una tecla para continuar..." );getchar (); } }else{ printf( "\n La lista esta vacia..." ); printf( "\n Pulse una tecla para continuar..." );getchar (); } } void modificar( struct nodo *pivote ){ int ok, ch, dto; do{ limpiar(); printf( "\n Dato a modificar.....: %d \n Ingrese nuevo dato...: ", pivote ->dato ); ok = scanf( "%d", &dto ) == 1 && dto >0 && dto <= INT_MAX ; while ((ch = getchar()) != EOF && ch != '\n'); }while( !ok ); pivote->dato = dto; } void borrar( struct lista *L, struct nodo *pivote ){ if( L->elementos == 1 ){ printf( "\n Es el unico dato..." ); } else if( pivote == L->primero){ printf( "\n Es el primer dato..." ); } else if( pivote->siguiente == NULL){ printf( "\n Es el ultimo dato..." ); } else{ printf( "\n Esta entre el primer dato y el ultimo..." ); } }
Es todo por el momento, es probable que me surgen algunas otras dudas. - Saludos.
|
|
|
135
|
Programación / Programación C/C++ / Re: Crear un array de caracteres mediante una funcion.
|
en: 21 Julio 2016, 16:29 pm
|
Hola. void limpiarBuffer( char cadena[] ){ char *p = NULL; size_t ch; if((p =strchr(cadena , '\n'))){ //LB01 *p='\0'; } else{ while((ch = getchar()) !='\n' && ch !=EOF ); //LB02 } }
/* LB01 strchr busca un carácter dentro de una cadena, si lo encuentra devuelve la dirección en memoria donde se encuentra el carácter , en este caso '\n' (Enter) si lo encuentra lo remplaza por '\0' que es el carácter que marca el final de cadena en C. LB02 Si no lo encuentra es que en el buffer del teclado han quedado caracteres sin leer, con este bucle y la función getchar el buffer queda limpio, sin nada pendiente de lectura.- Faltaria explicarte que pasa si el buffer queda con pendientes pero eso lo tengo entendido pero no me da para explicartelo. Saludos.
|
|
|
137
|
Programación / Programación C/C++ / Re: segmentation fault al mostrar lista simplemente ligada en lenguaje C.
|
en: 20 Julio 2016, 17:03 pm
|
Hola. Gracias, ya lo logre, juraría que en un momento lo intente de la manera que tú dices, pero algún otro error seguramente estaba cometiendo. void mostrar( struct lista *L ){ struct nodo *auxiliar; int i=0; if( L != NULL ){ auxiliar = L->primero; while( auxiliar != NULL ){ printf( "\n %d", auxiliar ->dato ); auxiliar = auxiliar->siguiente; i++; } }else{ printf( "\n La lista esta vacia..." ); } printf( "\n Pulse una tecla para continuar..." );getchar (); }
Gracias Alberto y un abrazo.
|
|
|
138
|
Programación / Programación C/C++ / segmentation fault al mostrar lista simplemente ligada en lenguaje C.
|
en: 20 Julio 2016, 16:28 pm
|
Hola, que tengan un muy buen día. Nuevamente Danielito con algún inconveniente con lista enlazada, lo que ocurre es que si ingreso un dato o más todo bien pero si la lista está vacía me da el error que dejo en la imagen a continuación. - Encuentro muchos ejs., pero casi todos son sin ingreso por teclado sino con datos ingresados antes de compilar, me parece que tiene que ver conque la lista esta igualada a NULL o sea que no apunta a ninguna dirección en concreto pero no logro dar con la tecla #include <stdio.h> #include <stdlib.h> #include <limits.h> struct nodo{ int dato; struct nodo *siguiente; }; struct lista{ struct nodo *primero; struct nodo *ultimo; int elementos; }; void menu( void ); void limpiar( void ); struct lista *agregar( struct lista *L ); struct nodo *crear( int dato ); void mostrar( struct lista *L ); int main( void ){ menu(); return 0; } void menu( void ){ struct lista *Lista = NULL; int opc, ok, ch; do{ do{ limpiar(); printf( "\n ========== Menu ==========\n" ); printf(" \n 1 - Agregar\n 2 - Buscar\n 3 - Borrar\n 4 - Ordenar " ); printf(" \n 5 - Total\n 6 - Finalizar\n\n Ingrese Opcion....: " ); ok = scanf( "%d", &opc ) == 1 && opc > 0 && opc <= 6; while ((ch = getchar()) != EOF && ch != '\n'); }while( !ok ); switch ( opc ){ case 1: Lista = agregar( Lista ); break; break; break; break; case 5: mostrar( Lista ); break; case 6:; break; } }while( opc != 6 ); } void limpiar( void ){ } 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; } } struct nodo *crear( int dato ){ struct nodo *e = calloc( sizeof( struct nodo ), 1 ); e->dato = dato; e->siguiente = NULL; return e; } void mostrar( struct lista *L ){ struct nodo *auxiliar; int i=0; auxiliar = L->primero; while( auxiliar != NULL ){ printf( "\n %d", auxiliar ->dato ); auxiliar = auxiliar->siguiente; i++; } if( i == 0 ) printf( "\n La lista esta vacia..." ); printf( "\n Pulse una tecla para continuar..." );getchar (); }
Saludos.
|
|
|
140
|
Programación / Programación C/C++ / Re: Documentar función para borrar nodo según petición del usuario en C.
|
en: 15 Julio 2016, 14:31 pm
|
Hola, Alberto. - Realmente hasta ayer no comprendía cuál ligado esta un papel y un lápiz y la programación, muchas gracias por el aporte. - Ahora una duda que tengo con la siguientes líneas de código: Que diferencias hay en declarar los punteros a la estructura de una u otra manera, leí por allí que no se debería declarar una nueva estructura que no era necesario o no era conveniente, no recuerdo. - struct lista{ struct nodo *primero; struct nodo *ultimo; struct nodo *elementos; }
struct lista *primero, *ultimo;
Saludos.
|
|
|
|
|
|
|