Кучи (14 октября 2019)
- Повторение V.E.B.
- [15 минут] MinMax heap [1986, Atkinson]. Inplace. Min, Max.
- У нас уже была Min-Max куча: хранить две бинарных и обратные ссылки.
- Новая идея: чётный уровень = max, нечётный уровень = min
- Операции Add, ExtractMin из обычной бинарной кучей выражаются через siftUp, siftDown, поэтому пропатчим 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
- Придумываем потенциал "число правых тяжёлых рёбер"
- (можно скипать) Альтернативный потенциал: число вершин, у которых d(r[v]) > d(l[v]).
- [5 минут] Списко-куча
- Мотивация: куча должна уметь Add, Min, Merge, DecreaseKey, ExtractMin. Обычная бинарная умеет всё кроме Merge за log, Merge за log2. Сегодня изучили Leftist м Skew, которые умеют всё за log. Наша конечная цель − куча Фибоначчи, которая всё кроме ExtractMin умеет за O(1), ExtractMin за O(logn).
- Куча, которая умеет Add за O(1), Min за O(1), Merge за O(1), DecreaseKey за O(1), ExtractMin за O(n)
- [15 минут] heap: lower bound on build
- build: permutation → heap. Общий способ доказательства нижних оценок: если k сравнениями мы из n! перестановок выдаём одну из H(n), то нужно log(n!/H(n)) сравнений.
- Док-во: пусть всего есть H(n) куч, а процедура делает не более k сравнений, она разбивает n! перестановок на 2k классов, в одном хотя бы n!/2k,
после build() все они различны, все они корректные кучи ⇒ H(n) ≥ n!/2^k
- Сколько есть различных корректных куч? H(n) = n! / ∏ sizei = n! / n(n/2)2(n/4)4... Доказываем по индукции: цэшка, факторилы сократятся.