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

 

 


Tema destacado: Los 10 CVE más críticos (peligrosos) de 2020


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Borrar nodo en lista simplemente enlazada[C]
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Borrar nodo en lista simplemente enlazada[C]  (Leído 6,005 veces)
NOB2014


Desconectado Desconectado

Mensajes: 366



Ver Perfil
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. -

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <limits.h>
  4.  
  5. struct nodo{
  6. int dato;
  7. struct nodo *siguiente;
  8. };
  9.  
  10. struct lista{
  11. struct nodo *primero;
  12. struct nodo *ultimo;
  13. int elementos;
  14. };
  15.  
  16. void menu( void );
  17. void menuUno( struct lista *L, struct nodo *N );
  18. void limpiar( void );
  19. struct lista *agregar( struct lista *L );
  20. struct nodo *crear( int dato );
  21. void mostrar( struct lista *L );
  22. void ordenar( struct lista *L );
  23. void buscar( struct lista *L );
  24. void modificar( struct nodo *pivote );
  25. void borrar( struct lista *L, struct nodo *pivote );
  26.  
  27.  
  28. int main( void ){
  29. menu();
  30.  
  31. return 0;
  32. }
  33.  
  34.  
  35. void menu( void ){
  36. struct lista *Lista = NULL;
  37. int opc, ok, ch;
  38.  
  39. do{
  40. do{
  41. limpiar();
  42. printf( "\n ========== Menu Principal ==========\n" );
  43. if( Lista != NULL)
  44. printf( "\n Total de datos.....:%d\n", Lista->elementos );
  45. printf(" \n 1 - Agregar\n 2 - buscar\n 3 - Ordenar " );
  46. printf(" \n 4 - Total\n 5 - Finalizar\n\n Ingrese Opcion....: "  );
  47. ok = scanf( "%d", &opc ) == 1 && opc > 0 && opc <= 5;
  48. while ((ch = getchar()) != EOF && ch != '\n');
  49. }while( !ok );
  50.  
  51. switch ( opc ){
  52. case 1: Lista = agregar( Lista );
  53. break;
  54. case 2: buscar( Lista );
  55. break;
  56. case 3: ordenar( Lista );
  57. break;
  58. case 4: mostrar( Lista );
  59. break;
  60. case 5:;
  61. free(Lista);
  62. break;
  63. }
  64. }while( opc != 5 );
  65. }
  66.  
  67. void menuUno( struct lista *L, struct nodo *N ){
  68. int opc, ok, ch;
  69.  
  70. do{
  71. do{
  72. limpiar();
  73. printf( "\n ========== Menu ==========\n" );
  74. printf(" \n 1 - Modificar\n 2 - Borrar\n 3 - Salir"
  75.   " \n\n Ingrese Opcion....: " );
  76. ok = scanf( "%d", &opc ) == 1 && opc > 0 && opc <= 5;
  77. while ((ch = getchar()) != EOF && ch != '\n');
  78. }while( !ok );
  79.  
  80. switch ( opc ){
  81. case 1: modificar( N );
  82. opc=3;
  83. break;
  84. case 2: borrar( L, N );
  85. opc=3;
  86. break;
  87. case 3:
  88. break;
  89. }
  90. }while( opc != 3 );
  91. }
  92.  
  93. void limpiar( void ){
  94. system("cls||clear");
  95. }
  96.  
  97. struct lista *agregar( struct lista *L ){
  98. int ok, ch, dto;
  99.  
  100. do{
  101. limpiar();
  102. printf( "\n Ingrese dato (mayor a 0 y menor a %d)....: ", INT_MAX );
  103. ok = scanf( "%d", &dto ) == 1 && dto >0 && dto <= INT_MAX;
  104. while ((ch = getchar()) != EOF && ch != '\n');
  105. }while( !ok );
  106.  
  107. if( L != NULL ){
  108. struct nodo *e = crear( dto );
  109. L->ultimo->siguiente = e;
  110. L->ultimo = e;
  111. L->elementos++;
  112. return L;
  113. }else{
  114. struct nodo *e = crear( dto );
  115. struct lista *l = calloc( sizeof( struct lista ), 1 );
  116. l->primero = e;
  117. l->ultimo = e;
  118. l->elementos = 1;
  119. return l;
  120. }
  121. }
  122.  
  123. struct nodo *crear( int dato ){
  124. struct nodo *e = calloc( sizeof( struct nodo), 1 );
  125. e->dato = dato;
  126. e->siguiente = NULL;
  127.  
  128. return e;
  129. }
  130.  
  131. void mostrar( struct lista *L ){
  132. struct nodo *auxiliar;
  133. int i=0;
  134.  
  135. if( L != NULL ){
  136. auxiliar = L->primero;
  137. while( auxiliar != NULL ){
  138. printf( "\n %d", auxiliar->dato );
  139. auxiliar = auxiliar->siguiente;
  140. i++;
  141. }
  142. }else{
  143. printf( "\n La lista esta vacia..." );
  144. }
  145.  
  146. printf( "\n Pulse una tecla para continuar..." );getchar();
  147. }
  148.  
  149. void ordenar( struct lista *L ){
  150. struct nodo *pivote = NULL, *actual = NULL;
  151. int tmp;
  152.  
  153. if( L != NULL ){
  154. pivote = L->primero;
  155. while( pivote != L->ultimo ){
  156. actual = pivote->siguiente;
  157. while( actual != NULL ){
  158. if( pivote->dato > actual->dato ){
  159. tmp = pivote->dato;
  160. pivote->dato = actual->dato;
  161. actual->dato = tmp;
  162. }
  163. actual = actual->siguiente;
  164. }
  165. pivote = pivote->siguiente;
  166. }
  167. mostrar( L );
  168. }else{
  169. printf( "\n La lista esta vacia..." );
  170. printf( "\n Pulse una tecla para continuar..." );getchar();
  171. }
  172. }
  173.  
  174. void buscar( struct lista *L ){
  175. int ok, ch, dto, i=0;
  176. struct nodo *pivote = NULL;
  177.  
  178. if( L != NULL ){
  179. do{
  180. limpiar();
  181. printf( "\n Ingrese el dato a buscar....: " );
  182. ok = scanf( "%d", &dto ) == 1 && dto >0 && dto <= INT_MAX;
  183. while ((ch = getchar()) != EOF && ch != '\n');
  184. }while( !ok );
  185.  
  186. pivote = L->primero;
  187. while( pivote != NULL ){
  188. if( pivote->dato == dto  ){
  189. menuUno( L, pivote );
  190. i++;
  191. break;
  192. }
  193. pivote = pivote->siguiente;
  194. }
  195. if( i == 0 ){
  196. printf( "\n El dato no existe..." );
  197. printf( "\n Pulse una tecla para continuar..." );getchar();
  198. }
  199. }else{
  200. printf( "\n La lista esta vacia..." );
  201. printf( "\n Pulse una tecla para continuar..." );getchar();
  202. }
  203. }
  204.  
  205. void modificar( struct nodo *pivote ){
  206. int ok, ch, dto;
  207.  
  208. do{
  209. limpiar();
  210. printf( "\n Dato a modificar.....: %d \n Ingrese nuevo dato...: ", pivote->dato );
  211. ok = scanf( "%d", &dto ) == 1 && dto >0 && dto <= INT_MAX;
  212. while ((ch = getchar()) != EOF && ch != '\n');
  213. }while( !ok );
  214. pivote->dato = dto;
  215. }
  216.  
  217. void borrar( struct lista *L, struct nodo *pivote ){
  218.  
  219. if( L->elementos == 1 ){
  220. printf( "\n Es el unico dato..." );
  221. }
  222. else if( pivote == L->primero){
  223. printf( "\n Es el primer dato..." );
  224. }
  225. else if( pivote->siguiente == NULL){
  226. printf( "\n Es el ultimo dato..." );
  227. }
  228. else{
  229. printf( "\n Esta entre el primer dato y el ultimo..." );
  230. }
  231. }
  232.  

