Персистентный стек — различия между версиями
(→Пример) |
(→Пример) |
||
Строка 26: | Строка 26: | ||
|-align = "center" | |-align = "center" | ||
!value | !value | ||
− | |<tex>null</tex> | + | |<tex>\mathtt{null}</tex> |
|-align = "center" | |-align = "center" | ||
!prev | !prev | ||
− | |<tex>null</tex> | + | |<tex>\mathtt{null}</tex> |
|} | |} | ||
Строка 42: | Строка 42: | ||
|-align = "center" | |-align = "center" | ||
!value | !value | ||
− | |<tex>null</tex> | + | |<tex>\mathtt{null}</tex> |
|3 | |3 | ||
|-align = "center" | |-align = "center" | ||
!prev | !prev | ||
− | |<tex>null</tex> | + | |<tex>\mathtt{null}</tex> |
|1 | |1 | ||
|} | |} | ||
Строка 61: | Строка 61: | ||
|-align = "center" | |-align = "center" | ||
!value | !value | ||
− | |<tex>null</tex> | + | |<tex>\mathtt{null}</tex> |
|3 | |3 | ||
|5 | |5 | ||
|-align = "center" | |-align = "center" | ||
!prev | !prev | ||
− | |<tex>null</tex> | + | |<tex>\mathtt{null}</tex> |
|1 | |1 | ||
|2 | |2 | ||
Строка 83: | Строка 83: | ||
|-align = "center" | |-align = "center" | ||
!value | !value | ||
− | |<tex>null</tex> | + | |<tex>\mathtt{null}</tex> |
|3 | |3 | ||
|5 | |5 | ||
Строка 89: | Строка 89: | ||
|-align = "center" | |-align = "center" | ||
!prev | !prev | ||
− | |<tex>null</tex> | + | |<tex>\mathtt{null}</tex> |
|1 | |1 | ||
|2 | |2 | ||
Строка 112: | Строка 112: | ||
|-align = "center" | |-align = "center" | ||
!value | !value | ||
− | |<tex>null</tex> | + | |<tex>\mathtt{null}</tex> |
|3 | |3 | ||
|5 | |5 | ||
Строка 118: | Строка 118: | ||
|6 | |6 | ||
|1 | |1 | ||
− | |<tex>null</tex> | + | |<tex>\mathtt{null}</tex> |
|5 | |5 | ||
|9 | |9 | ||
|-align = "center" | |-align = "center" | ||
!prev | !prev | ||
− | |<tex>null</tex> | + | |<tex>\mathtt{null}</tex> |
|1 | |1 | ||
|2 | |2 | ||
Строка 129: | Строка 129: | ||
|3 | |3 | ||
|5 | |5 | ||
− | |<tex>null</tex> | + | |<tex>\mathtt{null}</tex> |
|2 | |2 | ||
|7 | |7 |
Версия 21:36, 5 июня 2015
Эффективная реализация
Заведем массив запросов, модифицирующих стек.
У каждого элемента массива будет поля: значение в вершине стека и индекс предыдущей версии стека.
Тогда операции push и pop будут иметь следующий вид:
- — добавляет элемент в стек с номером , результирующий стек будет иметь номер .
function push(i : uint, x : T): s.top = s.top + 1 s[s.top].value = x s[s.top].prev = i
- — возвращает значение, хранящееся в элементе с номером и копирует элемент, предыдущий для него,
результирующий стек будет иметь номер
.T pop(i : uint): T k = s[i] k = s[k.prev] push(k.prev, k.value)
Пример
Пусть изначально у нас есть один пустой стек. Запишем его в массив.
index | 1 |
---|---|
value | |
prev |
Далее выполним . Создается новая вершина со значением , ссылающаяся на 1-ую, помещаем ее во 2-ую ячейку массива:
index | 1 | 2 |
---|---|---|
value | 3 | |
prev | 1 |
Аналогично выполним :
index | 1 | 2 | 3 |
---|---|---|---|
value | 3 | 5 | |
prev | 1 | 2 |
Выполним . он возвращает и копирует 2-ую вершину.
index | 1 | 2 | 3 | 4 |
---|---|---|---|---|
value | 3 | 5 | 3 | |
prev | 1 | 2 | 1 |
Так будет выглядеть массив после последовательности операций
index | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
value | 3 | 5 | 3 | 6 | 1 | 5 | 9 | ||
prev | 1 | 2 | 1 | 3 | 5 | 2 | 7 |
В итоге мы имеем доступ ко всем версиям стека за времени и памяти.