/
Inicio :: Foros

 F.A.Q.F.A.Q.                  Conéctese para revisar sus mensajesConéctese para revisar sus mensajes   

Lectura y Orden de lista enlazada de un fichero

 
      Índice del Foro elrincondelc.com -> Principiantes C/C++
Ver tema anterior :: Ver siguiente tema  
AutorMensaje
ZedGe



Registrado: 03 May 2011
Mensajes: 23

MensajePublicado: 06/05/2011 5:14 am
Título: Lectura y Orden de lista enlazada de un fichero

Tengo el siguiente codigo que ordena mis listas enlazadas a medida que voy leyendo el fichero pero el problema es:

Si hay mas de o 10 datos ingresados: Solo muestra 9 de mayor a menor.
Si hay menos de 10 datos ingresa pura basura hasta llenar los 10.

Pero Necesito que muestre 10 datos y con la informacion correspondiente.
O por Ultimo Que Lo Ordene Y me Muestre La Lista Entera Ordenada


Código:
void lectura(struct NodoVaca **primero)
{
   float resultado;
   system("cls"); 
   FILE *entrada;
   char linea[LONG_LINEA];
   struct NodoVaca *nuevo,*anterior,*actual,*p,*menor,*penultimo;
   
   if ((entrada = fopen("Datos.txt", "r")) == NULL)                     
      {
        perror("Datos.txt");
        getch();
        exit(1);
      }
   
   *primero = NULL;
   while (fgets(linea, LONG_LINEA, entrada) != NULL)                            //Leemos el contenido del archivo linea por linea 
        {
           nuevo = (struct NodoVaca *) malloc(sizeof(struct NodoVaca));         //Extraemos los campos de cada linea (registro)                                                       
           sscanf(                                                   
           linea,
           "%s %s %s %d %f %f %d %f %d %d",
           nuevo->RUT,
           nuevo->NombreCuidador,
           nuevo->NombreVaca,
           &nuevo->Edad,
           &nuevo->Porte,
           &nuevo->Peso,
           &nuevo->CalidadPasto,
           &nuevo->LitrosDiarios,
           &nuevo->VecesQueDaLeche,
           &nuevo->NumeroManchas   
           );
           resultado=(((3.14 + 3.14 * nuevo->CalidadPasto + 2.72 * nuevo->NumeroManchas + 3 - (sqrt((nuevo->Peso + nuevo->Porte)* nuevo->Edad))/ nuevo->CalidadPasto))/nuevo->LitrosDiarios)/100;
           nuevo->Calidad=resultado;
         
        int n;
       n = 0;
       p = *primero;
       while (p != NULL) {
         n++;
         p = p->siguiente;
       }
       printf("\nLa longitud de la Lista es de: %d", n);
       getch();
     
          anterior = actual = *primero;
         
 
         if (n<11)
            {     
              while (actual != NULL && actual->Calidad > nuevo->Calidad)        //se busca su posicion
                    {
                      anterior = actual;
                      actual = actual->siguiente;
                    }
             if (anterior == NULL || anterior == actual)                        //Se enlaza
                {
                   nuevo->siguiente = anterior;                                 //Se Inserta al principio
                   *primero = nuevo;
              //importante: al insertar al principio actuliza la cabecera */
                }
             else
                 {                                                              //inserta entre medias o al final
                   nuevo->siguiente = actual;
                   anterior->siguiente = nuevo;
                   
                 } 
          }
 
         else
              {
                 menor = *primero;                                         //siempre va a ser el ultimo de la lista
                penultimo = *primero;
              
                 while (menor->siguiente != NULL)
                        {
                         penultimo=menor;
                         menor=menor->siguiente;
                       
                        }
                 if (nuevo->Calidad > menor->Calidad)
                    {     
                       while (actual != NULL && actual->Calidad > nuevo->Calidad)// la misma para buscar posicion (mirar anterior)
                             {
                               anterior = actual;
                               actual = actual->siguiente;
                               
                             }
                if (anterior == NULL || anterior == actual)
                   {                                                            //inserta al principio */
                     nuevo->siguiente = anterior;
                     *primero = nuevo;                                          //importante: al insertar al principio actuliza la cabecera */
               
                   }
               else
                   {
                     nuevo->siguiente = actual;
                     anterior->siguiente = nuevo;
                     
                   }
              penultimo->siguiente = penultimo->siguiente->siguiente;
              free (menor);
             
    }
             }
system ("cls");               
 
   } 
   fclose(entrada);


}






Creo que el error esta en el else del if principal cuando deja de haber datos o se sobre pasa de los 11 :S
Alguien si tuviera el tiempo tambien me podria hacer otro codigo si le es mas conveniente con la misma idea?
Volver arriba
rir3760



