0

I want to do a breadth first search of a tree using a Queue

var q = new Queue<T>();

q.Enqueue(Root);

foreach(T root in q)
{
  foreach(T t in root.Children)
    q.Enqueue(t);
}

However I get a "Collection was modified after the enumerator was instantiated." Exception.

Is there a C# type that I can do this with?


Edit: a little reading make me thing I might be doing this totally wrong.

Is there a way to use a foreach to dequeue from a Queue?


this works but is ugly (OMHO)

var q = new Queue<T>();

q.Enqueue(Root);

while(q.Count > 0)
{
  T root = q.Dequeue();
  foreach(T t in root.Children)
    q.Enqueue(t);
}
dsolimano
  • 8,870
  • 3
  • 48
  • 63
BCS
  • 75,627
  • 68
  • 187
  • 294
  • What is your working example effectively doing? Unless I'm missing something, you are just continually adding then removing items, ultimately ending up with an empty queue. Is there supposed to be processing after the "Dequeue" command? – Andrew Shepherd Mar 02 '09 at 23:39

2 Answers2

8

You can't enumerate over an IEnumerable and change the same IEnumerable at the same time. I don't think there is a C# Collection that will allow this.

Restore the Data Dumps
  • 38,967
  • 12
  • 96
  • 122
2

The foreach construct won't work here.

You can solve the problem using a container that provides indexed access.

var l = new List<T>();
l.Add(Root);
int i = 0;
while(i < l.Count)
{
    T root = l[i];
    foreach(T t in root.Children)    
    {
        l.Add(t);
    }
    ++i;
}


// And because you really wanted a queue
var q = new Queue<T>(l);
Andrew Shepherd
  • 44,254
  • 30
  • 139
  • 205