PDA

View Full Version : [C] Alberi Binari Di Ricerca - Inserimento Di Un Elemento


xbubbax
01-05-2008, 21:19
Dov'è l'errore? Non capisco bene cosa inserire nella malloc..


struct nodo
{
int DATO;
struct nodo *DX; //PUNTATORE AL SOTTOALBERO DESTRO
struct nodo *SX; //PUNTATORE AL SOTTOALBERO SINISTRO
}NODO;

typedef struct nodo* tree;

tree InserimentoDiUnElemento(tree T, int e)
{
if(T==NULL)
{
tree new=NULL;
new=(nodo)malloc(sizeof(*tree));
new->DATO=e;
new->SX=NULL;
new->DX=NULL;
}

if(T->DATO==e)
{
printf(" ERRORE \n");
return NULL;
}

if(T->DATO>e)
{
InserimentoDiUnElemento(T->SX,e);
}else
{
InserimentoDiUnElemento(T->DX,e);
}
}

wisher
01-05-2008, 23:25
Perchè allochi un *tree e non un tree?
Lo spazio che devi allocare è per un nodo, non per un puntatore ad un nodo.

xbubbax
02-05-2008, 08:31
mi da ancora questi errori

error: expected identifier before '=' token


error: no matching function for call to `nodo::nodo(void*)'

xsatellitex
02-05-2008, 09:04
malloc restituisce un puntatore *void ;)


#include <stdio.h>

main(){
struct nodo
{
int DATO;
struct nodo *DX; //PUNTATORE AL SOTTOALBERO DESTRO
struct nodo *SX; //PUNTATORE AL SOTTOALBERO SINISTRO
}NODO;

typedef struct nodo* tree;

tree InserimentoDiUnElemento(tree T, int e)
{
if(T==NULL)
{
tree new=NULL;
new=(void *)malloc(sizeof(tree));
new->DATO=e;
new->SX=NULL;
new->DX=NULL;
}

if(T->DATO==e)
{
printf(" ERRORE \n");
return NULL;
}

if(T->DATO>e)
{
InserimentoDiUnElemento(T->SX,e);
}else
{
InserimentoDiUnElemento(T->DX,e);
}
}
}

xbubbax
02-05-2008, 09:33
come a char????

xbubbax
02-05-2008, 09:36
comq sbagliavo ad utilizzare la parola new che nel c non si può usare, però se metto char nella malloc da errore lo stesso

xsatellitex
02-05-2008, 09:41
scusami volevo dire void ... ho corretto sopra

xsatellitex
02-05-2008, 09:44
in C la keyword new non esiste... è come una qualsiasi altra parola...
tu la stai utilizzando come puntatore quindi va bene

xbubbax
02-05-2008, 09:49
mi da quest'altro errore ora
error: void value not ignored as it ought to be



tree InserimentoDiUnElemento(tree T, int e)
{
if(T==NULL)
{
tree nuo=NULL;
nuo=(void)malloc(sizeof(tree));
nuo->DATO=e;
nuo->SX=NULL;
nuo->DX=NULL;
}

if(T->DATO==e)
{
printf(" ERRORE \n");
return NULL;
}

if(T->DATO>e)
{
InserimentoDiUnElemento(T->SX,e);
}else
{
InserimentoDiUnElemento(T->DX,e);
}
}

xsatellitex
02-05-2008, 09:52
devi mettere l'asterisco dopo void come ho scritto sopra...
malloc ritorna un puntatore all'area di memoria allocata...
il puntatore restituito è di tipo void..

:)

xbubbax
02-05-2008, 10:08
niente, non va..puoi trovarmi tu l'errore?:D ti incollo tutto il file magari sbaglio in qualche altro punto..la zona che mi interessa sta in basso, senza che leggi tutte le funzioni

#include <iostream>
#include <stdlib.h>

using namespace std;

struct nodo
{
int DATO;
struct nodo *DX; //PUNTATORE AL SOTTOALBERO DESTRO
struct nodo *SX; //PUNTATORE AL SOTTOALBERO SINISTRO
}NODO;

typedef struct nodo* tree;

bool Is_Empty(tree RADICE)
//RESTITUISCE TRUE SE L'ALBERO E' VUOTO, ALTRIMENTI RESTITUISCE FALSE
{
return(RADICE==NULL);
}

tree Albero_Vuoto(void)
//COSTRUISCE UN ALBERO VUOTO
{
return NULL;
}

int Valore_Etichetta(tree RADICE)
//RESTITUISCE IL VALORE (O ETICHETTA) DEL NODO
{
if (Is_Empty(RADICE)) abort();
else return(RADICE->DATO);
}

tree Sinistro(tree RADICE)
//RESTITUISCE IL PUNTATORE AL SOTTOALBERO SINISTRO
{
if (Is_Empty(RADICE)) return NULL;
else return(RADICE->SX);
}

tree Destro(tree RADICE)
//RESTITUISCE IL PUNTATORE AL SOTTOALBERO DESTRO
{
if (Is_Empty(RADICE)) return(NULL);
else return(RADICE->DX);
}

tree Costruisci_Albero(int ETICHETTA,tree S,tree D)
//COSTRUISCE UN ALBERO BINARIO NON ORDINATO
{
tree RADICE;
RADICE = (nodo *) malloc(sizeof(NODO));
RADICE->DATO = ETICHETTA;
RADICE->SX = S;
RADICE->DX = D;
return (RADICE);
}

void Inorder(tree RADICE)
//STAMPA INORDER DELL'ALBERO
{
if (!(Is_Empty(RADICE))) {
Inorder(Sinistro(RADICE));
cout<<Valore_Etichetta(RADICE)<<" ";
Inorder(Destro(RADICE));
}
}


void Preorder(tree RADICE)
//STAMPA PREORDER DELL'ALBERO
{
if (!(Is_Empty(RADICE))) {
cout<<Valore_Etichetta(RADICE)<<" ";
Preorder(Sinistro(RADICE));
Preorder(Destro(RADICE));
}
}


void Postorder(tree RADICE)
//STAMPA POSTORDER DELL'ALBERO
{
if (!(Is_Empty(RADICE))) {
Postorder(Sinistro(RADICE));
Postorder(Destro(RADICE));
cout<<Valore_Etichetta(RADICE)<<" ";
}
}


int ContaNodi(tree RADICE)
//RESTITUISCE IL NUMERO DEI NODI DELL'ALBERO
{
if(Is_Empty(RADICE)) return 0;
else return(1 + ContaNodi(Sinistro(RADICE)) + ContaNodi(Destro(RADICE)));
}

int ContaFoglie(tree RADICE)
//RESTITUISCE IL NUMERO DELLE FOGLIE DELL'ALBERO
{
if(Is_Empty(RADICE))
return(0);
else {
if ((Sinistro(RADICE)==NULL) && (Destro(RADICE)==NULL))
return(1);
else return( ContaFoglie(Sinistro(RADICE)) + ContaFoglie(Destro(RADICE)) );
}
}

bool Perf_Bil(tree RADICE)
//Restituisce TRUE se l'albero è perfettamente bilanciato
{
if (Is_Empty(RADICE)) return(true); //Oppure ERROR, secondo la definizione
else {
if ((Sinistro(RADICE)==NULL) && (Destro(RADICE)==NULL)) //Praticamente: se il nodo è una foglia..
return(true);
else {
if ((Sinistro(RADICE)!=NULL) && (Destro(RADICE)!=NULL)) //Se il nodo ha tutti e due i figli..
return( Perf_Bil(Sinistro(RADICE)) && Perf_Bil(Destro(RADICE)) );
else return(false);
}
}
}


bool Ricerca(tree RADICE,int X)
//RICERCA UN VALORE X IN UN ALBERO PUNTATO DA RADICE
{
if (Is_Empty(RADICE))
return(false);
else {
if (X==Valore_Etichetta(RADICE))
return(true);
else
return(Ricerca(Sinistro(RADICE),X) || Ricerca(Destro(RADICE),X));
}
}


int Altezza_Nodo(tree N) //Restituisce l'altezza di un nodo (vedere definizione di altezza)
{
int ALTD=0,ALTS=0;
if (Is_Empty(N)) return(-1);
else {
ALTS=Altezza_Nodo(Sinistro(N));
ALTD=Altezza_Nodo(Destro(N));
if (ALTS>ALTD) return(ALTS+1);
else return(ALTD+1);
}
}

tree Ins_Ord(int E,tree RADICE)
//Costruisce un albero binario di ricerca (un albero "ordinato")
{
if (Is_Empty(RADICE)) {
RADICE=(tree)malloc(sizeof(NODO)); //chiede l'indirizzo di una cella di memoria libera
RADICE->DATO=E;
RADICE->SX=NULL;
RADICE->DX=NULL;
return RADICE;
}
else {
if(E<Valore_Etichetta(RADICE)) {
RADICE->SX=Ins_Ord(E,Sinistro(RADICE));
return RADICE;
}
else {
RADICE->DX=Ins_Ord(E,Destro(RADICE));
return RADICE;
}
}
}


bool RicercaBinaria(int X,tree RADICE)
//Ricerca dicotomica (o binaria) per alberi binari di ricerca (ordinati)
{
if (Is_Empty(RADICE)) return(false);
else {
if (X==Valore_Etichetta(RADICE)) return(true);
else {
if (X < Valore_Etichetta(RADICE))
return( RicercaBinaria(X,Sinistro(RADICE)) );
else
return( RicercaBinaria(X,Destro(RADICE)) );
}
}
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////

tree InserimentoDiUnElemento(tree T, int e)
{
if(T==NULL)
{
tree nuo=NULL;
nuo=(void*)malloc(sizeof(tree));
nuo->DATO=e;
nuo->SX=NULL;
nuo->DX=NULL;
}

if(T->DATO==e)
{
printf(" ERRORE \n");
return NULL;
}

if(T->DATO>e)
{
InserimentoDiUnElemento(T->SX,e);
}else
{
InserimentoDiUnElemento(T->DX,e);
}
}

int main(void)
{
tree t1,t2,t3,t4,t5,t6,t7;

t4=Costruisci_Albero(3,Albero_Vuoto(),Albero_Vuoto());
t5=Costruisci_Albero(6,Albero_Vuoto(),Albero_Vuoto());
t6=Costruisci_Albero(22,Albero_Vuoto(),Albero_Vuoto());
t7=Costruisci_Albero(26,Albero_Vuoto(),Albero_Vuoto());
t2=Costruisci_Albero(5,t4,t5);
t3=Costruisci_Albero(24,t6,t7);
t1=Costruisci_Albero(10,t2,t3);

t1=InserimentoDiUnElemento(t1,7);
Inorder(t1);




}

xsatellitex
02-05-2008, 10:32
hai dimenticato di nuovo il void in costruisci albero...
che errore ti da?

xbubbax
02-05-2008, 10:39
error: invalid conversion from `void*' to `nodo*'

