Стек (stack) — это коллекция, в которой элементы обрабатываются по схеме «последним вошел, первым вышел» (last in, first out — LIFO).
Элемент, вставленный в стек первым, последним же и читается.
Принципиальное отличие от очереди (FIFO-список) — в первой букве.
Примеры стеков: стопка тяжелых книг (добавлять и убирать можем только по одной книге), несколько патронов в магазине автомата — стрелкового оружия, стек как сегмент оперативной памяти компьютера (не куча!), см. примечание к статье Типы данных.
Краткие сведения и пример программы:
Вы можете создать массив из стеков, где номер элемента массива будет, например, определять приоритет.
Внутри каждого элемента массива будет стек, и обработка будет выполняться по принципу LIFO.
Стек реализуется с помощью классов Stack из пространства имен System.Collections и Stack<T> из пространства имен System.Collections.Generic (в нашем примере).
В классе Stack определяются приведенные ниже конструкторы:
public Stack()
public Stack(int initialCapacity)
public Stack(ICollection collect)
В первой форме конструктора создается пустой стек, во второй форме — пустой стек, первоначальный размер которого определяет первоначальная емкость, задаваемая параметром initialCapacity, и в третьей форме — стек, содержащий элементы указываемой коллекции collect. Его первоначальная емкость равна количеству указанных элементов.
В классе Stack определяется ряд собственных методов, помимо тех, что уже объявлены в интерфейсах, которые в нем реализуются.
Некоторые из наиболее часто используемых методов этого класса приведены ниже.
Для помещения объекта в вершину стека, вызывается метод Push().
Для того чтобы извлечь и удалить объект из вершины стека, вызывается метод Pop().
Если же объект требуется только извлечь, но не удалить из вершины стека, то вызывается метод Peek().
А если вызвать метод Pop() или Peek(), когда вызывающий стек пуст, то сгенерируется исключение InvalidOperationException.
Класс Stack<T> является обобщенным эквивалентом класса необобщенной коллекции Stack.
В нем поддерживается стек из элементов типа Т в виде списка, действующего по принципу LIFO.
В этом классе реализуются интерфейсы Collection, IEnumerable и IEnumerable<T>.
Кроме того, в классе Stack<T> непосредственно реализуются методы Clear(), Contains() и СоруТо(), определенные в интерфейсе ICollection<T>.
Mетоды Add() и Remove() в этом классе не поддерживаются, достаточно методов Push() и Рор().
Коллекция класса Stack<T> имеет динамический характер, расширяясь по мере необходимости, чтобы вместить все элементы, которые должны в ней храниться.
Давайте рассмотрим пример стека:
using System; using System.Collections.Generic; namespace Стек { struct Client // структура Client - элемент стека { public string Name; public Byte Age; public Client(string Name, Byte Age) // конструктор клиента { this.Name = Name; this.Age = Age; } public void WriteClient() // вывод данных о клиенте { Console.WriteLine("имя - {0} ; возраст - {1}", Name, Age); } } class Program { static void Main() { Client cl; // клиент (структура - запись) int n = 3; // задайте количество стеков целым числом Stack<Client> [] stc = new Stack<Client>[n]; // N стеков клиентов Random rn = new Random(); // генератор псевдослучайных чисел for (int j = 0; j < n; j++) // цикл по N стекам { stc[j] = new Stack<Client>(); // конструктор j-го стека без параметров for (int i = 0; i < 3; i++) // добавление в стек трех клиентов { cl.Name = "Клиент "+(i+1).ToString(); // имя клиента cl.Age=(byte)rn.Next(20, 60); // возраст клиента stc[j].Push(cl); // добавление в j-й стек } Console.WriteLine("длина стека = {0}", stc[j].Count); // количество элементов в стеке Console.Write("Исходный стек: \n"); foreach (Client kl in stc[j]) // весь j-й стек - на печать kl.WriteClient(); Client kg = stc[j].Peek(); // извлечение элемента из головы стека Console.WriteLine("длина стека = {0}", stc[j].Count); Console.Write("Головной элемент: \n"); kg.WriteClient(); // первый клиент в стеке stc[j].Pop(); // удаление элемента из вершины стека Console.WriteLine("длина стека = {0}", stc[j].Count); Console.Write("Стек: \n"); foreach (Client kl in stc[j]) // весь стек - на печать kl.WriteClient(); Console.WriteLine("-----------конец стека {0} ",j); } stc[0].Pop(); // удаление элемента из вершины 0-го стека Console.WriteLine("длина стека = {0}", stc[0].Count); stc[0].Pop(); // удаление элемента из вершины стека Console.WriteLine("длина стека = {0}", stc[0].Count); // stc[0].Pop(); // ОШИБКА при удалении элемента из вершины стека // возникает исключение InvalidOperationException, так как стек пуст! Console.ReadLine(); } } }
Результат:
Для проверки ошибки при извлечении элемента из пустого стека уберите комментарий в предпоследнем операторе.
NEW: Наш Чат, в котором вы можете обсудить любые вопросы, идеи, поделиться опытом или связаться с администраторами.
![]() |
![]() |
![]() |
![]() |
Привет) Я разраб на работе периодически готовлю к собеседованиям и собеседую. Сейчас решил подработать, готовлю к собеседованиям по C#. Телеграм al322se