Изменения

Перейти к: навигация, поиск

Дерево отрезков. Построение

4707 байт убрано, 07:19, 4 июня 2015
Нет описания правки
t[i] = t[2 * i + 1] <tex> \circ </tex> t[2 * i + 2]
</code>
 
==Персистентное дерево отрезков==
{{Определение
|definition=
'''Персистентной''' (англ. ''Persistent'') называется такая структура данных, которая хранит все свои промежуточные версии.
}}
{{Определение
|definition=
'''Полностью персистентной''' (англ. ''Fully persistent'') называется такая персистентная структура данных, в которой разрешено изменять любую её версию и делать запросы к любой её версии.
}}
На основе дерева отрезков можно построить полностью персистентную структуру данных.
 
===Структура дерева===
Для реализации персистентного дерева отрезков удобно несколько изменить структуру дерева. Для этого будем использовать явные указатели <tex>L</tex> и <tex>R</tex> для дочерних элементов. Кроме того, заведем массив <tex>roots[]</tex>, в котором <tex>roots[i]</tex> указывает на корень дерева отрезков версии <tex>i</tex>
 
===Построение===
Для построения персистентного дерева отрезков из <tex>n</tex> элементов необходимо применить <tex>n</tex> раз операцию добавления элемента к последней версии дерева. Для того, чтобы добавить новый элемент к <tex>k</tex>-ой версии дерева, необходимо проверить, является ли оно полным бинарным. Если да, то создадим новый корень, левым сыном сделаем <tex>roots[k]</tex>. Иначе, сделаем копию корня исходной версии. Добавим корень в конец массива корней. Далее, спускаясь от корня к первому свободному листу, будем создавать несуществующие узлы и клонировать существующие. После этого в новой ветке необходимо обновить значение функции и некоторые указатели дочерних элементов. Поэтому, возвращаясь из рекурсии, будем менять один указатель на только что созданную или скопированную вершину, а также обновим значение функции, для которой строилось дерево. После этой операции в дереве появится новая версия, содержащая вставленный элемент.
 
===Изменение элемента===
Для того, чтобы изменить элемент в персистентном дереве отрезков, необходимо сделать следующие действия: спустимся в дереве от корня нужной версии до требуемого элемента, скопируем его, изменим значение, и, поднимаясь по дереву, будем клонировать узлы. При этом необходимо менять указатель на одного из детей на узел, созданный при предыдущем клонировании. После копирования корня, добавим новый корень в конец массива корней.
 
[[Файл:persist.png]]
 
Здесь изображено персистентное дерево отрезков с операцией минимум, в котором изначально было 3 вершины. Сперва к нему была добавлена вершина со значением 2, а потом изменена вершина со значением 7. Цвет ребер и вершин соответствует времени их появления. Синий цвет элементов означает, что они были изначально, зеленый - что они появились после добавления, а оранжевый - что они появились после изменения элемента.
==См. также==
Анонимный участник

Навигация