PDA

Visualizza la versione completa : [C++] Struttura dati insieme: loop infinito nel metodo di unione


pietrol83
02-02-2012, 10:44
ciao a tutti, sto sempre sulla struttura ati insieme con lista di puntatori. ho un problema con il metodo unione che accetta come argomenti due insieme (passaggio per valore) e ne fa l'unione. nel primo ciclio il compilatore va in loop infinito ma non capisco perchè.

posto il codice che ho implementato.

listap.h

#ifndef listap_h
#define listap_h

#include "nodop.h"
#include "lista.h"
#include<iostream>
#include<stdlib.h>

using namespace std;

template<class tipoelem>
class listap : public lista<nodop<tipoelem> *, tipoelem>
{
public:
typedef nodop<tipoelem> *posizione;

listap();
void crealista();
bool listavuota();
posizione primolista();
bool finelista(posizione);
posizione predlista(posizione);
posizione suclista(posizione);
tipoelem leggilista(posizione);
void scrivilista(posizione, tipoelem);
void inslista(posizione, tipoelem);
void canclista(posizione);

private:
nodop<tipoelem> sentinella;
};
#endif

template<class tipoelem>
listap<tipoelem>::listap() : lista<nodop<tipoelem> *, tipoelem>(1)
{
this->crealista();
}

template<class tipoelem>
void listap<tipoelem>::crealista()
{
sentinella.setprec(&sentinella);
sentinella.setelem(0);
sentinella.setsuc(&sentinella);
}

template<class tipoelem>
bool listap<tipoelem>::listavuota()
{
return((sentinella.getprec() == &sentinella) && (sentinella.getsuc() == &sentinella));
}

template<class tipoelem>
typename listap<tipoelem>::posizione listap<tipoelem>::primolista()
{
return(sentinella.getsuc());
}

template<class tipoelem>
bool listap<tipoelem>::finelista(typename listap<tipoelem>::posizione pos)
{
return(pos->getsuc() == (&sentinella));
}

template<class tipoelem>
typename listap<tipoelem>::posizione listap<tipoelem>::predlista(typename listap<tipoelem>::posizione pos)
{
if(pos->getprec() == (&sentinella))
return(sentinella.getprec());
else
return(pos->getprec());
}

template<class tipoelem>
typename listap<tipoelem>::posizione listap<tipoelem>::suclista(typename listap<tipoelem>::posizione pos)
{
if(pos->getsuc() == (&sentinella))
return(sentinella.getsuc());
else
return(pos->getsuc());
}

template<class tipoelem>
tipoelem listap<tipoelem>::leggilista(typename listap<tipoelem>::posizione pos)
{
return(pos->getelem());
}

template<class tipoelem>
void listap<tipoelem>::scrivilista(typename listap<tipoelem>::posizione pos, tipoelem elem)
{
pos->setelem(elem);
}

template<class tipoelem>
void listap<tipoelem>::inslista(typename listap<tipoelem>::posizione pos, tipoelem elem)
{
posizione temp = new(nodop<tipoelem>);

temp->setprec(pos->getprec());
temp->setsuc(pos);
(pos->getprec())->setsuc(temp); //il problema sta in questa istruzione
pos->setprec(temp);
temp->setelem(elem);
pos = temp;
}

template<class tipoelem>
void listap<tipoelem>::canclista(typename listap<tipoelem>::posizione pos)
{
posizione temp = new(nodop<tipoelem>);

temp = pos;
(pos->getprec())->setsuc(pos->getsuc());
(pos->getsuc())->setprec(pos->getprec());
pos = pos->getsuc();
delete(temp);
}

insiemel.h

#ifndef insiemel_h
#define insiemel_h

#include<iostream>
#include<stdlib.h>
#include "listap.h"

using namespace std;

template<class tipoelem>
class insiemel
{
public:
insiemel();

void creainsieme();
bool insiemevuoto();
bool appartiene(tipoelem);
void inserisci(tipoelem);
void cancella(tipoelem);
void unione(insiemel, insiemel);
void intersezione(insiemel, insiemel);
void differenza(insiemel, insiemel);

tipoelem getelem();
//posizione getsuc(posizione);
void visualizzainsieme();
private:
listap<tipoelem> *elementi;
};
#endif

