Кучи (5 ноября 2019)
- [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.
- Доказательство: интуиция с числом единиц, ранг дерева, правильный инвариант