26 #ifndef MLN_UTIL_FIBONACCI_HEAP_HH
27 # define MLN_UTIL_FIBONACCI_HEAP_HH
31 # include <mln/core/concept/object.hh>
32 # include <mln/util/ord.hh>
50 template <
typename P,
typename T>
64 const T&
value()
const;
88 bool operator<(fibonacci_heap_node<P,T>&
rhs);
90 void print_(std::ostream& ostr)
const;
116 template <
typename P,
typename T>
170 std::ostream&
print_(std::ostream& ostr,
242 mutable long num_nodes;
243 mutable long num_trees;
244 mutable long num_marked_nodes;
249 template <
typename P,
typename T>
251 operator<<(std::ostream& ostr, const fibonacci_heap<P,T>& heap);
255 # ifndef MLN_INCLUDE_ONLY
267 template <
typename P,
typename T>
270 : left_(0), right_(0), parent_(0), child_(0),
271 degree_(0), mark_(0), priority_(0)
277 template <
typename P,
typename T>
279 fibonacci_heap_node<P,T>::fibonacci_heap_node(
const P& priority,
281 : left_(0), right_(0), parent_(0), child_(0),
282 degree_(0), mark_(0), priority_(priority), value_(new_value)
287 template <
typename P,
typename T>
289 fibonacci_heap_node<P,T>::~fibonacci_heap_node()
294 template <
typename P,
typename T>
303 template <
typename P,
typename T>
306 fibonacci_heap_node<P,T>::priority()
const
312 template <
typename P,
typename T>
314 fibonacci_heap_node<P,T> *
321 template <
typename P,
typename T>
323 fibonacci_heap_node<P,T> *
330 template <
typename P,
typename T>
332 fibonacci_heap_node<P,T> *
333 fibonacci_heap_node<P,T>::parent()
const
339 template <
typename P,
typename T>
341 fibonacci_heap_node<P,T> *
342 fibonacci_heap_node<P,T>::child()
const
348 template <
typename P,
typename T>
351 fibonacci_heap_node<P,T>::degree()
const
357 template <
typename P,
typename T>
360 fibonacci_heap_node<P,T>::mark()
const
366 template <
typename P,
typename T>
369 fibonacci_heap_node<P,T>::set_value(
const T&
value)
375 template <
typename P,
typename T>
378 fibonacci_heap_node<P,T>::set_left(fibonacci_heap_node<P,T> *node)
384 template <
typename P,
typename T>
387 fibonacci_heap_node<P,T>::set_right(fibonacci_heap_node<P,T> *node)
393 template <
typename P,
typename T>
396 fibonacci_heap_node<P,T>::set_parent(fibonacci_heap_node<P,T> *node)
402 template <
typename P,
typename T>
405 fibonacci_heap_node<P,T>::set_child(fibonacci_heap_node<P,T> *node)
411 template <
typename P,
typename T>
414 fibonacci_heap_node<P,T>::set_degree(
short degree)
420 template <
typename P,
typename T>
423 fibonacci_heap_node<P,T>::set_mark(
short mark)
429 template <
typename P,
typename T>
431 void fibonacci_heap_node<P,T>::operator=(fibonacci_heap_node<P,T>&
rhs)
433 priority_ = rhs.priority();
434 value_ = rhs.value();
438 template <
typename P,
typename T>
443 return priority_ == rhs.priority() && value_ == rhs.value();
447 template <
typename P,
typename T>
457 template <
typename P,
typename T>
459 void fibonacci_heap_node<P,T>::print_(std::ostream& ostr)
const
461 ostr << value_ <<
" (" << priority_ <<
")";
473 template <
typename P,
typename T>
475 fibonacci_heap<P,T>::fibonacci_heap()
481 template <
typename P,
typename T>
483 fibonacci_heap<P,T>::fibonacci_heap(
const fibonacci_heap<P,T>& rhs)
484 : Object< fibonacci_heap<P,
T> >()
486 min_root = rhs.min_root;
487 num_nodes = rhs.num_nodes;
488 num_trees = rhs.num_trees;
489 num_marked_nodes = rhs.num_marked_nodes;
496 rhs.num_marked_nodes = 0;
500 template <
typename P,
typename T>
508 template <
typename P,
typename T>
513 typedef internal::fibonacci_heap_node<P,T> node_t;
514 node_t *new_node =
new node_t(priority, value);
520 template <
typename P,
typename T>
525 if (other_heap.is_empty() || &other_heap ==
this)
530 internal::fibonacci_heap_node<P,T> *min1, *min2, *next1, *next2;
537 min2 = other_heap.min_root;
538 next1 = min1->right();
539 next2 = min2->right();
545 min1->set_right(next2);
546 next2->set_left(min1);
547 min2->set_right(next1);
548 next1->set_left(min2);
555 min_root = other_heap.min_root;
558 num_nodes += other_heap.num_nodes;
559 num_marked_nodes += other_heap.num_marked_nodes;
560 num_trees += other_heap.num_trees;
563 other_heap.soft_clear_();
565 mln_postcondition(other_heap.is_empty());
569 template <
typename P,
typename T>
574 return min_root->value();
578 template <
typename P,
typename T>
583 mln_precondition(is_valid());
584 mln_precondition(!is_empty());
586 internal::fibonacci_heap_node<P,T> *result = min_root;
587 fibonacci_heap<P,T> *child_heap = 0;
590 min_root = result->right();
591 result->right()->set_left(result->left());
592 result->left()->set_right(result->right());
594 result->set_right(0);
602 result->set_degree(0);
606 if (result->child() == 0)
608 if (min_root == result)
615 else if (min_root == result)
616 min_root = result->child();
623 child_heap =
new fibonacci_heap<P,T>();
624 child_heap->min_root = result->child();
628 if (result->child() != 0)
629 result->child()->set_parent(0);
630 result->set_child(0);
631 result->set_parent(0);
647 T val = result->value();
654 template <
typename P,
typename T>
657 fibonacci_heap<P,T>::decrease_key(internal::fibonacci_heap_node<P,T> *node,
658 internal::fibonacci_heap_node<P,T>& key)
660 internal::fibonacci_heap_node<P,T> *parent;
662 if (node == 0 || *node < key)
667 parent = node->parent();
668 if (parent != 0 && *node < *parent)
671 cascading_cut(parent);
674 if (*node < *min_root)
681 template <
typename P,
typename T>
684 fibonacci_heap<P,T>::remove(internal::fibonacci_heap_node<P,T> *node)
686 internal::fibonacci_heap_node<P,T> temp;
692 result = decrease_key(node, temp);
695 if (pop_front() == 0)
705 template <
typename P,
typename T>
710 return min_root == 0;
714 template <
typename P,
typename T>
719 return min_root != 0;
723 template <
typename P,
typename T>
728 while (min_root != 0)
733 template <
typename P,
typename T>
736 fibonacci_heap<P,T>::soft_clear_()
741 num_marked_nodes = 0;
745 template <
typename P,
typename T>
754 template <
typename P,
typename T>
761 min_root = rhs.min_root;
762 num_nodes = rhs.num_nodes;
763 num_trees = rhs.num_trees;
764 num_marked_nodes = rhs.num_marked_nodes;
771 template <
typename P,
typename T>
774 internal::fibonacci_heap_node<P,T> *tree,
775 internal::fibonacci_heap_node<P,T> *parent)
const
777 internal::fibonacci_heap_node<P,T>* temp = 0;
786 if (temp->left() == 0)
787 ostr <<
"(left is 0)";
789 if (temp->parent() != parent)
790 ostr <<
"(parent is incorrect)";
791 if (temp->right() == 0)
792 ostr <<
"(right is 0)";
793 else if (temp->right()->left() != temp)
794 ostr <<
"(Error in left link left) ->";
798 temp = temp->right();
800 }
while (temp != 0 && temp != tree);
803 ostr <<
" <empty>" << std::endl;
810 ostr <<
"children of " << temp->value() <<
": ";
811 if (temp->child() == 0)
812 ostr <<
"NONE" << std::endl;
813 else print_(ostr, temp->child(), temp);
814 temp = temp->right();
815 }
while (temp!=0 && temp != tree);
822 template <
typename P,
typename T>
824 void fibonacci_heap<P,T>::consolidate()
826 internal::fibonacci_heap_node<P,T> *x, *y, *w;
827 internal::fibonacci_heap_node<P,T> *a[1 + 8 *
sizeof (long)];
828 short dn = 1 + 8 *
sizeof (long);
831 for (
int i = 0; i < dn; ++i)
842 min_root->left()->set_right(0);
843 min_root->set_left(0);
859 if (w == y) w = y->right();
873 for (
int i = 0; i < dn; ++i)
875 add_to_root_list(a[i]);
879 template <
typename P,
typename T>
882 fibonacci_heap<P,T>::link(internal::fibonacci_heap_node<P,T> *y,
883 internal::fibonacci_heap_node<P,T> *x)
887 y->right()->set_left(y->left());
889 y->left()->set_right(y->right());
904 y->set_left(x->child());
905 y->set_right(x->child()->right());
906 x->child()->set_right(y);
907 y->right()->set_left(y);
911 x->set_degree(x->degree() + 1);
920 template <
typename P,
typename T>
923 fibonacci_heap<P,T>::add_to_root_list(internal::fibonacci_heap_node<P,T> *x)
934 template <
typename P,
typename T>
937 fibonacci_heap<P,T>::cut(internal::fibonacci_heap_node<P,T> *x,
938 internal::fibonacci_heap_node<P,T> *y)
941 y->child() = x->right();
945 y->set_degree(y->degree() - 1);
947 x->left()->right() = x->right();
948 x->right()->left() = x->left();
954 template <
typename P,
typename T>
957 fibonacci_heap<P,T>::cascading_cut(internal::fibonacci_heap_node<P,T> *y)
959 internal::fibonacci_heap_node<P,T> *z = y->parent();
979 template <
typename P,
typename T>
982 fibonacci_heap<P,T>::insert(internal::fibonacci_heap_node<P,T> *node)
992 node->set_left(node);
993 node->set_right(node);
999 node->set_right(min_root->right());
1000 node->set_left(min_root);
1003 node->left()->set_right(node);
1004 node->right()->set_left(node);
1008 if (*node < *min_root)
1015 node->set_parent(0);
1019 template <
typename P,
typename T>
1022 fibonacci_heap<P,T>::exchange(internal::fibonacci_heap_node<P,T>*& n1,
1023 internal::fibonacci_heap_node<P,T>*& n2)
1025 internal::fibonacci_heap_node<P,T> *temp;
1033 template <
typename P,
typename T>
1035 operator<<(std::ostream& ostr, const fibonacci_heap<P,T>& heap)
1037 return heap.print_(ostr);
1040 # endif // ! MLN_INCLUDE_ONLY
1048 #endif // ! MLN_UTIL_FIBONACCI_HEAP_HH