/*lista-doppia.cpp*/

using namespace std;

#include <iostream>
#include "lista-doppia.h"

// Inizializzazione della lista, da chiamare obbligatoriamente
// dopo la dichiarazione di una lista concatenata
void inizializza (nodo *&L)
{
// Crea il nodo sentinella
L = new nodo;
// Concatenalo circolarmente a se stesso
L->precedente = L->prossimo = L;
}

// Inserimento nella posizione precedente quella indicata da p
void inserisci_dopo (nodo *&L, nodo *p, int n)
{
// Crea un nuovo nodo
nodo *q = new nodo;

// Inseriscinserisci l'informazione
q->n = n;

// Concatenalo al posto giusto
q->prossimo = p->prossimo;
q->precedente = p;
q->prossimo->precedente = p->prossimo = q;
}

// Ricerca di un intero nella lista. Restituisce il puntatore al nodo che lo
// contiene, oppure NULL non e' presente il valore cercato
nodo *cerca (nodo *&L, int n)
{
nodo *q = L->prossimo; // q va alla testa della lista
while ( q != L && q->n != n ) // avanza finche' non finisce la lista o non trovi il valore cercato
q = q->prossimo;
return (q == L) ? NULL : q;
}

// Ricerca del primo nodo avente informazione maggiore o uguale a quella richiesta.
// La funzione non e' definita nel file header, perche' serve soltanto all'interno
// di questo file.
nodo *cerca_maggiore_o_uguale (nodo *&L, int n)
{
nodo *q = L->prossimo; // q va alla testa della lista
while ( q != L && q->n < n ) // avanza finche' non finisce la lista o non trovi un valore >= n
q = q->prossimo;
return q;
}

// Inserimento di un intero in una lista ordinata
void inserisci_ordinato (nodo *&L, int n)
{
inserisci_dopo (L, cerca_maggiore_o_uguale(L, n)->precedente, n);
}

// Cancellazione dell'elemento cui punta p
void cancella (nodo *&L, nodo *p)
{
p->prossimo->precedente = p->precedente;
p->precedente->prossimo = p->prossimo;
delete p;
}

// Stampa il contenuto della lista
void stampa (nodo *&L)
{
for ( nodo *q = L->prossimo; q != L; q = q->prossimo )
cout << q->n << ' ';
cout << endl;
}