TopK(int k, bool (*compare_func)(const T &t1, const T &t2)) { k_ = k; compare_ = compare_func; array_.reserve(k_); }
boolpush(const T &value);
voidheapify(int array_size);
std::vector<T> get() { return array_; }
voidbuild_heap(int array_size, int root);
private: int k_; std::vector<T> array_; bool (*compare_)(const T &t1, const T &t2); };
template<typename T> void TopK<T>::heapify(int array_size) { for (int i = (array_size - 1) / 2; i >= 0; i--) { build_heap(array_size, i); } }
template<typename T> bool TopK<T>::push(const T &value) { if (array_.size() < k_) { //array has less than k_ elements array_.push_back(value); heapify(array_.size()); returntrue; }
//array has k_ elements //user define compare func if (compare_ == NULL) returnfalse; //if heap is min-heap, compare is greater func //if heap is max-heap, compare is less func if (compare_(array_[0], value)) { //the value need to insert heap array_[0] = value; //0 for root build_heap(k_,0); } returntrue; }
template<typename T> void TopK<T>::build_heap(int array_size, int root) { int left = 2 * root + 1; int right = 2 * root + 2; int largest = root; if (left < array_size && compare_(array_[left], array_[largest])) { largest = left; } if (right < array_size && compare_(array_[right], array_[largest])) { largest = right; } if (largest != root) { std::swap(array_[largest], array_[root]); build_heap(array_size, largest); } }
voidbuild_heap(intarray[], int array_len, int root) { int left = root * 2 + 1; int right = root * 2 + 2; int largest = root; if (left < array_len && array[left] > array[largest]) { largest = left; }
if (right < array_len && array[right] > array[largest]) { largest = right; }
voidheap_sort(intarray[], int array_len) { //first build heap make sure the tree is a heap for (int i = (array_len - 1) / 2; i >= 0; i--) { build_heap(array, array_len, i); }
for (int i = array_len - 1; i >= 0; i--) { //put the max value to the last index std::swap(array[0], array[i]); build_heap(array, i, 0); } }
voidprint_array(intarray[], int array_len) { for (int i = 0; i < array_len; i++) { std::cout << array[i] << " "; } std::cout << std::endl; }