comq penso che l'errore sia solo nella funzione InserimentoDiUnElemento, perchè tutto il resto funziona, gia ho provato...

xsatellitex
02-05-2008, 10:46
main()
tree Albero_Vuoto()

al posto di

int main(void)
tree Albero_Vuoto(void)


fammi sapere
p.s. inserimentodiunelemento io ho compilato quello che ti ho scritto prima e va!

xbubbax
02-05-2008, 11:07
non va, ma com'è possibile...
mi mandi quello che a te compila?

xsatellitex
02-05-2008, 11:12
quello che a me compila l ho scritto sopra.

ti da ancora errore col void? ti dice anche a che riga ?

xbubbax
02-05-2008, 11:14
si errore con void, riga 198, io devo scappare a pranzo torno dopo, se scopri qualcosa lascia un messaggio comq, grazie:)


#include <iostream>
#include <stdlib.h>

using namespace std;

struct nodo
{
int DATO;
struct nodo *DX; //PUNTATORE AL SOTTOALBERO DESTRO
struct nodo *SX; //PUNTATORE AL SOTTOALBERO SINISTRO
}NODO;

typedef struct nodo* tree;

bool Is_Empty(tree RADICE)
//RESTITUISCE TRUE SE L'ALBERO E' VUOTO, ALTRIMENTI RESTITUISCE FALSE
{
return(RADICE==NULL);
}

