#include #include #include using

Transcript

#include #include #include using
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
//definisco il singolo nodo
class nodo{
public:
nodo *dx, *sx, *padre;
int val;
nodo(){dx=NULL; sx=NULL; padre=NULL;};
nodo(int v){dx=NULL; sx=NULL; padre=NULL; val=v;};
};
//costruttore
//costruttoe con parametro
//definisco la classe albero, che rispettera la seguente regola: gli elementi minori stanno tutti nel sottoalbero
di sx, quelli maggiori in quello di dx
class albero{
public:
nodo* root;
//il nodo raice
albero(){ root=NULL;}; //costruttore
~albero();
//distruttore
void aggiungi(int val); //aggiunge un nodo all'albero, piazzandolo nella posizione corretta
int min();
//restituisce il valore minimo dell'albero
int max();
//restituisce il valore massimo dell'albero
nodo* min(nodo* X); //restituisce il puntatore all'elemento minimo del sottoalbero di X
nodo* max(nodo* X); //restituisce il puntatore all'elemento massimo del sottoalbero di X
nodo* successivo(nodo* X); //restituisce il puntatore del nodo sucessivo a X
void ordina();
//stampa l'albero in ordine crescente
nodo* precedente(nodo* X); //restituisce il puntatore del nodo precedente a X
void ordinainverso();
//stampa l'albero in ordine decrescente
void stampar(ofstream &fout,nodo* X, int x, int y, int dx);
//funzione ricorsiva usata da stampa()
void stampa();
//stampa l'albero in un file html: albero.html
};
//aggiunge un nodo all'albero con valore "val", piazzandolo nella posizione corretta
void albero::aggiungi(int val){
nodo *X, *Xold;
if(root==NULL) {
//se il nodo radice non esiste creo quello e piazzo li il valore da aggiungere
root=new nodo(val);
}
else{
//in caso contrario
X=root;
//parto dalla radice
while(X!=NULL){
//continuo a scendere a destra o a sinistra a seconda del valore, fintanto che non trovo
un posto vuoto
Xold=X;
if(X->val > val) { X=X->sx;}
else{ X=X->dx; }
}
//al padre del posto vuoto aggiungo la foglia (a dx o a sx a seconda del valore)
if(Xold->val > val) {
Xold->sx=new nodo(val);
Xold->sx->padre=Xold;
}
else{
Xold->dx=new nodo(val);
Xold->dx->padre=Xold;
}
}
}
//per cercare il minimo scendo a sx
int albero::min(){
nodo*X;
X=root;
while(X->sx!=NULL) X=X->sx;
return X->val;
}
//per cercare il massimo scendo a dx
int albero::max(){
nodo*X;
X=root;
while(X->dx!=NULL) X=X->dx;
return X->val;
}
//ritorno un puntatore al minimo del sottoalbero di X
nodo* albero::min(nodo* X){
while(X->sx!=NULL) X=X->sx;
return X;
}
//ritorno un puntatore al massimo del sottoalbero di X
nodo* albero::max(nodo* X){
while(X->dx!=NULL) X=X->dx;
return X;
}
//ritorno un puntatore al successivo di X
nodo* albero::successivo(nodo* X){
nodo* Y;
if(X->dx!= NULL) {Y=min(X->dx);} //se a destra c'e' il figlio il successivo sara' il minimo del sottoalbero di
destra
else{
//in caso contrario
Y=X->padre;
//risalgo l'albero, fintano che c'e' il padre e che non devo spostarmi a sx
while(Y!=NULL && Y->sx!=X){
X=Y;
Y=X->padre;
}
}
return Y;
}
//ritorno un puntatore al precedente di X
nodo* albero::precedente(nodo* X){
nodo* Y;
if(X->sx!= NULL) {Y=max(X->sx);} //se a sx c'e' il figlio il precedente sara' il massimo del sottoalbero di sx
else{
//in caso contrario
Y=X->padre;
//risalgo l'albero, fintano che c'e' il padre e che non devo spostarmi a dx
while(Y!=NULL && Y->dx!=X){
X=Y;
Y=X->padre;
}
}
return Y;
}
//stampo in ordine gli elementi dell'albero: parto dal minimo e via via stampo il sucessivo
void albero::ordina(){
nodo *X;
X=min(root);
while(X!=NULL){
cout<< X->val<<endl;
X=successivo(X);
}
}
//stampo in ordine gli elementi dell'albero: parto dal massimo e via via stampo il precedente
void albero::ordinainverso(){
nodo *X;
X=max(root);
while(X!=NULL){
cout<< X->val<<endl;
X=precedente(X);
}
}
//elimino uno ad uno i nodi, partendo da quelli SENZA figli
albero::~albero(){
nodo *X,*Y;
int n=0;
X=root;
while(X!=NULL){ //mentre ho un nodo valido
if(X->dx==NULL && X->sx==NULL) { //se non ha figli lo cancello
Y=X->padre; //cerco suo padre
if(Y!=NULL){ //se suo padre esiste (la radice NON ha padre)
if(Y->dx==X) { Y->dx=NULL; } //tolgo dal padre il figlio che sto per eliminare
else Y->sx=NULL;
}
n++; //conto il numero di nodi che elimino, per debug
delete X; //elimino il nodo
X=Y; //torno a suo padre e ripeto l'operazione
}
else{
//se il nodo ha figli scendo lungo l'albero
if(X->dx!=NULL) { X=X->dx; }
else X=X->sx;
}
}
}
//funzione usata da stampa() per stampare il nodo e i suoi figli in modo ricorsivo su file html
void albero::stampar(ofstream &fout,nodo* X, int x, int y, int dx){
if(X!=NULL){
fout << "<div style='top:"<<y<<"; left:"<<x<<";'>"<<X->val<<"</div>"<<endl;
stampar(fout, X->dx, x+dx,y+80,dx/2);
stampar(fout, X->sx, x-dx,y+80,dx/2);
}
}
//per stampare l'albero su file html
void albero::stampa(){
ofstream fout("albero.html", ofstream::out);
fout << "<html>\n<head>\n<style type='text/css'>\ndiv{position:absolute;display:block;border:solid 1px
black;background:yellow;border-radius:15px;width:30px;height:30px;vertical-align:middle;text-align:center;zindex:4;}\n</style>\n</head>\n<body>\n";
fout << "<html>\n<head>\n<style type='text/css'>\ndiv{position:absolute;display:block;border:solid 1px
black;background:yellow;border-radius:15px;width:30px;height:30px;vertical-align:middle;text-align:center;zindex:4;}\n</style>\n</head>\n<body>\n";
stampar(fout, root, 600,10,300);
//
fout << "</body>\n</html>\n";
fout.close();
system("open albero.html");
cout << "Aprire il file albero.html per visualizzare l'albero"<<endl;
}
int main(){
albero XXX;
int n;
srand(time(NULL));
//aggiungo un elemento random all'albero, per 20 volte
for(int i=0; i<20; i++){
n=rand()%100;
cout << n << endl;
XXX.aggiungi(n);
}
//stampo massimo e minimo
cout <<"Minimo : " << XXX.min()<<endl;
cout <<"Massimo: " << XXX.max()<<endl;
//stampo in ordine gli elementi dell'albero
cout << "l'albero riordinato e': "<<endl;
XXX.ordina();
//stampo in ordine gli elementi dell'albero
cout << "l'albero riordinato in ordine inverso e': "<<endl;
XXX.ordinainverso();
//sampo l'albero in un file html, in modo da visualizzarlo
XXX.stampa();
system("pause");
return 0;
}