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

Insertar elemento en lista ordeanda

Estas en el tema de Insertar elemento en lista ordeanda en el foro de C/C++ en Foros del Web. Hola, a ver si me podeis hechar una mano con esto: Tengo una lista y le tengo que poder insertar elementos, pero al insertarlos tienen ...
  #1 (permalink)  
Antiguo 03/11/2014, 05:39
 
Fecha de Ingreso: octubre-2014
Ubicación: Cornellá de Llobregat
Mensajes: 8
Antigüedad: 9 años, 5 meses
Puntos: 2
Insertar elemento en lista ordeanda

Hola, a ver si me podeis hechar una mano con esto:

Tengo una lista y le tengo que poder insertar elementos, pero al insertarlos tienen que estar ordenados de menor a mayor. Tengo los siguientes ficheros y tengo que modificar la función insertarPrimero para que me añada los elementos ordenadamente. He probado varias cosas y no me han salido, así que os dejo el código para ver si me podéis hechar una mano.

Este es el archivo de las funciones:
Código C:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "Estudiante.h"
  4.  
  5.  
  6. void nuevaLista (tipo_Nodo **lista){
  7.    *lista = NULL;
  8. }
  9.  
  10. tipo_Nodo *getNode (tipo_info elemento){
  11.    tipo_Nodo *p;
  12.    /*Asigna memoria dinamicamente para un solo nodo*/
  13.    p = (tipo_Nodo *) malloc(sizeof(tipo_Nodo));
  14.    if (p != NULL)         /*Si obtuvo un nodo (p) de la memoria...*/
  15.       {
  16.        p->info = elemento;     /*guarda elemento en info*/
  17.        p->next = NULL;         /*next apunta a NULL*/
  18.       }
  19.    return p;
  20. }
  21.  
  22. int listaVacia (tipo_Nodo *lista){
  23.    if (lista == NULL)
  24.       return (1);          /*retorna 1 (Exito). Lista vacia*/
  25.    else
  26.       return (0);          /*retorna 0 (Error). Lista no vacia*/
  27. }
  28.  
  29. tipo_Nodo *insertarPrimero (tipo_Nodo **lista, tipo_info elemento){
  30.    tipo_Nodo *p;
  31.    p = getNode(elemento);         /*obtiene un nuevo nodo*/
  32.    if (p != NULL)                 /*Si obtuvo un nodo (p)...*/
  33.       {
  34.        if (listaVacia (*lista))  /*Si lista vacia...*/
  35.           *lista = p;            /*actualiza "lista" con p*/
  36.        else                      /*sino*/
  37.           {
  38.            /*Enlaza p antes del primero ("lista")*/
  39.            p->next = *lista;    /*p apunta a "lista"*/
  40.            *lista = p;          /*actualiza "lista" con p*/
  41.           }
  42.       }
  43.    return p;     /*retorna el nuevo nodo creado*/
  44. }
  45.  
  46. void mostrarLista (tipo_Nodo *lista){
  47.    tipo_Nodo *p;
  48.    p = lista;               /*guarda primer nodo en p*/
  49.    while (p != NULL)        /*recorre la lista*/
  50.    {
  51.       printf("%d,%d,%f\n", p->info.DNI, p->info.Edad,
  52.              p->info.PromedioCalif);
  53.       p = p->next;               /*avanza nodo p*/
  54.    }
  55.    printf("\n");
  56. }
  57.  
  58. int eliminarNodo (tipo_Nodo **lista, tipo_Nodo *nodo){
  59.    tipo_Nodo *q;
  60.    if (nodo == NULL)              /*Si el nodo de entrada es NULL...*/
  61.       return (-1);                /*no puede eliminar*/
  62.    if (listaVacia (*lista))       /*Si lista vacia...*/
  63.       return (-1);                /*(underflow) retorna -1*/
  64.    else                           /*sino*/
  65.       {
  66.        if (nodo == *lista)       /*Si el nodo de entrada es el primero...*/
  67.           *lista = nodo->next;   /*actualiza "lista" con siguiente de nodo*/
  68.        else                      /*sino*/
  69.           {
  70.            q = *lista;             /*Buscar nodo (q) anterior a nodo*/
  71.            while (q->next != nodo)
  72.              q = q->next;
  73.            /*Enlaza (q) anterior a nodo con siguiente de nodo*/
  74.            q->next = nodo->next;   /*q apunta a siguiente de nodo*/
  75.           }
  76.        free (nodo);              /*libera nodo (memoria dinamica)*/
  77.        return (1);           /*retorna elemento eliminado*/
  78.       }
  79. }
  80.  
  81. tipo_Nodo *buscar (tipo_Nodo *lista, tipo_info elemento){
  82.    tipo_Nodo *p;
  83.    p = lista;                     /*guarda primer nodo en p*/
  84.    while (p != NULL)              /*recorre la lista*/
  85.    {
  86.      if (p->info.DNI, elemento.DNI)  /*Si elemento encontrado*/
  87.         return p;                /*retorna nodo p*/
  88.      else
  89.         p = p->next;             /*avanza nodo p*/
  90.    }
  91.    return NULL;                   /*Si no encontrado, retorna NULL*/
  92. }

