Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Sony INZONE H6 Air: il primo headset open-back di Sony per giocatori
Sony INZONE H6 Air: il primo headset open-back di Sony per giocatori
Il primo headset open-back della linea INZONE arriva a 200 euro con driver derivati dalle cuffie da studio MDR-MV1 e un peso record di soli 199 grammi
Nutanix cambia pelle: dall’iperconvergenza alla piattaforma full stack per cloud ibrido e IA
Nutanix cambia pelle: dall’iperconvergenza alla piattaforma full stack per cloud ibrido e IA
Al .NEXT 2026 di Chicago, Nutanix ha mostrato quanto sia cambiata: una piattaforma software che gestisce VM, container e carichi di lavoro IA ovunque, dall’on-premise al cloud pubblico. Con un’esecuzione rapidissima sulle partnership e sulla migrazione da VMware
Recensione Xiaomi Pad 8 Pro: potenza bruta e HyperOS 3 per sfidare la fascia alta
Recensione Xiaomi Pad 8 Pro: potenza bruta e HyperOS 3 per sfidare la fascia alta
Xiaomi Pad 8 Pro adotta il potente Snapdragon 8 Elite all'interno di un corpo con spessore di soli 5,75 mm e pannello LCD a 144Hz flicker-free, per un tablet che può essere utilizzato con accessori dedicati di altissima qualità. Fra le caratteristiche esclusive, soprattutto per chi intende usarlo con la tastiera ufficiale, c'è la modalità Workstation di HyperOS 3, che trasforma Android in un sistema operativo con interfaccia a finestre
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 10-02-2010, 14:54   #1
xxxyyy
Senior Member
 
L'Avatar di xxxyyy
 
Iscritto dal: Apr 2002
Messaggi: 4401
Alberi binari e ricorsione. Come capirli?

Ciao,
allora... i problemi sono iniziati col meccanismo della ricorsione.
Qunado e' semplice semplice, nessun problema.
Ma quando si complica un po' devo "spaccarmi" la testa per per capirci qualcosa... figuriamoci se devo scrivere un programma...

Mi consigliate come/dove imparare bene questo metodo?

No perche' piu' o meno ero a posto cosi'... non devo diventare un genio della programmazione... ma poi sono arrivati sti maledetti alberi binari che bisogna trattarli per forza con la ricorsione.

Ed ecco la seconda domanda: come/dove imparo bene a districarmi ricorsivamentio tra gli alberi?

Grazie!

Ultima modifica di xxxyyy : 11-02-2010 alle 14:50.
xxxyyy è offline   Rispondi citando il messaggio o parte di esso
Old 10-02-2010, 15:20   #2
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Leggi questa discussione e vedi se ti serve: http://www.hwupgrade.it/forum/showth...ght=condizione
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 10-02-2010, 15:49   #3
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12966
La ricorsione non è un concetto immediatamente comprensibile, ma non è neanche impossibile.

La ricorsione prevede:

PASSO BASE: quando bisogna fermarsi.

PASSO RICORSIVO: richiamare la stessa funzione con un nuovo argomento che dipende dal precedente (non è sempre vero se operi su dati esterni alla funzione stessa).

Ad esempio per il calcolo del massimo comun divisore, applicando l'algoritmo di euclide:

Codice:
int gcd(x, y) {
if (x==y) return x; // passo base if (x>y) return gcd(x-y, y); // passo ricorsivo if (x<y) return gcd(x, y-x); // passo ricorsivo
}
Innanzitutto devi pensare a quando devi fermarti.

Un algoritmo di visita in profondità per un albero binario è il seguente:

Codice:
deep(node n) {
if (n==null) return; // passo base, se il nodo da visitare è nullo termina print n; // stampa nodo visitato deep(n.left); // visita nodo sinistro deep(n.right); // visita nodo destro
}
Facciamo un esempio con qualche nodo:

NODO A
NODO B
NODO C
NODO D

