/*
    72__studenti_u_listi.c
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
 
typedef struct __student {
    char *ime, *prezime;
    int broj_indexa;    
    float prosjek;
    struct __student *next;
} student;
 
void ispis (student *);
float prosjek (student *); 
student *sort (student *);
student *unos (student *);
void pocisti (student *);
student *brisi (student *, int);
 
int main ( void ) {
    int opcija=0, br;
    student *pocetak=NULL;  
 
    while (opcija!=6) {
        printf ("\n\n-------------------------\n");
         printf ("1 - Unos novog studenta\n");
         printf ("2 - Ispis studenata\n");
         printf ("3 - Sortiranje liste\n");
         printf ("4 - Ispis prosjeka\n");
         printf ("5 - Brisanje studenta\n");
         printf ("-------------------------\n");
         scanf ("%d", &opcija);
 
        switch (opcija) {
            case 1: pocetak=unos(pocetak); break;
            case 2: ispis(pocetak); break;
            case 3: pocetak=sort(pocetak); break;
            case 4: 
printf("Prosjek=%3.2f\n", prosjek
(pocetak
)); 
break;
             case 5: 
printf("Unesite broj indexa:");
                     scanf("%d", &br); 
                    pocetak=brisi (pocetak, br);
                    break;
            case 6: pocisti(pocetak);
            default: break;
        }
    }
 
    return 0;
}
 
void ispis (student *pocetak) {
    /* ispis (eventualno nesortirane) liste studenata */
    printf ("%15s %15s %6s %7s\n", 
"IME", 
"PREZIME", 
"BRIND", 
"PROSJEK");
  
    while (pocetak!=NULL) {
        printf("%15s %15s %6d %7.2f\n", 
                 pocetak->ime, pocetak->prezime,
                pocetak->broj_indexa, pocetak->prosjek);
 
        pocetak = pocetak->next;
    }
}
 
float prosjek (student *pocetak) {
    /* racuna prosjek ocjena svih studenata u listi */
    int n=0;
    float f=0.0f;
 
    while (pocetak!=NULL) {
        f += pocetak->prosjek;
        pocetak = pocetak->next;
        n++;
    }
 
    if (n==0) return 0.0f;
    else return f/n;
}
 
student *sort (student *prvi) {
    /* sortira listu studenata po prezimenima (bubble sort) */
    int nered=1; /* nered==1 <-> lista nije sortirana */
    student *trenutni, *prije, *iza;
 
    /* ako je lista prazna ili ima samo 1 clan, nemamo sto sortirati */
    if (prvi==NULL || prvi->next==NULL) return prvi;
 
    while (nered) {
        nered=0;
        trenutni=prvi;
        iza=prvi->next;
 
        if (strcmp(trenutni->prezime, iza->prezime) > 0) {
            /* ako su prva elementa u krivom poredku, zamijeni ih */
            trenutni->next = iza->next;
            iza->next = trenutni;
            prvi=iza;
            nered = 1;
        }
 
        prije = prvi;
        trenutni=prvi->next;
        iza = trenutni->next;
 
        while (iza!=NULL) {
            if (strcmp(trenutni->prezime, iza->prezime) > 0) {
                /* ako su neka 2 elementa u krivom poredku, zamijeni ih */
                prije->next = iza;
                trenutni->next = iza->next;
                iza->next = trenutni;
                nered = 1;
            }
            prije = prije->next;
            trenutni = prije->next;
            iza = trenutni->next;
        }
    }
    return prvi;
}
 
student *unos (student *pocetak)
{
    /* ucitava podatke o novom studentu i ubacuje ga na pocetak liste;
       vraca novi pocetak liste */
    student *novi;
    char temp[100];
 
    /* alociraj prostor za novu zapis u listi */    
    novi = (student *) malloc(sizeof(student));
 
    scanf ("%s", temp);     
    novi->ime = (char *) malloc((strlen(temp)+1) * sizeof(char));
    strcpy (novi->ime, temp);
 
    scanf ("%s", temp);     
    novi->prezime = (char *) malloc((strlen(temp)+1) * sizeof(char));
    strcpy (novi->prezime, temp);
 
    scanf ("%d", &novi->broj_indexa); 
 
    scanf ("%f", &novi->prosjek);
 
    /* ubacujem na pocetak liste */
    if (pocetak==NULL)
        novi->next = NULL;  
    else novi->next = pocetak;
 
    return novi;
}
 
void pocisti (student *st)
{   
    /* oslobadja memoriju koju zauzimaju podaci u listi */
    student *temp;
 
    while (st!=NULL){
        temp=st->next;
        free(st);
        st=temp;
    }
}
 
student *brisi (student *pocetak, int br)
{
    /* iz liste se uklanja student sa danim brojem index-a */
    /* vraca se pokazivac na pocetak liste */
    student *temp, *prethodni, *trenutni;
 
    /* ako je lista prazna, nemamo sto brisati */
    if (pocetak==NULL) return pocetak;
 
    if (br==pocetak->broj_indexa)
    {
        /* ako treba izbaciti studenta sa pocetka liste... */
        temp = pocetak->next;
        free (pocetak->ime);
        free (pocetak->prezime);
        free (pocetak);
        pocetak=temp;
 
        return pocetak;
    }
    else
    {
        prethodni = pocetak;
        trenutni = pocetak->next;
        while(trenutni!=NULL)
        {
            if (br==trenutni->broj_indexa)
            {
                /* podaci studenta kojeg treba izbaciti su u cvoru trenutni */
                prethodni->next=trenutni->next;
                free (trenutni->ime);
                free (trenutni->prezime);
                free (trenutni);
                return pocetak;
            }
 
            prethodni = trenutni;
            trenutni = trenutni->next;
        }
 
        return pocetak;
    }
}