Giusto per rendere le cose più incasinate del normale...
infatti la cancellazione ricorsiva del nodo non è di facile implementazione e facendola alla tua maniera c'è da spararsi un colpo in testa.
Ovviamente non ho inventato niente di nuovo, nulla di ciò che che è già stato scritto e riscritto, solo che l'ho modificato sia nella restituzione della radice senza agire internamente (molto più semplice), sia nella parte di ricerca key che insita nella cancellazione.
La funzione ricorsiva seguente è stata debuggata ad un livello superficiale con il memory profiler valgrind considerando le tre casistiche tipiche della rimozione del nodo (senza figli, un figlio, due figli), la disposizione dell inserimento e della cancellazione.... cmq verificala meglio nella sezione doppio figlio + modifica radice.
nodo *eliminazione(nodo *p, int val)
{
nodo *old=p;
if (val < p->dato )
p->ptrsx=eliminazione(p->ptrsx,val);
else if (val > p->dato )
p->ptrdx=eliminazione(p->ptrdx,val);
else
{
if (p->ptrsx==NULL)
{
p=p->ptrdx;
free (old);
}
else if (p->ptrdx==NULL)
{
p=p->ptrsx;
free (old);
}
else
{
nodo *prev = p->ptrsx;
while (prev->ptrdx) prev = prev->ptrdx;
int tmp = prev->dato;
prev->dato = p->dato;
p->dato = tmp;
p->ptrsx=eliminazione(prev, val);
}
}
return p;
}