<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=188.170.72.129&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=188.170.72.129&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/188.170.72.129"/>
		<updated>2026-05-20T01:54:18Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D1%82%D0%B5%D0%BA&amp;diff=63674</id>
		<title>Стек</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D1%82%D0%B5%D0%BA&amp;diff=63674"/>
				<updated>2018-01-23T02:38:35Z</updated>
		
		<summary type="html">&lt;p&gt;188.170.72.129: /* Определение */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Определение ==&lt;br /&gt;
[[Файл: lifo.png|thumb|right|200px|Стек]]&lt;br /&gt;
'''Стек''' (от англ. ''stack'' {{---}} стопка) {{---}} структура данных, представляющая из себя упорядоченный набор элементов, в которой добавление новых элементов и удаление существующих производится с одного конца, называемого вершиной стека. Притом первым из стека удаляется элемент, который был помещен туда последним, то есть в стеке реализуется стратегия «последним вошел {{---}} первым вышел» (last-in, first-out {{---}} LIFO). Примером стека в реальной жизни может являться стопка тарелок : когда мы хотим вытащить тарелку, мы должны снять все тарелки выше. Вернемся к описанию операций стека:&lt;br /&gt;
* &amp;lt;tex&amp;gt; \mathtt{empty} &amp;lt;/tex&amp;gt; {{---}} проверка стека на наличие в нем элементов,&lt;br /&gt;
* &amp;lt;tex&amp;gt; \mathtt{push} &amp;lt;/tex&amp;gt; (запись в стек) {{---}} операция вставки нового элемента,&lt;br /&gt;
* &amp;lt;tex&amp;gt; \mathtt{pop} &amp;lt;/tex&amp;gt; (снятие со стека) {{---}} операция удаления нового элемента.&lt;br /&gt;
&lt;br /&gt;
==Реализации==&lt;br /&gt;
Для стека с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; элементами требуется &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; памяти, так как она нужна лишь для хранения самих элементов.&lt;br /&gt;
===На массиве===&lt;br /&gt;
Перед реализацией стека выделим ключевые поля:&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathtt{s[1\dots n]} &amp;lt;/tex&amp;gt; {{---}} массив, с помощью которого реализуется стек, способный вместить не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; элементов,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathtt{s.top}&amp;lt;/tex&amp;gt; {{---}} индекс последнего помещенного в стек элемента.&lt;br /&gt;
&lt;br /&gt;
Стек состоит из элементов &amp;lt;tex&amp;gt;\mathtt {s[1\dots s.top]}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\mathtt{s[1]}&amp;lt;/tex&amp;gt; {{---}} элемент на дне стека, а &amp;lt;tex&amp;gt;\mathtt{s[s.top]}&amp;lt;/tex&amp;gt; {{---}} элемент на его вершине.&lt;br /&gt;
Если &amp;lt;tex&amp;gt;\mathtt{s.top = 0}&amp;lt;/tex&amp;gt;, то стек не содержит ни одного элемента и является пустым (англ. ''empty''). Протестировать стек на наличие в нем элементов можно с помощью операции {{---}} запроса &amp;lt;tex&amp;gt; \mathtt{stackEmpty} &amp;lt;/tex&amp;gt;. Если элемент снимается с пустого стека, говорят, что он опустошается (англ. ''underflow''), что обычно приводит к ошибке. Если значение &amp;lt;tex&amp;gt;\mathtt{s.top}&amp;lt;/tex&amp;gt; больше &amp;lt;tex&amp;gt;\mathtt{n}&amp;lt;/tex&amp;gt;, то стек переполняется (англ. ''overflow''). (В представленном ниже псевдокоде возможное переполнение во внимание не принимается.) &lt;br /&gt;
&lt;br /&gt;
Каждую операцию над стеком можно легко реализовать несколькими строками кода:&lt;br /&gt;
 &lt;br /&gt;
 '''boolean''' empty():&lt;br /&gt;
   '''return''' s.top == 0&lt;br /&gt;
&lt;br /&gt;
 '''function''' push(element : '''T'''):&lt;br /&gt;
   s.top = s.top + 1&lt;br /&gt;
   s[s.top] = element&lt;br /&gt;
&lt;br /&gt;
 '''T''' pop():&lt;br /&gt;
   '''if''' empty()&lt;br /&gt;
     '''return''' error &amp;quot;underflow&amp;quot;&lt;br /&gt;
   '''else''' &lt;br /&gt;
     s.top = s.top - 1&lt;br /&gt;
     '''return''' s[s.top + 1]&lt;br /&gt;
