E' normale visto che usi variabili locali non inizializzate, ma anche se lo fossero avresti altri problemi. Il punto (e qui rispondo alla seconda questione) è che un albero per sua natura è ricorsivo, quindi anche le varie funzioni dell'albero devono esserlo.
La ricorsione tra l'altro è anche uno dei concetti più difficili da comprendere, quindi è normale avere delle difficolta.
Ti mostro un esempio (volutamente ridotto all'osso e da completare) di come fare un inserimento nell'albero tramite la ricorsione. Compreso questo, il resto è in discesa (spero)
codice:
class Albero {
private :
struct Node {
int data;
Node* left;
Node* right;
};
Node* node;
void internal_insert(Node*&, int); // notare il passaggio del puntatore per reference.
public :
Albero() { node = NULL; }
~Albero() { }
void insert(int dato);
};
void Albero::internal_insert(Node*& nd, int dato) {
// punto a
// se viene ricevuto un nodo NULL occorre crearlo e ne settarne i parametri;
// passandone il reference le modifiche saranno riportate
// all'esterno e non su una copia locale.
if (nd == NULL) {
nd = new Node;
nd->data = dato;
nd->left = NULL;
nd->right = NULL;
} else {
// Qui il nodo esiste e stabilisco il criterio di inserimento.
// I valori maggiori del campo data vanno a destra, altrimenti a sinistra.
if (nd->data < dato) {
// Qui inizia la ricorsione. Richiamo la stessa funzione
// passando come valore il puntatore al nodo destro e il dato.
// L'attuale chiamata di internal_insert viene sospesa e ne verrà
// invocata una nuova che ripartirà dal punto a.
internal_insert(nd->right,dato);
} else {
// Qui inizia la ricorsione. Richiamo la stessa funzione
// passando come valore il puntatore al nodo sinistro e il dato.
// L'attuale chiamata di internal_insert viene sospesa e ne verrà
// invocata una nuova che ripartirà dal punto a.
internal_insert(nd->left,dato);
}
}
}
voidAlbero::insert(int dato) {
// passo il nodo radice e il dato alla vera funzione ricorsiva.
internal_insert(node,dato);
}