Es todo por el momento, es probable que me surgen algunas otras dudas. -
Saludos.


En línea

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


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: Borrar nodo en lista simplemente enlazada[C]
« Respuesta #1 en: 24 Julio 2016, 19:24 pm »

En primer lugar lo segundo: Si pones en la función L = NULL, no cambiará nada fuera de la función.
De todos modos, borrar el último nodo no significa "borrar la lista". Simplemente sería borrar el nodo que tiene, y ponerlo todo a 0: elementos, primero y ultimo.
E incluso si quisieras borrar la lista, tendrías que liberar la memoria con free().

Y con respecto a lo primero, no hay mucho que decir. Si quieres que esa función borre, impleméntalo. Ya en el camino verías qué comprobaciones necesitas hacer.
Desde luego, si no es el único, estará de primero, último u otra posición, está claro.


En línea

NOB2014


Desconectado Desconectado

Mensajes: 366



Ver Perfil
Re: Borrar nodo en lista simplemente enlazada[C]
« Respuesta #2 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. -


Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <limits.h>
  4.  
  5. struct nodo{
  6. int dato;
  7. struct nodo *siguiente;
  8. };
  9.  
  10. struct lista{
  11. struct nodo *primero;
  12. struct nodo *ultimo;
  13. int elementos;
  14. };
  15.  
  16. void menu( void );
  17. struct lista *menuUno( struct lista *L, struct nodo *N );
  18. void limpiar( void );
  19. struct lista *agregar( struct lista *L );
  20. struct nodo *crear( int dato );
  21. void mostrar( struct lista *L );
  22. void ordenar( struct lista *L );
  23. struct lista *buscar( struct lista *L );
  24. void modificar( struct nodo *pivote );
  25. struct lista *borrar( struct lista *L, struct nodo *borrar );
  26.  
  27.  
  28. int main( void ){
  29. menu();
  30.  
  31. return 0;
  32. }
  33.  
  34.  
  35. void menu( void ){
  36. struct lista *Lista = NULL;
  37. int opc, ok, ch;
  38.  
  39. do{
  40. do{
  41. limpiar();
  42. printf( "\n ========== Menu Principal ==========\n" );
  43. if( Lista != NULL)
  44. printf( "\n Total de datos.....:%d\n", Lista->elementos );
  45. printf(" \n 1 - Agregar\n 2 - buscar\n 3 - Ordenar " );
  46. printf(" \n 4 - Total\n 5 - Finalizar\n\n Ingrese Opcion....: "  );
  47. ok = scanf( "%d", &opc ) == 1 && opc > 0 && opc <= 5;
  48. while ((ch = getchar()) != EOF && ch != '\n');
  49. }while( !ok );
  50.  
  51. switch ( opc ){
  52. case 1: Lista = agregar( Lista );
  53. break;
  54. case 2: Lista = buscar( Lista );
  55. break;
  56. case 3: ordenar( Lista );
  57. break;
  58. case 4: mostrar( Lista );
  59. break;
  60. case 5:;
  61. free(Lista);
  62. break;
  63. }
  64. }while( opc != 5 );
  65. }
  66.  
  67. struct lista *menuUno( struct lista *L, struct nodo *N ){
  68. int opc, ok, ch;
  69.  
  70. do{
  71. do{
  72. limpiar();
  73. printf( "\n ========== Menu ==========\n" );
  74. printf(" \n 1 - Modificar\n 2 - Borrar\n 3 - Salir"
  75.   " \n\n Ingrese Opcion....: " );
  76. ok = scanf( "%d", &opc ) == 1 && opc > 0 && opc <= 5;
  77. while ((ch = getchar()) != EOF && ch != '\n');
  78. }while( !ok );
  79.  
  80. switch ( opc ){
  81. case 1: modificar( N );
  82. opc=3;
  83. break;
  84. case 2: L = borrar( L, N );
  85. opc=3;
  86. break;
  87. case 3:
  88. break;
  89. }
  90. }while( opc != 3 );
  91.  
  92. return L;
  93. }
  94.  
  95. void limpiar( void ){
  96. system("cls||clear");
  97. }
  98.  
  99. struct lista *agregar( struct lista *L ){
  100. int ok, ch, dto;
  101.  
  102. do{
  103. limpiar();
  104. printf( "\n Ingrese dato (mayor a 0 y menor a %d)....: ", INT_MAX );
  105. ok = scanf( "%d", &dto ) == 1 && dto >0 && dto <= INT_MAX;
  106. while ((ch = getchar()) != EOF && ch != '\n');
  107. }while( !ok );
  108.  
  109. if( L != NULL ){
  110. struct nodo *e = crear( dto );
  111. L->ultimo->siguiente = e;
  112. L->ultimo = e;
  113. L->elementos++;
  114. return L;
  115. }else{
  116. struct nodo *e = crear( dto );
  117. struct lista *l = calloc( sizeof( struct lista ), 1 );
  118. l->primero = e;
  119. l->ultimo = e;
  120. l->elementos = 1;
  121. return l;
  122. }
  123. }
  124.  
  125. struct nodo *crear( int dato ){
  126. struct nodo *e = calloc( sizeof( struct nodo), 1 );
  127. e->dato = dato;
  128. e->siguiente = NULL;
  129.  
  130. return e;
  131. }
  132.  
  133. void mostrar( struct lista *L ){
  134. struct nodo *auxiliar;
  135. int i=0;
  136.  
  137. if( L != NULL ){
  138. auxiliar = L->primero;
  139. while( auxiliar != NULL ){
  140. printf( "\n %d", auxiliar->dato );
  141. auxiliar = auxiliar->siguiente;
  142. i++;
  143. }
  144. }else{
  145. printf( "\n La lista esta vacia..." );
  146. }
  147.  
  148. printf( "\n Pulse una tecla para continuar..." );getchar();
  149. }
  150.  
  151. void ordenar( struct lista *L ){
  152. struct nodo *pivote = NULL, *actual = NULL;
  153. int tmp;
  154.  
  155. if( L != NULL ){
  156. pivote = L->primero;
  157. while( pivote != L->ultimo ){
  158. actual = pivote->siguiente;
  159. while( actual != NULL ){
  160. if( pivote->dato > actual->dato ){
  161. tmp = pivote->dato;
  162. pivote->dato = actual->dato;
  163. actual->dato = tmp;
  164. }
  165. actual = actual->siguiente;
  166. }
  167. pivote = pivote->siguiente;
  168. }
  169. mostrar( L );
  170. }else{
  171. printf( "\n La lista esta vacia..." );
  172. printf( "\n Pulse una tecla para continuar..." );getchar();
  173. }
  174. }
  175.  
  176. struct lista *buscar( struct lista *L ){
  177. int ok, ch, dto, i=0;
  178. struct nodo *pivote = NULL;
  179.  
  180. if( L != NULL ){
  181. do{
  182. limpiar();
  183. printf( "\n Ingrese el dato a buscar....: " );
  184. ok = scanf( "%d", &dto ) == 1 && dto >0 && dto <= INT_MAX;
  185. while ((ch = getchar()) != EOF && ch != '\n');
  186. }while( !ok );
  187.  
  188. pivote = L->primero;
  189. while( pivote != NULL ){
  190. if( pivote->dato == dto  ){
  191. L = menuUno( L, pivote );
  192. i++;
  193. break;
  194. }
  195. pivote = pivote->siguiente;
  196. }
  197. if( i == 0 ){
  198. printf( "\n El dato no existe..." );
  199. printf( "\n Pulse una tecla para continuar..." );getchar();
  200. }
  201. }else{
  202. printf( "\n La lista esta vacia..." );
  203. printf( "\n Pulse una tecla para continuar..." );getchar();
  204. }
  205. return L;
  206. }
  207.  
  208. void modificar( struct nodo *pivote ){
  209. int ok, ch, dto;
  210.  
  211. do{
  212. limpiar();
  213. printf( "\n Dato a modificar.....: %d \n Ingrese nuevo dato...: ", pivote->dato );
  214. ok = scanf( "%d", &dto ) == 1 && dto >0 && dto <= INT_MAX;
  215. while ((ch = getchar()) != EOF && ch != '\n');
  216. }while( !ok );
  217. pivote->dato = dto;
  218. }
  219.  
  220. struct lista *borrar( struct lista *L, struct nodo *borrar ){
  221.  
  222. if( L->elementos == 1 ){
  223. L = NULL;
  224. }
  225. else if( borrar == L->primero){
  226. L->primero = borrar->siguiente;
  227. L->elementos--;
  228. free( borrar );
  229. }
  230. else if( borrar->siguiente == NULL){
  231. struct nodo *aux = L->primero;
  232. while( aux->siguiente != NULL ){
  233. aux = aux->siguiente;
  234. }
  235. L->ultimo = aux;
  236. L->elementos--;
  237. aux->siguiente = NULL;
  238. free( aux );
  239. }
  240. else{
  241. printf( "\n Esta entre el primer dato y el ultimo..." );
  242. }
  243. return L;
  244. }
  245.  

