#pragma once #include #include // Template definition. template class Heap { public: void Push(const T &d); T Pop(); size_t Size() const; bool Empty() const; protected: std::vector h; }; // Template implementations. template size_t Heap::Size() const { return h.size(); } template bool Heap::Empty() const { return h.empty(); } /* With Push(), we append the new element to the end of the vector, and then percolate up. */ template void Heap::Push(const T &d) { int i, parent; T tmp; h.push_back(d); i = h.size()-1; while (1) { if (i == 0) return; parent = (i-1)/2; if (h[parent] > h[i]) { tmp = h[i]; h[i] = h[parent]; h[parent] = tmp; i = parent; } else { return; } } } /* With Pop(), after we error check, we move the last element to the root of the heap, and percolate down. */ template T Heap::Pop() { T retval; T tmp; size_t lc, rc; int index; if (h.empty()) throw (std::string) "Called Pop() on an empty heap"; retval = h[0]; h[0] = h[h.size()-1]; h.pop_back(); if (h.size() == 0) return retval; index = 0; while (1) { lc = index*2+1; rc = lc+1; /* If index is on the bottom of the heap, then return, because we can't percolate any more. */ if (lc >= h.size()) return retval; /* With this code, either there is no right child, or the left child is smaller than the right child. In this case, you need to compare the element at index with the left child. */ if (rc == h.size() || h[lc] <= h[rc]) { if (h[lc] < h[index]) { tmp = h[lc]; h[lc] = h[index]; h[index] = tmp; index = lc; } else { return retval; } /* Otherwise, we compare the element at index with the right child. */ } else if (h[rc] < h[index]) { tmp = h[rc]; h[rc] = h[index]; h[index] = tmp; index = rc; } else { return retval; } } }