Сортировки и кучи (16 октября 2017)
- [15 минут] V.E.B за loglogC
- Сформулируем задачу: heap для целых чисел от 0 до C-1. C = 22k (чисел битовой длины 2k).
- Интерфейс Min = O(1), Add и Del = O(k) = O(loglogC).
- Случаи: size = 0, size = 1, size ≥ 2,
struct Heapk: { Heapk-1 a; u_map<int,Heapk-1> b; int min, size; }
.
- Реализуем Add, пересчёт Min
- Реализуем Del
- [15 минут] MinMax heap [1986, Atkinson]. Inplace. Min, Max.
- У нас уже была Min-Max куча: хранить две бинарных и обратные ссылки.
- Новая идея: чётный уровень = max, нечётный уровень = min
- Операции, как с обычной бинарной кучей, нужно научиться делать siftUp, siftDown
- siftUp: сперва можем свопнуться в отцом, далее прыгаем на два вверх (1/2)
- siftDown: берём минимального из четырёх внуков, свпопаемся, решаем конфликт с отцом (5/2)
− Перерыв −
- [15 минут] Leftist heap [1971, Clark].
- merge → add, (для бинарной) extractMin.
- struct: l, r, x, d (ввели ссылочную структуру вместо массива)
- d(v) = (расстояние вниз от вершины до ближайшего ``отсутствия ребенка'') - 1 ≤ log n
- Левацкая (leftist):
d(l[v]) ≥ d(r[v]) ⇒ d(r[v]) ≤ d(v) - 1
Add(x): Merge with {x}
Merge: let x.key < y.key ⇒ x.right = merge(x.right, y)
if d[l[v]] < d[r[v]] then swap(l[v], r[v])
- [10 минут] skew heap [1986, Tarjan]
- Укорачиваем код merge из leftist
- Рассказ про лёгкие и тяжёлые рёбра, показываем, за сколько работает: k + logn
- Придумываем потенциал "число правых тяжёлых рёбер"
- [5 минут] куча, которая умеет Add за O(1), Min за O(1), Merge за O(1), DecreaseKey за O(1), ExtractMin за O(n)