2016-07-19 21 views
1

値がバイナリ検索ツリーに含まれているかどうかを確認しようとしていますが、再帰を使用してツリーをトラバースしています。問題は関数が真ではなく呼び出しスタックの最後の値としてfalseを返すことです。ここでJava return boolean true再帰を使用する

は擬似コードです:

public boolean containsValue(Node node, Value v) { 

    if (node.value.equals(v)) { 
    return true; 
    } 
    containsValue(node.left, v); // <- search left tree 
    containsValue(node.right, v); // <- search right tree 

    return false; 
} 

これは常にfalseを返します。二return文がデッドコードであるので、私はこれを行うことはできませんしかし

return containsValue(node.left, v); 
return containsValue(node.left, v); 

それでは、どのように私はこの問題を解決するのでしょうか?

答えて

3

ます。これは、現在のノードの値がパラメータ値と比較する方法をチェックします

public boolean containsValue(Node node, Value value){ 
    int result = node.value.compareTo(value); 
    if(result == 0){ 
     return true; 
    }else if(result < 0){ 
     if(node.left != null){ 
      return containsValue(node.left, v); 
     } 
     return false; 
    }else{ 
     if(node.right != null){ 
      return containsValue(node.right, v); 
     } 
     return false; 
    } 
} 

を行きます。パラメータ値が小さい場合は、左の子の結果を返します(<0)、同じ場合はtrueを返します(==0)、値渡しが大きい場合は、右の子(>0)の結果を返します。これは、値が見つかるまで、または検索が必要な子がnullになるまで続きます。

それはすべての変数をチェックして、Oの平均効率()N(ログ)を有していないので、この方法は、完全にバイナリ検索ツリーを利用だけのすべてのノードを通して見ることの平均効率を有するのに対しO(n)は非常に最悪です。

追記: その値を持つノードを取得する方法は、基本的に、あなただけのNode

例でnullbooleannodetruefalseを置き換えると同じである:一部の人々が愛する

public Node getNode(Node node, Value value){ 
    int result = node.value.compareTo(value); 
    if(result == 0){ 
     return node; 
    }else if(result < 0){ 
     if(node.left != null){ 
      return containsValue(node.left, v); 
     } 
     return null; 
    }else{ 
     if(node.right != null){ 
      return containsValue(node.right, v); 
     } 
     return null; 
    } 
} 
7

これはすぐに問題を解決しますが、左または右を見ることを決断しないので、バイナリツリーを検索するための正確で効率的な方法ではありません。その正解はhereです。


あなたは左のノードがそれを含んでいるか(||)右のノードがそれを含んでいる場合にtrueを返すようにしたいです。

return containsValue(node.left, v) || containsValue(node.right, v); 

また、左にそれが含まれていれば、短絡して右には見えないことに注意してください。

あなたも、全体のことを行うことができます。

return node.value.equals(v) || 
     containsValue(node.left, v) || 
     containsValue(node.right, v); 
+0

これはバイナリ検索ツリーを調べるための**間違った実装です。定義上、バイナリ検索ツリーの値は小さくなります。左に行くほど左に行くほど大きくなり、この方法ではこのプロパティを使用しないため、検索が非効率になります。 –

+0

@nickzoumあなたは大丈夫です!私はすぐに起こった問題を解決し、それが組織化された木であるということに取り組まなかった。私は、OPの変更があなたに受け入れられると、削除するつもりです。 – weston

+0

@Kingamere受け入れられた答えをニックネームに変更してください。 – weston

1

あなたはどちらかの分岐がtrueを返したかどうかを確認し、falseを返すようにしようとする前にそれに沿って渡すことができます。そこ

public boolean containsValue(Node node, Value v) { 

    if (node.value.equals(v)) { 
     return true; 
    } else if (containsValue(node.left, v)) { 
     return true; 
    } else if (containsValue(node.right, v)) { 
     return true; 
    } 

    return false; 
} 
0

ワンライナー:

public boolean containsValue(Node node, Value v) { 
    return node.value.equals(v) || containsValue(node.left, v) || containsValue(node.right, v); 
} 
0
public boolean containsValue(Node node, Value v) { 

    if (node.value.equals(v)) { 
    return true; 
    } 
    else if(containsValue(node.left, v)) 
    return true; // <- search left tree 

    else if(containsValue(node.right, v)) // <- search right tree 
    return true; 

    return false; 
} 

現在のところ、関数もtrueを返しますが、検索値と一致するノードに対してのみ、他のすべてのノードに対してはfalseを返します。したがって、コールスタック内で後方に/または上に移動しながら、最終的には最終的な答えとしてfalseを返します。ツリー内の1つのノードの場合にのみ正しくなり、検索値と一致します。