cgv
Loading...
Searching...
No Matches
dynamic_priority_queue.h
1#pragma once
2
3#include <vector>
4
5namespace cgv {
6 namespace data {
8template <typename T>
10{
11public:
12 typedef T element_type;
13protected:
16 {
17 element_type element;
18 bool is_empty : 1;
19 unsigned int link : 31;
20 };
22 std::vector<extended_element> elements;
26 std::vector<unsigned int> heap;
28 bool valid(unsigned int hp) const { return hp < heap.size(); }
30 void updateLink(unsigned int hp) { elements[heap[hp]].link = hp; }
32 bool isBetter(unsigned int hp1, unsigned int hp2) const {
33 return elements[heap[hp1]].element<elements[heap[hp2]].element;
34 }
36 bool exchangeIfBetter(unsigned int hp1, unsigned int hp2)
37 {
38 if (isBetter(hp1,hp2)) {
39 std::swap(heap[hp1], heap[hp2]);
40 updateLink(hp1);
41 updateLink(hp2);
42 return true;
43 }
44 return false;
45 }
47 void heapify(unsigned int hp) { if (!positionUpward(hp)) positionDownward(hp); }
49 void move(unsigned int hp1, unsigned int hp2)
50 {
51 heap[hp2] = heap[hp1];
52 updateLink(hp2);
53 }
55 void removeHeap(unsigned int hp)
56 {
57 if (hp != heap.size()-1) {
58 move((unsigned int)heap.size()-1,hp);
59 heap.pop_back();
60 heapify(hp);
61 }
62 else
63 heap.pop_back();
64 }
66 void positionDownward(unsigned int& hp)
67 {
68 unsigned int child;
69 while (valid(child = 2*hp+1)) {
70 unsigned int tmp = child+1;
71 if (valid(tmp) && isBetter(tmp,child)) child = tmp;
72 if (!exchangeIfBetter(child, hp)) break;
73 hp = child;
74 }
75 }
77 bool positionUpward(unsigned int& hp)
78 {
79 bool changed = false;
80 while (hp != 0) {
81 unsigned int pa = (hp-1)/2;
82 if (!exchangeIfBetter(hp, pa)) break;
83 hp = pa;
84 changed = true;
85 }
86 return changed;
87 }
88public:
92 void clear() { elements.clear(); heap.clear(); last_empty_element = -1; }
94 bool empty() const { return heap.size() == 0; }
96 size_t size() const { return heap.size(); }
98 size_t size_of_element_container() const { return elements.size(); }
99
103 unsigned int top() const { return heap[0]; }
105 void pop() { remove(top()); }
108 {
109 unsigned int tmp = top();
110 pop();
111 return tmp;
112 }
114
118 bool is_empty(unsigned int idx) const { return elements[idx].is_empty; }
120 const element_type& operator [] (unsigned int idx) const { return elements[idx].element; }
121 element_type& operator [] (unsigned int idx) { return elements[idx].element; }
123 unsigned int insert(const element_type& e)
124 {
125 unsigned int idx;
126 if (last_empty_element != -1) {
127 idx = last_empty_element;
128 if (elements[idx].link == idx)
130 else
131 last_empty_element = elements[idx].link;
132 }
133 else {
134 idx = (unsigned int) elements.size();
135 elements.resize(idx+1);
136 }
137 elements[idx].element = e;
138 elements[idx].is_empty = false;
139
140 unsigned int hp = (unsigned int) heap.size();
141 heap.push_back(idx);
142 updateLink(hp);
143 positionUpward(hp);
144
145 return idx;
146 }
148 void update(unsigned int idx)
149 {
150 if (!is_empty(idx))
151 heapify(elements[idx].link);
152 }
154 void remove(unsigned int idx)
155 {
156 if (is_empty(idx))
157 return;
158 removeHeap(elements[idx].link);
159 elements[idx].is_empty = true;
160 if (last_empty_element == -1)
161 elements[idx].link = idx;
162 else
163 elements[idx].link = last_empty_element;
164 last_empty_element = idx;
165 }
166};
167
168 }
169}
IndexHeap is a heap that allows changing of the elements.
void remove(unsigned int idx)
remove element at location idx
unsigned int top() const
return the top element
unsigned int insert(const element_type &e)
insert the given element and return its index in the element container
std::vector< extended_element > elements
container for elements
void update(unsigned int idx)
update after a change to the predicate
int last_empty_element
store index of last empty element or -1 if there is non
std::vector< unsigned int > heap
store indices to the elements on the heap
bool exchangeIfBetter(unsigned int hp1, unsigned int hp2)
check if hp1 is less than hp2, if true, exchange elements
void move(unsigned int hp1, unsigned int hp2)
move one element to another position, that should be empty
void updateLink(unsigned int hp)
make sure that the link for hp is ok
void positionDownward(unsigned int &hp)
move an element downward to the correct position
void removeHeap(unsigned int hp)
remove an element on a certain heap pos
bool empty() const
check if heap is empty
bool positionUpward(unsigned int &hp)
move an element upward to the correct position
size_t size() const
return the number of elements in the heap
bool isBetter(unsigned int hp1, unsigned int hp2) const
check if hp1 is less than hp2, if true, exchange elements
size_t size_of_element_container() const
return the number of elements in the heap
bool valid(unsigned int hp) const
check if a position is outside of range
the cgv namespace
Definition print.h:11
store per element, whether it is empty and a link to the next empty element or to the heap location