cgv
fibo_heap.h
1 #pragma once
2 #include <string.h>
3 
4 
5 namespace cgv{
6  namespace math{
7 
11 template <typename key_type,typename value_type, int max_degrees=20>
12 class fibo_heap
13 {
14  struct heap_node
15  {
16  heap_node* parent;
17  heap_node* left;
18  heap_node* right;
19  heap_node* children[max_degrees];
20  int num_children;
21  int degree;
22  key_type key;
23  value_type value;
24 
25  heap_node(const key_type& _key, const value_type&_value)
26  {
27  left = NULL;
28  right = NULL;
29  parent = NULL;
30  key = _key;
31  value =_value;
32  degree = 0;
33  num_children = 0;
34  memset(children, 0, sizeof(children));
35  }
36 
37 
38  };
39  public:
42  {
43  root_heap = NULL;
44  min_heap = NULL;
45  }
46 
47 
48 
51  {
52  heap_node* node = root_heap;
53 
54  while (node != NULL)
55  {
56  heap_node* next_node = node->right;
57 
58  delete_tree(node);
59  node = next_node;
60  }
61 
62  }
63 
65  void insert(const key_type& key, const value_type& value)
66  {
67  heap_node* new_node = new heap_node(key,value);
68  add_to_root_heap(new_node);
69 
70  }
71 
73  value_type delete_min()
74  {
75  assert(min_heap != NULL);
76 
77 
78  value_type k = min_heap->value;
79 
80  // Move the children into root
81  level_up(min_heap);
82 
83  // Remove the minimum node
84  remove_node(min_heap);
85  min_heap = NULL;
86 
87  // Re-assign a new one for min_heap
88  assign_min_node();
89 
90  // consolidate the heap trees
91  consolidate();
92  return k;
93  }
94 
95  bool empty()
96  {
97  return min_heap == NULL;
98  }
99 
100 
101 
102 private:
103  heap_node* root_heap;
104  heap_node* min_heap;
105 
106 
107  void add_to_root_heap(heap_node* node)
108  {
109  // First time
110  if (root_heap == NULL)
111  {
112  root_heap = node;
113  min_heap = node;
114  return;
115  }
116 
117  // Add to the most left of the root heap
118  node->right = root_heap;
119  root_heap->left = node;
120  root_heap = node;
121 
122  // Check the minimum heap
123  if (node->key < min_heap->key )
124  {
125  min_heap = node;
126  }
127 
128  }
129 
130  void consolidate()
131  {
132  // Make sure the degree of each tree is unique
133  heap_node* degree_nodes[max_degrees];
134  heap_node* node = root_heap;
135 
136  memset(degree_nodes, 0, sizeof(degree_nodes));
137  while (node != NULL)
138  {
139  if (degree_nodes[node->degree] == NULL)
140  {
141  degree_nodes[node->degree] = node;
142  node = node->right;
143  }
144  else // merge the two trees
145  {
146  heap_node* pre_node = degree_nodes[node->degree];
147 
148  if (node->key <pre_node->key)
149  {
150  attach_tree(pre_node, node);
151  }
152  else
153  {
154  attach_tree(node, pre_node);
155  }
156 
157  // Reset the search
158  memset(degree_nodes, 0, sizeof(degree_nodes));
159  node = root_heap;
160  }
161  }
162 
163  }
164 
165  void attach_tree(heap_node* from_node, heap_node* to_node)
166  {
167  if (from_node == root_heap)
168  {
169  root_heap = root_heap->right;
170  }
171 
172  // Break the link of from_node
173  if (from_node->left) from_node->left->right = from_node->right;
174  if (from_node->right) from_node->right->left = from_node->left;
175  from_node->left = NULL;
176  from_node->right = NULL;
177 
178  // Move the from_node under the to_node
179  to_node->children[ to_node->num_children ] = from_node;
180  from_node->parent = to_node;
181  to_node->num_children++;
182  to_node->degree++;
183 
184  }
185 
186  void level_up(heap_node* node)
187  {
188  for (int i = 0; i < node->num_children; i++)
189  {
190  heap_node* child_node = node->children[i];
191 
192  add_to_root_heap(child_node);
193  child_node->parent = NULL;
194  node->children[i] = NULL;
195  }
196 
197  node->num_children = 0;
198 
199  }
200 
201  void remove_node(heap_node* node)
202  {
203  if (node == NULL) return;
204 
205  if (node == root_heap)
206  {
207  root_heap = root_heap->right;
208  }
209  if (node->left) node->left->right = node->right;
210  if (node->right) node->right->left = node->left;
211  delete node;
212 
213  }
214 
215  void assign_min_node()
216  {
217  heap_node* check_node = root_heap;
218 
219  while (check_node != NULL)
220  {
221  if (min_heap == NULL || check_node->key < min_heap->key )
222  {
223  min_heap = check_node;
224  }
225 
226  check_node = check_node->right;
227  }
228 
229  }
230 
231  void delete_tree(heap_node* node)
232  {
233  if (node == NULL) return;
234 
235  for (int i = 0; i < node->num_children; i++)
236  {
237  heap_node* child_node = node->children[i];
238  delete_tree(child_node);
239  }
240 
241  delete node;
242 
243  }
244 };
245 
246  }
247 }
248 
249 
250 
251 
cgv::math::fibo_heap::fibo_heap
fibo_heap()
constructor
Definition: fibo_heap.h:41
cgv::math::fibo_heap::~fibo_heap
~fibo_heap()
destructor
Definition: fibo_heap.h:50
cgv::math::fibo_heap::delete_min
value_type delete_min()
delete and return smallest key in heap
Definition: fibo_heap.h:73
cgv::math::fibo_heap
Definition: fibo_heap.h:13
cgv
the cgv namespace
Definition: vr_calib.cxx:9
cgv::math::fibo_heap::insert
void insert(const key_type &key, const value_type &value)
insert key to heap
Definition: fibo_heap.h:65