elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Guía rápida para descarga de herramientas gratuitas de seguridad y desinfección


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  [?]Eliminar nodo
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [?]Eliminar nodo  (Leído 2,556 veces)
lerg96

Desconectado Desconectado

Mensajes: 4


Ver Perfil
[?]Eliminar nodo
« en: 27 Marzo 2015, 02:46 am »

Buenas, es la primera vez que posteo en estos foros así que no me amonesten si cometo faltas dentro de ellos, o no tan fuerte. Mi duda es la siguiente: Necesito que mi programa elimine un nodo en especifico a partir de un identificador, cuando coloco el identificador el programa si elimina el nodo. Pero ocurre un problema que es cuando el nodo que intento eliminar no es el primero y luego lo intento mostrar.




Tengo entendido que si el nodo esta al final de la lista(? (no estoy seguro si se dice así) se debe apuntar el nodo anterior a NULL, lo único es que no sé como hacerlo :(

Además de que tengo otro problema que es cuando el identificador que intento eliminar no lo encuentra, el programa



Estuve buscando ejemplos que pueda ver en el foro, pero no encuentro uno que pueda entender al 100%. Si pudieran ayudarme, se los agradeceria. Además de que puedan explicarme como es este proceso de eliminar (Como leer el código en sí)
Código
  1. [
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. struct nodo
  5. {
  6. int dato;
  7. char nombre[10],telefono[7];
  8. struct nodo *puntero;
  9. };
  10. typedef nodo lista;
  11. lista *nuevo,*inicio,*fin;
  12. void crear_nodos()
  13. {
  14. nuevo=new(nodo);
  15. printf("\nNuevo elemento.\n");
  16. printf("Identificador: ");
  17. scanf("%d",&nuevo->dato);
  18. printf("Nombre: ");
  19. fflush(stdin);
  20. fgets(nuevo->nombre,10,stdin);
  21. printf("Telefono: ");
  22. fgets(nuevo->telefono,7,stdin);
  23. nuevo->puntero= NULL;
  24. if (inicio==NULL)
  25. {
  26. printf("Primer elemento\n");
  27. inicio = nuevo;
  28. fin = nuevo;
  29. }
  30. else
  31. {
  32. fin->puntero = nuevo;
  33. /* hacemos que el nuevo sea ahora el último */
  34. fin = nuevo;
  35. }
  36. }
  37. void mostrar_nodos()
  38. {
  39. lista *auxiliar;
  40. auxiliar=inicio;
  41. while(auxiliar!=NULL)
  42. {
  43. printf("###################\n");
  44. printf("Identificador: %d\n",auxiliar->dato);
  45. printf("Nombre: %s\n",auxiliar->nombre);
  46. printf("Telefono: %s\n",auxiliar->telefono);
  47. auxiliar=auxiliar->puntero;
  48. }
  49. printf("\n");
  50. }
  51. void borrarNodo()
  52. {
  53.     system("cls");
  54. nuevo = inicio;
  55.     if(nuevo != NULL)
  56.     {
  57.  
  58.         nodo *aux = NULL, *ant = NULL;
  59.         ant = new nodo;  
  60.         aux = new nodo;
  61.         printf("INTRODUZCA EL ID A ELIMINAR: ");
  62. scanf("%d",&aux->dato);
  63. while(aux->dato != nuevo->dato)
  64.           {
  65.   ant = nuevo;
  66.   nuevo = nuevo->puntero;
  67.           }
  68. if(nuevo == inicio)
  69.           {          
  70.   inicio = inicio->puntero;
  71.              free(ant);
  72.              free(aux);
  73.              printf("ELEMENTO 1 ELIMINADO");
  74. }else if(aux->dato == nuevo->dato)
  75.                {                  
  76. ant = nuevo;
  77. nuevo = nuevo->puntero;                
  78.                   free(ant);
  79.                   free(aux);
  80.                   printf("ELEMENTO x ELIMINADO");
  81.                }                              
  82.    }else  
  83.       printf("NO HAY ELEMENTOS PARA ELIMINAR");
  84. }
  85. void menu()
  86. {
  87. int op;
  88. system("cls");
  89. printf (" Menu Principal\n");
  90. printf(" 1.- Insertar Nodos \n");
  91. printf(" 2.- Mostrar Nodos\n");
  92. printf(" 3.- Eliminar Nodos \n");
  93. printf(" 4.- Salir \n");
  94. printf(" Seleccione opcion: ");
  95. scanf("%d",&op);
  96. switch (op)
  97. {
  98. case 1: system("cls");
  99. printf("Ingresa los nodos a la lista");
  100. crear_nodos();
  101. system("pause");
  102. menu();
  103. case 2: system("cls");
  104. printf("Muestra los nodos de la lista\n");
  105. mostrar_nodos();
  106. system("pause");
  107. menu();
  108. case 3: system("cls");
  109. printf("Elimina nodos\n");
  110. borrarNodo();
  111. system("pause");
  112. menu();
  113. case 4: exit(0);
  114. default: printf("Opcion no valida");
  115. system("pause");
  116. menu();
  117. }
  118. }
  119. void main()
  120. {
  121. menu();
  122. }

Sé que no debo usar fflush(stdin); pero aún no sé una manera de pedir una variable entera sin usar scanf para que fgets no se salte xD

lo único que se me ocurre es poner

Código
  1.  
  2. ant->puntero= NULL;
  3. fin->puntero = ant;
  4. fin = ant;

pero nada me funciona


« Última modificación: 27 Marzo 2015, 03:32 am por lerg96 » En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: [?]Eliminar nodo
« Respuesta #1 en: 27 Marzo 2015, 15:51 pm »

En tu programa utilizas solo la biblioteca estándar de C cuando, por el uso de new, se trata de C++. Si estas aprendiendo C++ enfocate en su biblioteca estándar. En cuanto al uso intercalado de scanf y fgets (el problema similar en C++ aparece con el uso del operador ">>" y getline) hay un montón de temas en la base de datos de los foros, solo es cuestión de utilizar el motor de búsqueda.

También por favor lee el tema |Lo que no hay que hacer en C/C++. Nivel basico|.

----

Los problemas en su mayoría se encuentran en la función "borrarNodo", el que mencionas se genera si el nodo a eliminar no existe debido a este bucle:
Código
  1. printf("INTRODUZCA EL ID A ELIMINAR: ");
  2. scanf("%d", &aux->dato);
  3. while (aux->dato != nuevo->dato){
  4.   ant = nuevo;
  5.   nuevo = nuevo->puntero;
  6. }
En el se itera una y otra vez hasta encontrar un nodo con el valor buscado, si eso no sucede se tratara de procesar el nodo después del ultimo (NULL) causando el error que mencionas al realizar la operación (NULL)->puntero.

----

Mira que pensaba poner un listado de los errores en esa función pero, y recalco que no quiero sonar grosero, son demasiados: reservas memoria cuando no es necesario, no revisas si se alcanza el final de la lista, los nombres de las variables son malos ("nuevo" es el puntero para iterar la lista), hay que tener en cuenta variables "globales" que no son necesarias, etc..

La base para eliminar un nodo es:
Código
  1. void borrarNodo()
  2. {
  3.   if (inicio == NULL)
  4.      puts("Lista vacia");
  5.   else {
  6.      nodo *aux;
  7.      int dato;
  8.  
  9.      puts("Dato a eliminar:");
  10.      scanf("%d", &dato);
  11.  
  12.      if (inicio->dato == dato){
  13.         // Eliminamos el primero
  14.         aux = inicio;
  15.         inicio = inicio->puntero;
  16.         free(aux);
  17.      }else {
  18.         // Eliminamos (si aplica) algun nodo despues del primero
  19.         nodo *p = inicio;
  20.  
  21.         while (p->puntero != NULL && p->puntero->dato != dato)
  22.         p = p->puntero;
  23.  
  24.         // ...
  25.      }
  26.   }
  27. }

Por supuesto no esta completo, falta la parte mas importante y difícil (eliminar un nodo después del primero). Inténtalo tu solo y si tienes problemas te ayudamos.

Un saludo


En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
avesudra


Desconectado Desconectado

Mensajes: 724


Intentando ser mejor cada día :)


Ver Perfil
Re: [?]Eliminar nodo
« Respuesta #2 en: 27 Marzo 2015, 16:03 pm »

Hola lerg96 a parte de lo que te ha comentado rir3760 te comento que:

  • En la función menu, si escoges una opcion vuelves a llamar a menu recursivamente, esto se va acumulando en la pila de llamadas y no es bueno.
  • La función main debe tener un tipo de retorno entero, no puede ser void.
  • No deberías mezclar C++ con C, en C++ las bibliotecas adecuadas son cstdlib y cstdio, aunque ésta última es útil en casos muy concretos y su trabajo lo hace iostream prácticamente.
  • El typedef está mal puesto, tienes puesto:
Código
  1. typedef nodo lista;
Cuando lo correcto es:
Código
  1. typedef struct nodo lista;
  • En cuanto a lo del fflush(stdin), deberías usar fgets + sscanf(en C) o cin directamente en C++.
  • No debes usar system("pause") pues no funciona en todas las plataformas, lo puedes sustituir por un getchar(), o un cin.get()
  • No deberías usar system("cls"), podrías poner una directiva de preprocesador pero como trabajas sobre Visual Studio no sé como va en dicho compilador.

Lo del menu lo puedes arreglar con un do - while o con while simplemente.

Aunque como dice rir3760 el problema principal está en esa función.
En línea

Regístrate en
lerg96

Desconectado Desconectado

Mensajes: 4


Ver Perfil
Re: [?]Eliminar nodo
« Respuesta #3 en: 31 Marzo 2015, 04:07 am »

Mira que pensaba poner un listado de los errores en esa función pero, y recalco que no quiero sonar grosero, son demasiados: reservas memoria cuando no es necesario, no revisas si se alcanza el final de la lista, los nombres de las variables son malos ("nuevo" es el puntero para iterar la lista), hay que tener en cuenta variables "globales" que no son necesarias, etc..

Cuando estaba haciendo el procedimiento para borrar un nodo (Que por cierto, ni idea de lo que hacía en ese momento), me fije bastante de un tema que estaba aquí, básicamente copie, pegue y cambie algunas cosas hasta que me funcionara. Esa misma noche duré bastante buscando solución a esos problemas (Luego de haberlo posteado) hasta que di por fin con todos por mi cuenta.

Hola lerg96 a parte de lo que te ha comentado rir3760 te comento que:

  • En la función menu, si escoges una opcion vuelves a llamar a menu recursivamente, esto se va acumulando en la pila de llamadas y no es bueno.
  • La función main debe tener un tipo de retorno entero, no puede ser void.
  • No deberías mezclar C++ con C, en C++ las bibliotecas adecuadas son cstdlib y cstdio, aunque ésta última es útil en casos muy concretos y su trabajo lo hace iostream prácticamente.
  • El typedef está mal puesto, tienes puesto:
Código
  1. typedef nodo lista;
Cuando lo correcto es:
Código
  1. typedef struct nodo lista;
  • En cuanto a lo del fflush(stdin), deberías usar fgets + sscanf(en C) o cin directamente en C++.
  • No debes usar system("pause") pues no funciona en todas las plataformas, lo puedes sustituir por un getchar(), o un cin.get()
  • No deberías usar system("cls"), podrías poner una directiva de preprocesador pero como trabajas sobre Visual Studio no sé como va en dicho compilador.

Lo del menu lo puedes arreglar con un do - while o con while simplemente.

Aunque como dice rir3760 el problema principal está en esa función.



Sobre el resto del código, sé que hay demasiados errores. Esto es debido a los conocimientos que me imparte mi profesora de algoritmos. El tema que me recomendaste "|Lo que no hay que hacer en C/C++. Nivel básico|." Lo había leído antes, a mitad del trimestre, imagínate mi cara al darme cuenta que la mayoría de las cosas que me enseñan no sirven para hacer algo profesional, la última vez que intente usar algo más adecuado casi pierdo la nota total de un examen T_T  :-\


a la final el procedimiento para borrar quedo de esta manera:

Código
  1.     if(inicio != NULL)
  2.     {
  3. int dato;
  4.         nodo *aux = NULL, *ant = NULL;
  5.         ant = new nodo;  
  6.         aux = new nodo;
  7. aux = inicio;
  8.         printf("INTRODUZCA EL ID A ELIMINAR: ");
  9. scanf("%d",&dato);
  10. while(dato != aux->dato)
  11.           {
  12.   ant = aux;
  13.   aux = aux->puntero;
  14.   if (aux==NULL) break;
  15.           }
  16. if(aux==NULL)
  17. {
  18. printf("IDENTIFICADOR NO ENCONTRADO\n");
  19. system("pause");
  20.  
  21. }
  22. else
  23.  
  24. {
  25. if(aux == inicio)
  26.           {          
  27.   inicio = inicio->puntero;
  28.              free(ant);
  29.              free(aux);
  30.              printf("ELEMENTO 1 ELIMINADO");
  31. }
  32. else if((ant == inicio)&&(aux==fin))
  33.                {      
  34. ant->puntero= NULL;
  35. inicio = ant;
  36. fin = ant;
  37.                   printf("ELEMENTO ULTIMO ELIMINADO");
  38.                }
  39. else if(ant != NULL)
  40.                {      
  41. ant->puntero=aux->puntero;
  42. free(aux);
  43.                   printf("ELEMENTO x ELIMINADO");
  44.                }
  45.    }
  46. }
  47. else  
  48.       printf("NO HAY ELEMENTOS PARA ELIMINAR");

Pero eso fue lo que hice esa noche, que me ayudo bastante al entendimiento de este. Si creen que puede hacerse mejor o de otra manera, lo agradeceria bastante. Ya me encuentro probando con el codigo de rir3760, intentando completar las partes que mencionaste.

Muchas gracias por su atención, realmente mi intención es aprender, y hacer todo de la manera correcta. Un abrazo!!
« Última modificación: 31 Marzo 2015, 04:25 am por lerg96 » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Eliminar nodo de lista? « 1 2 »
Java
monsefoster 17 47,311 Último mensaje 10 Febrero 2010, 16:32 pm
por egyware
Eliminar nodo en un arbol binario
.NET (C#, VB.NET, ASP)
DaNuK 4 29,007 Último mensaje 6 Diciembre 2010, 20:19 pm
por DaNuK
Problema treeview al eliminar nodo hijo
Programación Visual Basic
elezekiel 0 2,577 Último mensaje 12 Noviembre 2014, 16:02 pm
por elezekiel
Eliminar nodo en lista enlazada: problema con el último nodo [C]
Programación C/C++
Rhessus 2 5,297 Último mensaje 20 Julio 2016, 06:08 am
por Rhessus
Lista simple eliminar nodo segun un valor
Programación C/C++
Beginner Web 2 1,652 Último mensaje 15 Septiembre 2018, 09:00 am
por Beginner Web
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines