3622
правки
Изменения
Нет описания правки
[[Файл:Tree_deque.png|thumb|Древовидная структура дека]]
Персистентный дек можно визуально представить как дерево, где каждый узел хранит пару первый - левый элемент и последнийправый дете, а также ''ребёнка'' - ссылку на следующий дек. Только с каждым уровнем вложенности левый и правый элемент представляют собой массив размера хранят в два раза большеобъектов, чем на предыдущем уровне.
Тип <tex>Pair</tex> хранит пару элементов <tex>first</tex> и <tex>last</tex> типов <tex>T_1</tex> и <tex>T_2</tex> соответственно.
<code>
};
</code>
<code>
push_front(x)
if first left == <tex> \varnothing </tex> // если левый ребенок не существует, то сделаем его новым элементом return Deque<T>(x, child, lastright)
else
// иначе объеденим его с новым элементов и попытаемся добавить в дек на следующем уровне return Deque<T>(<tex> \varnothing </tex>, cchild.push_front(Pair<x, firstleft>), lastright)
</code>
<code>
pop_front()
if first left <tex> \neq ~\varnothing</tex> // если левый ребёнок не пуст, то возвращаем пару из него и нового дека без левого ребёнка return <tex> \mathcal{h} </tex>firstleft, Deque<T>(<tex> \varnothing </tex>, child, lastright)<tex> \mathcal{i} </tex>
else if child == <tex> \varnothing</tex>
// если левый ребёнок оказался пуст, и при этом ссылка на следующий дек тоже отсутсвует, // значит, вернём пару из правого ребёнка и абсолютно пустого дека return <tex> \mathcal{h} </tex>lastright, Deque<T>(<tex> \varnothing ,~\varnothing ,~\varnothing </tex>)<tex> \mathcal{i} </tex>
else
/*
* если два предыдущих условия оказались невыполнены, то мы рекурсивно вызываем метод pop_front()
* и возвращённую пару "элемент-новый дек" сохраняем в переменные temp & newDeque
* Рекурсивные вызовы прекратятся, как только левый ребёнок окажется существующим
* или в деке будет отсутствовать ссылка на следущий дек
*/
temp, newDeque <tex> \leftarrow </tex> child.pop_front()
if temp == <tex> \varnothing </tex>
/* * это возможно только в случае, когда в деке на максимальной глубине все элементы оказались пусты * значит мы сейчас на предпоследнем уровне, и левый ребёнок пустой, а child ссылается на абсолютно пустой дек, * поэтому мы возвращаем right текущего дека, и пустой дек */ return <tex> \mathcal{h} </tex>lastright, Deque<T>(<tex> \varnothing ,~\varnothing ,~\varnothing </tex>)<tex> \mathcal{i} </tex>
else
/* * если всё же temp не пуст, то надо вернуть первый элементы пары temp, * в качестве left нового дека надо поставить temp.last (на уровне ниже, из которого он пришёл, temp хранил в два раза больше элементов * поэтому на текущем уровне temp.last будет соответствовать как раз требуемому количеству элементов), newDeque делаем child'ом * нового дека, а right текущего, right'ом нового */ return <tex> \mathcal{h} </tex>temp.first, Deque<T>(temp.childlast, newDeque, lastright)<tex> \mathcal{i} </tex>
</code>