Registrado: 01 Oct 2004
Mensajes: 7531
Ubicación: Mexico

MensajePublicado: 09/05/2011 8:46 am
Título:

Como ya te comente en el otro tema lo mas sencillo es separar la operacion en dos: primero lees todos los datos verificando errores. Lo siguiente es ordenar mediante las tres funciones (te comente de ellas en el otro tema).

Lo que sigue es C, tu debes ajustarlo para que funcione en tu programa (en C++).

Debo aclarar que sin ver y revisar el programa no puedo darte garantias de que funcione pero al menos no genera mensajes de error en la compilacion:
Código:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define LONG_LINEA  123

struct NodoVaca {
   char RUT[15];
   char NombreCuidador[15];
   char NombreVaca[15];

   int Edad;
   float Porte;
   float Peso;

   int CalidadPasto;
   float LitrosDiarios;
   int VecesQueDaLeche;
   int NumeroManchas;
   
   float Calidad;
   struct NodoVaca *siguiente;
};
typedef struct NodoVaca NodoVaca;

NodoVaca *extraer(NodoVaca **p);
void      insertar(NodoVaca **p, NodoVaca *nuevo);
void      lectura(NodoVaca **primero);
void      ordenar(NodoVaca **primero);


int main (void)
{
   /* ... */
   
   return EXIT_SUCCESS;
}


NodoVaca *extraer(NodoVaca **p)
{
   NodoVaca *rv;
   
   if ((rv = *p) != NULL)
      *p = (*p)->siguiente;
   
   return rv;
}


void insertar(NodoVaca **p, NodoVaca *nuevo)
{
   while (*p != NULL && nuevo->Calidad >= (*p)->Calidad)
      p = &(*p)->siguiente;
   
   nuevo->siguiente = *p;
   *p = nuevo;
}


void lectura(NodoVaca **primero)
{
   FILE *entrada;
   float resultado;
   char linea[LONG_LINEA];
   NodoVaca *nuevo;
   
   if ((entrada = fopen("Datos.txt", "r")) == NULL){
      perror ("Datos.txt");
      exit(EXIT_FAILURE);
   }
   
   *primero = NULL;
   //Leemos el contenido del archivo linea por linea
   while (fgets (linea, LONG_LINEA, entrada) != NULL){
      nuevo = (NodoVaca *) malloc(sizeof *nuevo);
     
      //Extraemos los campos de cada linea (registro)
      sscanf (
         linea,
         "%s %s %s %d %f %f %d %f %d %d",
         nuevo->RUT,
         nuevo->NombreCuidador,
         nuevo->NombreVaca,
         &nuevo->Edad,
         &nuevo->Porte,
         &nuevo->Peso,
         &nuevo->CalidadPasto,
         &nuevo->LitrosDiarios,
         &nuevo->VecesQueDaLeche,
         &nuevo->NumeroManchas
      );
      nuevo->Calidad = (((3.14 + 3.14 * nuevo->CalidadPasto +
         2.72 * nuevo->NumeroManchas + 3 -
         (sqrt((nuevo->Peso + nuevo->Porte) * nuevo->Edad)) /
         nuevo->CalidadPasto)) / nuevo->LitrosDiarios
      ) / 100;
     
      nuevo->siguiente = *primero;
      *primero = nuevo;
   }
   
   fclose(entrada);
}


void ordenar(NodoVaca **primero)
{
   NodoVaca *nueva_lista = NULL;
   NodoVaca *p;
   
   p = *primero;
   while (p != NULL)
      insertar(&nueva_lista, extraer(&p));
   
   *primero = nueva_lista;
}


Un saludo
_________________
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
Volver arriba
untio



Registrado: 17 Sep 2008
Mensajes: 380
Ubicación: MICA S.A.

MensajePublicado: 09/05/2011 9:11 am
Título:

Hola,
No sé si meteré la pata -probablemente la meta-, pero veo en el foro muchos posts sobre listas enlazadas.
Personalmente si de lo que se trata es de mantener una lista de datos, o estructuras de datos, me parece mucho más rápido utilizar un array de punteros a ellos. Si lo creas usas malloc. Si se han de añadir más punteros, se puede usar realloc. Si se han de eliminar unos cuantos se puede usar malloc y free.
Además veo mucho más rápido ordenar una lista de punteros que una lista enlazada. Bueno, no mucho más rápido, pero sí mucho más sencillo de ordenar y de crear.
Perdonadme si me equivoco.
Volver arriba
      Índice del Foro elrincondelc.com -> Principiantes C/C++
Página 1 de 1Todas las horas están en GMT - 8 Horas

 
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas

(c) ElRincondelC.com

Un proyecto de UrlanHeat.com