HOG2
Treap.h
Go to the documentation of this file.
1 //
2 // Treap.h
3 // hog2 mac native demos
4 //
5 // Created by Nathan Sturtevant on 12/29/19.
6 // Copyright © 2019 NS Software. All rights reserved.
7 //
8 
9 #ifndef Treap_h
10 #define Treap_h
11 #include <functional>
12 
13 template <class key>
14 class Treap
15 {
16  struct TreapNode
17  {
18  key value;
19  long randValue; // TODO: replace with C++11 rand
20  size_t left, right, parent;
21  };
22  typedef size_t TreapNodePtr;
23  const size_t nullTreapNode = -1;
24  const size_t rootOfTree = -2;
26 // TreapNodePtr freeList;
27  std::vector<TreapNode> nodes;
29  void Recycle(TreapNodePtr n);
31  void HeapifyUp(TreapNodePtr n);
32 
35  void PrintHelper(TreapNodePtr n, int depth);
36  void VerifyHelper(TreapNodePtr n);
37  void Remove(TreapNodePtr n);
38  size_t GetHeightHelper(TreapNodePtr n);
39  void IterateHelper(TreapNodePtr n, double, double, const std::function<void (const key &)> &);
40 public:
42  void Reset();
43  void Add(key k);
44  key RemoveSmallest();
45  bool Remove(key &k);
46  void Iterate(double, double, const std::function<void (const key &)> &);
47  const key &Peek();
48  void Print();
49  size_t Size();
50  size_t GetHeight();
51  key GetNode(size_t);
52  void Verify();
53 };
54 
55 
56 template <class key>
58 {
59  head = nullTreapNode;
60  nodes.resize(0);
61 }
62 
63 template <class key>
64 void Treap<key>::Add(key k)
65 {
66  TreapNodePtr n = GetNode();
67  nodes[n].value = k;
68  nodes[n].randValue = random();
69  assert(nodes[n].right == nullTreapNode);
70  assert(nodes[n].left == nullTreapNode);
71  if (head == nullTreapNode)
72  {
73  head = n;
74  nodes[n].parent = rootOfTree;
75  }
76  else {
77  Insert(n, head);
78  }
79 }
80 
81 template <class key>
83 {
84  while (nodes[n].parent != rootOfTree)
85  {
86  // heap invariant - parents value >= child value
87  if (nodes[nodes[n].parent].randValue >= nodes[n].randValue)
88  return; // done
89 
90  if (nodes[nodes[n].parent].left == n)
91  {
92  RotateLeftChildUp(nodes[n].parent);
93  }
94  else {
95  assert(nodes[nodes[n].parent].right == n);
96  RotateRightChildUp(nodes[n].parent);
97  }
98  }
99 }
100 
101 template <class key>
103 {
104 // Print();
105 // printf("LRotating %d:\n", nodes[n].value);
106 
107  // 1. left child gets parent as right child
108  // 2. parent gets left/right child as left child
109 
110  TreapNodePtr l = nodes[n].left;
111  TreapNodePtr lr = nodes[l].right;
112  if (nodes[n].parent != rootOfTree)
113  {
114  if (nodes[nodes[n].parent].right == n)
115  nodes[nodes[n].parent].right = l;
116  else {
117  assert(nodes[nodes[n].parent].left == n);
118  nodes[nodes[n].parent].left = l;
119  }
120  }
121  else {
122 // printf("At root\n");
123  head = l;
124  }
125 
126  nodes[l].parent = nodes[n].parent;
127  nodes[n].parent = l;
128  if (lr != nullTreapNode)
129  nodes[lr].parent = n;
130  nodes[n].left = lr;
131  nodes[l].right = n;
132 }
133 
134 template <class key>
136 {
137 // Print();
138 // printf("RRotating %d:\n", nodes[n].value);
139 
140  // 1. right child gets parent as left child
141  // 2. parent gets right/left child as right child
142 
143  TreapNodePtr r = nodes[n].right;
144  TreapNodePtr rl = nodes[r].left;
145  if (nodes[n].parent != rootOfTree)
146  {
147  if (nodes[nodes[n].parent].right == n)
148  nodes[nodes[n].parent].right = r;
149  else {
150  assert(nodes[nodes[n].parent].left == n);
151  nodes[nodes[n].parent].left = r;
152  }
153  }
154  else {
155 // printf("At root\n");
156  head = r;
157  }
158 
159  nodes[r].parent = nodes[n].parent;
160  nodes[n].parent = r;
161  if (rl != nullTreapNode)
162  nodes[rl].parent = n;
163  nodes[n].right = rl;
164  nodes[r].left = n;
165 }
166 
167 template <class key>
169 {
170  if (nodes[n].value < nodes[where].value) // insert left
171  {
172  if (nodes[where].left == nullTreapNode)
173  {
174  nodes[where].left = n;
175  nodes[n].parent = where;
176  HeapifyUp(n);
177 // Verify();
178  }
179  else {
180  Insert(n, nodes[where].left);
181  }
182  }
183  else { // insert right
184  if (nodes[where].right == nullTreapNode)
185  {
186  nodes[where].right = n;
187  nodes[n].parent = where;
188  HeapifyUp(n);
189 // Verify();
190  }
191  else {
192  Insert(n, nodes[where].right);
193  }
194  }
195 }
196 
197 template <class key>
199 {
200  TreapNodePtr t;
201 // if (freeList == nullTreapNode)
202 // {
203 // }
204 // else {
205 // t = freeList;
206 // freeList = nodes[t].parent;
207 // }
208  nodes.resize(nodes.size()+1);
209  t = nodes.size()-1;
210  nodes[t].right = nodes[t].left = nullTreapNode;
211  return t;
212 }
213 
214 template <class key>
216 {
217  // Lucky us - removing last element
218  if (n == nodes.size()-1)
219  {
220  nodes.resize(nodes.size()-1);
221  if (n == 0)
222  head = nullTreapNode;
223  return;
224  }
225  // Swap with end and switch pointers
226  nodes[n] = nodes[nodes.size()-1];
227  nodes.resize(nodes.size()-1);
228  if (nodes[n].parent != rootOfTree)
229  {
230  if (nodes[nodes[n].parent].right == nodes.size())
231  nodes[nodes[n].parent].right = n;
232  else {
233  assert(nodes[nodes[n].parent].left == nodes.size());
234  nodes[nodes[n].parent].left = n;
235  }
236  }
237  else {
238  head = n;
239  }
240 
241  if (nodes[n].left != nullTreapNode)
242  nodes[nodes[n].left].parent = n;
243 
244  if (nodes[n].right != nullTreapNode)
245  nodes[nodes[n].right].parent = n;
246 // Verify();
247  // nodes[n].parent = freeList;
248  // freeList = n;
249 }
250 
251 
252 template <class key>
253 bool Treap<key>::Remove(key &k)
254 {
255  // No elements in treap
256  TreapNodePtr n = head;
257  while (n != nullTreapNode)
258  {
259  if (k == nodes[n].value)
260  {
261  Remove(n);
262 // Verify();
263  return true;
264  }
265  if (k < nodes[n].value)
266  {
267  n = nodes[n].left;
268  }
269  else {
270  n = nodes[n].right;
271  }
272  }
273  return false;
274 }
275 
276 template <class key>
278 {
279  // No elements in treap
280  assert(head != nullTreapNode);
281  TreapNodePtr n = head;
282  while (nodes[n].left != nullTreapNode)
283  n = nodes[n].left;
284  key k = nodes[n].value;
285  Remove(n);
286  return k;
287 }
288 
289 template <class key>
290 void Treap<key>::Iterate(double low, double high, const std::function<void (const key &)> &f)
291 {
292  IterateHelper(head, low, high, f);
293 }
294 
295 template <class key>
296 void Treap<key>::IterateHelper(TreapNodePtr n, double low, double high, const std::function<void (const key &)> &f)
297 {
298  if (n == nullTreapNode)
299  return;
300  if (nodes[n].value > low && nodes[n].value <= high)
301  {
302  f(nodes[n].value);
303  }
304  if (nodes[n].value <= high)
305  IterateHelper(nodes[n].right, low, high, f);
306  if (nodes[n].value > low)
307  IterateHelper(nodes[n].left, low, high, f);
308 
309 }
310 
311 
312 template <class key>
313 const key &Treap<key>::Peek()
314 {
315  // No elements in treap
316  assert(head != nullTreapNode);
317  TreapNodePtr n = head;
318  while (nodes[n].left != nullTreapNode)
319  n = nodes[n].left;
320  return nodes[n].value;
321 }
322 
323 template <class key>
325 {
326  // Case 1: Leaf
327  if (nodes[n].left == nullTreapNode && nodes[n].right == nullTreapNode)
328  {
329  if (nodes[n].parent == rootOfTree)
330  {
331  head = nullTreapNode;
332  Recycle(n);
333  return;
334  }
335  if (nodes[nodes[n].parent].left == n)
336  {
337  nodes[nodes[n].parent].left = nullTreapNode;
338  }
339  else {
340  assert(nodes[nodes[n].parent].right == n);
341  nodes[nodes[n].parent].right = nullTreapNode;
342  }
343  Recycle(n);
344  }
345  // Case 2: Single child
346  else if (nodes[n].left == nullTreapNode)
347  {
348  if (nodes[n].parent == rootOfTree)
349  {
350  head = nodes[n].right;
351  nodes[nodes[n].right].parent = rootOfTree;
352  }
353  else if (nodes[nodes[n].parent].left == n)
354  {
355  nodes[nodes[n].parent].left = nodes[n].right;
356  nodes[nodes[n].right].parent = nodes[n].parent;
357  }
358  else {
359  assert(nodes[nodes[n].parent].right == n);
360  nodes[nodes[n].parent].right = nodes[n].right;
361  nodes[nodes[n].right].parent = nodes[n].parent;
362  }
363  Recycle(n);
364  }
365  else if (nodes[n].right == nullTreapNode)
366  {
367  if (nodes[n].parent == rootOfTree)
368  {
369  head = nodes[n].left;
370  nodes[nodes[n].left].parent = rootOfTree;
371  }
372  else if (nodes[nodes[n].parent].left == n)
373  {
374  nodes[nodes[n].parent].left = nodes[n].left;
375  nodes[nodes[n].left].parent = nodes[n].parent;
376  }
377  else {
378  assert(nodes[nodes[n].parent].right == n);
379  nodes[nodes[n].parent].right = nodes[n].left;
380  nodes[nodes[n].left].parent = nodes[n].parent;
381  }
382  Recycle(n);
383  }
384  // Case 3: Find next largest key and move it up
385  else {
386  // Q: What if we copy *just* the key up? Then the heap property is
387  // maintained, as is the binary tree property.
388  // Q: Does it violate the distribution of keys?
389  // A: I don't know - need to analyze this further.
390 
391  // 1. Find next key (right/->left)
392  TreapNodePtr next = nodes[n].right;
393  while (nodes[next].left != nullTreapNode)
394  next = nodes[next].left;
395  nodes[n].value = nodes[next].value;
396  Remove(next);
397  }
398 // Verify();
399 }
400 
401 
402 template <class key>
404 {
405  PrintHelper(head, 0);
406  std::cout << "\n";
407 }
408 
409 template <class key>
411 {
412  if (n == nullTreapNode)
413  return;
414  if (nodes[n].right != nullTreapNode)
415  PrintHelper(nodes[n].right, depth+1);
416  for (int x = 0; x < 4*depth; x++)
417  std::cout << " ";
418  std::cout << nodes[n].value << " (d" << depth << ", " << nodes[n].randValue << ")\n";
419  if (nodes[n].left != nullTreapNode)
420  PrintHelper(nodes[n].left, depth+1);
421 }
422 
423 template <class key>
425 {
426 // Print();
427  assert(nodes[head].parent == rootOfTree);
428  VerifyHelper(head);
429 }
430 
431 template <class key>
433 {
434  if (nodes[n].left != nullTreapNode)
435  {
436  assert(nodes[nodes[n].left].parent == n);
437  assert(nodes[n].randValue >= nodes[nodes[n].left].randValue);
438  VerifyHelper(nodes[n].left);
439  }
440  if (nodes[n].right != nullTreapNode)
441  {
442  assert(nodes[nodes[n].right].parent == n);
443  assert(nodes[n].randValue >= nodes[nodes[n].right].randValue);
444  VerifyHelper(nodes[n].right);
445  }
446 }
447 
448 template <class key>
450 {
451  return nodes.size();
452 }
453 
454 template <class key>
455 key Treap<key>::GetNode(size_t which)
456 {
457  return nodes[which].value;
458 }
459 
460 template <class key>
462 {
463  return GetHeightHelper(head);
464 }
465 
466 template <class key>
468 {
469  size_t h = 0;
470  if (n == nullTreapNode)
471  return h;
472  if (nodes[n].right != nullTreapNode)
473  h = std::max(h, 1+GetHeightHelper(nodes[n].right));
474  if (nodes[n].left != nullTreapNode)
475  h = std::max(h, 1+GetHeightHelper(nodes[n].left));
476  return h;
477 }
478 
479 
480 #endif /* Treap_h */
Treap::VerifyHelper
void VerifyHelper(TreapNodePtr n)
Definition: Treap.h:432
Treap::TreapNode::value
key value
Definition: Treap.h:18
Treap::Size
size_t Size()
Definition: Treap.h:449
Treap::Reset
void Reset()
Definition: Treap.h:57
Treap::TreapNode
Definition: Treap.h:16
Treap::Iterate
void Iterate(double, double, const std::function< void(const key &)> &)
Definition: Treap.h:290
Treap::RemoveSmallest
key RemoveSmallest()
Definition: Treap.h:277
Treap::IterateHelper
void IterateHelper(TreapNodePtr n, double, double, const std::function< void(const key &)> &)
Definition: Treap.h:296
Treap::TreapNode::left
size_t left
Definition: Treap.h:20
Treap::RotateRightChildUp
void RotateRightChildUp(TreapNodePtr n)
Definition: Treap.h:135
Treap::GetHeight
size_t GetHeight()
Definition: Treap.h:461
Treap::TreapNode::right
size_t right
Definition: Treap.h:20
Treap::PrintHelper
void PrintHelper(TreapNodePtr n, int depth)
Definition: Treap.h:410
Treap::HeapifyUp
void HeapifyUp(TreapNodePtr n)
Definition: Treap.h:82
Treap::GetHeightHelper
size_t GetHeightHelper(TreapNodePtr n)
Definition: Treap.h:467
Treap::Treap
Treap()
Definition: Treap.h:41
Treap::Add
void Add(key k)
Definition: Treap.h:64
Treap::GetNode
TreapNodePtr GetNode()
Definition: Treap.h:198
max
#define max(a, b)
Definition: MinimalSectorAbstraction.cpp:40
Treap::head
TreapNodePtr head
Definition: Treap.h:25
Treap
Definition: Treap.h:14
Treap::Recycle
void Recycle(TreapNodePtr n)
Definition: Treap.h:215
Treap::TreapNode::randValue
long randValue
Definition: Treap.h:19
Treap::TreapNode::parent
size_t parent
Definition: Treap.h:20
Treap::Verify
void Verify()
Definition: Treap.h:424
Treap::nullTreapNode
const size_t nullTreapNode
Definition: Treap.h:23
Treap::Remove
void Remove(TreapNodePtr n)
Definition: Treap.h:324
Treap::TreapNodePtr
size_t TreapNodePtr
Definition: Treap.h:22
Treap::Insert
void Insert(TreapNodePtr n, TreapNodePtr head)
Definition: Treap.h:168
Treap::Peek
const key & Peek()
Definition: Treap.h:313
Treap::RotateLeftChildUp
void RotateLeftChildUp(TreapNodePtr n)
Definition: Treap.h:102
Treap::Print
void Print()
Definition: Treap.h:403
Treap::nodes
std::vector< TreapNode > nodes
Definition: Treap.h:27
Treap::rootOfTree
const size_t rootOfTree
Definition: Treap.h:24