tree Albero_Vuoto(void)
//COSTRUISCE UN ALBERO VUOTO
{
return NULL;
}

int Valore_Etichetta(tree RADICE)
//RESTITUISCE IL VALORE (O ETICHETTA) DEL NODO
{
if (Is_Empty(RADICE)) abort();
else return(RADICE->DATO);
}

tree Sinistro(tree RADICE)
//RESTITUISCE IL PUNTATORE AL SOTTOALBERO SINISTRO
{
if (Is_Empty(RADICE)) return NULL;
else return(RADICE->SX);
}

tree Destro(tree RADICE)
//RESTITUISCE IL PUNTATORE AL SOTTOALBERO DESTRO
{
if (Is_Empty(RADICE)) return(NULL);
else return(RADICE->DX);
}

tree Costruisci_Albero(int ETICHETTA,tree S,tree D)
//COSTRUISCE UN ALBERO BINARIO NON ORDINATO
{
tree RADICE;
RADICE = (nodo *) malloc(sizeof(NODO));
RADICE->DATO = ETICHETTA;
RADICE->SX = S;
RADICE->DX = D;
return (RADICE);
}

void Inorder(tree RADICE)
//STAMPA INORDER DELL'ALBERO
{
if (!(Is_Empty(RADICE))) {
Inorder(Sinistro(RADICE));
cout<<Valore_Etichetta(RADICE)<<" ";
Inorder(Destro(RADICE));
}
}


void Preorder(tree RADICE)
//STAMPA PREORDER DELL'ALBERO
{
if (!(Is_Empty(RADICE))) {
cout<<Valore_Etichetta(RADICE)<<" ";
Preorder(Sinistro(RADICE));
Preorder(Destro(RADICE));
}
}


void Postorder(tree RADICE)
//STAMPA POSTORDER DELL'ALBERO
{
if (!(Is_Empty(RADICE))) {
Postorder(Sinistro(RADICE));
Postorder(Destro(RADICE));
cout<<Valore_Etichetta(RADICE)<<" ";
}
}


int ContaNodi(tree RADICE)
//RESTITUISCE IL NUMERO DEI NODI DELL'ALBERO
{
if(Is_Empty(RADICE)) return 0;
else return(1 + ContaNodi(Sinistro(RADICE)) + ContaNodi(Destro(RADICE)));
}

int ContaFoglie(tree RADICE)
//RESTITUISCE IL NUMERO DELLE FOGLIE DELL'ALBERO
{
if(Is_Empty(RADICE))
return(0);
else {
if ((Sinistro(RADICE)==NULL) && (Destro(RADICE)==NULL))
return(1);
else return( ContaFoglie(Sinistro(RADICE)) + ContaFoglie(Destro(RADICE)) );
}
}

bool Perf_Bil(tree RADICE)
//Restituisce TRUE se l'albero è perfettamente bilanciato
{
if (Is_Empty(RADICE)) return(true); //Oppure ERROR, secondo la definizione
else {
if ((Sinistro(RADICE)==NULL) && (Destro(RADICE)==NULL)) //Praticamente: se il nodo è una foglia..
return(true);
else {
if ((Sinistro(RADICE)!=NULL) && (Destro(RADICE)!=NULL)) //Se il nodo ha tutti e due i figli..
return( Perf_Bil(Sinistro(RADICE)) && Perf_Bil(Destro(RADICE)) );
else return(false);
}
}
}


bool Ricerca(tree RADICE,int X)
//RICERCA UN VALORE X IN UN ALBERO PUNTATO DA RADICE
{
if (Is_Empty(RADICE))
return(false);
else {
if (X==Valore_Etichetta(RADICE))
return(true);
else
return(Ricerca(Sinistro(RADICE),X) || Ricerca(Destro(RADICE),X));
}
}


int Altezza_Nodo(tree N) //Restituisce l'altezza di un nodo (vedere definizione di altezza)
{
int ALTD=0,ALTS=0;
if (Is_Empty(N)) return(-1);
else {
ALTS=Altezza_Nodo(Sinistro(N));
ALTD=Altezza_Nodo(Destro(N));
if (ALTS>ALTD) return(ALTS+1);
else return(ALTD+1);
}
}

tree Ins_Ord(int E,tree RADICE)
//Costruisce un albero binario di ricerca (un albero "ordinato")
{
if (Is_Empty(RADICE)) {
RADICE=(tree)malloc(sizeof(NODO)); //chiede l'indirizzo di una cella di memoria libera
RADICE->DATO=E;
RADICE->SX=NULL;
RADICE->DX=NULL;
return RADICE;
}
else {
if(E<Valore_Etichetta(RADICE)) {
RADICE->SX=Ins_Ord(E,Sinistro(RADICE));
return RADICE;
}
else {
RADICE->DX=Ins_Ord(E,Destro(RADICE));
return RADICE;
}
}
}


bool RicercaBinaria(int X,tree RADICE)
//Ricerca dicotomica (o binaria) per alberi binari di ricerca (ordinati)
{
if (Is_Empty(RADICE)) return(false);
else {
if (X==Valore_Etichetta(RADICE)) return(true);
else {
if (X < Valore_Etichetta(RADICE))
return( RicercaBinaria(X,Sinistro(RADICE)) );
else
return( RicercaBinaria(X,Destro(RADICE)) );
}
}
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////

tree InserimentoDiUnElemento(tree T, int e)
{
if(T==NULL)
{
tree nuo=NULL;
nuo=(void*)malloc(sizeof(tree));
nuo->DATO=e;
nuo->SX=NULL;
nuo->DX=NULL;
}

if(T->DATO==e)
{
printf(" ERRORE \n");
return NULL;
}

if(T->DATO>e)
{
InserimentoDiUnElemento(T->SX,e);
}else
{
InserimentoDiUnElemento(T->DX,e);
}
}

int main()
{
tree t1,t2,t3,t4,t5,t6,t7;

t4=Costruisci_Albero(3,Albero_Vuoto(),Albero_Vuoto());
t5=Costruisci_Albero(6,Albero_Vuoto(),Albero_Vuoto());
t6=Costruisci_Albero(22,Albero_Vuoto(),Albero_Vuoto());
t7=Costruisci_Albero(26,Albero_Vuoto(),Albero_Vuoto());
t2=Costruisci_Albero(5,t4,t5);
t3=Costruisci_Albero(24,t6,t7);
t1=Costruisci_Albero(10,t2,t3);

t1=InserimentoDiUnElemento(t1,7);
Inorder(t1);




}

wingman87
02-05-2008, 12:08
Provo a dare la soluzione :)
Ogni volta che fai la malloc quello che allochi è un nodo, giusto? Quindi alla sizeof dovresti passargli NODO. Con tree non dovrebbe funzionare (o meglio non dovrebbe fare quello che vuoi tu) perché tree non è di tipo NODO ma di tipo puntatore a NODO.
Inoltre la malloc ti restituisce un puntatore a void, quindi devi fare un casting al tipo desiderato, in questo caso un puntatore a nodo, quindi tree, o se preferisci *NODO.

xbubbax
02-05-2008, 12:12
ho corretto come dici tu però quando compilo mi da il classico errore "non inviare..." puoi provarlo un attimo tu?

#include <iostream>
#include <stdlib.h>

using namespace std;

struct nodo
{
int DATO;
struct nodo *DX; //PUNTATORE AL SOTTOALBERO DESTRO
struct nodo *SX; //PUNTATORE AL SOTTOALBERO SINISTRO
}NODO;

typedef struct nodo* tree;

bool Is_Empty(tree RADICE)
//RESTITUISCE TRUE SE L'ALBERO E' VUOTO, ALTRIMENTI RESTITUISCE FALSE
{
return(RADICE==NULL);
}

tree Albero_Vuoto(void)
//COSTRUISCE UN ALBERO VUOTO
{
return NULL;
}

int Valore_Etichetta(tree RADICE)
//RESTITUISCE IL VALORE (O ETICHETTA) DEL NODO
{
if (Is_Empty(RADICE)) abort();
else return(RADICE->DATO);
}

tree Sinistro(tree RADICE)
//RESTITUISCE IL PUNTATORE AL SOTTOALBERO SINISTRO
{
if (Is_Empty(RADICE)) return NULL;
else return(RADICE->SX);
}

tree Destro(tree RADICE)
//RESTITUISCE IL PUNTATORE AL SOTTOALBERO DESTRO
{
if (Is_Empty(RADICE)) return(NULL);
else return(RADICE->DX);
}

tree Costruisci_Albero(int ETICHETTA,tree S,tree D)
//COSTRUISCE UN ALBERO BINARIO NON ORDINATO
{
tree RADICE;
RADICE = (nodo *) malloc(sizeof(NODO));
RADICE->DATO = ETICHETTA;
RADICE->SX = S;
RADICE->DX = D;
return (RADICE);
}

void Inorder(tree RADICE)
//STAMPA INORDER DELL'ALBERO
{
if (!(Is_Empty(RADICE))) {
Inorder(Sinistro(RADICE));
cout<<Valore_Etichetta(RADICE)<<" ";
Inorder(Destro(RADICE));
}
}


void Preorder(tree RADICE)
//STAMPA PREORDER DELL'ALBERO
{
if (!(Is_Empty(RADICE))) {
cout<<Valore_Etichetta(RADICE)<<" ";
Preorder(Sinistro(RADICE));
Preorder(Destro(RADICE));
}
}


void Postorder(tree RADICE)
//STAMPA POSTORDER DELL'ALBERO
{
if (!(Is_Empty(RADICE))) {
Postorder(Sinistro(RADICE));
Postorder(Destro(RADICE));
cout<<Valore_Etichetta(RADICE)<<" ";
}
}


int ContaNodi(tree RADICE)
//RESTITUISCE IL NUMERO DEI NODI DELL'ALBERO
{
if(Is_Empty(RADICE)) return 0;
else return(1 + ContaNodi(Sinistro(RADICE)) + ContaNodi(Destro(RADICE)));
}

int ContaFoglie(tree RADICE)
//RESTITUISCE IL NUMERO DELLE FOGLIE DELL'ALBERO
{
if(Is_Empty(RADICE))
return(0);
else {
if ((Sinistro(RADICE)==NULL) && (Destro(RADICE)==NULL))
return(1);
else return( ContaFoglie(Sinistro(RADICE)) + ContaFoglie(Destro(RADICE)) );
}
}

bool Perf_Bil(tree RADICE)
//Restituisce TRUE se l'albero è perfettamente bilanciato
{
if (Is_Empty(RADICE)) return(true); //Oppure ERROR, secondo la definizione
else {
if ((Sinistro(RADICE)==NULL) && (Destro(RADICE)==NULL)) //Praticamente: se il nodo è una foglia..
return(true);
else {
if ((Sinistro(RADICE)!=NULL) && (Destro(RADICE)!=NULL)) //Se il nodo ha tutti e due i figli..
return( Perf_Bil(Sinistro(RADICE)) && Perf_Bil(Destro(RADICE)) );
else return(false);
}
}
}


