2017-01-18 8 views
1

タイトルに記載されているとおり、私は左と右の両方の子を持つBSTのノードを数えるだけでこの問題を解決しようとしています。私はこれを解決するための論理を考えるのに苦労しています。BST - 左と右の子を持つノードのカウント

私はこのようなことを考えました。

まず、ルートがnullかどうか、またはnullの子があるかどうかを確認します。次に、右に向かうツリーをたどって、子供をチェックし続け、条件が満たされたらカウンタを増分します。しかし、私が最終ノードに到達して、左の子が横断するノードに戻る必要がある場合はどうなりますか?私は一番前の親を追跡する一時ノードを持っていましたが、複数のレベルを上がる必要があるのはどうですか?私はこの問題に対する答えは再帰的に解決することを前提としていますが、どこから始めるべきか分かりません。ここで

は、私が持っているものです。

public int fullNodes() { 
    int count = 0; 
    Node n = root; 
    Node temp = null; 

    if (n == null || n.left == null && n.right == null) return count; 

    count++; //increment count, since the root has children on both sides 

    temp = n; //hold the previous place 
    n = n.right; //go right 

    //Now what? 

    return count; 
} 

私はまだ問題解決には、私の質問に加えて、どのように再帰的に考えることを学ぶないとき再帰的に考えるのに苦労していますか?ちょっとした練習、または問題を解決するために使うテクニックやヒントがありますか?

+1

バイナリツリーを持っていて、 eftとright子供?左側のサブツリー(存在する場合)の答えをすでに知っていて、右側のサブツリー(存在する場合)の回答をすでに知っているとします。あなたが両方の答えを知っているなら、あなたは木全体の答えをどのように計算しますか?それだけに焦点を当て、ツリーをどのように横断するか心配しないでください。それは再帰的に考えることができます。 – ajb

+0

nodesWithLeftAndRight(node):nodeがnullの場合、結果はゼロです。そうでない場合、結果はnodeWithLeftAndRight(左ノード)+ nodeWithLeftAndRight(右ノード)+(左ノードと右ノードの両方がヌルでない場合は1、その他の場合は0) –

答えて

1

以前のノードを保持するために一時変数を使用するのではなく、1の深さでしか動作しません。子ノードで同じ関数を呼び出します

再帰ツリートラバーサルは次のようになります:

public int countSomething (Node node) { 

    // Self; 
    // 
    int result = 1; // use your required logic here 

    // Children; 
    //  
    if (node.left != null) 
     result += countSomething(node.left); 
    if (node.right != null) 
     result += countSomething(node.right); 

    // done. 
    return result; 
} 


// example usages 
int treeTotal = countSomething(rootNode); 
int subtreeTotal = countSomething(subtree); 

実行コールスタックは、関数の再帰的呼び出し、その適切なコンテキストでそれぞれ開催します。トップレベルの呼び出しが返されると、呼び出されたツリー全体またはサブツリーに対する答えが合計されます。

ごBSTのための適切なロジックを置く代わりに、一定1.

+0

これはノードがカウントは上がる?もしそうなら、どこ?ここで何が起こっているのかちょっと混乱しています。 – 23k

+0

@ 23kこのメソッドは再帰を示していますが、私はあなたのためにすべての作業をしたくありませんでした。コードとその答えの両方に、ノード単位の規則を記述する必要があります。 –

+0

もちろん、私はあなたのコードがコメントだけでなく何をしているのか真に混乱しています。多分それは明らかに明白ですが、私はそれを見逃しているようです。 – 23k

1

の最初は、私たちが書く私たちは、その後、あなたのNodeクラスの表現

class Node { 
    public Node left; 
    public Node right; 
    public Node(){} 
    public Node(Node left, Node right) { 
     this.left = left; 
     this.right = right; 
    } 
} 

を作成してみましょう、の「ノードが&右子ども左の両方を持っています」私たちのrecusrive関数とあなたの関数を使っているクライアント

関連する問題