A.RIGHT = B
B.LEFT = D
B.RIGHT = C

E' un albero sbilanciato sulla destra:
A
\
B
/ \
D C

Chiamo deep(A):

Visito A
Visito A.LEFT => null
Visito A.RIGHT => B
Visito B.LEFT => D
Visito D.LEFT => null
Visito D.RIGHT => null
Visito B.RIGHT, => C
Visito C.LEFT => null
Visito C.RIGHT => null

Per capire perché opera in questo modo devi tenere presente che la struttura dati implicita nella ricorsione è una pila (o stack).

Immagina una pila di piatti, dove l'ultimo piatto che metti è il primo che puoi togliere.

Ad ogni visita che fai metti nello stack i nodi figli dopodiché questi vengono estratti uno alla volta e visitati.

Naturalmente man mano che visiti possono essere aggiunti nuovi nodi nello stack, per cui è possibile che se hai molti nodi sinistri passi del tempo prima di visitare i sotto-alberi destri.

Lo so l'ho spiegato male... spero che qualcosa risulti comprensibile.
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 10-02-2010, 16:03   #4
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2789
Il mio consiglio per scrivere una funzione ricorsiva sugli alberi è rifarsi sempre al principio di induzione strutturale: distinguere e risolvere il caso base (albero vuoto) e il caso generico (albero non vuoto) sapendo che le eventuali chiamate ricorsive restituiranno un risultato corretto.
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 10-02-2010, 20:31   #5
fero86
Senior Member
 
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
Quote:
Originariamente inviato da wingman87 Guarda i messaggi
Il mio consiglio per scrivere una funzione ricorsiva sugli alberi è rifarsi sempre al principio di induzione strutturale:
esatto: quotone!!
c'é chi dice (non in questo thread, in generale) che le funzioni ricorsive sono quelle che chiamano se stesse, ma é sbagliatissimo. un algoritmo ricorsivo é un algoritmo che é possibile definire induttivamente, e si parla di induzione strutturale di cui l'induzione matematica é un caso particolare. in particolare non é detto che ci sia un solo caso base e un solo caso induttivo: quando si fa induzione strutturale in generale ci sono tanti casi base e tanti casi induttivi.

definire funzioni ricorsive sugli alberi binari é facilissimo se li si pensa come elementi di un insieme definito per induzione strutturale. una definizione induttiva degll'insieme degli alberi binari tipicamente avrá un costruttore per il caso base che sará solo una funzione che spara un nodo, e un costruttore per il caso induttivo che sará una funzione che presi due alberi ne produce un altro attaccandoli come figli di un nuovo nodo.

essendoci due costruttori tu, nel definire induttivamente funzioni ricorsive, devi porti solamente due domande:
1) cosa faccio nel caso rappresentato dal primo costruttore?
2) cosa faccio nel caso rappresentato dal secondo costruttore?

traduzione:
1) cosa faccio nel caso particolare in cui come albero mi arriva solamente un nodo senza figli?
2) cosa faccio altrimenti in generale?

ovviamente devi considerare prima i casi base e poi quelli induttivi.

se non sai cos'é l'induzione strutturale probabilmente non avrai capito niente
peró almeno questo post ti avrá dato un punto di partenza per capire le funzioni ricorsive: studia l'induzione strutturale e le capirai perfettamente
fero86 è offline   Rispondi citando il messaggio o parte di esso
Old 10-02-2010, 20:35   #6
fero86
Senior Member
 
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
tra l'altro chi l'ha detto che gli alberi binari vanno trattati con la ricorsione?

in programmazione funzionale si parla di tail-call optimization, un'ottimizzazione che permette di convertire algoritmi ricorsivi di un certo tipo in algoritmi iterativi. in genere gli algoritmi sugli alberi binari possono essere convertiti in algoritmi iterativi. per esempio é possibile visitare iterativamente un albero binario (scusa se non ti scrivo il codice di esempio ma é troppo complicato la versione ricorsiva é 100 volte piu semplice).
fero86 è offline   Rispondi citando il messaggio o parte di esso
Old 10-02-2010, 20:39   #7
fero86
Senior Member
 
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
comunque cambia il titolo: il C non c'entra niente con questi argomenti, lascia perdere il fatto che qualche troglodita all'universitá te li sta facendo studiare utilizzando il C

