|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: Aug 2010
Messaggi: 138
|
[JAVA] problemi alberi binari
Ho risolto un'esercizio , ma non sono scuro che sia giusto.
Posto la traccia e la soluzione (sperando in qualche correzione): Codice:
Si consideri una classe AlberoB che rappresenta alberi binari in cui la parte
informativa di ogni nodo è un numero intero.
Si assuma che in tale classe siano implementati i seguenti metodi:
public interface AlberoB {
/* restituisce il sottoalbero destro dell’albero corrente/
public AlberoB destro( );
/* restituisce il sottoalbero sinistro dell’albero corrente*/
public AlberoB sinistro( );
/* restituisce il valore memorizzato nella radice dell’albero */
public int val( );
}
Si deve realizzare un metodo public static boolean eRipetuto (AlberoB a, int x) {…} che restituisce true se e solo se vi è almeno un nodo n nell’albero a tale che l’intero x appare sia nel sottoalbero sinistro che nel sottoalbero destro di n. soluzione: Codice:
public static boolean eRipetuto (AlberoB a, int x) {
if(a.val()==null)return false;
if(a.sinistro().val()==x && a.destro().val()==x) return true;
return eRipetuto (a.destro( ),x) || eRipetuto (a.sinistro( ),x);
}
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
mi sembra molto più semplice fare una visita iterativa dei due sottoalberi piuttosto che risolverlo ricorsivamente
|
|
|
|
|
|
#3 |
|
Member
Iscritto dal: Aug 2010
Messaggi: 138
|
no
devo farlo ricorsivo
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
non ha molto senso imho
|
|
|
|
|
|
#5 |
|
Member
Iscritto dal: Aug 2010
Messaggi: 138
|
che significa che non ha senso?
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
|
ha perfettamente senso invece: gli alberi binari sono strutture definite induttivamente, quindi é naturale che anche gli algoritmi su di essi siano definiti induttivamente (cioé che siano ricorsivi).
posto la mia soluzione non testata: Codice:
private boolean find(int x) {
if (val() == x) {
return true;
} else {
return destro().find(x) || sinistro().find(x);
}
}
public boolean eRipetuto(int x) {
if (destro().find(x)) {
if (sinistro().find(x)) {
return true;
} else {
return destro().eRipetuto(x);
}
} else {
if (sinistro().find(x)) {
return sinistro().eRipetuto(x);
} else {
return false;
}
}
}
__________________
3D Volley Demo (Facebook) | Reversi (Facebook) | Blockout (Facebook) | Puzzle15 (Facebook) Ultima modifica di fero86 : 05-08-2010 alle 00:00. |
|
|
|
|
|
#7 |
|
Member
Iscritto dal: Feb 2010
Messaggi: 31
|
.
__________________
-.-'' |
|
|
|
|
|
#8 | |
|
Member
Iscritto dal: Aug 2010
Messaggi: 138
|
Quote:
|
|
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
Quote:
|
|
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: Feb 2007
Città: Verona
Messaggi: 1060
|
Quote:
Metodi iterativi su alberi? che scherziamo?Mia congettura pronta per essere smontata: possiamo dire che andando a contare i nodi all'interno dell'albero a che hanno il valore x, se ne troviamo almeno due, eRipetuto(a, x) deve restituire true? Ho pensato che se in uno stesso albero esistono (almeno) due nodi con il valore x, possiamo trovare il genitore comune a quei due nodi. Dato il genitore comune, sappiamo che nel suo sottoalbero di destra e in quello di sinistra ci sono due nodi con lo stesso valore, quindi "vi è almeno un nodo n nell’albero a tale che l’intero x appare sia nel sottoalbero sinistro che nel sottoalbero destro di n" Per "genitore comune tra due nodi" intendo il nodo radice del sottoalbero più piccolo che contiene i due nodi.
__________________
|
|
|
|
|
|
|
#11 | ||
|
Senior Member
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
|
Quote:
Quote:
|
||
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
|
no, non possiamo: uno dei due nodi di valore x potrebbe essere il padre diretto dell'altro nodo, nel qual caso, se la mia interpretazione della traccia é corretta, il metodo deve restituire false.
|
|
|
|
|
|
#13 | |
|
Senior Member
Iscritto dal: Feb 2007
Città: Verona
Messaggi: 1060
|
Quote:
ccc'hai ragggione
__________________
|
|
|
|
|
|
|
#14 |
|
Member
Iscritto dal: Aug 2010
Messaggi: 138
|
si va bene Codice:
public static boolean eRipetuto (AlberoB a, int x) {
if(a.val()==null)return false;
if(a.sinistro().val()==x && a.destro().val()==x) return true;
return eRipetuto (a.destro( ),x) || eRipetuto (a.sinistro( ),x);
}
Ultima modifica di Gin&&Tonic : 05-08-2010 alle 10:00. |
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
no perché la condizione "a.sinistro().val()==x && a.destro().val()==x" non vuol dire "x è nel sottoalbero sinistro e nel destro", ma vuol dire "il nodo ha due figli che hanno valore x", dovresti visitare i due sottoalberi e vedere se c'è x, così sarebbe corretto (però sarebbe comunque meno efficiente della soluzione di fero, che effettua la chiamata ricorsiva solo nel sottoalbero in cui c'è almeno un nodo x)
|
|
|
|
|
|
#16 | |
|
Senior Member
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
|
Quote:
comunque, volendo mettere i puntini sulle i, anche la mia soluzione é sbagliata in quel caso base perché non ho fatto alcun controllo per vedere se i sottoalberi esistono o meno, di conseguenza immagino che la mia soluzione lanci una NullPointerException posto di seguito una versione piu completa: Codice:
interface AlberoB {
AlberoB destro();
AlberoB sinistro();
int val();
boolean eRipetuto(int x);
}
abstract class AlberoBImpl implements AlberoB {
public boolean find(int x);
}
final class AlberoVuoto extends AlberoBImpl {
AlberoB destro() {
throw IllegalStateException();
}
AlberoB sinistro() {
throw IllegalStateException();
}
public int val() {
throw IllegalStateException();
}
public boolean find(int x) {
return false;
}
public boolean eRipetuto(int x) {
return false;
}
}
final class AlberoNonVuoto extends AlberoBImpl {
private final AlberoBImpl destro;
private final AlberoBImpl sinistro;
private final int valore;
public AlberoNonVuoto() {
...
}
AlberoB destro() {
return destro;
}
AlberoB sinistro() {
return sinistro;
}
public int val() {
return valore;
}
public boolean find(int x) {
if (val() == x) {
return true;
} else {
return destro().find(x) || sinistro().find(x);
}
}
public boolean eRipetuto(int x) {
if (destro().find(x)) {
if (sinistro().find(x)) {
return true;
} else {
return destro().eRipetuto(x);
}
} else {
if (sinistro().find(x)) {
return sinistro().eRipetuto(x);
} else {
return false;
}
}
}
}
|
|
|
|
|
|
|
#17 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
[OT]
Perchè, non si possono avere metodi iterativi sugli alberi? In genere, una funzione ricorsiva può essere tradotta in una equivalente ma in forma iterativa. E a volte ci possono essere buone ragioni per farlo (basti considerare che i metodi di tree traversal ricorsivi richedono spazio sullo stack proporzionale alla profondità dell'albero...) Mi sono perso qualcosa, o mi sto confondendo con qualcos'altro?
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 05-08-2010 alle 17:42. |
|
|
|
|
|
#18 | |
|
Senior Member
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
|
Quote:
2) early optimization is the root of all evil |
|
|
|
|
|
|
#19 | |
|
Senior Member
Iscritto dal: Feb 2007
Città: Verona
Messaggi: 1060
|
Quote:
Comunque la vedo ostica trasformare una DFS da ricorsiva a iterativa ![]() Inoltre, statisticamente parlando penso possiamo dire che la profondità di un albero cresce logaritmicamente rispetto al numero dei nodi...
__________________
|
|
|
|
|
|
|
#20 | |
|
Senior Member
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
|
Quote:
Vedo più problematica la BFS (visita per livelli, nel caso degli alberi), ma anche là non è difficilissimo: basta usare una coda invece di uno stack.
__________________
C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai! |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 13:42.












che scherziamo?
ccc'hai ragggione









