Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Recensione Samsung Galaxy Z Fold7: un grande salto generazionale
Recensione Samsung Galaxy Z Fold7: un grande salto generazionale
Abbiamo provato per molti giorni il nuovo Z Fold7 di Samsung, un prodotto davvero interessante e costruito nei minimi dettagli. Rispetto al predecessore, cambiano parecchie cose, facendo un salto generazionale importante. Sarà lui il pieghevole di riferimento? Ecco la nostra recensione completa.
The Edge of Fate è Destiny 2.5. E questo è un problema
The Edge of Fate è Destiny 2.5. E questo è un problema
Bungie riesce a costruire una delle campagne più coinvolgenti della serie e introduce cambiamenti profondi al sistema di gioco, tra nuove stat e tier dell’equipaggiamento. Ma con risorse limitate e scelte discutibili, il vero salto evolutivo resta solo un’occasione mancata
Ryzen Threadripper 9980X e 9970X alla prova: AMD Zen 5 al massimo livello
Ryzen Threadripper 9980X e 9970X alla prova: AMD Zen 5 al massimo livello
AMD ha aggiornato l'offerta di CPU HEDT con i Ryzen Threadripper 9000 basati su architettura Zen 5. In questo articolo vediamo come si comportano i modelli con 64 e 32 core 9980X e 9970X. Venduti allo stesso prezzo dei predecessori e compatibili con il medesimo socket, le nuove proposte si candidano a essere ottimi compagni per chi è in cerca di potenza dei calcolo e tante linee PCI Express per workstation grafiche e destinate all'AI.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 07-04-2011, 10:43   #1
mame83
Member
 
Iscritto dal: Nov 2010
Messaggi: 71
[C] verificare se un albero binario è un abr

Ciao a tutti ho il seguente problema: devo verificare se un albero binario è un albero binario di ricerca. Spero che mi aiutate grazie
Codice:
void verifica(nod *radice, int abr)/*ritorna zero se e un abr 1 se non è*/
{
 
 if (radice!=NULL)
   {
    printf("radice uguale a %d \n",radice->info);
    if (((radice->sinistro==NULL)&&(radice->destro->info<radice->info))||
       ((radice->destro==NULL)&&(radice->sinistro->info>radice->info))||
       ((radice->destro->info<radice->info)&&(radice->sinistro->info<radice->info)))
        {
         
         abr=1;
         
        } 
    else
      { 
       verifica(radice->sinistro,0);
       verifica(radice->destro,0);
      }
   }   
  
}
mame83 è offline   Rispondi citando il messaggio o parte di esso
Old 07-04-2011, 13:43   #2
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2774
Faccio due considerazioni che dovrebbero condurti sulla buona strada:
- questa funzione deve restituire un valore, quindi perché è void?
- se sia il ramo sx che il dx sono NULL cosa succede?
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 07-04-2011, 16:41   #3
mame83
Member
 
Iscritto dal: Nov 2010
Messaggi: 71
ciao avevo pensato di usare una vodi visto che devo ricordarmi il valore di abr precedente. Poi per quanto riguarda se entrambi i figli sono uguali a null deve fermarsi e questo che non riesco a fare. Se saresti piu esplicito forse capisco meglio. grazie
mame83 è offline   Rispondi citando il messaggio o parte di esso
Old 07-04-2011, 17:02   #4
clockover
Senior Member
 
L'Avatar di clockover
 
Iscritto dal: Oct 2004
Messaggi: 1945
Quote:
Originariamente inviato da mame83 Guarda i messaggi
Ciao a tutti ho il seguente problema: devo verificare se un albero binario è un albero binario di ricerca. Spero che mi aiutate grazie
Codice:
void verifica(nod *radice, int abr)/*ritorna zero se e un abr 1 se non è*/
si ma non ritorna nulla con il void, sostituiscilo con int...

per quanto riguarda il fatto se un nodo non ha figlio destro e sinistro il risultato è true (cioè 1)....

io farei una cosa del tipo.... (molto al volo)
Codice:
se nodo == null
    return 1;
se nodo.left == null && nodo.right == null
    return 1;
qui effettui i controlli su entrambi i figli
se uno solo dei due non soddisfa la condizione puoi ritornare direttamente 0

ora qui fai una chiamata ricorsiva su entrambi i figli della funzione
ricorda che deve essere vero per entrambi
e la tua funzione falla così
Codice:
int isBst(nod * radice) //o comunque chiamala come vuoi
dato che ti serve solo la radice leva quell'altro parametro che non ti serve..
clockover è offline   Rispondi citando il messaggio o parte di esso
Old 08-04-2011, 12:00   #5
mame83
Member
 
Iscritto dal: Nov 2010
Messaggi: 71
ho fatto come mi dicevi.
Codice:
int verifica(nod *radice)/*ritorna zero se e un abr 1 se non è*/
{
 
 if ((radice==NULL)||((radice->sinistro==NULL)&&(radice->destro==NULL)))
   {
     
     return 0; 
   }
 else
   if (((radice->sinistro==NULL)&&(radice->destro->info<radice->info))||
       ((radice->destro==NULL)&&(radice->sinistro->info>radice->info))||
       ((radice->destro->info<radice->info)&&(radice->sinistro->info<radice->info)))
        {
         
         return 1;
        } 
   else
     {
      ;
       return (verifica(radice->sinistro));
       return (verifica(radice->destro));
     }          
}
però ho due problemi:
1 mi restituisce sempre 0, se non metto return 0 mi restituisce sempre 1.
2 non richiamo il figlio destro
SPero mi aiuti perche non so piu cha fare.
mame83 è offline   Rispondi citando il messaggio o parte di esso
Old 08-04-2011, 12:16   #6
clockover
Senior Member
 
L'Avatar di clockover
 
Iscritto dal: Oct 2004
Messaggi: 1945
Quote:
Originariamente inviato da mame83 Guarda i messaggi
return (verifica(radice->sinistro));
return (verifica(radice->destro));

però ho due problemi:
1 mi restituisce sempre 0, se non metto return 0 mi restituisce sempre 1.
2 non richiamo il figlio destro
SPero mi aiuti perche non so piu cha fare.
mamma mia e che ci hai messo qua

due return non si possono proprio vedere.....

semplifica la cosa levando un po di roba che almeno ti semplifica la vita...
intanto il passo base della ricorsione è fatto bene se non fosse che devi ritornare 1. Si perchè un albero binario è banalmente binario se non ha figli (cioè è una foglia) e il controllo se il nodo stesso è null diciamo che neanche servirebbe in questo caso ma ce lo mettiamo lo stesso
quindi
Codice:
se nodo == null || (nodo.left == null && nodo.right == null)return 1;
e qui ci siamo

controlli i figli
Codice:
se (nodo.left != null) && (nodo.left.info > nodo.info)return 0
se (nodo.right != null) && (nodo.right.info <= nodo.info) return 0
qui ho fatto una cosa semplice: non controllo se il sinistro è minore o uguale e il destro maggiore, ma il contrario! In questo modo posso ritornare 0 (cioè è violata la condizione) e bloccare subito il controllo!

adesso però devi vedere che tutti gli altri nodi non ritornino 0

Codice:
return isBst(nodo.left) && isBst(nodo.right)
questo vuol dire che se un solo nodo ritorna 0 il controllo si interrompe e restituisce 0, propagandolo fino alla radice! Quando è che ritorna 1? Quando sei arrivato ad una foglia e ritorni 1 (passo base della ricorsione)

spero di non aver sbagliato nulla


edit
gli else non servono a nulla in questo caso, omettili adesso almeno rendono un po più leggibile il codice
clockover è offline   Rispondi citando il messaggio o parte di esso
Old 08-04-2011, 16:42   #7
mame83
Member
 
Iscritto dal: Nov 2010
Messaggi: 71
Quote:
Originariamente inviato da clockover Guarda i messaggi
mamma mia e che ci hai messo qua

due return non si possono proprio vedere.....

semplifica la cosa levando un po di roba che almeno ti semplifica la vita...
intanto il passo base della ricorsione è fatto bene se non fosse che devi ritornare 1. Si perchè un albero binario è banalmente binario se non ha figli (cioè è una foglia) e il controllo se il nodo stesso è null diciamo che neanche servirebbe in questo caso ma ce lo mettiamo lo stesso
quindi
Codice:
se nodo == null || (nodo.left == null && nodo.right == null)return 1;
e qui ci siamo

