#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FLUSH while(getchar()!='\n')
#define S 15
typedef short boolean;
typedef struct {
char NomeMateria[S], codice[S];
unsigned int crediti, giorno, mese, anno, voto;
} tipobaseABR;
void LeggiStringa(char s[], unsigned int dim) {
unsigned int i;
for(i=0; i<dim-1; i++)
if((s[i]=getchar())=='\n')
break;
if(i==dim-1) while(getchar()!='\n');
s[i]='\0';
}
void LeggiElementoABR(tipobaseABR *x) {
printf("\nInserisci il nome della materia: ");
LeggiStringa(x->NomeMateria, S);
printf("\nInserisci il codice della materia: ");
LeggiStringa(x->codice, S);
printf("\nInserisci il numero di crediti: ");
scanf("%u", &(x)->crediti);
FLUSH;
printf("\nInserisci la data dell'esame:\n");
do {
printf("\nInserisci il giorno: ");
scanf("%u", &(x)->giorno);
FLUSH;
} while(x->giorno>31||x->giorno<1);
do {
printf("\nInserisci il mese: ");
scanf("%u", &(x)->mese);
FLUSH;
} while(x->mese>12||x->mese<1);
do {
printf("\nInserisci l'anno: ");
scanf("%u", &(x)->anno);
FLUSH;
} while(x->anno<1);
do {
printf("\nInserisci il voto: ");
scanf("%u", &(x)->voto);
FLUSH;
} while(x->voto<18 || x->voto>30);
}
void VisualizzaElementoABR(tipobaseABR x) {
printf("\nNome Materia: %s\n", x.NomeMateria);
printf("\nCodice Materia: %s\n", x.codice);
printf("\nData: %u / %u / %u\n", x.giorno, x.mese, x.anno);
printf("\nCrediti: %u\n", x.crediti);
printf("\nVoto: %u\n", x.voto);
}
int ConfrontaABR(tipobaseABR x, tipobaseABR y) {
return(strcmp(x.NomeMateria, y.NomeMateria));
}
unsigned int EstraiVoto(tipobaseABR x) {
return(x.voto);
}
/* Implementazione_ABR */
#define ALBEROVUOTO NULL
typedef struct nodoABR {
tipobaseABR info;
struct nodoABR * leftchild, * rightchild;
} * abr;
void MakeNullABR(abr *a) {
*a=ALBEROVUOTO;
}
boolean EmptyABR(abr a) {
return(a==ALBEROVUOTO);
}
boolean FullABR(abr a) {
struct nodoABR * tmp;
boolean full=0;
if((tmp=(struct nodoABR *) malloc (sizeof(struct nodoABR)))==ALBEROVUOTO)
full=1;
else free(tmp);
return full;
}
abr LeftChild(abr a) {
if(!EmptyABR(a))
return a->leftchild;
}
abr RightChild(abr a) {
if(!EmptyABR(a))
return a->rightchild;
}
tipobaseABR Label(abr a) {
if(!EmptyABR(a))
return(a->info);
}
boolean Member(abr a, tipobaseABR x) {
if(EmptyABR(a)) return 0;
else {
if(!ConfrontaABR(a->info, x))
return 1;
else if(ConfrontaABR(a->info, x)>0)
return(Member(a->leftchild, x));
else return(Member(a->rightchild, x));
}
}
void InsertABR(abr *a, tipobaseABR x) {
if(!FullABR(*a)) {
if(EmptyABR(*a)) {
*a=(struct nodoABR *) malloc (sizeof(struct nodoABR));
(*a)->info=x;
(*a)->rightchild=(*a)->leftchild=ALBEROVUOTO;
}
else if(ConfrontaABR((*a)->info, x)>0)
InsertABR(&(*a)->leftchild, x);
else
InsertABR(&(*a)->rightchild, x);
}
}
/* tipobaseList.h */
#define STR 20
typedef struct {
char cognome[S], nome[S], CodiceFiscale[STR];
char residenza[S], matricola[S];
abr materie;
} tipobaseList;
void LeggiElementoList(tipobaseList *x) {
printf("\nInserisci il cognome: ");
LeggiStringa(x->cognome, S);
printf("\nInserisci il nome: ");
LeggiStringa(x->nome, S);
printf("\nInserisci il codice fiscale: ");
LeggiStringa(x->CodiceFiscale, STR);
printf("\nInserisci la residenza: ");
LeggiStringa(x->residenza, S);
printf("\nInserisci il numero di matricola: ");
LeggiStringa(x->matricola, S);
MakeNullABR(&(x)->materie);
}
void CercaCognomeList(tipobaseList *x) {
printf("\nInserisci il cognome: ");
LeggiStringa(x->cognome, S);
}
void CercaElementoList(tipobaseList *x) {
printf("\nInserisci il cognome: ");
LeggiStringa(x->cognome, S);
printf("\nInserisci il nome: ");
LeggiStringa(x->nome, S);
printf("\nInserisci il codice fiscale: ");
LeggiStringa(x->CodiceFiscale, STR);
}
void VisualizzaElementoList(tipobaseList x) {
printf("\nCognome: %s\n", x.cognome);
printf("Nome: %s\n", x.nome);
printf("Codice Fiscale: %s\n", x.CodiceFiscale);
printf("Residenza: %s\n", x.residenza);
printf("Numero di matricola: %s\n", x.matricola);
}
int ConfrontaList(tipobaseList x, tipobaseList y) {
if(!strcmp(x.cognome, y.cognome))
if(!strcmp(x.nome, y.nome))
return(strcmp(x.CodiceFiscale, y.CodiceFiscale));
else return(strcmp(x.nome, y.nome));
else return(strcmp(x.cognome, y.cognome));
}
int ConfrontaCognome(tipobaseList x, tipobaseList y) {
return(strcmp(x.cognome, y.cognome));
}
abr EstraiABR(tipobaseList x) {
return (x.materie);
}
void AggiornaABR(tipobaseList *x, abr a) {
x->materie=a;
}
unsigned int Indice(tipobaseList x) {
if(x.cognome[0]>='A'&&x.cognome[0]<='Z')
return(x.cognome[0]-'A');
if(x.cognome[0]>='a'&&x.cognome[0]<='z')
return(x.cognome[0]-'a');
return 0;
}
/* Implementazione_list.h */
#define LISTAVUOTA NULL
typedef struct nodoList {
tipobaseList info;
struct nodoList * next;
} * list;
typedef list position;
void MakeNullList(list *l) {
*l=LISTAVUOTA;
}
boolean EmptyList(list l) {
return(l==LISTAVUOTA);
}
boolean FullList(list l) {
struct nodoList * tmp;
boolean full=0;
if((tmp=(struct nodoList *) malloc (sizeof(struct nodoList)))==LISTAVUOTA)
full=1;
else free(tmp);
return full;
}
tipobaseList Retrieve(list l, position p) {
if(!EmptyList(l)) {
if(p==LISTAVUOTA) return l->info;
return (p->next->info);
}
}
position First(list l) {
return LISTAVUOTA;
}
position End(list l) {
if(EmptyList(l)) return LISTAVUOTA;
while(l->next!=LISTAVUOTA)
l=l->next;
return l;
}
position Next(list l, position p) {
if(!EmptyList(l)) {
if(p==LISTAVUOTA) return l;
return (p->next);
}
}
position Locate(list l, tipobaseList x) {
if(EmptyList(l)) return LISTAVUOTA;
if(!ConfrontaList(l->info, x)) return LISTAVUOTA;
while(l->next!=LISTAVUOTA)
if(!ConfrontaList(l->next->info, x))
break;
else l=l->next;
return l;
}
void InsertList(list *l, position p, tipobaseList x) {
struct nodoList * tmp;
if(!FullList(*l)) {
tmp=(struct nodoList *) malloc (sizeof(struct nodoList));
tmp->info=x;
if(p==LISTAVUOTA) {
tmp->next=*l;
*l=tmp;
}
else {
tmp->next=p->next;
p->next=tmp;
}
}
}
void DeleteList(list *l, position p) {
struct nodoList * tmp;
if(!EmptyList(*l)) {
if(p==LISTAVUOTA) {
tmp=*l;
*l=tmp->next;
}
else {
tmp=p->next;
p->next=tmp->next;
}
free(tmp);
}
}
/* Svolgimento Compito */
#define DIM 26
list archivio[DIM];
void Media(abr a, unsigned int *x, unsigned int *numero) {
tipobaseABR y;
if(!EmptyABR(a)) {if(!EmptyABR(LeftChild(a)))
Media(LeftChild(a), x, numero);
y=Label(a);
*x=*x+EstraiVoto(y);
(*numero)=(*numero)+1;
if(!EmptyABR(RightChild(a)))
Media(RightChild(a), x, numero);
}
}
void Visitainord(abr a) {
if(!EmptyABR(a)) {
if(!EmptyABR(LeftChild(a)))
Visitainord(LeftChild(a));
VisualizzaElementoABR(Label(a));
if(!EmptyABR(RightChild(a)))
Visitainord(RightChild(a));
}
}
void Insord(list *l, tipobaseList x) {
tipobaseList y;
position p, u;
if(!FullList(*l)) { p=First(*l);
if(EmptyList(*l)) InsertList(l, p, x);
else {
u=End(*l);
if(Locate(*l, x)!=u) printf("\nStudente gia' presente\n");
else {
while(p!=u) {
y=Retrieve(*l, p);
if(ConfrontaList(y, x)>0)
break;
else p=Next(*l, p);
}
InsertList(l, p, x);
}
}
}
}
void InsMateria(list *l, tipobaseList x, tipobaseABR y) {
abr a;
position p, u;
if(EmptyList(*l)) { printf("\nLa lista e' vuota. Prima di inserire la materia "
"sara' inserito lo studente\n");
LeggiElementoList(&x);
Insord(l, x);
p=First(*l);
}
else { p=Locate(*l, x);
if(p==End(*l)) { printf("\nStudente non trovato. Prima di continuare con l'inserimento\n"
"della materia, verra' inserito lo studente in archivio\n");
LeggiElementoList(&x);
Insord(l, x);
p=Locate(*l, x);
}
else
x=Retrieve(*l, p);
}
a=EstraiABR(x);
if(!FullABR(a)) {
InsertABR(&a, y);
AggiornaABR(&x, a);
DeleteList(l, p);
InsertList(l, p, x);
}
}
void VisualizzaMaterie(list l, tipobaseList x) {
position p, u;
tipobaseList y;
abr a;
unsigned int somma=0, materie=0;
unsigned int flag=0;
float media;
if(EmptyList(l)) printf("\nLista vuota\n");
else {
p=First(l);
u=End(l);
while(p!=u) {
y=Retrieve(l, p);
if(!ConfrontaCognome(y, x)) {
VisualizzaElementoList(y);
flag=1;
}
p=Next(l, p);
}
if(!flag) printf("\nNon esiste alcuno studente con questo cognome in archivio\n");
else {
printf("\nQual e' lo studente cercato?\n");
CercaElementoList(&x);
p=Locate(l, x);
if(p==u) printf("\nStudente non presente\n");
else {
x=Retrieve(l, p);
a=EstraiABR(x);
if(EmptyABR(a)) printf("\nLo studente non ha dato nessuna materia\n");
else{
Media(a, &somma, &materie);
Visitainord(a);
media = (float) somma / (float ) materie;
printf("\nMedia: %g\n", media);
}
}
}
}
}
main() {
unsigned int scelta, i, indice, materie;
tipobaseList x;
tipobaseABR y;
for(i=0; i<DIM; i++)
MakeNullList(archivio+i);
do {
printf("\n\n\t\t\tMENU'\n");
printf("1) Inserisci un nuovo studente\n");
printf("2) Registra una nuova materia\n");
printf("3) Visualizza le materie date da uno studente\n");
printf("4) Esci\n");
scanf("%u", &scelta);
FLUSH;
switch(scelta) {
case 1: LeggiElementoList(&x);
indice=Indice(x);
Insord(&(archivio[indice]), x);
printf("\nLo studente ha gia' dato delle materie?\n"
"Scrivere il numero di materie date: ");
scanf("%u", &materie);
FLUSH;
if(materie>0)
for(i=0; i<materie; i++) {
LeggiElementoABR(&y);
InsMateria(&(archivio[indice]), x, y);
}
break;
case 2: CercaElementoList(&x);
indice=Indice(x);
LeggiElementoABR(&y);
InsMateria(&(archivio[indice]), x, y);
break;
case 3: CercaCognomeList(&x);
indice=Indice(x);
VisualizzaMaterie(archivio[indice], x);
break;
}
} while(scelta!=4);
}