Foros del Web » Programación para mayores de 30 ;) » C/C++ »

crear una lista enlazada

Estas en el tema de crear una lista enlazada en el foro de C/C++ en Foros del Web. Hola, el siguiente programa añade nodo al principio, al final, recorre la lista, busca nodo, elimina nodo y añade después de un nodo determinado. Sólo ...
  #1 (permalink)  
Antiguo 16/05/2010, 14:08
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 2 meses
Puntos: 0
crear una lista enlazada

Hola, el siguiente programa añade nodo al principio, al final, recorre la lista, busca nodo, elimina nodo y añade después de un nodo determinado. Sólo utilizo un dato de tipo char. He intentado añadir otro dato y hacer las operaciones, pero no me sale bien. A ver si alguien puede ayudarme. Gracias.

Código C:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #define LEE_CAD(c,n) { int i=0; \
  6.                      c[i]=getchar();\
  7.              while((c[i]=='\n') || (c[i]=='\t')) c[i]=getchar();\
  8.              while ((c[i]!='\n') && (i < (n-1))){ \
  9.                 i++;\
  10.             c[i]=getchar(); }\
  11.              c[i]='\0'; }
  12.  
  13. #define T_NOM 101
  14.  
  15.  
  16. struct persona {
  17.     char nom[100];
  18.         struct persona *siguiente;
  19. };
  20.  
  21. int main(){
  22.          struct persona *lista=NULL;
  23.          struct persona *nodo;
  24.  
  25.          int op;
  26.          void alta_inicio();
  27.          void alta_final();
  28.          void alta_despues_de();
  29.          void recorrer_lista();
  30.          void borrar_nodo();
  31.          struct persona * buscar_nodo();
  32.          
  33.          do{
  34.             do{
  35.                printf("Elija una opción:\n");
  36.                printf("1--> Añadir al principio.\n");
  37.                printf("2--> Añadir al final.\n");
  38.                printf("3--> Recorrer la lista.\n");
  39.                printf("4--> Buscar nodo.\n");
  40.                printf("5--> Eliminar nodo.\n");
  41.                printf("6--> Añadir despues de...\n");
  42.                printf("7--> Salir.\n");
  43.                scanf("%d",&op);
  44.             }while((op < 1) || (op > 7));
  45.          if(op != 7)  
  46.             switch(op){
  47.                 case 1: { alta_inicio(&lista);break;}
  48.                 case 2: { alta_final(&lista);break;}
  49.                 case 3: { recorrer_lista(&lista);break;}
  50.                 case 4: { nodo=buscar_nodo(&lista);
  51.                           printf("\n%s\n",nodo->nom);break;
  52.                 case 5: { borrar_nodo(&lista);break;}
  53.                 case 6: { alta_despues_de(&lista);break;}
  54.             }
  55.          }while(op != 7);
  56.          exit(0);
  57. }
  58. ////////////////////////////////////////////////////////////////////////////
  59. void alta_inicio(struct persona **lista){
  60.          struct persona *nuevo_nodo;
  61.          nuevo_nodo=(struct persona *)malloc(sizeof(struct persona));
  62.          if(nuevo_nodo != NULL){
  63.             nuevo_nodo->siguiente = *lista;
  64.             *lista = nuevo_nodo;
  65.             printf("Nombre: ");
  66.             LEE_CAD(nuevo_nodo->nom,T_NOM);
  67.          }
  68. }            
  69. ////////////////////////////////////////////////////////////////////////////////
  70. void recorrer_lista(struct persona **lista){
  71.           struct persona *nodo_aux;
  72.           nodo_aux = *lista;
  73.           while(nodo_aux != NULL){
  74.                printf("%s\n",nodo_aux->nom);
  75.                nodo_aux = nodo_aux->siguiente;
  76.           }
  77. }
  78. //////////////////////////////////////////////////////////////////////////////
  79. void alta_final(struct persona **lista){
  80.           struct persona *nuevo_nodo;
  81.           struct persona *nodo_aux;
  82.  
  83.           nuevo_nodo=(struct persona *)malloc(sizeof(struct persona));
  84.           if(nuevo_nodo != NULL){
  85.              nodo_aux = *lista;
  86.              while(nodo_aux->siguiente != NULL)
  87.                 nodo_aux = nodo_aux->siguiente;
  88.                 nodo_aux->siguiente=nuevo_nodo;
  89.                 nuevo_nodo->siguiente=NULL;
  90.                 printf("Nombre del nuevo elemento: ");
  91.                 LEE_CAD(nuevo_nodo->nom,T_NOM);
  92.           }
  93.           else
  94.                printf("Error al tomar memoria del nuevo nodo.\n");
  95. }
  96. /////////////////////////////////////////////////////////////////////////////////
  97. struct persona *buscar_nodo(struct persona **lista){
  98.           struct persona *nodo_aux, *resultado;
  99.           char nom[100];
  100.           char edad[3];
  101.           int encontrado = 0;
  102.  
  103.           printf("Nombre a buscar: ");
  104.           scanf("%99s",nom);
  105.          
  106.           nodo_aux = *lista;
  107.           while((nodo_aux->siguiente != NULL) && (!encontrado)){
  108.                 if(strcmp(nom,nodo_aux->nom) == 0)
  109.                   encontrado = 1;
  110.                 else
  111.                     nodo_aux = nodo_aux->siguiente;
  112.           }
  113.           if((nodo_aux->siguiente == NULL) && (!encontrado))
  114.               if(strcmp(nom,nodo_aux->nom) == 0)
  115.                  encontrado = 1;
  116.           if(encontrado)
  117.             resultado = NULL;
  118.           return(resultado);
  119. }
  120. ////////////////////////////////////////////////////////////////////////////////
  121. void borrar_nodo(struct persona **lista){
  122.           struct persona *nodo_aux, *nodo_anterior;
  123.           char nom[100];
  124.           char edad[3];
  125.           int encontrado = 0;
  126.  
  127.           printf("Nombre a borrar: ");
  128.           scanf("%99s",nom);
  129.           nodo_aux = *lista;
  130.  
  131.           if(strcmp(nom,nodo_aux->nom) == 0){
  132.             *lista=nodo_aux->siguiente;
  133.             free(nodo_aux);}
  134.           else{
  135.                nodo_anterior = nodo_aux;
  136.                nodo_aux = nodo_aux->siguiente;
  137.                while((nodo_aux->siguiente != NULL) && (!encontrado)){
  138.                    if(strcmp(nom,nodo_aux->nom) == 0)          
  139.                      encontrado = 1;
  140.                    else{
  141.                       nodo_anterior = nodo_aux;
  142.                       nodo_aux = nodo_aux->siguiente;
  143.                    }
  144.                }  
  145.                if((nodo_aux->siguiente == NULL) && (!encontrado))
  146.                   if(strcmp(nom,nodo_aux->nom) == 0)
  147.                      encontrado = 1;
  148.                if(encontrado){
  149.                   nodo_anterior->siguiente = nodo_aux->siguiente;
  150.                   free(nodo_aux);
  151.                }
  152.           }
  153. }
  154. ///////////////////////////////////////////////////////////////////////////////
  155. void alta_despues_de(struct persona **lista){
  156.            struct persona *nuevo_nodo;
  157.            struct persona *nodo_aux;
  158.            char nom[100];
  159.            char edad[3];
  160.            int encontrado = 0;
  161.            
  162.            printf("Nombre a buscar para insertar después de el: ");
  163.            scanf("%99s",nom);
  164.            
  165.            nuevo_nodo=(struct persona *)malloc(sizeof(struct persona));
  166.            
  167.  
  168.            if(nuevo_nodo != NULL){
  169.              nodo_aux = *lista;
  170.              while((nodo_aux->siguiente != NULL) && (!encontrado)){
  171.                   if(strcmp(nom,nodo_aux->nom) == 0)
  172.                      encontrado = 1;
  173.                   else{
  174.                        nodo_aux = nodo_aux->siguiente;
  175.                   }
  176.              }
  177.              if((nodo_aux->siguiente == NULL) && (!encontrado))
  178.                 if(strcmp(nom,nodo_aux->nom) == 0)
  179.                   encontrado = 1;
  180.  
  181.              if(encontrado){
  182.                 nuevo_nodo->siguiente=nodo_aux->siguiente;
  183.                 nodo_aux->siguiente=nuevo_nodo;
  184.                 printf("Nombre del nuevo elemento: ");
  185.                 scanf("%99s",nuevo_nodo->nom);
  186.              }
  187.              else{
  188.                   printf("Elemento no encontrado.\n");
  189.                   free(nuevo_nodo);
  190.              }
  191.            }
  192. }
  #2 (permalink)  
Antiguo 18/05/2010, 15:57
 
Fecha de Ingreso: enero-2008
Mensajes: 229
Antigüedad: 16 años, 3 meses
Puntos: 1
Respuesta: crear una lista enlazada

podrías poner la version con algun otro tipo de dato
  #3 (permalink)  
Antiguo 18/05/2010, 16:53
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: crear una lista enlazada

Si te fijas en la estructura tienes
struct persona {
char nom[100];
struct persona *siguiente;
};

Si le agregas nuevos valores a eso tendras mas campos. Eso si por ejemplo en recorrer lista tienes que adaptar la impresion para que aparezcan...
  #4 (permalink)  
Antiguo 19/05/2010, 04:43
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 2 meses
Puntos: 0
Respuesta: crear una lista enlazada

Hola, he añadido un nuevo dato a la lista el teléfono. Tengo un subprograma para borrar un nodo, en este pido el nombre a borrar, pero cuando lo compilo no entiendo por qué sólo con pedir el nombre a borrar me borra también el teléfono. Después cuando pido alta después de, es decir, después de un nodo en concreto, pongo el nombre a buscar para insertar después de él, a continuación pongo el nuevo nombre y cuando pido mostrar la lista me sale el nuevo nodo que he insertado, pero con el teléfono del anterior nodo que he borrado.

Voy a poner un ejemplo para que lo veáis más claro:

María 12, José 13, Pepe 14. Quiero borrar el 2º nodo, con introducir sólo el nombre a borrar, en este caso José, el resultado es: María 12, Pepe 14
Cuando pido insertar un nodo después de otro, por ejemplo, después de María, introduzco el nombre a buscar para insertar después de él y a continuación pongo el nuevo nombre. El resultado es este: María 12, Sara 13, Pepe 14. Si te fijas aparece el nuevo nombre Sara, pero el teléfono corresponde al nodo que he borrado antes. ¿Cómo puedo insertar el nuevo teléfono sin que me aparezca el teléfono de la persona que acabo de eliminar?

Este es el módulo para dar de alta después de un nodo determinado:

Código C:
Ver original
  1. void alta_despues_de(struct nodo_lista **lista){
  2.    struct nodo_lista *nuevo_nodo;
  3.    struct nodo_lista *nodo_aux;
  4.  
  5.    char nombre[T_NOM];
  6.    int encontrado = 0;
  7.  
  8.    printf("Nombre a buscar para insertar después de él: ");
  9.    LEE_CAD(nombre,T_NOM);
  10.  
  11.    nuevo_nodo=(struct nodo_lista *)malloc(sizeof(struct nodo_lista));
  12.  
  13.    if(nuevo_nodo != NULL){
  14.       nodo_aux = *lista;
  15.       while((nodo_aux->siguiente != NULL) && (!encontrado)){
  16.         if(strcmp(nombre,nodo_aux->nombre) == 0)
  17.           encontrado = 1;
  18.         else{
  19.              nodo_aux = nodo_aux->siguiente;
  20.         }
  21.       }
  22.       if((nodo_aux->siguiente == NULL) && (!encontrado))
  23.           if(strcmp(nombre,nodo_aux->nombre) == 0)
  24.             encontrado = 1;
  25.  
  26.       if(encontrado){
  27.           nuevo_nodo->siguiente=nodo_aux->siguiente;
  28.           nodo_aux->siguiente=nuevo_nodo;
  29.           printf("Nombre del nuevo elemento: ");
  30.           LEE_CAD(nuevo_nodo->nombre,T_NOM);
  31.       }
  32.       else{
  33.            printf("Elemento no encontrado.\n");
  34.            free(nuevo_nodo);
  35.       }
  36.    }
  37. }
  #5 (permalink)  
Antiguo 19/05/2010, 04:49
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 2 meses
Puntos: 0
Respuesta: crear una lista enlazada

Dejo también el módulo de borrar_nodo para que me digáis, por favor, si falta añadir algo

Código C:
Ver original
  1. void borrar_nodo(struct nodo_lista **lista){
  2.     /* Para borrar un nodo, tendremos que guardar un puntero al nodo anterior
  3.        del que nos encontramos, ya que este puntero pasará a apuntar al nodo
  4.        apuntado por el que vamos a borrar */
  5.     struct nodo_lista *nodo_aux, *nodo_anterior;
  6.     char nombre[T_NOM];
  7.     int encontrado = 0;
  8.  
  9.     printf("Nombre a borrar: ");
  10.     LEE_CAD(nombre,T_NOM);
  11.  
  12.     nodo_aux = *lista;
  13.     /* Comprueba si el elemento a borrar es el primero de la lista */
  14.     if(strcmp(nombre,nodo_aux->nombre)==0){
  15.        *lista=nodo_aux->siguiente; /* Ahora apunta al segundo de la lista */
  16.        free(nodo_aux);} /* Libera la memoria ocupada por el nodo borrado */
  17.     else{
  18.       nodo_anterior = nodo_aux;
  19.       nodo_aux = nodo_aux->siguiente;}
  20.       while ((nodo_aux->siguiente != NULL) && (!encontrado)){
  21.         if(strcmp(nombre,nodo_aux->nombre) == 0) /* Iguales */
  22.            encontrado = 1;
  23.         else{
  24.            nodo_anterior = nodo_aux;
  25.            nodo_aux = nodo_aux->siguiente;
  26.         }
  27.       }
  28.       if((nodo_aux->siguiente == NULL) && (!encontrado))
  29.        if(strcmp(nombre,nodo_aux->nombre) == 0) /* Iguales */
  30.          encontrado = 1;
  31.       if(encontrado){
  32.         nodo_anterior->siguiente = nodo_aux->siguiente;
  33.         free(nodo_aux); /* Libera la memoria ocupada por el nodo borrado */
  34.       }
  35. }
  #6 (permalink)  
Antiguo 19/05/2010, 11:36
 
Fecha de Ingreso: enero-2008
Mensajes: 229
Antigüedad: 16 años, 3 meses
Puntos: 1
Respuesta: crear una lista enlazada

al parecer nunca pides el numero de tel nuevo.

una forma de mejorar tu algoritmo de busqueda:

Código C++:
Ver original
  1. nodo_aux = *lista;
  2.     /* Comprueba si el elemento a borrar es el primero de la lista */
  3.     if(strcmp(nombre,nodo_aux->nombre)==0){
  4.        *lista=nodo_aux->siguiente; /* Ahora apunta al segundo de la lista */
  5.  
  6.        free(nodo_aux);} /* Libera la memoria ocupada por el nodo borrado */
  7.  
  8.     else{
  9.      nodo_anterior = nodo_aux;
  10.       nodo_aux = nodo_aux->siguiente;
  11.           }
  12.       while ((nodo_aux->siguiente != NULL) && (!encontrado)){
  13.         if(strcmp(nombre,nodo_aux->nombre) == 0) /* Iguales */
  14.            encontrado = 1;
  15.         else{
  16.            nodo_anterior = nodo_aux;
  17.            nodo_aux = nodo_aux->siguiente;
  18.         }
  19.       }
  20.       if((nodo_aux->siguiente == NULL) && (!encontrado))
  21.        if(strcmp(nombre,nodo_aux->nombre) == 0) /* Iguales */
  22.          encontrado = 1;
  23.       if(encontrado){
  24.         nodo_anterior->siguiente = nodo_aux->siguiente;
  25.         free(nodo_aux); /* Libera la memoria ocupada por el nodo borrado */
  26.       }

sería de esta forma

Código C++:
Ver original
  1. nodo_aux = lista;
  2.             while (strcmp(nombre, nodo_aux->nombre))
  3.             {
  4.                 nodo_anterior = nodo_aux;
  5.                 nodo_aux = nodo_aux->siguiente;
  6.                 if(nodo_aux == NULL)
  7.                     break;
  8.             }
  9.  
  10.             if(nodo_aux != NULL)//o if(!nodo_aux)
  11.             {
  12.                 if(nodo_aux == lista)
  13.                     lista = nodo_aux->siguiente;
  14.                 else
  15.                     nodo_anterior->siguiente = nodo_aux->siguiente;
  16.                 free(nodo_aux); /* Libera la memoria ocupada por el nodo borrado */
  17.             }

una variante interesante seria q en lugar de buscar por un nombre en concreto, los nombres los insertaras de forma alfabetica. asi no tendrias k pedir el nombre, que te parece
  #7 (permalink)  
Antiguo 20/05/2010, 04:19
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 2 meses
Puntos: 0
Respuesta: crear una lista enlazada

En el modulo borrar_nodo que publiqué además de pedir el nombre a borrar también pido el teléfono a borrar de un nodo en concreto, lo he hecho así:

Código C:
Ver original
  1. void borrar_nodo(struct nodo_lista **lista){
  2.     /* Para borrar un nodo, tendremos que guardar un puntero al nodo anterior
  3.        del que nos encontramos, ya que este puntero pasará a apuntar al nodo
  4.        apuntado por el que vamos a borrar */
  5.     struct nodo_lista *nodo_aux, *nodo_anterior;
  6.     char nombre[T_NOM];
  7.     char telefono[T_TEL];
  8.     int encontrado = 0;
  9.  
  10.     printf("Nombre a borrar: ");
  11.     LEE_CAD(nombre,T_NOM);
  12.  
  13.     nodo_aux = *lista;
  14.     /* Comprueba si el elemento a borrar es el primero de la lista */
  15.     if(strcmp(nombre,nodo_aux->nombre)==0){
  16.        *lista=nodo_aux->siguiente; /* Ahora apunta al segundo de la lista */
  17.        free(nodo_aux);} /* Libera la memoria ocupada por el nodo borrado */
  18.     else{
  19.       nodo_anterior = nodo_aux;
  20.       nodo_aux = nodo_aux->siguiente;}
  21.       while ((nodo_aux->siguiente != NULL) && (!encontrado)){
  22.         if(strcmp(nombre,nodo_aux->nombre) == 0) /* Iguales */
  23.            encontrado = 1;
  24.         else{
  25.            nodo_anterior = nodo_aux;
  26.            nodo_aux = nodo_aux->siguiente;
  27.         }
  28.       }
  29.       if((nodo_aux->siguiente == NULL) && (!encontrado))
  30.        if(strcmp(nombre,nodo_aux->nombre) == 0) /* Iguales */
  31.          encontrado = 1;
  32.       if(encontrado){
  33.         nodo_anterior->siguiente = nodo_aux->siguiente;
  34.         free(nodo_aux); /* Libera la memoria ocupada por el nodo borrado */
  35.       }
  36.       printf("Telefono a borrar: ");
  37.     LEE_CAD(telefono,T_TEL);
  38.  
  39.     nodo_aux = *lista;
  40.     /* Comprueba si el elemento a borrar es el primero de la lista */
  41.     if(strcmp(telefono,nodo_aux->telefono)==0){
  42.        *lista=nodo_aux->siguiente; /* Ahora apunta al segundo de la lista */
  43.        free(nodo_aux);} /* Libera la memoria ocupada por el nodo borrado */
  44.     else{
  45.       nodo_anterior = nodo_aux;
  46.       nodo_aux = nodo_aux->siguiente;}
  47.       while ((nodo_aux->siguiente != NULL) && (!encontrado)){
  48.         if(strcmp(telefono,nodo_aux->telefono) == 0) /* Iguales */
  49.            encontrado = 1;
  50.         else{
  51.            nodo_anterior = nodo_aux;
  52.            nodo_aux = nodo_aux->siguiente;
  53.         }
  54.       }
  55.       if((nodo_aux->siguiente == NULL) && (!encontrado))
  56.        if(strcmp(telefono,nodo_aux->telefono) == 0) /* Iguales */
  57.          encontrado = 1;
  58.       if(encontrado){
  59.         nodo_anterior->siguiente = nodo_aux->siguiente;
  60.         free(nodo_aux); /* Libera la memoria ocupada por el nodo borrado */
  61.       }
  62. }
Cuando lo compilo introduzco esto: Maria 12, Lola 13, Pepe 14 a continuación me pide nombre a borrar pongo Maria y cuando le doy Enter para que me pide el teléfono a borrar me da fallo de segmentación. Después si quiero borrar el 2º nodo compuesto por Lola y 13 y le doy a mostrar lista me ha borrado el 2º y el 3º nodo y me muestra sólo Maria 12. Finalmente si elimino el 3º nodo y muestro la lista me ha borrado el 3º y el anterior, mostrándome sólo Maria 12.
¿Por qué el modulo que he hecho no funciona correctamente? Por favor, ayúdenme, gracias.
  #8 (permalink)  
Antiguo 20/05/2010, 14:19
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 2 meses
Puntos: 0
Respuesta: crear una lista enlazada

Contestadme, por favor.
  #9 (permalink)  
Antiguo 20/05/2010, 17:06
 
Fecha de Ingreso: enero-2008
Mensajes: 229
Antigüedad: 16 años, 3 meses
Puntos: 1
Respuesta: crear una lista enlazada

1. Esta parte de código, si bien no kieres utilizar mi sugerencia de codigo, este el porque te marca error

if(strcmp(nombre,nodo_aux->nombre)==0){
*lista=nodo_aux->siguiente; /* Ahora apunta al segundo de la lista */
free(nodo_aux);} /* Libera la memoria ocupada por el nodo borrado */
else{
nodo_anterior = nodo_aux;
nodo_aux = nodo_aux->siguiente;}//quita esta llave de aquí
while ((nodo_aux->siguiente != NULL) && (!encontrado)){
if(strcmp(nombre,nodo_aux->nombre) == 0) /* Iguales */
encontrado = 1;
else{
nodo_anterior = nodo_aux;
nodo_aux = nodo_aux->siguiente;
}
}
if((nodo_aux->siguiente == NULL) && (!encontrado))
if(strcmp(nombre,nodo_aux->nombre) == 0) /* Iguales */
encontrado = 1;
if(encontrado){
nodo_anterior->siguiente = nodo_aux->siguiente;
free(nodo_aux); /* Libera la memoria ocupada por el nodo borrado */
}
}//deberia estar aquí

