/* Possibile soluzione al compito del 20 settembre 1999 per coloro che dovevano sostenere
* l'esame di FONDAMENTI DI INFORMATICA 2
*
* ATTENZIONE: dato che questo programma e' stato sviluppato a fini didattici
* risulta eccessivamente pieno di commenti. NON prendetelo ad esempio dal
* punto di vista dei commenti!!! */
#include<stdio.h>
#include<stdlib.h> /* molti di voi si dimenticano di includere stdlib
* che pero' e' necessaria per le funzioni di
* allocazione dinamica della memoria !! */
/* definizione struttura dati per il nodo dell'albero binario */
struct elemento{
int codice;
int giacenza;
int valid;
struct elemento *maggiori;
struct elemento *minori;
} *mytree;
struct elemento *mylist=NULL;
/* prototipi delle funzioni */
void *Malloc(size_t);
FILE *Fopen(const char *, const char *);
void inserisci_in_albero(struct elemento);
void libera_albero(struct elemento*);
void visita_albero(FILE *,struct elemento*);
struct elemento *trova_punto_di_inserzione(struct elemento *, int);
struct elemento *ricerca_in_albero(struct elemento *, int);
/*************************************************************************/
int main(int argc, char **argv){
FILE *dati;
struct elemento elemento_tmp; /* struttura temporanea per dati in lettura */
struct elemento *p; /* puntatore al nodo ricercato */
/* prima fase: leggo il file e man mano inserisco gli elementi
* nella lista */
dati=Fopen("giacenze.dat","r");
while(!feof(dati)){
fscanf(dati, "%d;%d\n", &elemento_tmp.codice,&elemento_tmp.giacenza);
/* ora posso inserire nella lista */
inserisci_in_albero(elemento_tmp);
}
fclose(dati);
/* seconda fase: leggo il secondo file e aggiorno l'albero */
dati=Fopen("ordini.dat","r");
while(!feof(dati)){
fscanf(dati, "%d;%d\n", &elemento_tmp.codice,&elemento_tmp.giacenza);
/* ricerco il nodo che contiene il dato con lo stesso codice */
p=ricerca_in_albero(mytree, elemento_tmp.codice);
/* aggiorno il dato giacenza */
p->giacenza-=elemento_tmp.giacenza;
}
fclose(dati);
/* terza fase: aggiorno il primo file */
dati=Fopen("giacenze.dat","w");
/* visito l'albero (la modalita' non importa) */
visita_albero(dati, mytree);
fclose(dati);
/* la liberazione della memoria
* e' banale usando una funzione ricorsiva */
libera_albero(mytree);
return 0;
}
/*************************************************************************/
void libera_albero(struct elemento *o){
if(!o)return;
libera_albero(o->maggiori);
libera_albero(o->minori);
free(o);
}
/*************************************************************************/
void visita_albero(FILE *scrivo, struct elemento *o){
if(!o)return;
fprintf(scrivo,"%d;%d\n",o->codice,o->giacenza);
visita_albero(scrivo, o->maggiori);
visita_albero(scrivo, o->minori);
}
/*************************************************************************/
/* ricerca nell'albero l'elemento di codice a. Sfrutto la ricorsione */
struct elemento *ricerca_in_albero(struct elemento *p, int a){
/* suppongo che NON ci siano errori nei file !!!
* chiaramente e' un'ipotesi critica ! */
if(p->codice==a)return p;
if(p->codice>a)return ricerca_in_albero(p->minori,a);
else return ricerca_in_albero(p->maggiori,a);
}
/*************************************************************************/
/* inserisce un elemento in un albero binario di ricerca. Il testo non lo
* dice ma e' evidente che l'albero sara' ordinato usando il codice */
void inserisci_in_albero(struct elemento nuovo){
struct elemento *p; /* punto di inserzione */
if(mytree==NULL){ /* e' il primo elemento */
p=mytree=Malloc(sizeof(struct elemento));
}else{ /* dovro' trovare dove inserire */
p=trova_punto_di_inserzione(mytree, nuovo.codice);
if(p->codice>nuovo.codice){
p->minori=Malloc(sizeof(struct elemento));
p=p->minori;
}else{
p->maggiori=Malloc(sizeof(struct elemento));
p=p->maggiori;
}
}
/* a questo punto comunque sia p e' il nodo da usare: copio i dati */
p->maggiori=NULL;
p->minori=NULL;
p->codice=nuovo.codice;
p->giacenza=nuovo.giacenza;
}
/*************************************************************************/
/* restituisce il nodo sotto cui inserire un elemento di chiave a */
struct elemento *trova_punto_di_inserzione(struct elemento *p, int a){
if(p->codice>a){
if(p->minori)return trova_punto_di_inserzione(p->minori,a);
else return p;
}
/* suppongo non ci siano errori nei file e quindi e' chiaro
* che a questo punto p->codice<a */
if(p->maggiori)return trova_punto_di_inserzione(p->maggiori,a);
else return p;
}
/*************************************************************************/
/* da qui in poi sono semplici funzioni di utilita' gia' viste a lezione */
void *Malloc(size_t size)
{
void *genericp;
if((genericp=malloc(size))==NULL)
{
perror("Malloc");
exit(1);
}
return genericp;
}
/*************************************************************************/
FILE *Fopen(const char *nome, const char *modo)
{
FILE *tmp;
if((tmp=fopen(nome, modo))==NULL)
{
fprintf(stderr, "Non riesco ad aprire il file %s in maniera %s\n",nome, modo);
perror("Fopen");
exit(1);
}
return tmp;
}