codice:
#include <iostream>
#include <stdlib.h>
using namespace std;
template<class posizione, class tipoelem>
class lista
{
public:
virtual void crealista();
virtual bool listavuota();
virtual posizione primolista();
virtual bool finelista(posizione);
virtual posizione succlista(posizione);
virtual posizione predlista(posizione);
virtual tipoelem leggilista(posizione);
virtual void scrivilista(posizione, tipoelem);
virtual void inslista(posizione, tipoelem);
virtual void canclista(posizione);
void stampalista();
void fondiordinate(lista &, lista &);
void epurazione();
void naturalmergesort();
private:
void distribuisci(lista &, lista &);
void copiacatena(posizione, lista &, posizione, lista &);
void copia(posizione, lista &, posizione, lista &, bool *);
void merge(lista &, lista &, lista &, int *);
void fondicatena(posizione, lista &, posizione, lista &, posizione, lista &);
};
template<class posizione, class tipoelem>
void lista<posizione, tipoelem>::stampalista()
{
posizione p = primolista();
while(!finelista(p))
{
cout << leggilista(p) << "\n";
p = succlista(p);
}
cout << "\n";
}
template<class posizione, class tipoelem>
void lista<posizione, tipoelem>::fondiordinate(lista<posizione, tipoelem> &A, lista<posizione, tipoelem> &B)
{
posizione pa = A.primolista();
posizione pb = B.primolista();
posizione pc = primolista();
tipoelem elem1 = A.leggilista(pa);
tipoelem elem2 = B.leggilista(pb);
while(!A.finelista(pa) && !B.finelista(pb))
{
if(elem1 <= elem2)
{
inslista(pc, elem1);
pa = A.succlista(pa);
}
else
{
inslista(pc, elem2);
pb = B.succlista(pb);
}
elem1 = A.leggilista(pa);
elem2 = B.leggilista(pb);
}
while(!A.finelista(pa))
{
inslista(pc, elem1);
pa = A.succlista(pa);
elem1 = A.leggilista(pa);
}
while(!B.finelista(pb))
{
inslista(pc, elem2);
pb = B.succlista(pb);
elem2 = B.leggilista(pb);
}
}
template<class posizione, class tipoelem>
void lista<posizione, tipoelem>::epurazione()
{
posizione p = primolista();
posizione q;
posizione t;
while(!finelista(p))
{
q = succlista(p);
while(!finelista(q))
{
if(leggilista(p) == leggilista(q))
{
t = succlista(q);
canclista(q);
q = t;
}
else
q = succlista(q);
}
p = succlista(p);
}
}
template<class posizione, class tipoelem>
void lista<posizione, tipoelem>::naturalmergesort()
{
int numerocatene;
lista<posizione, tipoelem> A, B, L;
do
{
A.crealista();
B.crealista();
distribuisci(A, B);
numerocatene = 0;
crealista();
merge(A, B, L, &numerocatene);
}while(numerocatene != 1);
}
template<class posizione, class tipoelem>
void lista<posizione, tipoelem>::distribuisci(lista<posizione, tipoelem> &A, lista<posizione, tipoelem> &B)
{
posizione p = primolista();
posizione pa = A.primolista();
posizione pb = B.primolista();
do
{
copiacatena(p, *this, pa, A);
if(!finelista(p))
copiacatena(p, *this, pb, B);
}while(!finelista(p));
}
template<class posizione, class tipoelem>
void lista<posizione, tipoelem>::copiacatena(posizione p, lista<posizione, tipoelem> &L, posizione pa, lista<posizione, tipoelem> &A)
{
bool finecatena = false;
do
copia(p, L, pa, A, &finecatena);
while(!finecatena);
}
template<class posizione, class tipoelem>
void lista<posizione, tipoelem>::copia(posizione p, lista<posizione, tipoelem> &L, posizione pa, lista<posizione, tipoelem> &A, bool *finecatena)
{
bool esito = *finecatena;
finecatena = &esito;
tipoelem elemento = leggilista(p);
A.inslista(pa, elemento);
p = succlista(p);
pa = succlista(pa);
if(finelista(p))
esito = true;
else
esito = (elemento > leggilista(p));
finecatena = &esito;
}
template<class posizione, class tipoelem>
void lista<posizione, tipoelem>::merge(lista<posizione, tipoelem> &A, lista<posizione, tipoelem> &B, lista<posizione, tipoelem> &L, int *numcatene)
{
posizione p = primolista();
posizione pa = A.primolista();
posizione pb = B.primolista();
while(!A.finelista(pa) && !B.finelista(pb))
{
fondicatena(pa, A, pb, B, p, L);
numcatene++;
}
while(!A.finelista(pa))
{
copiacatena(pa, A, p, L);
numcatene++;
}
while(!B.finelista(pb))
{
copiacatena(pb, B, p, L);
numcatene++;
}
}
template<class posizione, class tipoelem>
void lista<posizione, tipoelem>::fondicatena(posizione pa, lista<posizione, tipoelem> &A, posizione pb, lista<posizione, tipoelem> &B, posizione p, lista<posizione, tipoelem> &L)
{
bool finecatena = false;
do
{
if(A.leggilista(pa) < B.leggilista(pb))
{
copia(pa, A, p, *this, &finecatena);
if(finecatena)
copiacatena(pb, B, p, *this);
}
else
{
copia(pb, B, p, *this, &finecatena);
if(finecatena)
copiacatena(pa, A, p, *this);
}
}while(finecatena);
}
listap.h