In solchen Dingen ist es oft einfacher, rückwärts zu denken. Überlegen Sie also zuerst, was Sie brauchen. Lassen Sie uns anhand Ihrer Beschreibung Folgendes auflisten:
- Rekursion
- Gültigkeit
- Anzahl der vollständigen Knoten
OK, das ist eine ziemlich kurze Liste, diese sollte überschaubar sein. Beginnen wir mit einer leeren Methode und fügen eine Beschreibung hinzu, was passieren soll.
valid_bst () {
}
Jetzt Gültigkeit. Wie prüft man die Gültigkeit? Im Chat sagten Sie, ein Baum sei gültig, "wenn ... alle linken Kinder kleiner als die Eltern sind und die rechten Kinder größer als die Eltern". Ich bin sicher, Sie wollten auch Gleichheit zulassen. Das wäre t.left.value <= t.value <= t.right.value
.
valid_bst () {
This node is valid if t.left.value <= t.value <= t.right.value
}
Aber was ist, wenn eines der Kinder vermisst wird? Nach allem, was Sie gesagt haben, wissen Sie, dass der Knoten noch gültig ist, wenn einer fehlt (oder beide fehlen). Fügen wir dies hinzu und strukturieren uns leicht um:
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, wir wissen jetzt, ob dieser Knoten gültig ist. Wie prüfen wir, ob der gesamte Baum gültig ist? Es befindet sich nicht in einem Array, daher können / wollen wir es wahrscheinlich nicht linear durchlaufen. Ihre Aufgabe gibt die Antwort: Rekursion. Aber wie akkumulieren wir eine Antwort durch Rekursion? Wir haben Zugriff auf drei Informationen, ob dieser Knoten gültig ist, und das Ergebnis von Aufrufen, in denen gefragt wird, ob der linke und der rechte Knoten gültig sind. Offensichtlich ist der Baum nur gültig, wenn alle drei wahr sind.
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.
}
Wenn Sie aufpassen, sagt uns das sogar, was unsere Funktion zurückgeben muss.
Wie integrieren wir nun die Zählung? Sie sagen, was zählt ("ein übergeordneter Knoten mit linken und rechten untergeordneten Knoten"), und das sollte nicht schwer in tatsächlichen Code zu übersetzen sein. Überprüfen Sie, ob diese Bedingung erfüllt ist, und erhöhen Sie den Zähler entsprechend. Denken Sie daran, dass dies irgendwo sein muss, wo es jedes Mal erreicht wird, wenn es wahr ist.
Und natürlich habe ich einige Details wie die Rekursionsstoppbedingung weggelassen und nach Null gesucht.
<
auf Knoten definiert?