Easy3D 2.5.3
heap.h
1/********************************************************************
2 * Copyright (C) 2015 Liangliang Nan <liangliang.nan@gmail.com>
3 * https://3d.bk.tudelft.nl/liangliang/
4 *
5 * This file is part of Easy3D. If it is useful in your research/work,
6 * I would be grateful if you show your appreciation by citing it:
7 * ------------------------------------------------------------------
8 * Liangliang Nan.
9 * Easy3D: a lightweight, easy-to-use, and efficient C++ library
10 * for processing and rendering 3D data.
11 * Journal of Open Source Software, 6(64), 3255, 2021.
12 * ------------------------------------------------------------------
13 *
14 * Easy3D is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License Version 3
16 * as published by the Free Software Foundation.
17 *
18 * Easy3D is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 ********************************************************************/
26
27#ifndef EASY3D_CORE_HEAP_H
28#define EASY3D_CORE_HEAP_H
29
30#include <vector>
31
32namespace easy3d {
33
58 template<class HeapEntry, class HeapInterface>
59 class Heap : private std::vector<HeapEntry> {
60 public:
62
64 Heap() : HeapVector() {}
65
67 explicit Heap(const HeapInterface &i) : HeapVector(), interface_(i) {}
68
70 ~Heap() = default;
71
73 void clear() { HeapVector::clear(); }
74
76 bool empty() { return HeapVector::empty(); }
77
79 unsigned int size() { return (unsigned int) HeapVector::size(); }
80
82 void reserve(unsigned int n) { HeapVector::reserve(n); }
83
85 void reset_heap_position(HeapEntry h) {
86 interface_.set_heap_position(h, -1);
87 }
88
90 bool is_stored(HeapEntry h) {
91 return interface_.get_heap_position(h) != -1;
92 }
93
95 void insert(HeapEntry h) {
96 This::push_back(h);
97 upheap(size() - 1);
98 }
99
101 HeapEntry front() {
102 assert(!empty());
103 return entry(0);
104 }
105
107 void pop_front() {
108 assert(!empty());
109 interface_.set_heap_position(entry(0), -1);
110 if (size() > 1) {
111 entry(0, entry(size() - 1));
112 HeapVector::resize(size() - 1);
113 downheap(0);
114 } else
115 HeapVector::resize(size() - 1);
116 }
117
119 void remove(HeapEntry h) {
120 int pos = interface_.get_heap_position(h);
121 interface_.set_heap_position(h, -1);
122
123 assert(pos != -1);
124 assert((unsigned int) pos < size());
125
126 // last item ?
127 if ((unsigned int) pos == size() - 1)
128 HeapVector::resize(size() - 1);
129
130 else {
131 entry(pos, entry(size() - 1)); // move last elem to pos
132 HeapVector::resize(size() - 1);
133 downheap(pos);
134 upheap(pos);
135 }
136 }
137
140 void update(HeapEntry h) {
141 int pos = interface_.get_heap_position(h);
142 assert(pos != -1);
143 assert((unsigned int) pos < size());
144 downheap(pos);
145 upheap(pos);
146 }
147
149 bool check() {
150 bool ok(true);
151 unsigned int i, j;
152 for (i = 0; i < size(); ++i) {
153 if (((j = left(i)) < size()) &&
154 interface_.greater(entry(i), entry(j))) {
155 std::cerr << "Heap condition violated\n";
156 ok = false;
157 }
158 if (((j = right(i)) < size()) &&
159 interface_.greater(entry(i), entry(j))) {
160 std::cerr << "Heap condition violated\n";
161 ok = false;
162 }
163 }
164 return ok;
165 }
166
167 private:
168 // typedef
169 typedef std::vector<HeapEntry> HeapVector;
170
172 void upheap(unsigned int idx) {
173 HeapEntry h = entry(idx);
174 unsigned int parentIdx;
175
176 while ((idx > 0) && interface_.less(h, entry(parentIdx = parent(idx)))) {
177 entry(idx, entry(parentIdx));
178 idx = parentIdx;
179 }
180
181 entry(idx, h);
182 }
183
185 void downheap(unsigned int idx) {
186 HeapEntry h = entry(idx);
187 unsigned int childIdx;
188 unsigned int s = size();
189
190 while (idx < s) {
191 childIdx = left(idx);
192 if (childIdx >= s)
193 break;
194
195 if ((childIdx + 1 < s) &&
196 (interface_.less(entry(childIdx + 1), entry(childIdx))))
197 ++childIdx;
198
199 if (interface_.less(h, entry(childIdx)))
200 break;
201
202 entry(idx, entry(childIdx));
203 idx = childIdx;
204 }
205
206 entry(idx, h);
207 }
208
210 inline HeapEntry entry(unsigned int idx) {
211 assert(idx < size());
212 return (This::operator[](idx));
213 }
214
216 inline void entry(unsigned int idx, HeapEntry h) {
217 assert(idx < size());
218 This::operator[](idx) = h;
219 interface_.set_heap_position(h, idx);
220 }
221
223 inline unsigned int parent(unsigned int i) { return (i - 1) >> 1; }
224
226 inline unsigned int left(unsigned int i) { return (i << 1) + 1; }
227
229 inline unsigned int right(unsigned int i) { return (i << 1) + 2; }
230
232 HeapInterface interface_;
233 };
234
235//=============================================================================
236} // namespace easy3d
237
238#endif // EASY3D_CORE_HEAP_H
A class implementing a heap.
Definition: heap.h:59
void remove(HeapEntry h)
remove an entry
Definition: heap.h:119
bool empty()
is heap empty?
Definition: heap.h:76
HeapEntry front()
get the first entry
Definition: heap.h:101
void pop_front()
delete the first entry
Definition: heap.h:107
Heap()
Constructor.
Definition: heap.h:64
unsigned int size()
returns the size of heap
Definition: heap.h:79
void update(HeapEntry h)
update an entry: change the key and update the position to reestablish the heap property.
Definition: heap.h:140
void insert(HeapEntry h)
insert the entry h
Definition: heap.h:95
~Heap()=default
Destructor.
void reset_heap_position(HeapEntry h)
reset heap position to -1 (not in heap)
Definition: heap.h:85
void clear()
clear the heap
Definition: heap.h:73
bool is_stored(HeapEntry h)
is an entry in the heap?
Definition: heap.h:90
bool check()
check heap condition
Definition: heap.h:149
void reserve(unsigned int n)
reserve space for N entries
Definition: heap.h:82
Heap(const HeapInterface &i)
Construct with a given HeapInterface.
Definition: heap.h:67
Definition: collider.cpp:182