Come si può scrivere un iteratore Java (cioè bisogno della next
e hasNext
metodi) che prende la radice di un albero binario e scorre attraverso i nodi dell'albero binario in in ordine moda ?In ordine iteratore per albero binario
risposta
Il primo elemento di un sottostruttura è sempre il più a sinistra. L'elemento successivo dopo un elemento è il primo elemento della sottostruttura di destra. Se l'elemento non ha un figlio destro, l'elemento successivo è il primo antenato di destra dell'elemento. Se l'elemento non ha né un figlio destro né un antenato destro, è l'elemento più a destra ed è l'ultimo in iterazione.
Spero che il mio codice sia leggibile dall'uomo e copra tutti i casi.
public class TreeIterator {
private Node next;
public TreeIterator(Node root) {
next = root;
if(next == null)
return;
while (next.left != null)
next = next.left;
}
public boolean hasNext(){
return next != null;
}
public Node next(){
if(!hasNext()) throw new NoSuchElementException();
Node r = next;
// If you can walk right, walk right, then fully left.
// otherwise, walk up until you come from left.
if(next.right != null) {
next = next.right;
while (next.left != null)
next = next.left;
return r;
}
while(true) {
if(next.parent == null) {
next = null;
return r;
}
if(next.parent.left == next) {
next = next.parent;
return r;
}
next = next.parent;
}
}
}
Si consideri il seguente albero:
d
/ \
b f
/\ /\
a c e g
- Il primo elemento è "completamente a sinistra dalla radice"
a
non hai figlio destro, quindi l'elemento successivo è "up fino a quando non vieni da sinistra "b
ha un figlio destro, quindi itera la sottostruttura di destrac
non ha un figlio giusto. È genitore èb
, che è stato attraversato. Il prossimo genitore èd
, che non è stato attraversato, quindi fermati qui.d
ha una sottostruttura giusta. Il suo elemento più a sinistra èe
.- ...
g
non ha sottostruttura di destra, quindi camminare.f
è stato visitato, poiché siamo venuti da destra.d
è stato visitato.d
non ha genitore, quindi non possiamo andare oltre. Siamo arrivati dal nodo più a destra e abbiamo finito di ripetere.
C'era una ragione per cui non ho inserito un iteratore valido nella mia risposta, ed era così che l'OP avrebbe dovuto farlo da sé. Dare risposte come queste non giova a nessuno. –
@HunterMcMillen buon punto. Howerer, questa non è comunque una copia e incolla. Almeno una riga deve essere cambiata ;-) ma confesso che non è stata deliberata. Il mio obiettivo era la leggibilità, non la correttezza. Non l'ho nemmeno provato ;-) –
Adoro la tua idea di archiviare il prossimo. Potevo solo pensare di memorizzare il nodo corrente, non il prossimo, e stavo avendo così tanti problemi a trovare un modo per stampare il primo elemento. Grazie. – Variadicism
E 'piuttosto semplice, per l'attraversamento in ordine di visitare il figlio sinistro se ce n'è uno, quindi il nodo radice, allora il bambino a destra:
visit_node(node)
if node.left: visit_node(node.left)
// visit the root node
if node.right: visit_node(node.right)
Diagramma:
a
/ \ (in-order traversal would give bac)
b c
Ma quando si scrive un iteratore (ad esempio un iteratore Java che richiede i metodi 'next' e' hasNext'), come si può incorporare un metodo ricorsivo come quello? –
@PaulSeangwongree: puoi sempre prendere i nodi in ordine e aggiungerli a qualche altra raccolta. –
Per ottenere la voce successiva, 'nextEntry()', per l'iteratore, ho guardato i frammenti da java.util.TreeMap
incollati di seguito. In parole povere, direi che assicuri che il nodo radice non sia nullo, altrimenti restituisca null. Se non lo è, consulta il nodo giusto se non è nullo. Quindi visita la sinistra (se non è nullo) e visita quella sinistra ripetutamente in un ciclo while fino a colpire null. Se il nodo destro originale è nullo, invece di tutto ciò, visitare il nodo genitore se non è nullo. Ora inserisci un ciclo while in cui visiti il genitore finché non è nullo o il nodo che stai visitando ha il nodo destro (figlio) uguale alla tua ultima posizione. Ora restituisci qualunque voce tu stia visitando. In mancanza di tutte queste opzioni, restituisce il nodo root (originale). 'HasNext()' si limita a verificare se questa "voce successiva" che si sta restituendo è nullo o no.
public final boolean hasNext() {
return next != null;
}
final TreeMap.Entry<K,V> nextEntry() {
TreeMap.Entry<K,V> e = next;
if (e == null || e.key == fenceKey)
throw new NoSuchElementException();
if (m.modCount != expectedModCount)
throw new ConcurrentModificationException();
next = successor(e);
lastReturned = e;
return e;
}
static <K,V> TreeMap.Entry<K,V> successor(Entry<K,V> t) {
if (t == null)
return null;
else if (t.right != null) {
Entry<K,V> p = t.right;
while (p.left != null)
p = p.left;
return p;
} else {
Entry<K,V> p = t.parent;
Entry<K,V> ch = t;
while (p != null && ch == p.right) {
ch = p;
p = p.parent;
}
return p;
}
}
Sì, l'ho fatto. Per favore pubblica il tuo e potrebbe essere la risposta accettata se uguale o migliore alla mia spiegazione. In realtà afferma nel file TreeMap.java compresso con il jdk che il codice è properietary. Se questo è il caso, dirò che ~ 30 linee su 2400 sono fair use per scopi educativi. – apcris
Ho pubblicato la mia risposta. –
Non sono sicuro che la trascrizione aiuti a capire ... –
- 1. Implementazione di un iteratore su un albero di ricerca binario
- 2. Determinare se un albero binario è sottostruttura di un altro albero binario utilizzando le stringhe pre-ordine e in ordine
- 3. Un albero non binario può essere percorso in ordine?
- 4. Albero binario Ricerca in ampiezza
- 5. albero binario implementazione in Ruby
- 6. Differenza tra albero binario completo e albero binario bilanciato
- 7. Albero binario dall'albero generale
- 8. stampa confine albero binario
- 9. Trasferimento ad albero binario
- 10. Albero di ricerca binario su albero AVL
- 11. Un albero binario contiene un altro albero?
- 12. Creazione albero somma di albero binario Scala
- 13. C# - Albero binario semplice
- 14. Albero di ricerca binario per intenzioni specifiche
- 15. albero binario rappresentata utilizzando matrice
- 16. Albero binario di espressioni matematiche
- 17. Programmazione genetica ad albero binario
- 18. albero binario metodi statici in Java
- 19. Trova un loop in un albero binario
- 20. Implementazione di un iteratore di albero depth-first in Python
- 21. eliminazione ricorsiva su un albero binario
- 22. Costruire un albero binario bilanciato con foldr
- 23. stampa un albero binario su un lato
- 24. GraphViz albero binario destro e sinistro bambino
- 25. BIT: utilizzando un albero indicizzato binario?
- 26. Come implementare un albero non binario
- 27. Iteratore inverso per elenco?
- 28. Come eliminare elementi in un albero binario in C?
- 29. Come convertire un albero binario in un albero di ricerca binario sul posto, cioè non possiamo usare alcuno spazio aggiuntivo
- 30. Come si crea un albero di ricerca binario in Clojure?
Penso che la domanda sia abbastanza chiara, se si sa cos'è un albero binario e si ha esperienza nell'analizzarle. – ilomambo
Penso che sia la vera domanda, va bene. Probabilmente avrebbe dovuto essere invece chiuso come troppo ampio. –