Salve,ho necessità di un consiglio x migliorare il programma sotto riporato.
Mi è stato già suggerito di allocare i molti oggetti allocati dinamicamente in maniera statica; volrrei chiedervi se avete altri suggerimenti x renderlo più efficente e leggibile..
Ci tengo a precisare che il prog nn deve rispettare specifiche particolari, deve implamentare un albero binario utilizzando template e grosso modo deve effettuare le operazioni di inserimento, cancellazione, trovare max, il min ecc insomma + o- tutte quelle che ho gia definito.. Qualsiasi suggerimento è ben accetto. Grazie
------------------------------------------------------------------------------------
codice:
//main.cpp
//programma di verifica della classe Albero

#include "proj.h"

int main(){
    Albero<int> P;
    int v[]={47,25,11,7,17,43,31,44,77,65,68,93};
    for (int i=0;i<12;i++){
      P.inserisci(v[i]);
	}

    cout<<P;
    P.MostraRadice();
	P.Massimo();
	P.Minimo();
	P.Ricerca(7);
	P.Cancella(7);
	cout<<P;
    P.MostraRadice();
	P.Massimo();
	P.Minimo();
    return 0;
}
--------------------------------------------------------------------------------------
codice:
//proj.h
//Implementazione di un albero binario tramite programmazione generica[template] 

#ifndef ALBEROBIN_H
#define ALBEROBIN_H
#include <iostream>

using namespace std;

template<class T>class Albero{

	friend ostream& operator<<(ostream &,Albero<T>);
	  

      public:
             Albero(){Radice=0; }
            ~Albero(){}

   		     class Nodo{
                    public:
                           Nodo(){
                                  sinistro=0;
                                  destro=0;
                                  chiave=0;
                                  padre=0;
                                  }
						   ~Nodo(){}
                           Nodo * sinistro;
                           Nodo * destro;
                           Nodo * padre;
                           T chiave;
			 };

                   void inserisci(T);//inserisce un nodo nell'albero
			       void Massimo();//stampa il massimo
			       void Cancella(T);//interfaccia per la funzione cancella
			       void Ricerca(T);//interfaccia per la funzione ricerca
                   void Minimo();//stampa il minimo
			       void MostraRadice();//stampa la radice
                   void Stampa(ostream &);//utilizzata nella funzione che ridefinisce 
				                          //l'operatore << per accedere alle funzioni 
				                          //membro private

          private:

		  //funzioni membro private 
          void cancella(T,Nodo **);//cancella un nodo che ha una certa chiave 
          bool ricerca(T,Nodo **);//ricerca un nodo che ha una certa chiave 
          void successore(Nodo **);//trova il successore di un nodo
          void minimo(Nodo **);//scorre l'albero fino a trovare il nodo che ha chiave minore
          void massimo(Nodo **);//scorre l'albero fino a trovare il nodo con chiave minore
          void InOrdine(Nodo *,ostream &);//visualizza in ordine simmetrico
		  void PreOrdine(Nodo *,ostream &);//visualizza in ordine anticipato
		  void PostOrdine(Nodo *,ostream &);//visualizza in ordine posticipato
		          
		  Nodo * Radice;  //radice dell'albero
     };

//definizione delle funzioni membro pubbliche; la classe Nodo è resa trasparente all'utente
template<class T>void Albero<T>::Massimo(){
	Nodo *x=new Nodo();
	x=Radice;
	massimo(&x);
	cout<<"La chiave di valore maggiore contenuta nell'albero e':"<<x->chiave<<endl;
}

template<class T>void Albero<T>::Cancella(T chiave){
	Nodo *x=new Nodo();
	x=Radice;
	cout<<"Cancellazione del nodo con chiave "<<chiave<<endl;
	cancella(chiave,&x);
	cout<<"Nodo cancellato"<<endl;
}

template<class T>void Albero<T>::Ricerca(T chiave){
	Nodo *x=new Nodo();
	cout<<"Ricerca della chiave "<<chiave<<".. ";
	if(ricerca(chiave,&x)) cout<<"trovata"<<endl;
    else cout<<"chiave non trovata"<<endl;
}
	
template <class T>void Albero<T>::Minimo(){
	Nodo *x=new Nodo();
	x=Radice;
	minimo(&x);
	cout<<"La chiave minore contenuta nell'albero e': "<<x->chiave<<endl;
}

template <class T>void Albero<T>::MostraRadice(){
    Nodo *x=new Nodo();
	x=Radice;
	cout<<"La radice dell'albero e': "<<x->chiave<<endl;
}

template <class T>void Albero<T>::Stampa(ostream &out){
	out<<"Visualizzazione in Ordine Simmetrico: ";
		InOrdine(Radice,out);
        out<<"\nVisualizzazione in Ordine Anticipato: ";
		PreOrdine(Radice,out);
		out<<"\nVisualizzazione in Ordine Posticipato: ";
		PostOrdine(Radice,out);
		out<<endl;
}




