-
Notifications
You must be signed in to change notification settings - Fork 0
/
Heap.cpp
101 lines (85 loc) · 3.04 KB
/
Heap.cpp
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <iostream>
#include <vector>
using std::vector;
namespace heap {
template <typename ValueType,
typename Comparator = std::less <ValueType>
>
class Heap {
vector<ValueType> heap_;
vector<size_t> point_to_id_;
vector<size_t> id_to_point_;
Comparator comparator;
size_t Parent(size_t point) const {
return point / 2;
}
size_t LeftChild(size_t point) const {
return point * 2 < heap_.size() ? point * 2 : 0;
}
size_t RightChild(size_t point) const {
return (1 + point * 2) < heap_.size() ? 1 + point * 2 : 0;
}
void Swap (size_t first_point, size_t second_point) {
std::swap(heap_[first_point], heap_[second_point]);
std::swap(point_to_id_[first_point], point_to_id_[second_point]);
std::swap(id_to_point_[point_to_id_[first_point]], id_to_point_[point_to_id_[second_point]]);
}
void SiftUp(size_t point) {
while (Parent(point) && comparator(heap_[point], heap_[Parent(point)])) {
Swap(point, Parent(point));
point = Parent(point);
}
}
void SiftDown(size_t point) {
while ((LeftChild(point) && comparator(heap_[LeftChild(point)], heap_[point])) ||
(RightChild(point) && comparator(heap_[RightChild(point)], heap_[point]))) {
if (!RightChild(point)) {
Swap(point, LeftChild(point));
point = LeftChild(point);
continue;
}
if (comparator(heap_[LeftChild(point)], heap_[RightChild(point)])) {
Swap(point, LeftChild(point));
point = LeftChild(point);
} else {
Swap(point, RightChild(point));
point = RightChild(point);
}
}
}
public:
explicit Heap(int max_num, Comparator comparator = Comparator()):
heap_(1),
point_to_id_(1),
id_to_point_(max_num),
comparator(comparator)
{}
void insert(const ValueType &value, size_t id) {
heap_.push_back(value);
point_to_id_.push_back(id);
id_to_point_[id] = point_to_id_.size() - 1;
SiftUp(heap_.size() - 1);
}
void extract_min() {
Swap(1, heap_.size() - 1);
heap_.pop_back();
id_to_point_[point_to_id_[point_to_id_.size() - 1]] = 0;
point_to_id_.pop_back();
SiftDown(1);
}
void decrease (size_t id, const ValueType &val) {
size_t point = id_to_point_[id];
heap_[point] = val;
SiftUp(point);
}
const ValueType &get_min() const {
return heap_[1];
}
size_t size() const {
return heap_.size() - 1;
}
bool empty() const {
return size() == 0;
}
};
}