puoi lasciare il subject senza alcun tag, se cionci mi conferma: l'uso tag é stato introdotto in questa sezione per quegli utenti che credono che nell'universo esiste solo quello che fanno loro e se ne escono con 2 pagine di supercazzola pretendendo un universo di aiuti e una soluzione istantanea ad un problema tecnico molto specifico di una sola piattaforma senza aver neanche specificato la piattaforma. questa invece é una questione teorica, addirittura uno dei pilastri portanti dell'informatica.
fero86 è offline   Rispondi citando il messaggio o parte di esso
Old 11-02-2010, 15:11   #8
xxxyyy
Senior Member
 
L'Avatar di xxxyyy
 
Iscritto dal: Apr 2002
Messaggi: 4401
Hummm...

vi scrivo un esempio "trovare la profondita' di un abero binario":

typedef struct NodoAlbero {
Tipo dato;
struct NodoAlbero *left;
struct NodoAlbero *right;
} nodo;
typedef nodo *tree;

int depth ( tree t )
{
int D, S;
if (t == NULL)
return 0;
S = depth( t->left );
D = depth( t->right );
if ( S > D )
return S + 1;
else
return D + 1;
}

Come si fa ad arrivare al ragionamento induttivo? La condizione base, perche' non si metta, ad esempio, anche:

if t->left==NULL && t->right==NULL return 1?

Fini a dove si deve arrivare aspecificare le condizioni base?

Un programma che non riesco proprio a fare e' "sapere se due alberi binari contengono gli stessi elementi (trascurando le ripetizioni)" (alberi ovviamente con numero di nodi differenti, in generale)
Come (diavolo) di fa?
xxxyyy è offline   Rispondi citando il messaggio o parte di esso
Old 11-02-2010, 15:24   #9
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Puoi mettere anche:

if(t->left==NULL && t->right==NULL) return 1;

Ha perfettamente senso.
Però devi gestire anche il caso dell'albero vuoto (passo 0 del ragionamento induttivo), quindi quella sopra te la puoi risparmiare perché comunque quando depth verrà richiamata su t->left e t->right tornerebbe zero e di fatto la funzione avrebbe comunque 1 come valore di ritorno.
Ci sono anche casi in cui la condizione di arresto è molto più complicata. Non sempre è semplice come quella sopra.

Inoltre la funzione sopra ti dovrebbe ritornare almeno un warning perché manca il return in fondo alla funzione (anche se non verrà mai raggiunto).
Codice:
if ( S > D )
   return S + 1;

