Деревья поиска, часть 2 (16 апреля 2018)
- [12 минут] Случайные деревья
- Определения: средняя глубина вершины, глубина дерева, случайное дерево (Def1: добавляем случайную перестановку; Def2: корнем является случайный элемент)
- Lm: сумма размеров поддеревьев равна сумме глубин
- Оценка средней глубины случайного дерева 2ln(n) и такая же на глубину вершины (ссылаемся на QuickSort, в котором доказали факт про сумму размеров поддеревьев)
- Все операции в случайном дереве поиска работают за O(logn). Если исходные данные случайны, то дерево на выходе тоже случайно.
- Утверждение без док-ва: оценка максимальной глубины дерева, полученного при добавлении случайной перестановки 4ln(n)
- [18 минут] Декартово Дерево (treap, дерамида, дуча, курево) (1989 Aragon + Seidel)
- Cartesian tree : BST по xi, Heap по yi. Наивный алгоритм построения.
- Treap для ключей {xi} − Cartesian tree для {xi, yi=random}.
- Единственность декартового дерева и оценка средней глубины: см. тему случайные деревья
- Общая идея деревьев, начинающихся со split и merge : add и del получаем бесплатно.
- Операции split и merge, пишем split и merge.
- [skipped] [практика] Операция insert через 1 split и delete через 1 merge
- [skipped] [практика] Построение Cartesian tree по сортированным xi за O(n)
− Перерыв −
- Персистентные структуры данных: база
- Дерево поиска уже есть (минусы: больше памяти).
- Массив (O(1) → O(logn)) через дерево поиска по неявному ключу.
- Весь мир (состоит из массивов и деревьев).
- Простейший персистентный массив (дерево отрезков) и разница с персистентным деревом по неявному ключу (как у B и B*)
- Дерево версий для offline-задач
- Персистентные структуры данных: продвинутые
- RBST (решаем проблему y-ков)
- PersistentStack, PersistentQueue через лениво копирующийся стек за O(1) (5 стеков).
- PersistentDequeue (L,Pairs,R) за O(logn)
- garbage collector : ссылочный, stack-allocator + rebuild
− Перерыв −
- Частичная персистентность и fat node.
- Виды персистентности: partial, full, confluent (functional)
- Идея fat node. Наивное применение для массива: проблемы в full, O(log n) для partial.
- Применение для дерева поиска: 1 доп ячейка на вершину. Получаем изменение за O(1) доп времени и памяти.
- Какие BST хороши в данном контексте: AVL сбалансированно, делает O(1) изменений указателей и высот ⇒ идеально. Кстати, O(1) для высот даже не обязательно.
- Задачи, которые мы можем так решать: persistent scanline с O(n) памяти. Жутко полезная задача: локализация точки в планарном графе [O(n), O(logn)].
- Что ещё мы получили? Любую ссылочную структуру, у которой не более p = O(1) входящих ссылок можно поддерживать через p+1 доп ячеек на вершину. Например, двусвязный список, дек.
- Деревья, хранящие только размер
- Spacegoat tree: size left, size right ≤ α*size
- Chinese tree: деревья, которые следят за "размер внука не более половины меня"