controlli i figli
Codice:
se (nodo.left != null) && (nodo.left.info > nodo.info)return 0
se (nodo.right != null) && (nodo.right.info <= nodo.info) return 0
qui ho fatto una cosa semplice: non controllo se il sinistro è minore o uguale e il destro maggiore, ma il contrario! In questo modo posso ritornare 0 (cioè è violata la condizione) e bloccare subito il controllo!

adesso però devi vedere che tutti gli altri nodi non ritornino 0

Codice:
return isBst(nodo.left) && isBst(nodo.right)
questo vuol dire che se un solo nodo ritorna 0 il controllo si interrompe e restituisce 0, propagandolo fino alla radice! Quando è che ritorna 1? Quando sei arrivato ad una foglia e ritorni 1 (passo base della ricorsione)

spero di non aver sbagliato nulla


edit
gli else non servono a nulla in questo caso, omettili adesso almeno rendono un po più leggibile il codice
ho capito che due return uno dietro l altro non funzionano perche ne farà sempre solo il primo. ma la funzione deve restituire 0 se è un abr 1 se non lo è
mame83 è offline   Rispondi citando il messaggio o parte di esso
Old 08-04-2011, 18:13   #8
clockover
Senior Member
 
L'Avatar di clockover
 
Iscritto dal: Oct 2004
Messaggi: 1945
Non ci avevo fatto caso che doveva essere il contrario...vabbè comunque basta davvero poco per modificarlo...
clockover è offline   Rispondi citando il messaggio o parte di esso
Old 11-04-2011, 10:41   #9
mame83
Member
 
Iscritto dal: Nov 2010
Messaggi: 71
scusa ma il caso base e che il nodo non ha figli o e lui stesso NULL e restituisce 0 come avevo fatto......
mame83 è offline   Rispondi citando il messaggio o parte di esso
Old 11-04-2011, 10:53   #10
clockover
Senior Member
 
L'Avatar di clockover
 
Iscritto dal: Oct 2004
Messaggi: 1945
Guarda stai impazzendo per nulla... se hai capito quello che ti ho scritto prima ti basta modificare poche cose...più di questo dovrei darti la soluzione...e non mi pare il caso

comunque posta il tuo codice.
clockover è offline   Rispondi citando il messaggio o parte di esso
Old 11-04-2011, 11:26   #11
mame83
Member
 
Iscritto dal: Nov 2010
Messaggi: 71
continua a non funzionarmi come in questo caso:
5
\
7
/
3
va in loop. 5 radice 7 figlio destro di 5 e 3 figlio sinistro di 7.

Codice:
int verifica(nod *radice)/*ritorna zero se e un abr 1 se non è*/
{
 
 if ((radice==NULL)||((radice->sinistro==NULL)&&(radice->destro==NULL)))
   {
     printf("fine \n");
     return 0; 
   }
 else
   if (((radice->sinistro==NULL)&&(radice->destro->info<radice->info))||
       ((radice->destro==NULL)&&(radice->sinistro->info>radice->info))||
       ((radice->destro->info<radice->info)&&(radice->sinistro->info<radice->info)))
        {
         printf("l albero non e' un abr \n");
         return 1;
        } 
   else
     {
       printf("andiamo avanti con la funzione \n");
       return (verifica(radice->sinistro)||verifica(radice->destro));
       
       
     }          
}
non riesco a capire perche va in loop
mame83 è offline   Rispondi citando il messaggio o parte di esso
Old 11-04-2011, 14:09   #12
sottovento
Senior Member
 
L'Avatar di sottovento
 
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
Prova a semplificarlo ancora un po:

