/***********************************************************************
 * Implementierung einer linearen Liste  ( Syspro Uebung 2 Aufgabe 1 ) *
 ***********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct student {                   /* Struktur des Datensatzes:    */
  int		matnum;                /* Matrikelnummer, Vor-         */
  char		vorname[20];           /* und Nachname sind Eintraege. */ 
  char		nachname[20];          /* Die Datenbank ist eine       */
  struct student  *next_student;         /* einfach verkettete Liste     */
 } Student;                         

Student *studenten_liste=NULL;      /* Initialisierung der Datenbank */

int is_empty() {                      /* Ist die Datenbank leer?       */
  return(studenten_liste==NULL);
}


void insert(int matnum,              /* Einfuegen eines Elementes     */
             char vorname[20],
             char nachname[20]) {
  Student *curr,*next,*neuer_student;

  neuer_student=malloc(sizeof(Student));  /* Speicher fuer Element   */
  strcpy(neuer_student->vorname,vorname);   /* anfordern und mit Daten */
  strcpy(neuer_student->nachname,nachname); /* fuellen                 */
  neuer_student->matnum=matnum;
                                     
  curr=studenten_liste;               /* Neues Element in DB einfuegen */
  if ((curr==NULL)||(curr->matnum>neuer_student->matnum)) {
    neuer_student->next_student=curr; /* Sonderfall: an erster Stelle  */
    studenten_liste=neuer_student;    /* einfuegen                     */
  }
  else {
    next=curr->next_student;          /* Durchmustern der DB           */
    while ((next!=NULL)&&(next->matnum<neuer_student->matnum)) {
      curr=next;                      
      next=next->next_student;        
    }
    neuer_student->next_student=next; /* Neues Element nach curr und   */
    curr->next_student=neuer_student; /* vor next einfuegen            */
  }
}


int erase(int matnum) {             /* Löschen eines Elementes       */
  Student *curr,*next;

  if (is_empty(studenten_liste))
    return(0);                        /* Rückgabewert: Fehler!         */

  curr=studenten_liste;
  if (curr->matnum==matnum) {         /* Sonderfall: erstes Element    */
    studenten_liste=curr->next_student; /* loeschen                    */
    free(curr);                       /* Speicher freigeben            */
    return(1);                        /* Rückgabewert: OK.             */
  }

  next=curr->next_student;            /* Durchmustern der DB           */
  while ((next!=NULL)&&(next->matnum<matnum)) {
    curr=next;
    next=next->next_student;
  }
  if ((next==NULL)||(next->matnum!=matnum))
    return(0);                        /* Rückgabewert: Fehler!         */
  curr->next_student=next->next_student;  /* Element loeschen          */
  free(next);                         /* Speicher wieder freigeben     */
  return(1);                          /* Rückgabewert: OK.             */
}


int get_student(int matnum,           /* Auslesen eines Elementes      */
                char vorname[20],
                char nachname[20]) {
  Student *curr;

  curr=studenten_liste;               /* Durchmustern der DB           */
  while ((curr!=NULL)&&(curr->matnum<matnum)) curr=curr->next_student;
  if ((curr==NULL)||(curr->matnum!=matnum))
    return(0);                        /* Rückgabewert: Fehler!         */
  else {
    strcpy(vorname,curr->vorname);
    strcpy(nachname,curr->nachname);
    return(1);                        /* Rückgabewert: OK.             */
  }
}

int main() {                              /* Test der Listenfunktionen     */
  char vorname[20],nachname[20];
  Student *curr;

  printf(">>> Fuege neuen Studenten in die Liste ein: Bill Clinton [6666] ...\n");
  insert(6666,"Bill","Clinton");

  printf(">>> Fuege neuen Studenten in die Liste ein: Hillary Clinton [4711] ...\n");
  insert(4711,"Hillary","Clinton");

  printf(">>> Fuege neuen Studenten in die Liste ein: Newt Gingrich [9999] ...\n");
  insert(9999,"Newt","Gingrich");

  printf(">>> Test, ob die Matrikelnummer 0815 bereits erfasst wurde ...\n");
  if (get_student(815,vorname,nachname)) 
    printf("    Matrikelnummer %4i: %s %s\n",815,vorname,nachname);
  else
    printf("    Matrikelnummer %4i ist unbekannt\n",815);

  printf(">>> Fuege neuen Studenten in die Liste ein: Monica Lewinsky [0815] ...\n");
  insert(815,"Monica","Lewinsky");

  printf(">>> Loesche die Matrikelnummer 4711 ...\n");
  if (erase(4711)) 
    printf("    Matrikelnummer %4i geloescht\n",4711);
  else
    printf("    Matrikelnummer %4i war nicht erfasst\n",4711);

  printf(">>> Test ob die Studentenliste leer ist ...\n");
  if (is_empty())
    printf("    Die Studentenliste ist leer \n");
  else
    printf("    Die Studentenliste ist nicht leer \n");

  printf(">>> Test, ob die Matrikelnummer 6666 bereits erfasst wurde ...\n");
  if (get_student(6666,vorname,nachname)) 
    printf("    Matrikelnummer %4i: %s %s\n",6666,vorname,nachname);
  else
    printf("    Matrikelnummer %4i ist unbekannt\n",6666);

  printf(">>> Loesche die Matrikelnummer 9998 ...\n");
  if (erase(9998)) 
    printf("    Matrikelnummer %4i geloescht\n",9998);
  else
    printf("    Matrikelnummer %4i war nicht erfasst\n",9998);

  printf(">>> Loesche die Matrikelnummer 9999 ...\n");
  if (erase(9999)) 
    printf("    Matrikelnummer %4i geloescht\n",9999);
  else
    printf("    Matrikelnummer %4i war nicht erfasst\n",9999);

  printf(">>> Gebe alle erfassten Studenten aus ...\n");
  curr=studenten_liste;
  while(curr!=NULL) {
    printf("    Matrikelnummer %4i: %s %s\n",curr->matnum,curr->vorname,curr->nachname);
    curr=curr->next_student;
  }
  return 0;
}


