Ранее в моей карьере меня попросили объяснить разницу между стеком и очередью. Это довольно простой вопрос, я поделюсь своим объяснением и предоставлю образцы кода для каждого.
Куча
Стек - это просто неуниверсальная коллекция объектов «последним вошел - первым ушел» (LIFO). Говоря простым языком, это означает, что объекты в стеке упорядочены и доступны только для последних добавленных.
Хорошие визуальные представления стека видны повсюду. Например, когда вы идете в продуктовый магазин. Вы можете увидеть поддоны с ящиками с водой или какой-либо жидкостью. Если вам нужно несколько ящиков с чем бы то ни было, вы должны начать с вершины, идя вниз.
Если вы много или редко едите вне дома, вероятно, вы видели что-то похожее на изображение ниже.
Я знаю, что вы, наверное, проголодались, увидев это изображение, но эти восхитительные блины, которые зовут ваше имя, сложены друг на друга. Если у вас нет навыков фокусника, вы не сможете просто получить нижний, не переместив сначала верхний. Именно так упорядочиваются и доступны объекты в стеке.
Давайте создадим стек, добавим несколько значений и распечатаем их.
Stack stack = new Stack(); //add values stack.Push("James"); stack.Push("Jacob"); stack.Push("Jordan"); stack.Push("Jared"); stack.Push("Jones"); //print stack Console.WriteLine(); stack.ToArray().ToList().ForEach(Console.WriteLine);
Теперь давайте удалим несколько значений, предварительно просмотрите текущий объект в верхней части стека, а затем очистим весь стек.
Console.WriteLine("Count before removing values"); Console.WriteLine(stack.Count); //remove values stack.Pop(); stack.Pop(); Console.WriteLine("Count after removing values"); Console.WriteLine(stack.Count); stack.ToArray().ToList().ForEach(Console.WriteLine); //peek at current object Console.WriteLine("Peeking at top object"); Console.WriteLine(stack.Peek()); //clearing stack stack.Clear();
Если мы запустим эти примеры кодов, наш результат должен выглядеть следующим образом.
Jones Jared Jordan Jacob James Count before removing values 5 Count after removing values 3 Jordan Jacob James Peeking at top object Jordan
Если вы хотите проверить потокобезопасность стека, используйте свойство IsSynchronized.
Очередь
Очередь из нескольких слов противоположна стеку. Это просто неуниверсальная коллекция объектов в порядке очереди (FIFO).
Как и в случае с примерами стека, вы наверняка видели примеры очередей во многих местах. Если вы пошли в кафе или супермаркет, вы стояли в очереди. Мой любимый - это люди, стоящие в очереди за последней модной вещью.
В очереди есть почти все доступные методы, которые есть в стеке. Основное отличие состоит в том, что мы ставим в очередь вместо выполнения Push и Dequeue вместо Pop. Мы используем Enqueue, когда нам нужно добавить значение в очередь, и D equeue, когда мы хотим получить и удалить значение из очереди. Мы можем посмотреть, подсчитать, очистить и проверить, является ли очередь потокобезопасной
Давайте теперь создадим и выполним те же задачи, что и раньше для стека очереди.
Queue queue = new Queue(); //queueing queue.Enqueue("James"); queue.Enqueue("Jacob"); queue.Enqueue("Jordan"); queue.Enqueue("Jared"); queue.Enqueue("Jones"); queue.ToArray().ToList().ForEach(Console.WriteLine); Console.WriteLine("Queue count: " + queue.Count); //dequeueing Console.Write("Dequeuing..."); Console.WriteLine(queue.Dequeue()); Console.Write("Dequeuing..."); Console.WriteLine(queue.Dequeue()); Console.WriteLine("Queue count: " + queue.Count); //peeking Console.WriteLine("Peeking..."); Console.WriteLine(queue.Peek()); Console.WriteLine("Is thread-safe? " + queue.IsSynchronized); //clearing queue queue.Clear();
Как мы установили на примере кода, эти два объекта очень похожи, но основное различие состоит в структуре данных, то есть FIFO и LIFO. Поэтому в следующий раз, когда вам понадобится реализовать структуру данных FIFO или LIFO, обратите внимание на одну из этих двух. Один из них может удовлетворить ваши потребности.