Invece di chiamare self.left/right.
in
_order_list()
, si sta chiamando self.left/right.
pre
_order_list()
.
per realizzare ciò che si vuole fare una funzione generatore potrebbe essere migliore (meno memoria lunga e più divinatorio) rispetto ad accumulare i valori in un elenco:
class Tree(object):
...
def in_order(self):
if self.left is not None:
for value in self.left.in_order():
yield value
yield self.value # <-- yielding the value of the node, not the node itself
if self.right is not None:
for value in self.right.in_order():
yield value
...
tree = Tree(...)
in_order_values = list(tree.in_order())
In questo modo, si don' t deve creare un elenco se desideri solo per scorrere i valori:
for value in tree.in_order():
...
l'algoritmo funziona così: il generatore prima discende ricorsivamente lungo il ramo sinistro di ogni nodo fino a quando non colpisce uno senza sub-sinistra nodo. Quindi restituisce il valore del nodo corrente. Dopo di ciò, fa lo stesso sul sub-nodo destro, ma a partire dal nodo corrente, non dal nodo radice. Se supponiamo che non ci siano cicli nell'albero e nessun ramo infinito, allora ci saranno sicuramente nodi foglia, cioè nodi senza sub-nodo sinistro o destro. Nodi IOW, per i quali sono stati raggiunti entrambi i casi di base (self.left/right is None
). Pertanto, le chiamate ricorsive torneranno, speriamo prima che la memoria sia esaurita o il limite massimo.
Il ciclo sopra self.left/right.in_order()
occorre dovuto al fatto che ciò che la chiamata alla in_order()
rendimenti è un generatore, quindi il funzionamento del generatore di nome . Il generatore restituito deve essere in qualche modo esaurito, ad es. attraverso un ciclo.Nel corpo del loop restituiamo i valori su un livello, dove vengono nuovamente restituiti, fino a raggiungere il livello più alto. Lì usiamo i valori.
Se si desidera recuperare i nodi themself invece di solo i loro campi di valore, si potrebbe fare così:
class Tree(object):
...
def in_order(self):
if self.left is not None:
for node in self.left.in_order():
yield node
yield self # <-- yielding the node itself
if self.right is not None:
for node in self.right.in_order():
yield node
Probabilmente vuole fare questo, perché non solo si può ancora accedere ai valori di i nodi:
for node in tree.in_order():
do_something_with(node.value)
ma anche si può fare quello che vuoi con i nodi:
for node in tree.in_order():
whatever(node.some_other_attribute)
Dove è pre elenco degli ordini definito.Qual è la struttura dati del grafico? –