//esliste.cpp
//Mostra le funzioni di lettura, stampa e eliminazione di una lista semplice.
//Le funzioni sono definite sia in modo ricorsivo che in modo iterativo.

#include <iostream.h>

struct rec {
  int info;
  rec* next;
};


//lettura: legge una sequenza di interi terminata da 0 e costruisce una lista
//contenente tale sequenza (escluso lo 0 finale)

//versione ricorsiva
rec* LeggiListaR()
{
  int val;
  cin >> val;
  if (val == 0) return NULL;
  else {
    rec* l = new rec;
    l->info = val;
    l->next = LeggiListaR();
    return l;
  }
}

//versione iterativa
rec* LeggiListaI()
{
  int val;
  //primo elemento trattato in modo speciale
  cin >> val;
  if (val == 0) return NULL;
  else {
    rec* l = new rec;
    l->info = val;
    rec* ll = l;
    cin >> val;
    //inserimento elementi successivi
    while (val != 0) {
      ll->next = new rec;
      ll = ll->next;
      ll->info = val;
      cin >> val;
    }
    ll->next = NULL; //nota dobbiamo chiudere la lista!

    return l;
  }
}

//versione iterativa con uso del record generatore
rec* LeggiListaIRG()
{
  rec* l = new rec; //creazione record generatore
  rec* ll = l;

  int val;
  cin >> val;
  while (val != 0) {
    ll->next = new rec;
    ll = ll->next;
    ll->info = val;
    cin >> val;
  }
  ll->next = NULL;

  ll = l;      //eliminazione record generatore
  l = l->next;
  delete ll;

  return l;
}


//stampa: stampa la lista il cui punt iniziale e' passato alla funzione

//versione ricorsiva
void StampaListaR(rec* l)
{
  if (l ==NULL) cout << endl;
  else {
    cout << l->info << ' ';
    StampaListaR(l->next);
  }
}

//versione iterativa
void StampaListaI(rec* l)
{
  while (l != NULL) {
    cout << l->info << ' ';
    l = l->next;
  }
  cout << endl;
}


//cancellazione: cancella la lista il cui punt iniziale e' passato alla
//funzione

//versione ricorsiva
void CancellaListaR(rec*& l)
{
  if (l != NULL) {
    CancellaListaR(l->next);  //elimina resto della lista
    delete l; //elimina record puntato da l;
    l = NULL; //poni l a NULL
  }
}

//versione iterativa
void CancellaListaI(rec*& l)
{
  while (l != NULL) {
    rec* ll = l;
    l = l->next;
    delete ll;
  }
  l = NULL; //poni l a NULL
}


void main()
{
  rec* lis;

  lis = LeggiListaR();
  StampaListaR(lis);
  CancellaListaR(lis);

  lis = LeggiListaI();
  StampaListaI(lis);
  CancellaListaI(lis);

  lis = LeggiListaIRG();
  StampaListaI(lis);
  CancellaListaI(lis);
}