debes observar que al realizar la busqueda por telefon tienes el mismo error.

por otra parte, no entiendo por que pides tanto el nombre como el numero de telefono. Con solo pedir el nombre basta para borrar un nodo. Ahora si lo que quieres es que para borrar un nodo necesitas que coicida tanto el nombre como el telefono , entoces en este if

Código C++:
Ver original
  1. if(strcmp(nombre,nodo_aux->nombre) == 0) /* Iguales */

debes tambien comparar si el telefono es igual. En este caso ya no sería neceserio el segundo proceso de busqueda.

2. Cuando insertas al incio, debes verificar si el primer elemento de la lista si es asi, su puntero a siguiente debe apuntar a NULL.
  #10 (permalink)  
Antiguo 21/05/2010, 05:17
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 2 meses
Puntos: 0
Respuesta: crear una lista enlazada

Respecto a lo que dices de borrar el nodo de forma que coincida el nombre y el teléfono he añadido lo siguiente al modulo borrar_nodo, pero no acaba de funcionar correctamente:

Código C:
Ver original
  1. void borrar_nodo(struct nodo_lista **lista){
  2.     /* Para borrar un nodo, tendremos que guardar un puntero al nodo anterior
  3.        del que nos encontramos, ya que este puntero pasará a apuntar al nodo
  4.        apuntado por el que vamos a borrar */
  5.     struct nodo_lista *nodo_aux, *nodo_anterior;
  6.     char nombre[T_NOM];
  7.     char telefono[T_TEL];
  8.     int encontrado = 0;
  9.  
  10.     printf("Nombre a borrar: ");
  11.     LEE_CAD(nombre,T_NOM);
  12.     nodo_aux = *lista;
  13.     /* Comprueba si el elemento a borrar es el primero de la lista */
  14.     if(strcmp(nombre,nodo_aux->nombre)==0){
  15.        *lista=nodo_aux->siguiente; /* Ahora apunta al segundo de la lista */
  16.        free(nodo_aux);} /* Libera la memoria ocupada por el nodo borrado */
  17.     else{
  18.       nodo_anterior = nodo_aux;
  19.       nodo_aux = nodo_aux->siguiente;
  20.       while ((nodo_aux->siguiente != NULL) && (!encontrado)){
  21.         if(strcmp(nombre,nodo_aux->nombre) == 0) /* Iguales */
  22.            encontrado = 1;
  23.         else{
  24.            nodo_anterior = nodo_aux;
  25.            nodo_aux = nodo_aux->siguiente;
  26.         }
  27.       }
  28.       if((nodo_aux->siguiente == NULL) && (!encontrado))
  29.        if(strcmp(nombre,nodo_aux->nombre) == 0) /* Iguales */
  30.          encontrado = 1;
  31.  
  32.       if(encontrado){
  33.         nodo_anterior->siguiente = nodo_aux->siguiente;
  34.         free(nodo_aux); /* Libera la memoria ocupada por el nodo borrado */
  35.       }
  36.     }
  37.     printf("Telefono a borrar: ");
  38.     LEE_CAD(telefono,T_TEL);
  39.     nodo_aux = *lista;
  40.     /* Comprueba si el elemento a borrar es el primero de la lista */
  41.     if(strcmp(telefono,nodo_aux->telefono)==0){
  42.        *lista=nodo_aux->siguiente; /* Ahora apunta al segundo de la lista */
  43.        free(nodo_aux);} /* Libera la memoria ocupada por el nodo borrado */
  44.     else{
  45.       nodo_anterior = nodo_aux;
  46.       nodo_aux = nodo_aux->siguiente;
  47.       while ((nodo_aux->siguiente != NULL) && (!encontrado)){
  48.         if(strcmp(telefono,nodo_aux->telefono) == 0) /* Iguales */
  49.            encontrado = 1;
  50.         else{
  51.            nodo_anterior = nodo_aux;
  52.            nodo_aux = nodo_aux->siguiente;
  53.         }
  54.       }
  55.       if((nodo_aux->siguiente == NULL) && (!encontrado))
  56.        if(strcmp(telefono,nodo_aux->telefono) == 0) /* Iguales */
  57.          encontrado = 1;
  58.  
  59.       if(encontrado){
  60.         nodo_anterior->siguiente = nodo_aux->siguiente;
  61.         free(nodo_aux); /* Libera la memoria ocupada por el nodo borrado */
  62.       }
  63.     }
  64. }
