47 static_assert(Arity >= 2,
"arity must be at least 2");
48 static_assert(std::numeric_limits<Index>::is_integer,
49 "Index must be an integer");
50 static_assert(std::numeric_limits<Priority>::is_specialized,
51 "Priority must be an integer or floating-point type");
58 Load(elements, universe_size);
62 const std::vector<Priority>& priorities,
64 Load(indices, priorities, universe_size);
69 heap_positions_.clear();
73 void Load(
const std::vector<Aggregate>& elements,
HeapIndex universe_size) {
74 data_.resize(elements.size());
75 heap_size_ = elements.size();
76 std::copy(elements.begin(), elements.end(), data_.begin());
77 heap_positions_.resize(universe_size, kNonExistent);
78 for (
HeapIndex i = 0; i < data_.size(); ++i) {
79 heap_positions_[
index(i)] = i;
84 void Load(
const std::vector<Index>& indices,
85 const std::vector<Priority>& priorities,
HeapIndex universe_size) {
86 std::copy(indices.begin(), indices.end(), indices_.begin());
87 std::copy(priorities.begin(), priorities.end(), priorities_.begin());
88 heap_size_ = indices.size();
89 heap_positions_.resize(universe_size, kNonExistent);
90 for (
HeapIndex i = 0; i < data_.size(); ++i) {
91 heap_positions_[indices_[i]] = i;
101 CHECK(RemoveAtHeapPosition(0));
109 return data_[0].second;
118 return data_[0].first;
129 const Index
index = element.second;
130 if (
index >= heap_positions_.size()) {
131 heap_positions_.resize(
index + 1, kNonExistent);
133 if (GetHeapPosition(
index) == kNonExistent) {
134 heap_positions_[
index] = heap_size_;
135 if (heap_size_ < data_.size()) {
136 data_[heap_size_] = element;
138 data_.push_back(element);
150 return heap_position != kNonExistent ? RemoveAtHeapPosition(heap_position)
157 const HeapIndex heap_position = GetHeapPosition(element.second);
158 DCHECK_GE(heap_position, 0);
159 DCHECK_LT(heap_position, heap_positions_.size());
160 data_[heap_position] = element;
161 if (HasPriority(heap_position, Parent(heap_position))) {
162 SiftUp(heap_position);
164 SiftDown(heap_position);
170 return GetHeapPosition(
index) != kNonExistent;
176 CHECK(HasPriority(Parent(i), i))
177 <<
"Parent " << Parent(i) <<
" with priority " << priority(Parent(i))
178 <<
" does not have priority over " << i <<
" with priority "
179 << priority(i) <<
" , heap_size = " <<
heap_size()
180 <<
", priority difference = " << priority(i) - priority(Parent(i));
182 CHECK_LE(
heap_size(), heap_positions_.size());
189 HeapIndex GetHeapPosition(Index i)
const {
191 DCHECK_LT(i, heap_positions_.size());
192 return heap_positions_[i];
196 bool RemoveAtHeapPosition(
HeapIndex heap_index) {
198 DCHECK_GE(heap_index, 0);
199 if (heap_index >=
heap_size())
return false;
200 PerformSwap(heap_index,
heap_size() - 1);
202 if (HasPriority(heap_index, Parent(heap_index))) {
205 SiftDown(heap_index);
207 heap_positions_[
index(heap_size_)] = kNonExistent;
230 const HeapIndex highest_priority_child = GetHighestPriorityChild(
index);
231 if (highest_priority_child ==
index)
return;
232 PerformSwap(
index, highest_priority_child);
233 index = highest_priority_child;
244 if (HasPriority(i, highest_priority_child)) {
245 highest_priority_child =
i;
248 return highest_priority_child;
254 std::swap(data_[i], data_[j]);
255 std::swap(heap_positions_[
index(i)], heap_positions_[
index(j)]);
262 return IsMaxHeap ? data_[j] < data_[
i] : data_[
i] < data_[j];
287 Priority priority(
HeapIndex i)
const {
return data_[
i].first; }
290 std::vector<Aggregate> data_;
297 std::vector<Index> indices_;
298 std::vector<Priority> priorities_;
301 std::vector<Index> heap_positions_;
309 const Index kNonExistent = -1;