<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/index.php?action=history&amp;feed=atom&amp;title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%3ARybak%2F%D0%A7%D0%B5%D1%80%D0%BD%D0%BE%D0%B2%D0%B8%D0%BA</id>
		<title>Участник:Rybak/Черновик - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/index.php?action=history&amp;feed=atom&amp;title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%3ARybak%2F%D0%A7%D0%B5%D1%80%D0%BD%D0%BE%D0%B2%D0%B8%D0%BA"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rybak/%D0%A7%D0%B5%D1%80%D0%BD%D0%BE%D0%B2%D0%B8%D0%BA&amp;action=history"/>
		<updated>2026-05-17T16:31:58Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rybak/%D0%A7%D0%B5%D1%80%D0%BD%D0%BE%D0%B2%D0%B8%D0%BA&amp;diff=19200&amp;oldid=prev</id>
		<title>Rybak: Новая страница: « {{Определение |definition =  '''Дек''' (англ. deque {{---}} double ended queue {{---}} очередь с двумя концами) {{---}} с...»</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rybak/%D0%A7%D0%B5%D1%80%D0%BD%D0%BE%D0%B2%D0%B8%D0%BA&amp;diff=19200&amp;oldid=prev"/>
				<updated>2012-03-10T13:10:20Z</updated>
		
		<summary type="html">&lt;p&gt;Новая страница: « {{Определение |definition =  &amp;#039;&amp;#039;&amp;#039;Дек&amp;#039;&amp;#039;&amp;#039; (англ. deque {{---}} double ended queue {{---}} очередь с двумя концами) {{---}} с...»&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = &lt;br /&gt;
'''Дек''' (англ. deque {{---}} double ended queue {{---}} очередь с двумя концами) {{---}} структура данных с двусторонним доступом к элементам, т. е. их можно удалять и добавлять как в начало, так и в конец дека.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Deque.png|thumb|220px|Дек]]&lt;br /&gt;
Кроме дека ещё существует структура данных, называемая ''steque'', которая представляет собой объединение стека и очереди - элементы можно добавлять только в один конец, а извлекать можно с обоих.&lt;br /&gt;
&lt;br /&gt;
== Эффективная реализация ==&lt;br /&gt;
[[Файл:Tree_deque.png|thumb|220px|right|Древовидная структура дека]]&lt;br /&gt;
Написать дек на массиве не представляет особого труда, зная уже, как работают стек и очередь. Далее будет приведена реализация операций добавление элемента и извлечение из одного конца дека за истинное время работы &amp;lt;tex&amp;gt; O(\log ~ n). &amp;lt;/tex&amp;gt; Добавление и исключение из другого конца делается симметрично.&lt;br /&gt;
&lt;br /&gt;
Персистентный дек можно визуально представить как дерево, где каждый узел хранит пару - левый элемент и правый, а также ''ребёнка'' - ссылку на следующий дек. Только с каждым уровнем вложенности левый и правый элемент хранят в два раза больше объектов, чем на предыдущем уровне.&lt;br /&gt;
&lt;br /&gt;
Тип &amp;lt;tex&amp;gt;Pair&amp;lt;/tex&amp;gt; хранит пару элементов &amp;lt;tex&amp;gt;first&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;last&amp;lt;/tex&amp;gt; типов &amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_2&amp;lt;/tex&amp;gt; соответственно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code style = &amp;quot;display: inline-block;&amp;quot;&amp;gt;&lt;br /&gt;
  Pair&amp;lt;&amp;lt;tex&amp;gt;T_1, ~T_2&amp;lt;/tex&amp;gt;&amp;gt; {&lt;br /&gt;
    &amp;lt;tex&amp;gt;T_1 ~first;&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;T_2 ~last;&amp;lt;/tex&amp;gt;&lt;br /&gt;
  };&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сам дек можно инициализировать напрямую, вызвав конструктор &amp;lt;tex&amp;gt;Deque(left, ~child, ~right)&amp;lt;/tex&amp;gt;, или через шаблоны &amp;lt;tex&amp;gt;Deque&amp;lt;Pair&amp;lt;T_1, ~T_2&amp;gt;&amp;gt;&amp;lt;/tex&amp;gt;, тогда произойдёт следующее&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  Deque&amp;lt;Pair&amp;lt;&amp;lt;tex&amp;gt; T_1, ~T_2 &amp;lt;/tex&amp;gt;&amp;gt;&amp;gt; {&lt;br /&gt;
    &amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt; left;&lt;br /&gt;
    &amp;lt;tex&amp;gt;T_2&amp;lt;/tex&amp;gt; right;&lt;br /&gt;
    Deque&amp;lt;Pair&amp;lt;Pair&amp;lt;&amp;lt;tex&amp;gt; T_1, ~T_2 &amp;lt;/tex&amp;gt;&amp;gt;, Pair&amp;lt;&amp;lt;tex&amp;gt; T_1, ~T_2 &amp;lt;/tex&amp;gt;&amp;gt;&amp;gt; child;&lt;br /&gt;
  };&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Таким образом, элементы с начала хранятся в левой ветке дерева, а с конца - в правой.&lt;br /&gt;
&lt;br /&gt;
Наша структура данных персистентна, следовательно операция &amp;lt;tex&amp;gt; D.push\_front(x) &amp;lt;/tex&amp;gt; возвращает новый дек &amp;lt;tex&amp;gt; D' &amp;lt;/tex&amp;gt;, c элементом &amp;lt;tex&amp;gt; x &amp;lt;/tex&amp;gt; в начале.&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  push_front(x)&lt;br /&gt;
    if left == &amp;lt;tex&amp;gt; \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      // если левый ребенок не существует, то сделаем его новым элементом&lt;br /&gt;
      return Deque(x, child, right)&lt;br /&gt;
    else&lt;br /&gt;
      // иначе объеденим его с новым элементов и попытаемся добавить в дек на следующем уровне&lt;br /&gt;
      return Deque(&amp;lt;tex&amp;gt; \varnothing &amp;lt;/tex&amp;gt;, child.push_front(Pair&amp;lt;x, left&amp;gt;), right)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Метод &amp;lt;tex&amp;gt; D.pop\_front() &amp;lt;/tex&amp;gt; возвращает пару &amp;lt;tex&amp;gt; \left \langle e, ~D' \right \rangle &amp;lt;/tex&amp;gt; из первого элемента и нового дека, полученного из старого изъятием этого элемента.&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  pop_front()&lt;br /&gt;
    if left &amp;lt;tex&amp;gt; \neq ~\varnothing&amp;lt;/tex&amp;gt;&lt;br /&gt;
      // если левый ребёнок не пуст, то возвращаем пару из него и нового дека без левого ребёнка&lt;br /&gt;
      return &amp;lt;tex&amp;gt; \mathcal{h} &amp;lt;/tex&amp;gt;left, Deque(&amp;lt;tex&amp;gt; \varnothing &amp;lt;/tex&amp;gt;, child, right)&amp;lt;tex&amp;gt; \mathcal{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
    else if child == &amp;lt;tex&amp;gt; \varnothing&amp;lt;/tex&amp;gt;&lt;br /&gt;
      // если левый ребёнок оказался пуст, и при этом ссылка на следующий дек тоже отсутсвует,&lt;br /&gt;
      // значит, вернём пару из правого ребёнка и абсолютно пустого дека&lt;br /&gt;
      return &amp;lt;tex&amp;gt; \mathcal{h} &amp;lt;/tex&amp;gt;right, Deque(&amp;lt;tex&amp;gt; \varnothing ,~\varnothing ,~\varnothing &amp;lt;/tex&amp;gt;)&amp;lt;tex&amp;gt; \mathcal{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
    else&lt;br /&gt;
      /* &lt;br /&gt;
       * если два предыдущих условия оказались невыполнены, то мы рекурсивно вызываем метод pop_front()&lt;br /&gt;
       * и возвращённую пару &amp;quot;элемент-новый дек&amp;quot; сохраняем в переменные temp &amp;amp; newDeque&lt;br /&gt;
       * Рекурсивные вызовы прекратятся, как только левый ребёнок окажется существующим &lt;br /&gt;
       * или в деке будет отсутствовать ссылка на следущий дек&lt;br /&gt;
       */     &lt;br /&gt;
      temp, newDeque &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; child.pop_front()&lt;br /&gt;
      if temp == &amp;lt;tex&amp;gt; \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
        /*&lt;br /&gt;
         * это возможно только в случае, когда в деке на максимальной глубине все элементы оказались пусты&lt;br /&gt;
         * значит мы сейчас на предпоследнем уровне, и левый ребёнок пустой, а child ссылается на абсолютно пустой дек,&lt;br /&gt;
         * поэтому мы возвращаем right текущего дека, и пустой дек&lt;br /&gt;
         */&lt;br /&gt;
        return &amp;lt;tex&amp;gt; \mathcal{h} &amp;lt;/tex&amp;gt;right, Deque(&amp;lt;tex&amp;gt; \varnothing ,~\varnothing ,~\varnothing &amp;lt;/tex&amp;gt;)&amp;lt;tex&amp;gt; \mathcal{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
      else&lt;br /&gt;
        /*&lt;br /&gt;
         * если всё же temp не пуст, то надо вернуть первый элементы пары temp, &lt;br /&gt;
         * в качестве left нового дека надо поставить temp.last (на уровне ниже, из которого он пришёл, &lt;br /&gt;
         * temp хранил в два раза больше элементов, поэтому на текущем уровне temp.last будет соответствовать &lt;br /&gt;
         * как раз требуемому количеству элементов), newDeque делаем child'ом&lt;br /&gt;
         * нового дека, а right текущего, right'ом нового&lt;br /&gt;
         */&lt;br /&gt;
        return &amp;lt;tex&amp;gt; \mathcal{h} &amp;lt;/tex&amp;gt;temp.first, Deque(temp.last, newDeque, right)&amp;lt;tex&amp;gt; \mathcal{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы извлечь элемент, придётся спуститься не больше, чем на глубину дерева. Аналогично для добавления. Поэтому обе операции выполняются за &amp;lt;tex&amp;gt; O(\log ~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;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
&lt;br /&gt;
* [http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.13.3451 Purely Functional Deques with Catenation by Robert E. Tarjan]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Амортизационный анализ]]&lt;/div&gt;</summary>
		<author><name>Rybak</name></author>	</entry>

	</feed>