return D + 1;
Secondo me l'ultimo quesito ha non c'entra niente con la ricorsione (o meglio c'entra solo di riflesso).
Sai ricercare un elemento all'interno di un albero ? Mi immagino di sì. Sai fare una qualsiasi visita dell'albero (anticipata, simmetrica, posticipata) ? Mi immagino di sì. Quindi il problema è già risolto.
Ogni volta in cui ti trovi in un nodo non NULL, fai una ricerca sull'altro albero. Se non l'elemento non viene trovato allora ritorni false e termini la visita.
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 11-02-2010, 18:11   #10
xxxyyy
Senior Member
 
L'Avatar di xxxyyy
 
Iscritto dal: Apr 2002
Messaggi: 4401
Quote:
Originariamente inviato da cionci Guarda i messaggi
Sai fare una qualsiasi visita dell'albero (anticipata, simmetrica, posticipata) ? Mi immagino di sì. Quindi il problema è già risolto.


la funzione di ricerca nell'albero ce l'ho gia' fatta... e capita come funziona... ma da li a scriverla io...

xxxyyy è offline   Rispondi citando il messaggio o parte di esso
Old 11-02-2010, 19:01   #11
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12966
Quote:
Originariamente inviato da xxxyyy Guarda i messaggi


la funzione di ricerca nell'albero ce l'ho gia' fatta... e capita come funziona... ma da li a scriverla io...

Qual è la condizione base per cui è elementare la soluzione del problema?

Come ha detto cionci è l'albero vuoto. Ragiona su questo.

L'albero vuoto che profondità ha?
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 11-02-2010, 21:08   #12
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Quote:
Originariamente inviato da xxxyyy Guarda i messaggi


la funzione di ricerca nell'albero ce l'ho gia' fatta... e capita come funziona... ma da li a scriverla io...

Scrivimi questa:
trovare quante volte un dato valore è ripetuto all'interno dell'albero.

Descrivimi a parole il ragionamento (prima di scrivere qualsiasi codice).
Ricordati di analizzare: passo 0, passo 1 e passo N. Al pari di una dimostrazione per induzione.
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 11-02-2010, 21:22   #13
xxxyyy
Senior Member
 
L'Avatar di xxxyyy
 
Iscritto dal: Apr 2002
Messaggi: 4401
Quote:
Originariamente inviato da cionci Guarda i messaggi
Scrivimi questa:
trovare quante volte un dato valore è ripetuto all'interno dell'albero.

Descrivimi a parole il ragionamento (prima di scrivere qualsiasi codice).
Ricordati di analizzare: passo 0, passo 1 e passo N. Al pari di una dimostrazione per induzione.
Se non c'e albero, 0.
Se c'e' solo la radice, 1.
E poi?
Vado a sinistra... e tengo la somma incrementando una variabile quando trovo l'elemento, se no vado a destra e faccio la stessa cosa.
Alla fini ritorno la variabile.







,
xxxyyy è offline   Rispondi citando il messaggio o parte di esso
Old 11-02-2010, 21:32   #14
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Il passo N esprimilo sotto forma di formula. f(p, v) è la funzione e p è il puntatore, v è il valore da cercare.

Il passo 1 non mi torna (stai attento perché non sempre il passo 1 va espresso in codice). Perché ritorni 1 ?
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 12-02-2010, 14:26   #15
xxxyyy
Senior Member
 
L'Avatar di xxxyyy
 
Iscritto dal: Apr 2002
Messaggi: 4401
Quote:
Originariamente inviato da cionci Guarda i messaggi
Il passo N esprimilo sotto forma di formula. f(p, v) è la funzione e p è il puntatore, v è il valore da cercare.

Il passo 1 non mi torna (stai attento perché non sempre il passo 1 va espresso in codice). Perché ritorni 1 ?
Ritorno 1 perche' se c'e' solo un elemento nell'albero... c'e' solo lui e il risultato e' 1.

Non saprei proprio da dove incominciare per fare il passo generico...

PS: la funzione che mi cerca un elemento nell'albero la so fare (nel senso che ce l'ho gia' fatta e ho capito piu' o meno come funziona).
xxxyyy è offline   Rispondi citando il messaggio o parte di esso
Old 12-02-2010, 14:28   #16
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Quote:
Originariamente inviato da xxxyyy Guarda i messaggi
Ritorno 1 perche' se c'e' solo un elemento nell'albero... c'e' solo lui e il risultato e' 1.
E chi ti dice che sia l'elemento che stavi cercando ?
Devi analizza i dati che hai a disposizione al passo generico:
- il valore del nodo corrente
- il numero di ricorrenze nel sotto albero destro (dando per scontato che il valore ritornato sia corretto, così come si fa nelle dimostrazioni per induzione al passo generico)
- il numero di ricorrenze nel sotto albero sinistro

Ultima modifica di cionci : 12-02-2010 alle 14:31.
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 12-02-2010, 15:04   #17
xxxyyy
Senior Member
 
