このような場合、多くの場合、後向きに考える方が簡単なので、まず必要なものを検討します。あなたの説明から、それらをリストしましょう:
OK、これはかなり短いリストですが、これは扱いやすいはずです。空のメソッドから始めましょう。何が発生するのかについての説明を追加します。
valid_bst () {
}
今妥当性。どのように有効性をチェックしますか?チャットで、ツリーは有効であると言いました。「...左のすべての子が親よりも小さく、右の子が親よりも大きい場合」あなたも平等を認めるつもりだったと思います。それはでしょうt.left.value <= t.value <= t.right.value
。
valid_bst () {
This node is valid if t.left.value <= t.value <= t.right.value
}
しかし、子どもの一人が行方不明になった場合はどうなりますか?あなたが言ったことから、一方が欠落している(または両方が欠落している)場合でも、ノードはまだ有効であることがわかります。これを追加して、少し再構成します。
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.
}
これで、このノードが有効かどうかがわかりました。ツリー全体が有効かどうかを確認するにはどうすればよいですか?それは配列にないので、線形にループすることはおそらくできません。あなたの割り当ては答えを与えます:再帰。しかし、再帰を使用してどのように答えを蓄積するのでしょうか?このノードが有効かどうか、および左右のノードが有効かどうかを尋ねる呼び出しの結果の3つの情報にアクセスできます。明らかに、ツリーはこれら3つすべてが真である場合にのみ有効です。
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.
}
あなたが注意を払っているなら、それは私たちの関数が返す必要があるものを教えてくれます。
では、どのようにカウントを統合しますか?あなたは何が重要であるか(「左と右の両方の子ノードを持つ親ノード」)を言います、そしてそれは実際のコードに変換することは難しくありません。その条件が満たされているかどうかを確認し、カウンターを適切に増分します。これが本当であるたびに到達するどこかにある必要があることを覚えておいてください。
そしてもちろん、再帰の停止条件やnullのチェックなど、いくつかの詳細は省略しました。
<
ノードで比較演算子はどのように定義されますか?