Este es el archivo h:
Código C:
Ver original
  1. #ifndef ESTUDIANTE_H
  2. #define ESTUDIANTE_H
  3.  
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6.  
  7.  
  8. /*Definicion de Tipo para elementos*/
  9. typedef struct nodo_estudiante {
  10.     int DNI;
  11.     int Edad;
  12.     float PromedioCalif;
  13. } tipo_info;
  14.  
  15. /*Definicion de Tipo para una Lista*/
  16. typedef struct nodo_Lista {
  17.     tipo_info info;
  18.     struct    nodo_Lista *next;
  19. } tipo_Nodo;
  20.  
  21.  
  22. void nuevaLista (tipo_Nodo **lista);
  23.  
  24. tipo_Nodo *getNode (tipo_info elemento);
  25.  
  26. int listaVacia (tipo_Nodo *lista);
  27.  
  28. tipo_Nodo *insertarPrimero (tipo_Nodo **lista, tipo_info elemento);
  29.  
  30. void mostrarLista (tipo_Nodo *lista);
  31.  
  32. int eliminarNodo (tipo_Nodo **lista, tipo_Nodo *nodo);
  33.  
  34. tipo_Nodo *buscar (tipo_Nodo *lista, tipo_info elemento);
  35.  
  36. #endif

Muchas gracias :)
  #2 (permalink)  
Antiguo 03/11/2014, 05:52
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Insertar elemento en lista ordeanda

Código C++:
Ver original
  1. tipo_Nodo *insertarPrimero (tipo_Nodo **lista, tipo_info elemento);

Esa función cumple perfectamente su cometido, que es añadir un elemento al inicio de la lista. Si tu idea es que la lista ha de estar ordenada deberías, aunque parezca una tontería, empezar por cambiar el nombre de la función. Quizás algo del tipo "insertarElemento( )"

Para crear una lista de forma ordenada has de partir de la base de que los elementos que ya existen en la base se encuentran ya ordenados. Si partes de esa base, insertar un elemento nuevo se basa en recorrer la lista y comparar elemento por elemento hasta encontrar su posición (el elemento anterior es más pequeño y el siguiente más grande, o al revés). Para poder hacer esto tienes que tener claro qué información es la que determina el orden de la lista (DNI ascendente o DNI descendente serían las opciones más obvias con la estructura que tienes)
  #3 (permalink)  
Antiguo 03/11/2014, 10:03
 
Fecha de Ingreso: octubre-2014
Ubicación: Cornellá de Llobregat
Mensajes: 8
Antigüedad: 9 años, 5 meses
Puntos: 2
Respuesta: Insertar elemento en lista ordeanda

Otra pregunta, he creado una función para modificar los valores de un nodo pero al ejecutar la modificacion se me cambian los valores del ultimo nodo que he añadido a mi lista. Primero hago uso de la función buscar que me devuelve el nodo que quiero modificar, y luego he creado una función modificarElemento:
Código C:
Ver original
  1. void modificarElemento (tipo_Nodo *nodo, tipo_info elemento){
  2.  
  3.   nodo->info.DNI = elemento.DNI;
  4.   nodo->info.Edad = elemento.Edad;
  5.   nodo->info.PromedioCalif = elemento.PromedioCalif;
  6. }

Le paso por argumento el nodo que quiero modificar y los valores nuevos, pero al ejecutar la función lo que me hace es sobreescribirme el ultimo nodo que he añadido a mi lista.

Me podéis echar una mano?

Muchas gracias,
  #4 (permalink)  
Antiguo 03/11/2014, 10:13
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Insertar elemento en lista ordeanda

Cita:
Iniciado por yeraypg Ver Mensaje
Otra pregunta, he creado una función para modificar los valores de un nodo pero al ejecutar la modificacion se me cambian los valores del ultimo nodo que he añadido a mi lista. Primero hago uso de la función buscar que me devuelve el nodo que quiero modificar, y luego he creado una función modificarElemento:
Código C:
Ver original
  1. void modificarElemento (tipo_Nodo *nodo, tipo_info elemento){
  2.  
  3.   nodo->info.DNI = elemento.DNI;
  4.   nodo->info.Edad = elemento.Edad;
  5.   nodo->info.PromedioCalif = elemento.PromedioCalif;
  6. }

Le paso por argumento el nodo que quiero modificar y los valores nuevos, pero al ejecutar la función lo que me hace es sobreescribirme el ultimo nodo que he añadido a mi lista.

Me podéis echar una mano?

Muchas gracias,
El problema no está en esa función... está en el código que llama a esa función. Esa función lo único que hace es sobreescribr la información de un nodo referenciado mediante un puntero... el código que llama a esta función está pasando el puntero que no es.
  #5 (permalink)  
Antiguo 03/11/2014, 10:24
 
Fecha de Ingreso: octubre-2014
Ubicación: Cornellá de Llobregat
Mensajes: 8
Antigüedad: 9 años, 5 meses
Puntos: 2
Respuesta: Insertar elemento en lista ordeanda

