cgv
dynamic_priority_queue.h
1 #pragma once
2 
3 #include <vector>
4 
5 namespace cgv {
6  namespace data {
8 template <typename T>
10 {
11 public:
12  typedef T element_type;
13 protected:
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  }
88 public:
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 
102  unsigned int top() const { return heap[0]; }
105  void pop() { remove(top()); }
107  int extract()
108  {
109  unsigned int tmp = top();
110  pop();
111  return tmp;
112  }
114 
117  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)
129  last_empty_element = -1;
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 }
cgv::data::dynamic_priority_queue::size
size_t size() const
return the number of elements in the heap
Definition: dynamic_priority_queue.h:96
cgv::data::dynamic_priority_queue::elements
std::vector< extended_element > elements
container for elements
Definition: dynamic_priority_queue.h:22
cgv::data::dynamic_priority_queue::exchangeIfBetter
bool exchangeIfBetter(unsigned int hp1, unsigned int hp2)
check if hp1 is less than hp2, if true, exchange elements
Definition: dynamic_priority_queue.h:36
cgv::data::dynamic_priority_queue::heap
std::vector< unsigned int > heap
store indices to the elements on the heap
Definition: dynamic_priority_queue.h:26
cgv::data::dynamic_priority_queue::last_empty_element
int last_empty_element
store index of last empty element or -1 if there is non
Definition: dynamic_priority_queue.h:24
cgv::data::dynamic_priority_queue::empty
bool empty() const
check if heap is empty
Definition: dynamic_priority_queue.h:94
cgv::data::dynamic_priority_queue::pop
void pop()
remove top element
Definition: dynamic_priority_queue.h:105
cgv::data::dynamic_priority_queue::positionUpward
bool positionUpward(unsigned int &hp)
move an element upward to the correct position
Definition: dynamic_priority_queue.h:77
cgv::data::dynamic_priority_queue::update
void update(unsigned int idx)
update after a change to the predicate
Definition: dynamic_priority_queue.h:148
cgv::data::dynamic_priority_queue::valid
bool valid(unsigned int hp) const
check if a position is outside of range
Definition: dynamic_priority_queue.h:28
cgv::data::dynamic_priority_queue
Definition: dynamic_priority_queue.h:10
cgv::data::dynamic_priority_queue::remove
void remove(unsigned int idx)
remove element at location idx
Definition: dynamic_priority_queue.h:154
cgv::data::dynamic_priority_queue::size_of_element_container
size_t size_of_element_container() const
return the number of elements in the heap
Definition: dynamic_priority_queue.h:98
cgv::data::dynamic_priority_queue::clear
void clear()
remove all elements
Definition: dynamic_priority_queue.h:92
cgv::data::dynamic_priority_queue::extract
int extract()
extract top element
Definition: dynamic_priority_queue.h:107
cgv::data::dynamic_priority_queue::move
void move(unsigned int hp1, unsigned int hp2)
move one element to another position, that should be empty
Definition: dynamic_priority_queue.h:49
cgv::data::dynamic_priority_queue::positionDownward
void positionDownward(unsigned int &hp)
move an element downward to the correct position
Definition: dynamic_priority_queue.h:66
cgv::data::dynamic_priority_queue::updateLink
void updateLink(unsigned int hp)
make sure that the link for hp is ok
Definition: dynamic_priority_queue.h:30
cgv::data::dynamic_priority_queue::dynamic_priority_queue
dynamic_priority_queue()
empty construction
Definition: dynamic_priority_queue.h:90
cgv::data::dynamic_priority_queue::insert
unsigned int insert(const element_type &e)
insert the given element and return its index in the element container
Definition: dynamic_priority_queue.h:123
cgv::data::dynamic_priority_queue::extended_element
store per element, whether it is empty and a link to the next empty element or to the heap location
Definition: dynamic_priority_queue.h:16
cgv::data::dynamic_priority_queue::isBetter
bool isBetter(unsigned int hp1, unsigned int hp2) const
check if hp1 is less than hp2, if true, exchange elements
Definition: dynamic_priority_queue.h:32
cgv
the cgv namespace
Definition: vr_calib.cxx:9
cgv::data::dynamic_priority_queue::removeHeap
void removeHeap(unsigned int hp)
remove an element on a certain heap pos
Definition: dynamic_priority_queue.h:55
cgv::data::dynamic_priority_queue::top
unsigned int top() const
return the top element
Definition: dynamic_priority_queue.h:103