AMH
AMH

Reputation: 6451

Recursion and stackoverflow

I have class like

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

to get all the nested classes I use recursion using method like

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;
        }
    }
}

I use it like

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

but it give stackoverflow Exception any idea how to fix that please

Upvotes: 0

Views: 71

Answers (1)

BradleyDotNET
BradleyDotNET

Reputation: 61369

Since similarity is bi-directional, you need to keep a "visited" list and check against it:

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;
        }
    }
}

There are other ways to check against the visited list as well, but this will give you an idea of how to do it. Also, if this is being called multiple times, be sure to clear/instantiate the list before starting a new traversal!

Upvotes: 2

Related Questions