L'Avatar di xxxyyy
 
Iscritto dal: Apr 2002
Messaggi: 4401
No aspetta... non stavamo facendo la funzione che mi diceva quante volte un elemento e' ripetuto in un albero?

Comunque, a me servirebbe capire questo:
Ho la funzione che mi dice se un elemento particolare c'e' o non c'e' in un albero.

Se l'albero sinistro e' vuoto, e quello destro pure, ritorno 1, sono uguali.
Se il sinistro e' vuoto e il destro no, ritorno 0.

Ora mi metto sul primo elemento dell'albero sinistro (la radice) e controllo che ci sia nel destro. Se c'e', 1. Se non c'e', 0.

Adesso come faccio a controllare, a fissare, gli altri elementi dell'albero sinistro e farli passare tutti? e farli controllare tutti con quelli dell'albero destro?
xxxyyy è offline   Rispondi citando il messaggio o parte di esso
Old 12-02-2010, 15:08   #18
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Quote:
Originariamente inviato da xxxyyy Guarda i messaggi
No aspetta... non stavamo facendo la funzione che mi diceva quante volte un elemento e' ripetuto in un albero?
Sì appunto.
Continuiamo un secondo con questa.
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 12-02-2010, 15:15   #19
xxxyyy
Senior Member
 
L'Avatar di xxxyyy
 
Iscritto dal: Apr 2002
Messaggi: 4401
Be', allora, se l'elemnto non e' quello cercato, ritorno 0.
Se e' quello cercato, 1.
Parlo sempre della radice dell'albero.
Il passo successivo?
Potrei cercarlo sul ramo sinistro e se lol trovo incremento una variabile contatore.
Poi sul destro.
E poi ritorno questa varabile contatore.
xxxyyy è offline   Rispondi citando il messaggio o parte di esso
Old 12-02-2010, 15:22   #20
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Assumiamo che la funzione ritorni correttamente il numero di ricorrenze in un albero.

Non pensare al passo successivo pensa al passo generico in cui tu hai a disposizione solamente il nodo corrente.
Dal punto di vista logico quante saranno le occorrenze in un albero composto dal nodo corrente e dai suoi due sottoalberi siniistro e destro.
cionci è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Sony INZONE H6 Air: il primo headset open-back di Sony per giocatori Sony INZONE H6 Air: il primo headset open-back d...
Nutanix cambia pelle: dall’iperconvergenza alla piattaforma full stack per cloud ibrido e IA Nutanix cambia pelle: dall’iperconvergenza alla ...
Recensione Xiaomi Pad 8 Pro: potenza bruta e HyperOS 3 per sfidare la fascia alta Recensione Xiaomi Pad 8 Pro: potenza bruta e Hyp...
NZXT H9 Flow RGB+, Kraken Elite 420 e F140X: abbiamo provato il tris d'assi di NZXT NZXT H9 Flow RGB+, Kraken Elite 420 e F140X: abb...
ASUS ROG Swift OLED PG34WCDN recensione: il primo QD-OLED RGB da 360 Hz ASUS ROG Swift OLED PG34WCDN recensione: il prim...
L'IA ha fatto incetta anche di processor...
Affidabilità delle GPU NVIDIA cro...
Maxi incendio in un parcheggio BYD: fiam...
Apple potrebbe diventare il terzo produt...
L'IA aiuta i computer quantistici con i ...
Nutanix Database Platform è ora i...
iliad lancia il 5G Standalone in Italia:...
Alexa+ da oggi disponibile anche in Ital...
SpaceX Starship: Ship 39 ha eseguito il ...
Auto usate: Peugeot 3008 tra le peggiori...
YMTC, il produttore di memorie 100% cine...
I gamer rinunciano alla RAM ma non agli ...
Oltre 100 estensioni Chrome malevole rub...
Multi Frame Generation 5x e 6x anche su ...
Kraken sotto ricatto dopo due accessi in...
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: 23:42.


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