codice:
#include <iostream>
#include <stdlib.h>
using namespace std;
template<class posizione, class tipoelem>
class lista
{
public:
virtual void crealista() = 0;
virtual bool listavuota() = 0;
virtual posizione primolista() = 0;
virtual bool finelista(posizione) = 0;
virtual posizione succlista(posizione) = 0;
virtual posizione predlista(posizione) = 0;
virtual tipoelem leggilista(posizione) = 0;
virtual void scrivilista(posizione, tipoelem) = 0;
virtual void inslista(posizione, tipoelem) = 0;
virtual void canclista(posizione) = 0;
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);
}
h
template<class posizione, class tipoelem>
void lista<posizione, tipoelem>::copia(posizione *p, lista<posizione, tipoelem> *L, posizione *pa, lista<posizione, tipoelem> *A, bool *finecatena)
{
tipoelem elemento = leggilista(p);
A->inslista(pa, elemento);
p = succlista(p);
pa = succlista(pa);
if(finelista(p))
finecatena = true;
else
finecatena = (elemento > leggilista(p));
}
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++;
}
}
in pratica il problema è il seguente: