@@ -71,3 +71,169 @@ class MaxHeap:
7171 self ._sink(self .heap, 0 )
7272 return item
7373```
74+ ## C++
75+ ```
76+ #ifndef HEAP_H
77+ #define HEAP_H
78+
79+ #include <algorithm>
80+ #include <functional>
81+ #include <stdexcept>
82+ #include <unordered_map>
83+ #include <utility>
84+ #include <vector>
85+ template <typename T, typename TComparator = std::equal_to<T>,
86+ typename PComparator = std::less<double>,
87+ typename Hasher = std::hash<T> >
88+ class Heap {
89+ public:
90+ /// Constructs an m-ary heap. M should be >= 2
91+ Heap(int m = 2, const PComparator &c = PComparator(),
92+ const Hasher &hash = Hasher(), const TComparator &tcomp = TComparator());
93+
94+ /// Destructor as needed
95+ ~Heap();
96+
97+ /// Adds an item with the provided priority
98+ void push(double pri, const T &item);
99+
100+ /// returns the element at the top of the heap
101+ /// max (if max-heap) or min (if min-heap)
102+ T const &top() const;
103+
104+ /// Removes the top element
105+ void pop();
106+
107+ /// returns true if the heap is empty
108+ bool empty() const;
109+
110+ /// decreaseKey reduces the current priority of
111+ /// item to newpri, moving it up in the heap
112+ /// as appropriate.
113+ void decreaseKey(double newpri, const T &item);
114+
115+ private:
116+ /// Add whatever helper functions you need below
117+ void trickleUp(int loc);
118+ void trickleDown(int loc);
119+
120+ // These should be all the data members you need.
121+ std::vector<std::pair<double, T> > store_;
122+ int m_; // degree
123+ PComparator c_;
124+ std::unordered_map<T, size_t, Hasher, TComparator> keyToLocation_;
125+ };
126+
127+ // Complete
128+ template <typename T, typename TComparator, typename PComparator,
129+ typename Hasher>
130+ Heap<T, TComparator, PComparator, Hasher>::Heap(int m, const PComparator &c,
131+ const Hasher &hash,
132+ const TComparator &tcomp)
133+ : store_(), m_(m), c_(c), keyToLocation_(100, hash, tcomp) {
134+ }
135+
136+ // Complete
137+ template <typename T, typename TComparator, typename PComparator,
138+ typename Hasher>
139+ Heap<T, TComparator, PComparator, Hasher>::~Heap() {
140+ }
141+
142+ template <typename T, typename TComparator, typename PComparator,
143+ typename Hasher>
144+ void Heap<T, TComparator, PComparator, Hasher>::push(double priority,
145+ const T &item) {
146+ // You complete.
147+ std::pair<double, T> temp(priority, item);
148+ store_.push_back(temp);
149+ keyToLocation_[item] = store_.size();
150+ // insert(std::make_pair(item, store_.size()));
151+ trickleUp(store_.size()-1);
152+ }
153+
154+ template <typename T, typename TComparator, typename PComparator,
155+ typename Hasher>
156+ void Heap<T, TComparator, PComparator, Hasher>::trickleUp(int loc) {
157+ int parent = (loc-1)/m_;
158+ while(parent >= 0 && c_(store_[loc].first, store_[parent].first)) {
159+ //swap loc with parent
160+ std::pair<double, T> temp = store_[loc];
161+ store_[loc] = store_[parent];
162+ store_[parent] = temp;
163+ double to_swap = keyToLocation_[store_[loc].second];
164+ keyToLocation_[store_[loc].second] = keyToLocation_[store_[parent].second];
165+ keyToLocation_[store_[parent].second] = to_swap;
166+ loc = parent;
167+ parent = (loc-1)/m_;
168+ }
169+ }
170+
171+
172+ template <typename T, typename TComparator, typename PComparator,
173+ typename Hasher>
174+ void Heap<T, TComparator, PComparator, Hasher>::decreaseKey(double priority,
175+ const T &item) {
176+ std::pair<double, T> temp = store_[keyToLocation_[item]];
177+ temp.first = priority;
178+ trickleUp(keyToLocation_[item]);
179+ }
180+
181+ template <typename T, typename TComparator, typename PComparator,
182+ typename Hasher>
183+ T const &Heap<T, TComparator, PComparator, Hasher>::top() const {
184+ // Here we use exceptions to handle the case of trying
185+ // to access the top element of an empty heap
186+ if (empty()) {
187+ throw std::logic_error("can't top an empty heap");
188+ }
189+ return store_[0].second;
190+ }
191+
192+ /// Removes the top element
193+ template <typename T, typename TComparator, typename PComparator,
194+ typename Hasher>
195+ void Heap<T, TComparator, PComparator, Hasher>::pop() {
196+ if (empty()) {
197+ throw std::logic_error("can't pop an empty heap");
198+ }
199+ store_[0] = store_[store_.size()-1];
200+ keyToLocation_.erase(store_[0].second);
201+ store_.pop_back();
202+ if(empty()) return;
203+ trickleDown(0);
204+ }
205+ template <typename T, typename TComparator, typename PComparator,
206+ typename Hasher>
207+ void Heap<T, TComparator, PComparator, Hasher>::trickleDown(int loc) {
208+ if (loc*m_+1 > store_.size()-1) return;
209+ int smallerChild = m_*loc+1; // start w/ left
210+ for (size_t i = 1; i < m_; i++) {
211+ if (m_*loc+i < store_.size()) {//if the right exist
212+ int rChild = m_*loc+i+1;
213+ if(c_(store_[rChild].first, store_[smallerChild].first)) {
214+ smallerChild = rChild;
215+ }
216+ }
217+ }
218+ if(c_(store_[smallerChild].first, store_[loc].first)) {
219+ //swap smallerChild and loc
220+ std::pair<double, T> temp = store_[loc];
221+ store_[loc] = store_[smallerChild];
222+ store_[smallerChild] = temp;
223+ double to_swap = keyToLocation_[store_[loc].second];
224+ keyToLocation_[store_[loc].second] = keyToLocation_[store_[smallerChild].second];
225+ keyToLocation_[store_[smallerChild].second] = to_swap;
226+ trickleDown(smallerChild);
227+ }
228+ }
229+
230+
231+ /// returns true if the heap is empty
232+ template <typename T, typename TComparator, typename PComparator,
233+ typename Hasher>
234+ bool Heap<T, TComparator, PComparator, Hasher>::empty() const {
235+ return store_.empty();
236+ }
237+
238+ #endif
239+ ```
0 commit comments