Персистентный стек — различия между версиями
Yurik (обсуждение | вклад) |
Shersh (обсуждение | вклад) |
||
| Строка 27: | Строка 27: | ||
Пусть изначально у нас есть один пустой стек. Для удобства, будем хранить его как «голову» с пометкой пустого стека: | Пусть изначально у нас есть один пустой стек. Для удобства, будем хранить его как «голову» с пометкой пустого стека: | ||
<br> | <br> | ||
| − | [[Файл:B5bb212f3702e565498c4412e13242a7.jpg| | + | [[Файл:B5bb212f3702e565498c4412e13242a7.jpg|Картинка]]<br> |
<br> | <br> | ||
<br> | <br> | ||
| Строка 58: | Строка 58: | ||
* [[Стек]] | * [[Стек]] | ||
| + | * [[Персистентный дек]] | ||
== Ссылки == | == Ссылки == | ||
Версия 21:24, 6 марта 2012
| Определение: |
| Персистентными структурами данных называются такие структуры, что при всяком их изменении остается доступ ко всем предыдущим версиям этой структуры. |
Рассмотрим такую структуру на примере стека.
Наивная реализация
Самое простое и очевидное решение этой задачи — честное копирование стека при каждой операции.
Очевидно, что это не самое эффективное решение. Сложность одной операции составляет и количество требуемой памяти — .
Эффективная реализация
Попробуем решить задачу эффективнее. Заведем массив указателей, ссылающихся на каждую версию стека.
Вместо n копий стека будем хранить n первых элементов. Тогда операции push и pop будут иметь следующий вид:
- - создает новый элемент со значением x, который ссылается на элемент с номером i как на предыдущий элемент в стеке.
- - возвращает значение, хранящееся в элементе с номером i и копирует элемент, предыдущий для него.
Результирующие стеки будут иметь номер n + 1.
Пример
Пусть изначально у нас есть один пустой стек. Для удобства, будем хранить его как «голову» с пометкой пустого стека:
![]()
Далее выполним . Создается новая вершина со значением 5, ссылающаяся на 1-ую:
![]()
Аналогично выполним и :
Очевидно, что все 4 стека сейчас верно построены и легко восстанавливаются. Давайте теперь попробуем выполнить последовательно операции и :
- возвращает 5 и копирует 1-ую вершину. Результирующий пятый стек — пустой.
- возвращает 10 и копирует 2-ую вершину: получаем шестой стек.
В итоге мы имеем доступ ко всем версиям стека за времени и памяти (массив длины n и n самих "стеков").

