-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathheap.hpp
More file actions
65 lines (52 loc) · 1.53 KB
/
heap.hpp
File metadata and controls
65 lines (52 loc) · 1.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#ifndef CUSTOM_HEAP_HPP
#define CUSTOM_HEAP_HPP
#include <vector>
#include <cstddef>
// Binary max-heap.. generic.. uses a KeyExtractor functor
// push, top, pop, empty, size .. implemented
template<typename Item, typename KeyExtractor>
class BinaryMaxHeap {
private:
std::vector<Item> a;
KeyExtractor getKey;
inline size_t parent(size_t i) const { return (i - 1) / 2; }
inline size_t left(size_t i) const { return 2 * i + 1; }
inline size_t right(size_t i) const { return 2 * i + 2; }
bool cmp(size_t i, size_t j) const {
return getKey(a[i]) > getKey(a[j]);
}
void shiftUp(size_t i) {
while (i > 0 && !cmp(parent(i), i)) {
std::swap(a[i], a[parent(i)]);
i = parent(i);
}
}
void shiftDown(size_t i) {
while (true) {
size_t l = left(i), r = right(i);
size_t best = i;
if (l < a.size() && !cmp(best, l)) best = l;
if (r < a.size() && !cmp(best, r)) best = r;
if (best == i) break;
std::swap(a[i], a[best]);
i = best;
}
}
public:
BinaryMaxHeap() : a(), getKey(KeyExtractor()) {}
void push(const Item& it) {
a.push_back(it);
shiftUp(a.size() - 1);
}
const Item& top() const {
return a.front();
}
void pop() {
std::swap(a.front(), a.back());
a.pop_back();
if (!a.empty()) shiftDown(0);
}
bool empty() const { return a.empty(); }
size_t size() const { return a.size(); }
};
#endif