Кучи (23 октября 2017)
- [15 минут] lower bound on build
- build : permutation → heap
- Сколько есть различных корректных куч? n! / ∏ sizei = n! / n(n/2)2(n/4)4...
- Пусть всего есть H куч, а процедура делает не более k сравнений, она разбивает n! перестановок на 2k классов, в одном хотя бы n!/2k элементов, что должно быть не более H.
- [10 минут] Недофибоначчи. Разбор домашнего задания.
- [20 минут] Биномиальная [1978, Vuillemin]
- Определяем деревья (Tn+1 = Tn + Tn), леммы про них (размер, степень, дети, глубина), определяем кучу (список деревьев различных рангов)
- Как хранить? {next, child, x, rank}. По ссылкам next односвязный список. Куча = список корней.
- Пишем add в список, join(Tn, Tn). 2D-картинка со списками.
- extractMin: нашли минимум, удалили из списка; вызвали merge для детей.
- merge: используем
vector<Node*> roots[maxLog]
, складываем туда все корни. Время работы = Roots + maxLog.
- Add и Merge за O(1) (ленивое добавление, слияние)
- Пишем Build за O(n) = n * Add, важно показать, как он вяглядит внутри.
− Перерыв −
- [40 минут] Фибоначчи [1984, Fredman & Tarjan]
- Описание кучи без decreaseKey: биномиальная куча с Add и Merge за O(1)
- decreaseKey: алгоритм (отрезаем себя и или помечаем отца, или рекурсивно идём в него)
- Доказательство: лемма про числа фибоначчи Fn = 1 + Fn-2 + Fn-3 + ..., фибоначчиевы деревья Sizen ≥ Fn.
- Доказательство: интуиция с числом единиц, ранг дерева, правильный инвариант