28 # ifndef TPL_BINHEAP_H 29 # define TPL_BINHEAP_H 32 # include <tpl_arrayStack.H> 33 # include <tpl_binNode.H> 34 # include <tpl_dynListQueue.H> 36 using namespace Aleph;
40 class BinHeapNode_Data
48 BinHeapNode_Data * pLink;
49 Control_Fields control_fields;
53 BinHeapNode_Data() noexcept : pLink(
nullptr)
55 control_fields.is_leaf =
true;
56 control_fields.is_left =
true;
59 BinHeapNode_Data *& getU() noexcept {
return pLink; }
61 Control_Fields & get_control_fields() noexcept {
return control_fields; }
65 control_fields.is_leaf =
true;
66 control_fields.is_left =
true;
72 # define PREV(p) (p->getL()) 73 # define NEXT(p) (p->getR()) 74 # define ULINK(p) reinterpret_cast<Node*&>((p)->getU()) 75 # define IS_LEAF(p) ((p)->get_control_fields().is_leaf) 76 # define IS_LEFT(p) ((p)->get_control_fields().is_left) 77 # define CTRL_BITS(p) ((p)->get_control_fields()) 101 template <
template <
class>
class NodeType,
typename Key,
102 class Compare = Aleph::less<Key>>
111 using Node = NodeType<Key>;
113 Compare & key_comp() noexcept {
return cmp; }
115 Compare & get_compare() noexcept {
return cmp; }
129 std::swap(root, h.root);
130 std::swap(last, h.last);
131 std::swap(num_nodes, h.num_nodes);
132 std::swap(cmp, h.cmp);
137 static bool is_in_list(Node * p) noexcept
145 static bool has_sibling(Node * p) noexcept
147 return ULINK(p) !=
RLINK(p);
150 void swap_with_parent(Node * p) noexcept
152 assert(num_nodes >= 2);
157 const bool p_has_sibling = has_sibling(p);
158 const bool p_is_in_list = is_in_list(p);
159 const bool pp_is_in_list = is_in_list(pp);
160 const bool p_has_child = not IS_LEAF(p);
162 std::swap(CTRL_BITS(pp), CTRL_BITS(p));
167 Node *ppp = ULINK(pp);
172 if (
LLINK(ppp) == pp)
181 assert(ULINK(sp) == pp);
191 Node *lcp =
LLINK(p);
192 Node *rcp =
RLINK(p);
212 if (not p_is_in_list)
214 ULINK(lcp) = ULINK(rcp) = pp;
218 assert(
RLINK(pp) == sp);
224 assert(
LLINK(pp) == sp);
235 if (not pp_is_in_list)
238 ULINK(
LLINK(p)) = pp;
244 assert(
RLINK(pp) == sp);
250 assert(
LLINK(pp) == sp);
269 virtual void sift_up(Node * p) noexcept
271 while (p != root and cmp (
KEY(p),
KEY(ULINK(p))))
275 virtual void sift_down(Node * p) noexcept
277 while (not IS_LEAF(p))
279 Node * cp =
LLINK(p);
284 if (cmp (
KEY(p),
KEY(cp)))
287 swap_with_parent(cp);
291 void swap_root_with_last() noexcept
293 assert(num_nodes > 1);
294 assert(ULINK(root) == head);
295 assert(not IS_LEAF(root));
296 assert(IS_LEAF(last));
300 Node * lRoot =
LLINK(root);
301 Node * rRoot =
RLINK(root);
302 Node * f_last = ULINK(last);
303 Node * prev_last =
LLINK(last);
304 Node * next_last =
RLINK(last);
306 if (
LLINK(f_last) == last)
307 LLINK(f_last) = root;
309 RLINK(f_last) = root;
311 if (
RLINK(root) != last)
312 std::swap(ULINK(root), ULINK(last));
322 ULINK(lRoot) = ULINK(rRoot) = last;
327 PREV(root) = prev_last;
328 NEXT(root) = next_last;
330 NEXT(prev_last) = PREV(next_last) = root;
332 else if (num_nodes == 3)
334 assert(
RLINK(root) == last);
337 ULINK(last) = ULINK(root);
340 Node *s_last =
LLINK(last);
341 ULINK(s_last) = last;
343 LLINK(last) = s_last;
351 assert(
LLINK(root) == last);
353 ULINK(last) = ULINK(root);
359 std::swap(CTRL_BITS(root), CTRL_BITS(last));
360 std::swap(root, last);
363 Node * remove_last() noexcept
365 assert(last != root and num_nodes > 0);
366 assert(IS_LEAF(last));
368 Node * ret_val = last;
369 Node * pp = ULINK(last);
370 Node * new_last =
LLINK(last);
375 LLINK(pp) = new_last;
391 void replace_node(Node * node, Node * new_node) noexcept
393 assert(node != new_node);
394 assert(node != last);
397 Node * parent = ULINK(node);
398 Node * left_child =
LLINK(node);
399 Node * right_child =
RLINK(node);
402 ULINK(new_node) = parent;
403 LLINK(new_node) = left_child;
404 RLINK(new_node) = right_child;
409 assert(
LLINK(parent) == node);
410 LLINK(parent) = new_node;
414 assert(
RLINK(parent) == node);
415 RLINK(parent) = new_node;
421 RLINK(left_child) = new_node;
422 LLINK(right_child) = new_node;
426 ULINK(left_child) = new_node;
428 if (ULINK(right_child) == node)
429 ULINK(right_child) = new_node;
432 assert(left_child == last);
433 RLINK(left_child) = new_node;
434 LLINK(right_child) = new_node;
438 CTRL_BITS(new_node) = CTRL_BITS(node);
441 static void __postorder_delete(Node * p, Node * incomplete_node) noexcept
449 __postorder_delete(
LLINK(p), incomplete_node);
451 if (p != incomplete_node)
452 __postorder_delete(
RLINK(p), incomplete_node);
459 Node * getRoot() noexcept {
return root; }
461 Node * getRoot()
const noexcept {
return const_cast<Node*
>(root); }
465 template <
class Operation>
static 466 void __for_each_in_preorder(Node * p, Operation & operation)
472 __for_each_in_preorder(advance_left(p), operation);
473 __for_each_in_preorder(advance_right(p), operation);
476 template <
class Operation>
static 477 void __for_each_in_inorder(Node * p, Operation & operation)
482 __for_each_in_inorder(advance_left(p), operation);
484 __for_each_in_inorder(advance_right(p), operation);
487 template <
class Operation>
488 bool preorder_traverse(Node * p, Operation op)
const noexcept(noexcept(op))
494 if (not preorder_traverse(advance_left(p), op))
496 return preorder_traverse(advance_right(p), op);
501 template <
class Operation>
502 bool preorder_traverse(Operation op)
const noexcept(noexcept(op))
504 return preorder_traverse(getRoot(), op);
507 template <
class Operation>
508 void for_each_in_preorder(Operation & operation)
const 510 return __for_each_in_preorder<Operation>(getRoot(), operation);
513 template <
class Operation>
514 void for_each_in_preorder(Operation && operation = Operation())
const 516 return for_each_in_preorder(operation);
519 template <
class Operation>
520 void for_each_in_inorder(Operation & operation)
const 522 return __for_each_in_inorder<Operation>(getRoot(), operation);
525 template <
class Operation>
526 void for_each_in_inorder(Operation && operation = Operation())
const 528 return for_each_in_inorder(operation);
534 bool __level_traverse(Node * root, Op & operation)
const 544 Node * p = queue.
get();
546 if (not operation(p))
549 Node * c = advance_left(p);
555 c = advance_right(p);
568 return __level_traverse(getRoot(), operation);
571 GenBinHeap(Compare __cmp = Compare()) noexcept
572 : cmp(__cmp), head(&head_node), root(
RLINK(head)), last(&head_node),
594 assert(num_nodes == 0);
606 Node * pp =
RLINK(last);
625 assert(not IS_LEAF(pp));
634 Node * getMin_ne() noexcept
636 Node *ret_val = root;
646 swap_root_with_last();
666 throw std::underflow_error (
"Heap is empty");
701 Node *
remove(Node * node)
704 throw std::underflow_error (
"Heap is empty");
710 return remove_last();
712 Node * p = remove_last();
721 replace_node(node, p);
737 while (not this->is_empty())
743 __postorder_delete(root, ULINK(last));
745 __postorder_delete(root,
nullptr);
757 throw std::underflow_error (
"Heap is empty");
763 const size_t &
size() const noexcept {
return num_nodes; }
766 bool is_empty() const noexcept {
return size() == 0; }
770 static Node * advance_left(Node * p) noexcept
778 static Node * advance_right(Node * p) noexcept
783 if (not has_sibling(
LLINK(p)))
789 virtual bool verify_heap(Node * p)
const 791 Node * left_link = advance_left(p);
792 if (left_link ==
nullptr)
798 if (cmp (
KEY(left_link),
KEY(p)))
801 Node * right_link = advance_right(p);
802 if (right_link ==
nullptr)
803 return verify_heap(left_link);
805 if (cmp (
KEY(right_link),
KEY(p)))
808 return verify_heap(right_link);
813 bool verify_heap()
const 818 return verify_heap(root);
823 static const size_t Stack_Size = 64;
827 Node * curr =
nullptr;
833 : heap_ptr(&const_cast<GenBinHeap&>(h)), s(Stack_Size)
840 void reset_first() noexcept
846 curr = heap_ptr->root;
850 void reset_last() noexcept
857 auto ptr = heap_ptr->root;
861 ptr = advance_right(ptr);
867 pos = heap_ptr->num_nodes - 1;
870 bool has_curr()
const noexcept {
return curr !=
nullptr; }
872 Node * get_curr_ne()
const noexcept {
return curr; }
874 Node * get_curr()
const 877 throw std::overflow_error(
"Iterator overflow");
878 return get_curr_ne();
881 void next_ne() noexcept
884 auto l = advance_left(curr), r = advance_right(curr);
908 throw std::overflow_error(
"Iterator overflow");
912 size_t get_pos()
const noexcept {
return pos; }
918 pos = heap_ptr->num_nodes;
939 template <
class Key,
typename Compare = Aleph::less<Key> >
943 using Node = BinHeapNode<Key>;
964 template <
class Key,
typename Compare = Aleph::less<Key> >
968 using Node = BinHeapNodeVtl<Key>;
979 # endif // TPL_BINHEAP_H
T pop() noexcept
Pop by moving the top of stack.
Definition: tpl_arrayStack.H:430
bool is_empty() const noexcept
rioReturn true if this is empty
Definition: tpl_dynListQueue.H:112
Node * insert(Node *p) noexcept
Definition: tpl_binHeap.H:587
Node * top()
Definition: tpl_binHeap.H:754
Definition: tpl_dynListQueue.H:50
Node * getMax()
Definition: tpl_binHeap.H:671
Node::Key_Type & KEY(Node *p) noexcept
Definition: tpl_binNode.H:318
Definition: tpl_arrayStack.H:302
void update(Node *p) noexcept
Definition: tpl_binHeap.H:686
Definition: tpl_binHeap.H:103
Node *& LLINK(Node *p) noexcept
Definition: tpl_binNode.H:298
bool is_empty() const noexcept
Return true if stack is empty.
Definition: tpl_arrayStack.H:477
Node * getMin()
Definition: tpl_binHeap.H:663
bool level_traverse(Node *root, Operation &operation)
Definition: tpl_binNodeUtils.H:662
Definition: tpl_binHeap.H:940
Definition: tpl_binHeap.H:965
#define DECLARE_BINNODE(Name, height, Control_Data)
Definition: tpl_binNode.H:232
void empty() noexcept
Empty the stack.
Definition: tpl_arrayStack.H:480
void remove_all_and_delete() noexcept
Definition: tpl_binHeap.H:730
T & push(const T &data) noexcept
Definition: tpl_arrayStack.H:385
const size_t & size() const noexcept
Retorna la cardinalidad del heap.
Definition: tpl_binHeap.H:763
bool is_empty() const noexcept
Retorna true si el heap está vacÃo.
Definition: tpl_binHeap.H:766
T get()
Definition: tpl_dynListQueue.H:165
Node *& RLINK(Node *p) noexcept
Definition: tpl_binNode.H:307
T & put(const T &data)
The type of element.
Definition: tpl_dynListQueue.H:125