В других ответах не упоминается большая часть: конечно, pop() занимает большую часть вашего времени: это единственная функция, которая выполняет любую реальную работу!
Как вы, возможно, читали, границы операций Фибоначчи-Кучи являются амортизированными границами. Это означает, что , если вы выполняете достаточно операций в хорошей последовательности, границы будут в среднем равны этому. Однако фактические затраты полностью скрыты.
Каждый раз, когда вы вставляете элемент, ничего не происходит. Он просто забрасывается в корневой список. Бум, O (1) раз. Каждый раз, когда вы объединяете два дерева, его корень просто связан с корневым списком. Бум, O (1) раз. Но держитесь, ваша структура не является допустимой кучей Фибоначчи! Вот где приходит pop() (или extract-root): каждый раз, когда эта операция вызывается, вся куча реструктурируется обратно в правильную форму. Корень удаляется, его дети вырезаются в корневом списке, а затем мы начинаем слияние деревьев в корневом списке, чтобы в корневом списке не было двух деревьев с одинаковой степенью (количество детей).
Итак, вся работа Insert (e) и Merge (t) на самом деле задерживается до тех пор, пока не вызывается Pop(), которая затем выполняет всю работу. Как насчет других операций?
Удалить (e) красиво. Мы выполняем Decrease-Key (e, -inf), чтобы элемент e стал корнем. И теперь мы выполняем Pop()! Опять же, работа выполняется Pop().
Decrease-Key (e, v) выполняет свою работу сам по себе: он разрезает e в корневой список и запускает срезающий каскад, чтобы также поместить своих детей в корневой список (что также может сократить их дочерние списки). Таким образом, Decrease-Key помещает в список корней множество элементов. Можете ли вы угадать, какая функция должна это исправить?
TL; DR: Pop() является рабочей лошадью Кучи Фибоначчи. Все остальные операции выполняются эффективно, поскольку они создают работу для операции Pop(). Pop() собирает работу и выполняет ее за один раз (что может занять до O (n)). Это действительно эффективно, потому что «сгруппированные» работы могут выполняться быстрее, чем каждая операция отдельно.
Так что да, естественно, что Pop() занимает большую часть вашего времени!
Релевантно: [Кто-нибудь действительно эффективно использовал Fibonacci-Heap?] (Http://stackoverflow.com/q/504823/395760) – delnan
Благодарим вас за комментарий. Я уже видел этот пост, и я не слишком понял его. Я проверил свой код с кучей самообучения, и он был еще медленнее. Нынешняя производительность не так уж плоха, я просто беспокоюсь о том, чтобы что-то делать неправильно. –