#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; }