Saludos y desde ya muchas gracias. -
En línea

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
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.696


🏴 Libertad!!!!!


Ver Perfil WWW
Re: Borrar nodo en lista simplemente enlazada[C]
« Respuesta #3 en: 28 Julio 2016, 04:40 am »

Hola

Código
  1. if( borrar->siguiente == NULL){ //Supongo que aqui estas evaluanfo por el ultimo Nodo
  2. //a esta altura el nodo a borrar es el ultimo
  3. struct nodo *aux = L->primero;
  4. while( aux->siguiente != borrar ){
  5. aux = aux->siguiente;
  6.        }
  7. //a esta altura el nodo aux es el penultimo
  8. L->ultimo = aux; //El que antes era penultimo ahora sera el ultimo
  9. L->elementos--;
  10. aux->siguiente = NULL; //El apuntador siguiente del ultimo Nodo debe de apuntar a NULL
  11. free( borrar );
  12. }
En línea

NOB2014


Desconectado Desconectado

Mensajes: 366



Ver Perfil
Re: Borrar nodo en lista simplemente enlazada[C]
« Respuesta #4 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. -

Código
  1. struct lista *borrar( struct lista *L, struct nodo *borrar ){
  2.  
  3. if( L->elementos == 1 ){ //LSE001
  4. L = NULL;
  5. free( borrar );
  6. }
  7. else if( L->primero == borrar ){ //LSE002
  8. L->primero = borrar->siguiente; //LSE003
  9. L->elementos--;
  10. free( borrar );
  11. }
  12. else if( borrar->siguiente == NULL){ //LSE004
  13. struct nodo *aux = L->primero;
  14.  
  15. while( aux->siguiente != borrar ){
  16. aux = aux->siguiente;
  17. }
  18. //LSE005
  19. L->ultimo = aux; //LSE006
  20. L->elementos--;
  21. aux->siguiente = NULL; //LSE007
  22. free( borrar );
  23. }
  24. else{ //LSE008
  25. struct nodo *aux = L->primero;
  26.  
  27. while( aux->siguiente != borrar ){ //LSE009
  28. aux = aux->siguiente;
  29. }
  30. aux->siguiente = borrar->siguiente; //LSE010
  31. L->elementos--; //LSE011
  32. free( borrar ); //LSE012
  33. }
  34. return L;
  35. }
  36.  
  37. /*
  38. =============================== Ayuda ===============================
  39.  
  40. LSE001 Verificamos si la cantidad de ingresos es un solo dato, de ser así con L = NULL
  41. inicializamos toda la lista a cero, pero permanece en memoria para nuevos ingresos.
  42.  
  43. LSE002 En caso de no ser el único ingreso verificamos si es el primer Nodo,  
  44. LSE003 De ser así igualamos el primer Nodo a borrar->siguiente, de esa manera el que
  45. era el segundo pasa a ser el primero Nodo y el primero es borrado.  
  46.  
  47. LSE004 A esta altura el nodo a borrar es el último.
  48. LSE005 A esta altura el nodo aux es el penultimo.
  49. LSE006 El que antes era penúltimo ahora será el último.
  50. LSE007 El apuntador siguiente del último Nodo debe de apuntar a NULL.
  51.  
  52. LSE008 Por último, llegamos a este else porque el Nodo a borrar no es el único
  53. ni es el primero ni es el último, se encuentra entre estos dos.
  54.  
  55. LSE009 Con este bucle obtenemos la dirección de memoria donde está el nodo anterior
  56. al que queremos borrar.
  57. LSE010 aux->siguiente ahora ya no apunta al Nodo siguiente que es el que queremos borrar
  58. apunta al Nodo siguiente al que borraremos.
  59. LSE011 Decrementamos el contador de nodos.
  60. LSE012 Liberamos memoria.
  61. */  
« Última modificación: 29 Julio 2016, 15:49 pm por NOB2014 » En línea

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.-
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines