View Full Version : [C] Alberi Binari Di Ricerca - Inserimento Di Un Elemento
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);
}
}
Perchè allochi un *tree e non un tree?
Lo spazio che devi allocare è per un nodo, non per un puntatore ad un nodo.
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);
}
}
}
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
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..
:)
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?
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!
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 ?
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.
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++
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
funziona ora...ma che diavolo sbagliavo oltre alla malloc?
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
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.
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
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.