In cose come questa, è spesso più facile pensare all'indietro, quindi prima considera ciò di cui hai bisogno. Dalla tua descrizione, elenchiamoli:
- ricorsione
- Validità
- Conteggio dei nodi completi
OK, questo è un elenco abbastanza breve, questo dovrebbe essere gestibile. Cominciamo con un metodo vuoto e aggiungerò una descrizione di ciò che dovrebbe accadere.
valid_bst () {
}
Ora validità. Come si verifica la validità? Nella chat hai detto che un albero è valido "se ... tutti i bambini a sinistra sono inferiori al genitore e i bambini a destra sono maggiori del genitore". Sono sicuro che intendevi consentire anche l'uguaglianza. Quello sarebbe t.left.value <= t.value <= t.right.value
.
valid_bst () {
This node is valid if t.left.value <= t.value <= t.right.value
}
E se mancasse uno dei bambini? Da quello che hai detto, credo che tu sappia che il nodo è ancora valido se uno (o entrambi mancano). Aggiungiamo questo, ristrutturando leggermente:
valid_bst () {
This node is valid to the left if
there is no left child or
it is no greater than the current node.
This node is valid to the right if
there is no right child or
it is no less than the current node.
This node is valid overall if it is valid to the left and right.
}
OK, ora sappiamo se questo nodo è valido. Come controlliamo se l'intero albero è valido? Non è in un array, quindi probabilmente non possiamo / non vogliamo scorrere su di esso in modo lineare. Il tuo compito dà la risposta: ricorsione. Ma come accumuliamo una risposta usando la ricorsione? Abbiamo accesso a tre informazioni, se questo nodo è valido e il risultato di chiamate che chiedono se i nodi sinistro e destro sono validi. Ovviamente l'albero è valido solo se tutti e tre sono veri.
valid_bst () {
This node is valid to the left if
there is no left child or
it is no greater than the current node.
This node is valid to the right if
there is no right child or
it is no less than the current node.
This node is valid overall if it is valid to the left and right.
Is the left child valid?
Is the right child valid?
This tree is only valid if this node and both its children are.
}
Se stai prestando attenzione, questo ci dice anche ciò che la nostra funzione deve tornare.
Ora, come possiamo integrare il conteggio? Dici ciò che conta ("un nodo genitore con entrambi i nodi figlio destro e sinistro") e non dovrebbe essere difficile da tradurre in codice reale. Controllare se tale condizione è soddisfatta e incrementare il contatore in modo appropriato. Ricorda solo che questo deve essere da qualche parte dove sarà raggiunto ogni volta che è vero.
E ovviamente ho tralasciato alcuni dettagli come la condizione di arresto della ricorsione e la verifica di null.
<
definito l' operatore di confronto sui nodi?