Cuando pido eliminar nombre y teléfono del primer nodo lo hace bien, en cambio cuando hago la misma operación en el segundo nodo me lo borra, pero también borra el que va a continuación de éste y finalmente si pido eliminar el tercer y último nodo me lo borra, pero haciendo lo mismo con el anterior. ¿Puedes decirme donde está el error?. Gracias.
  #11 (permalink)  
Antiguo 21/05/2010, 11:55
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 2 meses
Puntos: 0
Respuesta: crear una lista enlazada

Ayudadme, por favor, llevo varios días con este ejercicio.
  #12 (permalink)  
Antiguo 21/05/2010, 14:37
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: crear una lista enlazada

Esa funcion te va a borrar dos nodos, el que coicida con el telefono y otro que coicida con el nombre. Pon estos asi:

(strcmp(nombre,nodo_aux->nombre)==0) && (strcmp(telefono,nodo_aux->telefono) == 0)
A la hora de comparar. Pon los dos scanf al principio asi cargas los datos. y saca la segunda parte del codigo la que borraria el telefono.
  #13 (permalink)  
Antiguo 22/05/2010, 09:49
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 2 meses
Puntos: 0
Respuesta: crear una lista enlazada

¿Así está bien?. Cuando lo compilo me da el siguiente error: En la función ‘borrar_nodo’:
272: error: expected identifier before ‘(’ token


Código C:
Ver original
  1. void borrar_nodo(struct nodo_lista **lista){
  2.     /* Para borrar un nodo, tendremos que guardar un puntero al nodo anterior
  3.        del que nos encontramos, ya que este puntero pasará a apuntar al nodo
  4.        apuntado por el que vamos a borrar */
  5.     struct nodo_lista *nodo_aux, *nodo_anterior;
  6.     char nombre[T_NOM];
  7.     char telefono[T_TEL];
  8.     int encontrado = 0;
  9.  
  10.     printf("Nombre a borrar: ");
  11.     LEE_CAD(nombre,T_NOM);
  12.     printf("Telefono a borrar: ");
  13.     LEE_CAD(telefono,T_TEL);
  14.     nodo_aux = *lista;
  15.     /* Comprueba si el elemento a borrar es el primero de la lista */
  16.     if(strcmp(nombre,nodo_aux->nombre)==0) && (strcmp(telefono,nodo_aux->telefono) == 0){
  17.        *lista=nodo_aux->siguiente; /* Ahora apunta al segundo de la lista */
  18.        free(nodo_aux);} /* Libera la memoria ocupada por el nodo borrado */
  19.     else{
  20.       nodo_anterior = nodo_aux;
  21.       nodo_aux = nodo_aux->siguiente;
  22.       while ((nodo_aux->siguiente != NULL) && (!encontrado)){
  23.         if(strcmp(nombre,nodo_aux->nombre) == 0) && (strcmp(telefono,nodo_aux->telefono) == 0) /* Iguales */
  24.            encontrado = 1;
  25.         else{
  26.            nodo_anterior = nodo_aux;
  27.            nodo_aux = nodo_aux->siguiente;
  28.         }
  29.       }
  30.       if((nodo_aux->siguiente == NULL) && (!encontrado))
  31.        if(strcmp(nombre,nodo_aux->nombre) == 0) && (strcmp(telefono,nodo_aux->telefono) == 0) /* Iguales */
  32.          encontrado = 1;
  33.  
  34.       if(encontrado){
  35.         nodo_anterior->siguiente = nodo_aux->siguiente;
  36.         free(nodo_aux); /* Libera la memoria ocupada por el nodo borrado */
  37.       }
  38.     }
  39. }
  #14 (permalink)  
Antiguo 22/05/2010, 09:52
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 2 meses
Puntos: 0
Respuesta: crear una lista enlazada

El error me lo indica en el primer strcmp, pero yo no veo que le falte nada.
  #15 (permalink)  
Antiguo 22/05/2010, 09:58
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: crear una lista enlazada

Te faltan los parentesis exteriores, que indican todo la expresion que pertenece al if.

Asi va corregido:

if ((strcmp(nombre,nodo_aux->nombre)==0) && (strcmp(telefono,nodo_aux->telefono) == 0)){
  #16 (permalink)  
Antiguo 22/05/2010, 10:50
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 2 meses
Puntos: 0
Respuesta: crear una lista enlazada

Muchísimas gracias por tu ayuda, por fin me ha salido el ejercicio. Al ver que compilaba bien he sentido una enorme satisfacción, puesto que hace días que me estaba peleando con este ejercicio.
  #17 (permalink)  
Antiguo 22/05/2010, 11:22
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 2 meses
Puntos: 0
Respuesta: crear una lista enlazada

Si este mismo ejercicio lo quiero guardar en un fichero binario para posteriormente realizar operaciones con la lista enlazada, ¿cómo se haría?

Te muestro la información que pueda servirte de ayuda

Código C:
Ver original
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4.  
  5. #define LEE_CAD(c,n) { int i=0; \
  6.                      c[i]=getchar();\
  7.              while((c[i]=='\n') || (c[i]=='\t')) c[i]=getchar();\
  8.              while ((c[i]!='\n') && (i < (n-1))){ \
  9.                 i++;\
  10.             c[i]=getchar(); }\
  11.              c[i]='\0'; }
  12.  
  13. #define T_NOM 101
  14. #define T_TEL 10
  15.  
  16.  
  17. struct nodo_lista{
  18.    char nombre[T_NOM];
  19.    char telefono[T_TEL];
  20.    struct nodo_lista * siguiente; /*Puntero al siguiente elemento de la lista*/
  21. };
  22.  
  23. int main(){
  24.   struct nodo_lista *lista = NULL; /* Puntero al inicio de la lista, vacía */
  25.   struct nodo_lista *nodo;
  26.                                
  27.   int op; /* Variable para tomar la opción del menú del programa */
  28.  
  29.   void alta_inicio();
  30.   void alta_final();
  31.   void alta_despues_de();
  32.   void mostrar_lista();
  33.   void ordenar();
  34.   void borrar_nodo();
  35.  
  36.  
  37.   struct nodo_lista * buscar_nodo_nombre(); /* Devuelve un puntero al nodo buscado */
  38.   struct nodo_lista * buscar_nodo_telefono();
  39.  
  40.  
  41.   do{
  42.     do{
  43.        printf("1--> Añadir al Principio.\n");
  44.        printf("2--> Añadir al Final.\n");
  45.        printf("3--> Añadir después de.\n");
  46.        printf("4--> mostrar el total de la lista.\n");
  47.        printf("5--> Buscar (nodo)nombre para saber el telefono.\n");
  48.        printf("6--> Buscar (nodo)telefono para saber el nombre.\n");
  49.        printf("7--> Eliminar nodo.\n");
  50.        printf("8--> ordenar filas alfabeticamente\n");
  51.        printf("9--> Salir.\n");
  52.        scanf("%d",&op);
  53.      }while((op < 1) || (op > 9));
  54.      if( op != 9)
  55.        switch(op){
  56.           case 1: { alta_inicio(&lista); break;}
  57.           case 2: { alta_final(&lista); break;}
  58.           case 3: { alta_despues_de(&lista);break;}
  59.           case 4: { mostrar_lista(&lista); break;}
  60.           case 5: { nodo = buscar_nodo_nombre(&lista);
  61.                     printf("\n%s\n",nodo->telefono);
  62.                     break;}
  63.           case 6: { nodo = buscar_nodo_telefono(&lista);
  64.                     printf("\n%s\n",nodo->nombre);
  65.                     break;}
  66.           case 7: { borrar_nodo(&lista); break;}
  67.       case 8: { ordenar(&lista);break;}
  68.        }
  69.   }while(op != 9);
  70. }
  71. ////////////////////////////////////////////////////////////////////
  72. Aquí sólo te muestro las definiciones de los modulos puesto que no tengo espacio suficiente para publicar todo el código:
  73.  
  74. void alta_inicio(struct nodo_lista **lista){    
  75.   struct nodo_lista *nuevo_nodo; /* Variable usada para crear nuevos nodos
  76.                                     que serán añadidos a la lista */        
  77.        
  78.  
  79. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  80. void mostrar_lista(struct nodo_lista **lista){
  81.   struct nodo_lista *nodo_aux; /* Nodo auxiliar para recorrer la lista */
  82.  
  83.   nodo_aux = *lista;
  84.   while ( nodo_aux != NULL){
  85.      printf("%s  %s\n",nodo_aux->nombre,nodo_aux->telefono);
  86.      nodo_aux = nodo_aux->siguiente; /* El nodo auxiliar ahora apunta al
  87.                                         elemento siguiente */
  88.   }
  89. }
  90. /////////////////////////////////////////////////////////////////////////////////////////////
  91. void alta_final(struct nodo_lista **lista){
  92.   struct nodo_lista *nuevo_nodo; /* Variable usada para crear nuevos nodos
  93.                                     que serán añadidos a la lista */
  94.   struct nodo_lista *nodo_aux; /* Nodo auxiliar para recorrer la lista */
  95.  
  96.  
  97. /////////////////////////////////////////////////////////////////////////////////////////////
  98. void alta_despues_de(struct nodo_lista **lista){
  99.    struct nodo_lista *nuevo_nodo;
  100.    struct nodo_lista *nodo_aux;
  101.  
  102.    
  103. //////////////////////////////////////////////////////////////////////////////////////////////
  104. struct nodo_lista * buscar_nodo_nombre(struct nodo_lista **lista){
  105.     struct nodo_lista *nodo_aux, *resultado; /* Nodo auxiliar para recorrer la lista */
  106.    
  107. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  108. struct nodo_lista * buscar_nodo_telefono(struct nodo_lista **lista){
  109.     struct nodo_lista *nodo_aux, *resultado; /* Nodo auxiliar para recorrer la lista */
  110.    
  111. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  112. void borrar_nodo(struct nodo_lista **lista){
  113.     /* Para borrar un nodo, tendremos que guardar un puntero al nodo anterior
  114.        del que nos encontramos, ya que este puntero pasará a apuntar al nodo
  115.        apuntado por el que vamos a borrar */
  116.     struct nodo_lista *nodo_aux, *nodo_anterior;
  117.    
  118. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  119. void ordenar(struct nodo_lista **lista){
  120.   struct nodo_lista *nodo, *nodo_siguiente, *nodo_aux; /* Nodos para recorrer la lista */
  121.  
  122. ////////////////////////////////////////////////////////////////////////////////////////////////
  #18 (permalink)  
Antiguo 23/05/2010, 07:01
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 2 meses
Puntos: 0
Respuesta: crear una lista enlazada

Ayudadme, con la última duda que he planteado, por favor.
  #19 (permalink)  
Antiguo 24/05/2010, 04:17
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 2 meses
Puntos: 0
Respuesta: crear una lista enlazada

¿Alguien puede darme una solución a la última duda que he formulado?, es importante. Gracias.
  #20 (permalink)  
Antiguo 24/05/2010, 08:44
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: crear una lista enlazada

Primero tienes que pensar en una forma de separar una lista. Por ejemplo la "," separa los campos y por cada linea tienes una nueva entrada. Osea:
Pedro,4582351
Juan, 6565465

Para manejar archivos tienes muchas formas, yo te diria que uses fprintf y fscanf. Busca en google que hay un monton de datos. Sino mira esta pagina:

http://www.cplusplus.com/reference/c...stdio/fprintf/
  #21 (permalink)  
Antiguo 24/05/2010, 12:08
 
Fecha de Ingreso: enero-2008
Mensajes: 229
Antigüedad: 16 años, 3 meses
Puntos: 1
Respuesta: crear una lista enlazada

bien si el fprintf y fscanf, funcionan, si lo que quieres es guardalo como una estructura, utiliza las siguientes funciones fseek, fwrite, y fread. Debes tomar en cuenta que solo funcionan con estructuras cuyos elementos no sean punteros(enteros, flotantes, caracteres, o arreglos). Si no tendrias
  #22 (permalink)  
Antiguo 24/05/2010, 16:28
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 2 meses
Puntos: 0
Respuesta: crear una lista enlazada

Pensándolo mejor, lo que quiero hacer es guardar la lista que he creado en un fichero binario y luego poder leer el contenido de dicho fichero. ¿Con la información que he publicado me podéis mostrar el código de cómo hacerlo es que ando muy perdida con la gestión de ficheros?, os lo agradecería mucho. Gracias.

Etiquetas: enlazada, lista
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 12:50.