bool Ricerca(tree RADICE,int X)
//RICERCA UN VALORE X IN UN ALBERO PUNTATO DA RADICE
{
if (Is_Empty(RADICE))
return(false);
else {
if (X==Valore_Etichetta(RADICE))
return(true);
else
return(Ricerca(Sinistro(RADICE),X) || Ricerca(Destro(RADICE),X));
}
}


int Altezza_Nodo(tree N) //Restituisce l'altezza di un nodo (vedere definizione di altezza)
{
int ALTD=0,ALTS=0;
if (Is_Empty(N)) return(-1);
else {
ALTS=Altezza_Nodo(Sinistro(N));
ALTD=Altezza_Nodo(Destro(N));
if (ALTS>ALTD) return(ALTS+1);
else return(ALTD+1);
}
}

tree Ins_Ord(int E,tree RADICE)
//Costruisce un albero binario di ricerca (un albero "ordinato")
{
if (Is_Empty(RADICE)) {
RADICE=(tree)malloc(sizeof(NODO)); //chiede l'indirizzo di una cella di memoria libera
RADICE->DATO=E;
RADICE->SX=NULL;
RADICE->DX=NULL;
return RADICE;
}
else {
if(E<Valore_Etichetta(RADICE)) {
RADICE->SX=Ins_Ord(E,Sinistro(RADICE));
return RADICE;
}
else {
RADICE->DX=Ins_Ord(E,Destro(RADICE));
return RADICE;
}
}
}


