2015-02-04 110 views
0

我上課喜歡遞歸和計算器

public class Question 
    { 
     private readonly int questionID; 
       private List<Question> similarquestions; // Similarity is bidirectional 
} 

讓所有的嵌套類我用的使用方法遞歸像

public static IEnumerable<T> Traversal<T>(
    T root, 
    Func<T, IEnumerable<T>> getChildren) 
{ 
    if (root == null) 
    { 
     yield break; 
    } 

    yield return root; 

    var children = getChildren(root); 
    if (children == null) 
    { 
     yield break; 
    } 

    foreach (var child in children) 
    { 
     foreach (var node in Traversal(child, getChildren)) 
     { 
      yield return node; 
     } 
    } 
} 

我使用它像

var classes = Traversal(movie, x => x.similarquestions) 

,但它給stackoverflow例外任何想法如何修復請

+0

在調試器中運行它,看看遞歸是否實際工作。 –

+0

是工作無限 – AMH

+2

如果'問題'指向對方,那麼這永遠不會終止。 –

回答

2

自相似性是雙向的,你需要保持一個「拜訪」列表和對證:

List<Question> visited = new List<Question>(); 

public static IEnumerable<T> Traversal<T>(
    T root, 
    Func<T, IEnumerable<T>> getChildren) 
{ 
    if (root == null) 
    { 
     yield break; 
    } 

    //We visited this node! 
    visited.Add(root); 

    yield return root; 

    var children = getChildren(root); 
    if (children == null) 
    { 
     yield break; 
    } 

    //Don't re-visit nodes we have seen before! 
    foreach (var child in children.Except(visited)) 
    { 
     foreach (var node in Traversal(child, getChildren)) 
     { 
      yield return node; 
     } 
    } 
} 

還有其他的方法來檢查對訪問列表爲好,但是這會給你一個想法如何做到這一點。另外,如果這被多次調用,請務必在開始新的遍歷之前清除/實例化列表!