2016-10-22 10 views
1

私はテンプレート付きのbstクラスを作成しましたが、私はGetEnumeratorを実装しましたが、実際に何が行われたかに満足していません。再帰での収量

ので、最初私はヘルパー関数に、内側の訪問

private IEnumerable<Node<T>> innerVisit(Node<T> root) 
    { 
     if(root== null) 
     yield break; 

     if (root.Left != null) 
     { 
      var l = innerVisit(root.Left); 
      foreach (var item in l) 
       yield return item; 
     } 


     yield return root; 

     if (root.Right != null) 
     { 
      var r = innerVisit(root.Right); 
      foreach (var item in r) 
       yield return item; 
     } 


    } 

を必要と感じたすべての私は本当に繰り返しコードを嫌いますが、それ への適切な解決策を見つけることができませんでした、明確にループを繰り返すことは不浄であるだけでなく、私は、これに飛びつくような機能の下にそれを埋め込むと、それほど言わないことは悪い習慣になると感じています。どのようにこれを正しく行うための提案?

私がいないなど

答えて

2

をも私は

 public IEnumerator<Node<T>> GetEnumerator() 
    { 

     var res = innerVisit(_root); 

     foreach (var item in res) 
      yield return item; 

    } 

を書いた実装を完了しますが、それはあまりにも、それは、foreachループ内で動作しますことを確認することが悪いとハックのより感じ、同じような操作を繰り返さずに問題を解決できると思いますが、わかりやすい方法で実行できると思います。IEumerableを返すための要件の一部です。再帰的にやりたい利回り操作を行うことを妨げることはできません(ただし、自分ですべてを書く必要はありませんが、System.LINQがそれを助けます)。

foreachとyield yieldをEnumerable.Concatメソッドで置き換えることができます。これを使用して、ノード自身(現在のノードの1つのアイテムを持つ配列)と右のInnerVisitのために作成する左のInnerVisit IEnumerable、IEnumerable IEnumerableを:それがnullの場合、それは、内部呼び出しで、後でそれを確認しますので、あなたが再帰的なメソッドを呼び出す前に、我々はEnumerable.Empty<Node<T>>を代わりに返します左または右がnullであるかどうかを確認する必要がないことを

private IEnumerable<Node<T>> InnerVisit(Node<T> node) 
{ 
    if(node == null) 
    {   
     return Enumerable.Empty<Node<T>>; 
    } 
    return InnerVisit(node.Left).Concat(new[] { node }).Concat(InnerVisit(node.Right)); 
} 

お知らせあなたがしたように利回りを使用する。

我々はまた、このようなルートInnerVisit、何かの結果に直接GetEnumeratorメソッドを呼び出すことによって、GetEnumeratorメソッドを簡素化することができます。

public IEnumerator<Node<T>> GetEnumerator() 
{ 
    return InnerVisit(_root).GetEnumerator(); 
} 
+0

これが効果的にOPが書いたのと同じコード、ちょうど今ワンライナーです。あなたは、OPの懸案事項に対処していません。最初にやっていたことを効果的に行う構文を効果的に提示しました。 – Enigmativity

+0

"繰り返しコードが嫌いですが、適切な解決策を見つけることができませんでした"と、このコードはすべての歩留まりとforeachループを繰り返すわけではありません。彼はちょうど同じforeachを繰り返さず、場所全体にコードを生成したくない別のアルゴリズムを求めなかった。 – YuvShap

+0

'InnerVisit'を呼び出すたびに、それが要素であれば' yield'を呼び出すことになります。これはOPのコードと同じ回数だけ実行されます。そして、あなたは左に 'InnerVisit'を、右に' InnerVisit'を呼んでいます - これはコードの繰り返しです。これは効果的にOPと同じコードです。あなたはあなたのソリューションがどのように異なっているか説明しようとするべきです。 – Enigmativity