- caso base: Se il nodo e' NULL allora ritorna 1 (si, e' un albero di ricerca);
- caso base: se uno dei due nodi, sinistro/destro e' NULL, allora ritorna 1 in accordo all'ordine che hai scelto (cioe', se sx!=NULL, allora confronta sx con root e se sx < root ritorni 1);

- caso base :Se sia sx sia dx sono != NULL (quindi hai fatto i controlli di cui sopra) allora puoi confrontare sx->root->dx. Se non rispettano l'ordine, ritorni 0. Siccome hai trovato un caso, tutto l'albero non e' di ricerca e le tue ricorsioni verranno interrotte perche' sai gia' il risultato.

Infine (caso ricorsivo) ti rimane che sx e dx sono != NULL e sono nell'ordine giusto. Allora puoi fare l'AND fra le chiamate ricorsive a sx e dx e ritornare il risultato.

Fai le prove partendo da alberi semplici (i.e. verifica i casi base prima di tutto)

Spero ti sia d'aiuto
__________________
In God we trust; all others bring data
sottovento è offline   Rispondi citando il messaggio o parte di esso
Old 11-04-2011, 14:30   #13
clockover
Senior Member
 
L'Avatar di clockover
 
Iscritto dal: Oct 2004
Messaggi: 1945
Quote:
Originariamente inviato da mame83 Guarda i messaggi
continua a non funzionarmi come in questo caso:
5
\
7
/
3
va in loop. 5 radice 7 figlio destro di 5 e 3 figlio sinistro di 7.

Codice:
int verifica(nod *radice)/*ritorna zero se e un abr 1 se non è*/
{
 
 if ((radice==NULL)||((radice->sinistro==NULL)&&(radice->destro==NULL)))
   {
     printf("fine \n");
     return 0; 
   }
else
   if (((radice->sinistro==NULL)&&(radice->destro->info<radice->info))||
       ((radice->destro==NULL)&&(radice->sinistro->info>radice->info))||
       ((radice->destro->info<radice->info)&&(radice->sinistro->info<radice->info)))
        {
         printf("l albero non e' un abr \n");
         return 1;
        } 
   else
     {
       printf("andiamo avanti con la funzione \n");
       return (verifica(radice->sinistro)||verifica(radice->destro));
       
       
     }          
}
non riesco a capire perche va in loop
non riesco a capire perchè devi complicarti la vita in questo modo
mettendo tutta quella roba in un'unica espressione rischi di fare degli errori e non riuscire a capire dove

quella parte in rosso cancellala totalmente...
sostituisci con qualcosa del tipo
Codice:
se nodo.left != null && nodo.left.value > nodo.value return 1
se nodo.right != null && nodo.right.value <= nodo.value return 1

Cancella anche tutti gli else che ci sono. Non sono un errore usarli, ma non servono ora e levandoli migliori la lettura del codice

Comunque fattelo dire ritornare 0 (false) se è un albero binario e 1 (true) se non lo è è una cosa molto anomala...
clockover è offline   Rispondi citando il messaggio o parte di esso
Old 11-04-2011, 20:00   #14
mame83
Member
 
Iscritto dal: Nov 2010
Messaggi: 71
Quote:
Originariamente inviato da clockover Guarda i messaggi
non riesco a capire perchè devi complicarti la vita in questo modo
mettendo tutta quella roba in un'unica espressione rischi di fare degli errori e non riuscire a capire dove

quella parte in rosso cancellala totalmente...
sostituisci con qualcosa del tipo
Codice:
se nodo.left != null && nodo.left.value > nodo.value return 1
se nodo.right != null && nodo.right.value <= nodo.value return 1

Cancella anche tutti gli else che ci sono. Non sono un errore usarli, ma non servono ora e levandoli migliori la lettura del codice

Comunque fattelo dire ritornare 0 (false) se è un albero binario e 1 (true) se non lo è è una cosa molto anomala...
ho fatto come dici tu le semplificazioni ma mi da sempre 1 cioe che non è un abr
anke in caso di albero semplice :
5
3 6
Codice:
int verifica(nod *radice)/*ritorna zero se e un abr 1 se non è*/
{
 
 if ((radice==NULL)||((radice->sinistro==NULL)&&(radice->destro==NULL)))
   {
     printf("fine \n");
     return 0; 
   }
 else
   {
    printf("valore del nodo analizzato uguale a %d \n",radice->info);        
    if ((radice->sinistro!=NULL)&&(radice->sinistro->info>radice->info))
      return 1;
    if  ((radice->destro!=NULL)&&(radice->destro->info>radice->info))
      return 1;
    return (verifica(radice->sinistro)&&verifica(radice->destro));
   }
                
}
mame83 è offline   Rispondi citando il messaggio o parte di esso
Old 11-04-2011, 20:06   #15
clockover
Senior Member
 
L'Avatar di clockover
 
Iscritto dal: Oct 2004
Messaggi: 1945
C'è un errore nel return finale che prima non avevi fatto
clockover è offline   Rispondi citando il messaggio o parte di esso
Old 12-04-2011, 10:12   #16
mame83
Member
 
Iscritto dal: Nov 2010
Messaggi: 71
Quote:
Originariamente inviato da clockover Guarda i messaggi
C'è un errore nel return finale che prima non avevi fatto
ho sbagliato il secondo if per ritornare 1 deve essere destro<radice
per quanto riguardo il return finale devo mettere l else del secondo if?
mame83 è offline   Rispondi citando il messaggio o parte di esso
Old 12-04-2011, 10:16   #17
clockover
Senior Member
 
L'Avatar di clockover
 
Iscritto dal: Oct 2004
Messaggi: 1945
Quote:
Originariamente inviato da mame83 Guarda i messaggi
ho sbagliato il secondo if per ritornare 1 deve essere destro<radice
per quanto riguardo il return finale devo mettere l else del secondo if?
Si giusto... metti minore/uguale per il figlio destro... nel return finale sostituisci and con or
clockover è offline   Rispondi citando il messaggio o parte di esso
Old 12-04-2011, 11:22   #18
mame83
Member
 
Iscritto dal: Nov 2010
Messaggi: 71
ho fatto come dicevi
Codice:
int verifica(nod *radice)/*ritorna zero se e un abr 1 se non è*/
{
 
 
 if ((radice==NULL)||((radice->sinistro==NULL)&&(radice->destro==NULL)))
   {
     
     return 0; 
   }
 else
   {
            
    if ((radice->sinistro!=NULL)&&(radice->sinistro->info>radice->info))
                                                                      
       return 1;
       
    if  ((radice->destro!=NULL)&&(radice->destro->info<radice->info))
      
       return 1;
       
    else  
      return (verifica(radice->sinistro)||verifica(radice->destro));
   }
                
}
un caso che non avevo considerato e che forse dovrei cambiare quasi tt il codice è questo:
se io ho un albero in cui i figli rispettano la proprieta verso il padre ma non verso il nonno diciamo cosi quest algoritmo non va bene.
ESEMPIO
5
\
7
/
2
in questo caso mi restituisce che e un ABR perche controlla che 2 è minore di 7 e che 7 è maggiore di 5. ma non che 2 stando a destra di 5 dovrebbe essere maggiore di 5. non so se ho reso l idea
mame83 è offline   Rispondi citando il messaggio o parte di esso
Old 12-04-2011, 14:43   #19
clockover
Senior Member
 
L'Avatar di clockover
 
Iscritto dal: Oct 2004
Messaggi: 1945
Effettivamente hai ragione.. non avevamo considerato questa cosa! Potresti provare allora con una visita in-order e verificare che ogni nodo sia minore del successivo... Questa cosa mi era proprio sfuggita
clockover è offline   Rispondi citando il messaggio o parte di esso
Old 12-04-2011, 15:56   #20
mame83
Member
 
Iscritto dal: Nov 2010
Messaggi: 71
hai ragione proverò a farlo
mame83 è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Recensione Samsung Galaxy Z Fold7: un grande salto generazionale Recensione Samsung Galaxy Z Fold7: un grande sal...
The Edge of Fate è Destiny 2.5. E questo è un problema The Edge of Fate è Destiny 2.5. E questo ...
Ryzen Threadripper 9980X e 9970X alla prova: AMD Zen 5 al massimo livello Ryzen Threadripper 9980X e 9970X alla prova: AMD...
Acer TravelMate P4 14: tanta sostanza per l'utente aziendale Acer TravelMate P4 14: tanta sostanza per l'uten...
Hisense M2 Pro: dove lo metti, sta. Mini proiettore laser 4K per il cinema ovunque Hisense M2 Pro: dove lo metti, sta. Mini proiett...
SpaceX Starship: Ship 37 ha eseguito due...
Sharkoon punta sui case a basso costo, m...
La tua rete Wi-Fi fa pena? Questi FRITZ!...
Amazon, un weekend di fuoco per gli scon...
Ancora 3 smartwatch Amazfit in forte sco...
Sharkoon A60 RGB: dissipatore ad aria du...
HONOR 400 Pro a prezzo bomba su Amazon: ...
Offerte da non perdere: robot aspirapolv...
Apple Watch e Galaxy Watch ai minimi sto...
Il rover NASA Perseverance ha ''raccolto...
NASA e ISRO hanno lanciato il satellite ...
Switch 2 ha venduto 5,82 milioni di cons...
Assassin's Creed Black Flag Remake: le m...
Cosa ci fa una Xiaomi SU7 Ultra alle por...
Promo AliExpress Choice Day: prezzi stra...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 05:53.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v