Стек. Пример обобщенной коллекции

Стек (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: Наш Чат, в котором вы можете обсудить любые вопросы, идеи, поделиться опытом или связаться с администраторами.


Помощь проекту:

Понравилась статья? Поделиться с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
1 Комментарий
Новые
Старые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

Привет) Я разраб на работе периодически готовлю к собеседованиям и собеседую. Сейчас решил подработать, готовлю к собеседованиям по C#. Телеграм al322se

1
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x
()
x