bool RicercaBinaria(int X,tree RADICE)
//Ricerca dicotomica (o binaria) per alberi binari di ricerca (ordinati)
{
if (Is_Empty(RADICE)) return(false);
else {
if (X==Valore_Etichetta(RADICE)) return(true);
else {
if (X < Valore_Etichetta(RADICE))
return( RicercaBinaria(X,Sinistro(RADICE)) );
else
return( RicercaBinaria(X,Destro(RADICE)) );
}
}
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////

tree InserimentoDiUnElemento(tree T, int e)
{
if(T==NULL)
{
tree nuovo;
nuovo=(tree)malloc(sizeof(NODO));
nuovo->DATO=e;
nuovo->SX=NULL;
nuovo->DX=NULL;
}

if(T->DATO==e)
{
printf(" ERRORE \n");
return NULL;
}

if(T->DATO>e)
{
InserimentoDiUnElemento(T->SX,e);
}else
{
InserimentoDiUnElemento(T->DX,e);
}
}

int main()
{
tree t1,t2,t3,t4,t5,t6,t7;

t4=Costruisci_Albero(3,Albero_Vuoto(),Albero_Vuoto());
t5=Costruisci_Albero(6,Albero_Vuoto(),Albero_Vuoto());
t6=Costruisci_Albero(22,Albero_Vuoto(),Albero_Vuoto());
t7=Costruisci_Albero(26,Albero_Vuoto(),Albero_Vuoto());
t2=Costruisci_Albero(5,t4,t5);
t3=Costruisci_Albero(24,t6,t7);
t1=Costruisci_Albero(10,t2,t3);

t1=InserimentoDiUnElemento(t1,7);
Inorder(t1);

}

wingman87
02-05-2008, 13:52
void InserimentoDiUnElemento(tree T, int e)
{
if(T==NULL)
{
tree nuovo;
nuovo=(tree)malloc(sizeof(NODO));
nuovo->DATO=e;
nuovo->SX=NULL;
nuovo->DX=NULL;
}
//Ho creato una catena di else if
else if(T->DATO==e)
{
printf(" ERRORE \n");
//Ho tolto il return
}

else if(T->DATO>e)
{
InserimentoDiUnElemento(T->SX,e);
}else
{
InserimentoDiUnElemento(T->DX,e);
}
}

int main()
{
tree t1,t2,t3,t4,t5,t6,t7;

t4=Costruisci_Albero(3,Albero_Vuoto(),Albero_Vuoto());
t5=Costruisci_Albero(6,Albero_Vuoto(),Albero_Vuoto());
t6=Costruisci_Albero(22,Albero_Vuoto(),Albero_Vuoto());
t7=Costruisci_Albero(26,Albero_Vuoto(),Albero_Vuoto());
t2=Costruisci_Albero(5,t4,t5);
t3=Costruisci_Albero(24,t6,t7);
t1=Costruisci_Albero(10,t2,t3);

/*Ho tolto l'assegnamento*/InserimentoDiUnElemento(t1,7);
Inorder(t1);
system("pause");
}
Comunque stai mischiando C con C++, iostream è una libreria C++

xbubbax
02-05-2008, 14:04
sisi lo so che sto mischiando ma funziona tutto, tranne questo programma che nonostante le tue modifiche ancora non funziona


#include <iostream>
#include <stdlib.h>

using namespace std;

struct nodo
{
int DATO;
struct nodo *DX; //PUNTATORE AL SOTTOALBERO DESTRO
struct nodo *SX; //PUNTATORE AL SOTTOALBERO SINISTRO
}NODO;

typedef struct nodo* tree;

bool Is_Empty(tree RADICE)
//RESTITUISCE TRUE SE L'ALBERO E' VUOTO, ALTRIMENTI RESTITUISCE FALSE
{
return(RADICE==NULL);
}

tree Albero_Vuoto(void)
//COSTRUISCE UN ALBERO VUOTO
{
return NULL;
}

int Valore_Etichetta(tree RADICE)
//RESTITUISCE IL VALORE (O ETICHETTA) DEL NODO
{
if (Is_Empty(RADICE)) abort();
else return(RADICE->DATO);
}

tree Sinistro(tree RADICE)
//RESTITUISCE IL PUNTATORE AL SOTTOALBERO SINISTRO
{
if (Is_Empty(RADICE)) return NULL;
else return(RADICE->SX);
}

tree Destro(tree RADICE)
//RESTITUISCE IL PUNTATORE AL SOTTOALBERO DESTRO
{
if (Is_Empty(RADICE)) return(NULL);
else return(RADICE->DX);
}

tree Costruisci_Albero(int ETICHETTA,tree S,tree D)
//COSTRUISCE UN ALBERO BINARIO NON ORDINATO
{
tree RADICE;
RADICE = (nodo *) malloc(sizeof(NODO));
RADICE->DATO = ETICHETTA;
RADICE->SX = S;
RADICE->DX = D;
return (RADICE);
}

void Inorder(tree RADICE)
//STAMPA INORDER DELL'ALBERO
{
if (!(Is_Empty(RADICE))) {
Inorder(Sinistro(RADICE));
cout<<Valore_Etichetta(RADICE)<<" ";
Inorder(Destro(RADICE));
}
}


void Preorder(tree RADICE)
//STAMPA PREORDER DELL'ALBERO
{
if (!(Is_Empty(RADICE))) {
cout<<Valore_Etichetta(RADICE)<<" ";
Preorder(Sinistro(RADICE));
Preorder(Destro(RADICE));
}
}


void Postorder(tree RADICE)
//STAMPA POSTORDER DELL'ALBERO
{
if (!(Is_Empty(RADICE))) {
Postorder(Sinistro(RADICE));
Postorder(Destro(RADICE));
cout<<Valore_Etichetta(RADICE)<<" ";
}
}


int ContaNodi(tree RADICE)
//RESTITUISCE IL NUMERO DEI NODI DELL'ALBERO
{
if(Is_Empty(RADICE)) return 0;
else return(1 + ContaNodi(Sinistro(RADICE)) + ContaNodi(Destro(RADICE)));
}

int ContaFoglie(tree RADICE)
//RESTITUISCE IL NUMERO DELLE FOGLIE DELL'ALBERO
{
if(Is_Empty(RADICE))
return(0);
else {
if ((Sinistro(RADICE)==NULL) && (Destro(RADICE)==NULL))
return(1);
else return( ContaFoglie(Sinistro(RADICE)) + ContaFoglie(Destro(RADICE)) );
}
}

bool Perf_Bil(tree RADICE)
//Restituisce TRUE se l'albero è perfettamente bilanciato
{
if (Is_Empty(RADICE)) return(true); //Oppure ERROR, secondo la definizione
else {
if ((Sinistro(RADICE)==NULL) && (Destro(RADICE)==NULL)) //Praticamente: se il nodo è una foglia..
return(true);
else {
if ((Sinistro(RADICE)!=NULL) && (Destro(RADICE)!=NULL)) //Se il nodo ha tutti e due i figli..
return( Perf_Bil(Sinistro(RADICE)) && Perf_Bil(Destro(RADICE)) );
else return(false);
}
}
}


bool Ricerca(tree RADICE,int X)
//RICERCA UN VALORE X IN UN ALBERO PUNTATO DA RADICE
{
if (Is_Empty(RADICE))
return(false);
else {
if (X==Valore_Etichetta(RADICE))
return(true);
else
return(Ricerca(Sinistro(RADICE),X) || Ricerca(Destro(RADICE),X));
}
}


int Altezza_Nodo(tree N) //Restituisce l'altezza di un nodo (vedere definizione di altezza)
{
int ALTD=0,ALTS=0;
if (Is_Empty(N)) return(-1);
else {
ALTS=Altezza_Nodo(Sinistro(N));
ALTD=Altezza_Nodo(Destro(N));
if (ALTS>ALTD) return(ALTS+1);
else return(ALTD+1);
}
}

tree Ins_Ord(int E,tree RADICE)
//Costruisce un albero binario di ricerca (un albero "ordinato")
{
if (Is_Empty(RADICE)) {
RADICE=(tree)malloc(sizeof(NODO)); //chiede l'indirizzo di una cella di memoria libera
RADICE->DATO=E;
RADICE->SX=NULL;
RADICE->DX=NULL;
return RADICE;
}
else {
if(E<Valore_Etichetta(RADICE)) {
RADICE->SX=Ins_Ord(E,Sinistro(RADICE));
return RADICE;
}
else {
RADICE->DX=Ins_Ord(E,Destro(RADICE));
return RADICE;
}
}
}


bool RicercaBinaria(int X,tree RADICE)
//Ricerca dicotomica (o binaria) per alberi binari di ricerca (ordinati)
{
if (Is_Empty(RADICE)) return(false);
else {
if (X==Valore_Etichetta(RADICE)) return(true);
else {
if (X < Valore_Etichetta(RADICE))
return( RicercaBinaria(X,Sinistro(RADICE)) );
else
return( RicercaBinaria(X,Destro(RADICE)) );
}
}
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////

void InserimentoDiUnElemento(tree T, int e)
{
if(T==NULL)
{
tree nuovo;
nuovo=(tree)malloc(sizeof(NODO));
nuovo->DATO=e;
nuovo->SX=NULL;
nuovo->DX=NULL;
}

if(T->DATO==e)
{
printf(" ERRORE \n");

}

if(T->DATO>e)
{
InserimentoDiUnElemento(T->SX,e);
}else
{
InserimentoDiUnElemento(T->DX,e);
}
}

int main()
{
tree t1,t2,t3,t4,t5,t6,t7;

t4=Costruisci_Albero(3,Albero_Vuoto(),Albero_Vuoto());
t5=Costruisci_Albero(6,Albero_Vuoto(),Albero_Vuoto());
t6=Costruisci_Albero(22,Albero_Vuoto(),Albero_Vuoto());
t7=Costruisci_Albero(26,Albero_Vuoto(),Albero_Vuoto());
t2=Costruisci_Albero(5,t4,t5);
t3=Costruisci_Albero(24,t6,t7);
t1=Costruisci_Albero(10,t2,t3);

InserimentoDiUnElemento(t1,7);
Inorder(t1);

}

wingman87
02-05-2008, 14:08
Non hai corretto tutto, non hai fatto la catena di else if

xbubbax
02-05-2008, 14:11
funziona ora...ma che diavolo sbagliavo oltre alla malloc?

xbubbax
02-05-2008, 14:13
no non funziona:D

cioè non mi da piu errore ma quando stampo l'albero, l'elemento che ho inserito non lo stampa

wingman87
02-05-2008, 14:17
Beh, è normale... Quando fai l'inserimento ti devi fermare prima di arrivare al riferimento NULL, altrimenti il nodo che crei non si aggancia al precedente ma rimane sospeso nel nulla

xbubbax
02-05-2008, 14:18
quindi?:D :D non ho capito cosa devo correggere

wingman87
02-05-2008, 14:21
Praticamente in InserimentoDiUnElemento prima di fare la chiamata ricorsiva devi controllare che non stai per passare un riferimento NULL. Se stai per farlo significa che è quello il momento in cui devi creare il nuovo nodo e agganciarlo a quello che stai visitando.

xbubbax
02-05-2008, 14:34
non capisco..che senso ha fare il controllo del null prima della chiamata ricorsiva se viene fatto prima? cioè se arriva a quel punto significa che non è null...

puoi farmi un esempio..

wingman87
02-05-2008, 14:43
Allora, ti faccio un esempio con una lista che dovrebbe farti capire lo stesso il concetto.
Mettiamo di avere una lista non ordinata così:
1->3->2->NULL
Dobbiamo inserire un elemento in fondo, proviamo con un metodo simile al tuo:
-Il primo nodo è NULL? No, allora facciamo la chiamata ricorsiva (passo il riferimento al secondo nodo)
-Il secondo è NULL? No, allora facciamo la chiamata ricorsiva(passo il riferimento al terzo nodo)
-Il terzo è NULL? No, allora facciamo la chiamata ricorsiva (passo il riferimento al quarto nodo, ma questo non esiste, quindi sto passando NULL)
-Il quarto è NULL? Sì, creo il nodo e ho finito
Sembra corretto ma non lo è, dove si trova infatti il riferimento al nodo che ho creato?

L'approccio corretto invece è il seguente:
-Il primo nodo è NULL? No.
Il suo successivo è NULL? No, allora facciamo la chiamata ricorsiva (passo il riferimento al secondo nodo)
-Il secondo è NULL? No
Il suo successivo è NULL? No, allora facciamo la chiamata ricorsiva(passo il riferimento al terzo nodo)
-Il terzo è NULL? No
Il suo successivo è NULL? Sì, quindi creo il nuovo nodo e copio il suo riferimento nel next. Ho finito