#include "binary_heap.h" #include "../index/priority_queue.h" #include template void BinaryHeap::sift_up(size_t idx) { while (idx > 0) { size_t parent = (idx - 1) / 2; if (comp_(heap_[idx], heap_[parent], items_)) { std::swap(heap_[idx], heap_[parent]); idx = parent; } else { break; } } } template void BinaryHeap::sift_down(size_t idx) { const size_t n = heap_.size(); while (true) { size_t smallest = idx; size_t left = 2 * idx + 1; size_t right = 2 * idx + 2; if (left < n && comp_(heap_[left], heap_[smallest], items_)) { smallest = left; } if (right < n && comp_(heap_[right], heap_[smallest], items_)) { smallest = right; } if (smallest != idx) { std::swap(heap_[idx], heap_[smallest]); idx = smallest; } else { break; } } } template BinaryHeap::BinaryHeap(const std::vector& items, Comparator comp) : items_(items), comp_(comp) {} template void BinaryHeap::build(const std::vector& indices) { heap_ = indices; // Heapify from bottom up for (int i = static_cast(heap_.size()) / 2 - 1; i >= 0; --i) { sift_down(static_cast(i)); } } template size_t BinaryHeap::pop() { if (heap_.empty()) { return SIZE_MAX; } size_t result = heap_[0]; heap_[0] = heap_.back(); heap_.pop_back(); if (!heap_.empty()) { sift_down(0); } return result; } template std::vector BinaryHeap::sorted() const { std::vector result = heap_; std::vector sorted_result; sorted_result.reserve(result.size()); // Create a copy to use for sifting std::vector items_copy(items_); BinaryHeap temp_heap(items_copy, comp_); temp_heap.build(result); while (!temp_heap.empty()) { sorted_result.push_back(temp_heap.pop()); } return sorted_result; } // Explicit instantiation for IndexEntry type used in priority queue template class BinaryHeap;