&lt;br /&gt;
Как видно из псевдокода выше, все операции со стеком выполняются за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===На саморасширяющемся массиве===&lt;br /&gt;
Возможна реализация стека на [[Саморасширяющийся_массив| динамическом массиве]], в результате чего появляется существенное преимущество над обычной реализацией: при операции push мы никогда не сможем выйти за границы массива, тем самым избежим ошибки исполнения.&lt;br /&gt;
&lt;br /&gt;
Создадим вектор и определим операции стека на нём. В функции &amp;lt;tex&amp;gt; \mathtt {push} &amp;lt;/tex&amp;gt; Перед тем, как добавить новый элемент, будем проверять, не нужно ли расширить массив вдвое, а в &amp;lt;tex&amp;gt; \mathtt {pop} &amp;lt;/tex&amp;gt;, перед тем, как изъять элемент из массива, {{---}} не нужно ли вдвое сузить размер вектора. Ниже приведён пример реализации на векторе.&lt;br /&gt;
&lt;br /&gt;
Ключевые поля:&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathtt{s[0\dots n-1]}&amp;lt;/tex&amp;gt; {{---}} старый массив, в котором хранится стек,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathtt{newStack[0\dots newSize]}&amp;lt;/tex&amp;gt; {{---}} временный массив, где хранятся элементы после перекопирования,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathtt{head}&amp;lt;/tex&amp;gt; {{---}} верхушка стека,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathtt{capacity}&amp;lt;/tex&amp;gt; {{---}} размер массива.&lt;br /&gt;
&lt;br /&gt;
 '''function''' push(element : '''T'''):&lt;br /&gt;
   '''if''' head == capacity - 1&lt;br /&gt;
     '''T''' newStack[capacity * 2]&lt;br /&gt;
     '''for''' i = 0 '''to''' capacity - 1&lt;br /&gt;
       newStack[i] = s[i]&lt;br /&gt;
     s = newStack&lt;br /&gt;
     capacity = capacity * 2&lt;br /&gt;
   head++&lt;br /&gt;
   s[head] = element&lt;br /&gt;
&lt;br /&gt;
 '''T''' pop():&lt;br /&gt;
   temp = s[head]&lt;br /&gt;
   head--&lt;br /&gt;
   '''if''' head &amp;lt; capacity / 4&lt;br /&gt;
     '''T''' newStack[capacity / 2]&lt;br /&gt;
     '''for''' i = 0 '''to''' capacity / 4 - 1&lt;br /&gt;
       newStack[i] = s[i]&lt;br /&gt;
     s = newStack&lt;br /&gt;
     capacity = capacity / 2&lt;br /&gt;
   '''return''' temp&lt;br /&gt;
&lt;br /&gt;
===На списке===&lt;br /&gt;
Стек можно реализовать и на [[Список | списке]]. Для этого необходимо создать список и операции работы стека на созданном списке. Ниже представлен пример реализации стека на односвязном списке. Стек будем &amp;quot;держать&amp;quot; за голову. Добавляться новые элементы посредством операции &amp;lt;tex&amp;gt; \mathtt{push} &amp;lt;/tex&amp;gt; будут перед головой, сами при этом становясь новой головой, а элементом для изъятия из стека с помощью &amp;lt;tex&amp;gt; \mathtt{pop} &amp;lt;/tex&amp;gt; будет текущая голова. После вызова функции &amp;lt;tex&amp;gt; \mathtt{push} &amp;lt;/tex&amp;gt; текущая голова уже станет старой и будет являться следующим элементом за добавленным, то есть ссылка на следующий элемент нового элемента будет указывать на старую голову. После вызова функции &amp;lt;tex&amp;gt; \mathtt{pop} &amp;lt;/tex&amp;gt; будет получена и возвращена информация, хранящаяся в текущей голове. Сама голова будет изъята из стека, а новой головой станет элемент, который следовал за изъятой головой.&lt;br /&gt;
&lt;br /&gt;
Заведем конструктор вида &amp;lt;code&amp;gt;ListItem(next : '''ListItem''', data : '''T''')&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ключевые поля:&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathtt{head.data}&amp;lt;/tex&amp;gt; {{---}} значение в верхушке стека,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathtt{head.next}&amp;lt;/tex&amp;gt; {{---}} значение следующее за верхушкой стека.&lt;br /&gt;
&lt;br /&gt;
 '''function''' push(element : '''T'''):&lt;br /&gt;
   head = ListItem(head, element)&lt;br /&gt;
&lt;br /&gt;
 '''T''' pop():&lt;br /&gt;
   data = head.data&lt;br /&gt;
   head = head.next&lt;br /&gt;
   '''return''' data&lt;br /&gt;
&lt;br /&gt;
В реализации на списке, кроме самих данных, хранятся указатели на следующие элементы, которых столько же, сколько и элементов, то есть, так же &amp;lt;tex&amp;gt;\mathtt{n}&amp;lt;/tex&amp;gt;. Стоит заметить, что стек требует &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; дополнительной памяти на указатели в списке.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Очередь]]&lt;br /&gt;
* [[Персистентный стек]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [[wikipedia:ru:Стек|Википедия {{---}} Стек]]&lt;br /&gt;
*Т. Кормен. «Алгоритмы. Построение и анализ» второе издание, Глава 10&lt;br /&gt;
*T. H. Cormen. «Introduction to Algorithms» third edition, Chapter 10.1&lt;br /&gt;
* [http://comp-science.narod.ru/Progr/Stack.htm Динамические структуры данных: стеки]&lt;br /&gt;
[[Категория:Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория:Амортизационный анализ]]&lt;br /&gt;
[[Категория:Структуры данных]]&lt;/div&gt;</summary>
		<author><name>188.170.72.129</name></author>	</entry>

	</feed>