//definizione delle funzioni membro private
template<class T>void Albero<T>::inserisci(T ChiaveDaInserire){
               
               Nodo * y=new Nodo();
               Nodo * x=new Nodo();
               Nodo * z=new Nodo();
			   y=0; 
			   x=0;
			   
              x=Radice;
              (z->chiave)=ChiaveDaInserire;//preparazione del nodo da inserire
              while (x!=0){//ricerca della corretta posizione per l'inserimento
                     y=x;
                     if((z->chiave)<(x->chiave)) x=x->sinistro;
                     else x=x->destro;
                     
               }
               z->padre=y;
               //inserzione del nodo
               if (y==0) Radice=z;
               else if((z->chiave)<(y->chiave)) y->sinistro=z;
               else y->destro=z;
                             
}



template<class T>void Albero<T>::cancella(T ChiaveDaCancellare,Nodo **z){
               
	           Nodo *y=new Nodo();
               Nodo *x=new Nodo();
          
               ricerca(ChiaveDaCancellare,z);//ricerca del nodo da cancellare
               
			   if(((*z)->sinistro==0)||((*z)->destro==0)) y=*z;//si determina se il nodo da 
                                                               //cancellare ha figli
			   
               else {
				   successore(z);//se ce li ha entrambi se ne trova il successore
			       y=(*z);
			   }                    //che necessariamente ha un solo figlio
               
			   if(y->sinistro!=0) x=y->sinistro;
			   else x=y->destro;//in x si memorizza il figlio del nodo da cancellare
			
			   if(x!=0) x->padre=y->padre;//se x esiste si attacca al padre del nodo da 
			                              //cancellare 
					
			   if((y->padre)==0) x=Radice;//se il nodo cancellato era la radice
			                              //la nuova radice è x
						
			   if(y=(y->padre->sinistro)) y->padre->sinistro=x;
			   else y->padre->destro=x;//se il nodo cancellato era il figlio sinistro/destro
			                           //si aggiorna il puntatore sinistro/destro
			   
			   if(y!=(*z)) (*z)->chiave=y->chiave;//se il nodo da cancellare ha richiesto 
			                                //la determinazione del successore copia la chiave  
			                                //del successore
               (*z)=y;//restituisce il nodo cancellato
}


template<class T>bool Albero<T>::ricerca(T ChiaveDaRicercare,Nodo **x){//ricerca iterativa

	           
			    *x=Radice;//partiamo dalla radice si scorre l'albero fino a trovare la chiave
			    while(((*x)!=0)&&((*x)->chiave!=ChiaveDaRicercare)){
				   if(ChiaveDaRicercare<((*x)->chiave)) *x=(*x)->sinistro;
				   else (*x)=(*x)->destro;

			   }
				
				if((*x)!=0)return true;
			    else return false;
}


template<class T>void Albero<T>::successore(Nodo **x){
	           
	           Nodo *y=new Nodo();
			   if((*x)->destro!=0){
				   minimo(&((*x)->destro));//se il nodo ha figlio destro il successore 
			       return;           //coincide con il nodo minimo del sottoalbero 
			   }                     //destro

			   y=(*x)->padre;//se non ha un figlio destro 
			   while((y!=0)&&((*x)=y->destro)){
				   (*x)=y;       //si risale gli antenati di x fino a trovare il nodo   
				   y=(*x)->padre;//antenato meno lontano e più piccolo
			   }
			   (*x)=y;
}

//dato un nodo ne discende tutti i figli alla sinistra fino  a trovare il minimo
template<class T>void Albero<T>::minimo(Nodo **x){
	while(((*x)->sinistro)!=0) {(*x)=(*x)->sinistro;}
	
}

//dato un nodo ne discende tutti i figli alla destra fino  a trovare il massimo
template<class T>void Albero<T>::massimo(Nodo **x){
	while(((*x)->destro)!=0) {(*x)=(*x)->destro;}
	
}
      
//visualizzazzione dei nodi     
template<class T>void Albero<T>::InOrdine(Nodo *x,ostream &out){
	
    
	if (x!=0) {
		InOrdine(x->sinistro,out);
		out<<(x->chiave)<<" ";
		InOrdine(x->destro,out);
	}
	
}

template<class T>void Albero<T>::PreOrdine(Nodo *x,ostream &out){
	
	
	if (x!=0) {
		out<<(x->chiave)<<" ";
		PreOrdine(x->sinistro,out);
		PreOrdine(x->destro,out);
	}
	
}

template<class T>void Albero<T>::PostOrdine(Nodo *x,ostream &out){
	if (x!=0) {
		PostOrdine(x->sinistro,out);
		PostOrdine(x->destro,out);
        out<<(x->chiave)<<" ";
	}
	
}


//definizione della classe friend che effettua una ridefinizione dell'operatore << e permette
//dato un albero la stampa dei suoi elementi in ordine anticipato simmetrico e posticipato
template <class T> ostream& operator<<(ostream &out,Albero<T> A){
	    
		out<<"##########Visualizzazione dei nodi##########\n";
		A.Stampa(out);
        return out;
	}


#endif