Вопрос

Я хочу выполнить поиск дерева в ширину, используя очередь.

var q = new Queue<T>();

q.Enqueue(Root);

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

Однако я получаю «коллекцию была изменена после того, как перечисление было создано». Исключение.

Есть ли тип C#, с которым я могу это сделать?


Редактировать:небольшое чтение заставляет меня задуматься, что я, возможно, делаю это совершенно неправильно.

Есть ли способ использовать foreach для исключения из очереди?


это работает, но некрасиво (ОМХО)

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);
}
Это было полезно?

Решение

Вы не можете перечислять IEnumerable и одновременно изменять один и тот же IEnumerable.Я не думаю, что существует коллекция C#, которая позволит это сделать.

Другие советы

А для каждого конструкция здесь не будет работать.

Решить проблему можно с помощью контейнера, обеспечивающего индексированный доступ.

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);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top