Выбор конкретного объекта в очереди (т.е. взглянуть +1) - PullRequest
11 голосов
/ 26 мая 2011

если Peek возвращает следующий объект в очереди, есть ли метод, который я могу использовать, чтобы получить конкретный объект?Например, я хочу найти третий объект в очереди и изменить одно из его значений?

сейчас я просто делаю foreach через очередь, что может быть лучшим решением, но я не знал, было личто-то особенное, что вы можете использовать с Peek?т.е. Queue.Peek (2)

Ответы [ 4 ]

15 голосов
/ 26 мая 2011

Если вы хотите получить доступ к элементам напрямую (с помощью операции O(1)), используйте массив вместо очереди, потому что очередь имеет другую функцию (FIFO).

Операция произвольного доступа в очереди будет O(n), поскольку она должна выполнять итерацию по каждому элементу в коллекции ... что, в свою очередь, делает его последовательным, а не прямым произвольным доступом.


Опять же, поскольку вы используете C #, вы можете использовать queue.ElementAt(n) из System.Linq (поскольку Queue реализует IEnumerable), но это не будет O(1), т. Е. Он все еще будет перебирать элементы .

8 голосов
/ 26 мая 2011

Хотя это все еще O (n), его, безусловно, легче читать, если вы используете методы расширения LINQ ElementAt() или ElementAtOrDefault(), это расширения IEnumerable<T>, которые Queue<T> реализует.

using System.Linq;

Queue<T> queue = new Queue<T>();
T result; 
result = queue.ElementAt(2);
result = queue.ElementAtOrDefault(2);

Редактировать Если вы согласны с другими предложениями по преобразованию своей очереди в массив только для этой операции, вам нужно решить, оправдывают ли вероятные размеры вашей очереди и расстояние до индекса, который вы будете искать с начала своей очереди. O (n) операция вызова .ToArray (). ElementAt (m), не говоря уже о требованиях к пространству для создания вторичного хранилища для него.

4 голосов
/ 26 мая 2011

foreach через очередь.Своего рода парадокс.

Однако, если вы можете использовать foreach, это IEnumerable, поэтому применяются обычные расширения linq:

queue.Skip(1).FirstOrDefault()

или

queue.ElementAt(1)
1 голос
/ 26 мая 2011

Вы можете сделать что-то вроде этого как один раз:

object thirdObjectInQueue = queue.ToArray()[2];

Однако я бы не рекомендовал использовать это много раз, так как он копирует всю очередь в массив, тем самым перебирая всев любом случае.

...