Es que no encuentro donde puede estar el error :(
Código C:
Ver original
  1. if (opcion == 4){     /*opcion 4: Modificar un elemento de lista*/
  2.        
  3.             printf("Ingrese el DNI a modificar: \n");
  4.             scanf ("%d", &elemento.DNI);
  5.            
  6.             /*Buscar elemento*/
  7.             nodo2 = buscar (lista, elemento);
  8.            
  9.             /*Modificar nodo*/
  10.             printf("Ingrese el nuevo valor del DNI (Si lo quiere dejar igual ponga el mismo): \n");
  11.             scanf ("%d", &elemento2.DNI);
  12.             printf("Ingrese el nuevo valor de la Edad (Si lo quiere dejar igual ponga el mismo): \n");
  13.             scanf ("%d", &elemento2.Edad);
  14.             printf("Ingrese el nuevo valor del Promedio (Si lo quiere dejar igual ponga el mismo): \n");
  15.             scanf ("%f", &elemento2.PromedioCalif);
  16.  
  17.             nodo2 = modificarElemento(nodo2, elemento2);
  18.            
  19.             printf("\nElemento %d modificado...\n", elemento.DNI);
  20.         }
  21.     }

Te paso el código de la parte del main en la que uso esa función.

Muchas gracias por molestarte en ayudar a uno que tiene líos con punteros.. jajaja
  #6 (permalink)  
Antiguo 03/11/2014, 10:42
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Insertar elemento en lista ordeanda

Dos cosas:

Código C++:
Ver original
  1. nodo2 = buscar (lista, elemento);

Si estás escribiendo siempre en el último nodo es porque esa función no está funcionando como es debido.

Código C++:
Ver original
  1. printf("Ingrese el DNI a modificar: \n");
  2. scanf ("%d", &elemento.DNI);
  3.            
  4. /*Buscar elemento*/
  5. nodo2 = buscar (lista, elemento);
  6.            
  7. /*Modificar nodo*/
  8. printf("Ingrese el nuevo valor del DNI (Si lo quiere dejar igual ponga el mismo): \n");
  9. scanf ("%d", &elemento2.DNI);
  10. printf("Ingrese el nuevo valor de la Edad (Si lo quiere dejar igual ponga el mismo): \n");
  11. scanf ("%d", &elemento2.Edad);
  12. printf("Ingrese el nuevo valor del Promedio (Si lo quiere dejar igual ponga el mismo): \n");
  13. scanf ("%f", &elemento2.PromedioCalif);
  14.  
  15. nodo2 = modificarElemento(nodo2, elemento2);

¿Por qué usas un nodo temporal? Es algo que te puedes ahorrar:

Código C++:
Ver original
  1. int dni;
  2. printf("Ingrese el DNI a modificar: \n");
  3. scanf ("%d", &dni);
  4.            
  5. /*Buscar elemento*/
  6. nodo2 = buscar (lista, dni); // Ahora el segundo parámetro de la función es un int
  7.            
  8. /*Modificar nodo*/
  9. printf("Ingrese el nuevo valor del DNI (Si lo quiere dejar igual ponga el mismo): \n");
  10. scanf ("%d", &nodo2->DNI);
  11. printf("Ingrese el nuevo valor de la Edad (Si lo quiere dejar igual ponga el mismo): \n");
  12. scanf ("%d", &nodo2->Edad);
  13. printf("Ingrese el nuevo valor del Promedio (Si lo quiere dejar igual ponga el mismo): \n");
  14. scanf ("%f", &nodo2->PromedioCalif);
  15.  
  16. //nodo2 = modificarElemento(nodo2, elemento2); Esta llamada sobra
  #7 (permalink)  
Antiguo 03/11/2014, 10:52
 
Fecha de Ingreso: octubre-2014
Ubicación: Cornellá de Llobregat
Mensajes: 8
Antigüedad: 9 años, 5 meses
Puntos: 2
Respuesta: Insertar elemento en lista ordeanda

Pero cuando &nodo2->DNI, por ejemplo, no puede ser no? Porque tipo_nodo no contiene esos atributos.

Los nodos y los atributos los tengo hechos así:
Código C:
Ver original
  1. typedef struct nodo_estudiante {
  2.     int DNI;
  3.     int Edad;
  4.     float PromedioCalif;
  5. } tipo_info;
  6.  
  7. /*Definicion de Tipo para una Lista*/
  8. typedef struct nodo_Lista {
  9.     tipo_info info;
  10.     struct    nodo_Lista *next;
  11. } tipo_Nodo;
  #8 (permalink)  
Antiguo 04/11/2014, 01:35
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Insertar elemento en lista ordeanda

Cita:
Iniciado por yeraypg Ver Mensaje
Pero cuando &nodo2->DNI, por ejemplo, no puede ser no? Porque tipo_nodo no contiene esos atributos.
Cierto, no me di cuenta del detalle. En tal caso sería &nodo2->info.DNI

Etiquetas: lista, ordenada
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 19:50.