template<class tipoelem>
tipoelem insiemel<tipoelem>::getelem()
{
return(elementi->leggilista(elementi->primolista()));
}

template<class tipoelem>
void insiemel<tipoelem>::visualizzainsieme()
{
elementi->stampalista();
}

template<class tipoelem>
insiemel<tipoelem>::insiemel()
{
this->creainsieme();
}

template<class tipoelem>
void insiemel<tipoelem>::creainsieme()
{
elementi = new listap<tipoelem>;
}

template<class tipoelem>
bool insiemel<tipoelem>::insiemevuoto()
{
return(elementi->listavuota());
}

template<class tipoelem>
bool insiemel<tipoelem>::appartiene(tipoelem elem)
{
bool trovato = false;
typename listap<tipoelem>::posizione p = elementi->primolista();
while((p != elementi->predlista(elementi->primolista())) && !trovato)
{
if(elementi->leggilista(p) == elem)
trovato = true;
else
p = elementi->suclista(p);
}
return trovato;
}

template<class tipoelem>
void insiemel<tipoelem>::inserisci(tipoelem elem)
{
if(!this->appartiene(elem))
this->elementi->inslista(elementi->primolista(), elem);
}

template<class tipoelem>
void insiemel<tipoelem>::cancella(tipoelem elem)
{
bool trovato = false;
typename listap<tipoelem>::posizione p = elementi->primolista();
while(!elementi->finelista(p) && !trovato)
{
if(this->getelem() == elem)
{
trovato = true;
elementi->canclista(p);
}
else
p = elementi->suclista(p);
}
}

template<class tipoelem>
void insiemel<tipoelem>::unione(insiemel<tipoelem> A, insiemel<tipoelem> B)
{
while(!A.insiemevuoto())
{
cout << "A.getelem() = " << A.getelem() << "\n";
this->inserisci(A.getelem());
A.cancella(A.getelem());
system("pause");
}
while(!B.insiemevuoto())
{
this->inserisci(B.getelem());
B.cancella(B.getelem());
}
}

template<class tipoelem>
void insiemel<tipoelem>::intersezione(insiemel<tipoelem> A, insiemel<tipoelem> B)
{
while(!A.insiemevuoto())
{
if(B.appartiene(A.getelem()))
this->inserisci(A.getelem());
A.cancella(A.getelem());
}
}

template<class tipoelem>
void insiemel<tipoelem>::differenza(insiemel<tipoelem> A, insiemel<tipoelem> B)
{
while(!A.insiemevuoto())
{
if(!B.appartiene(A.getelem()))
this->inserisci(A.getelem());
A.cancella(A.getelem());
}
}

testinsiemel.cpp

#include "insiemel.h"
#include<iostream>
#include<stdlib.h>

using namespace std;

int main()
{
insiemel<int> set;

cout << "insiemevuoto() = " << set.insiemevuoto() << "\n";

for(int i = 0; i < 10; i++)
set.inserisci(i);

cout << "insiemevuoto() = " << set.insiemevuoto() << "\n";

cout << "appartiene(5) = " << set.appartiene(5) << "\n";
cout << "appartiene(15) = " << set.appartiene(15) << "\n";


set.cancella(5);
cout << "appartiene(5) = " << set.appartiene(5) << "\n";
set.visualizzainsieme();

insiemel<int> set2;
for(int i = 0; i < 10; i++)
set2.inserisci(i * 2);
set2.visualizzainsieme();
system("pause");

insiemel<int> set3;
set3.unione(set, set2);
system("pause");
set3.visualizzainsieme();

insiemel<int> set4;
set4.intersezione(set, set2);
set4.visualizzainsieme();

insiemel<int> set5;
set5.differenza(set, set2);
set5.visualizzainsieme();

system("pause");
return 0;
}

come ho detto prima, nel metodo unione si va in loop infinito. perchè???

Loading