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>
51 class fibonacci_heap_node
56 fibonacci_heap_node();
59 fibonacci_heap_node(
const P& priority,
const T& value);
61 ~fibonacci_heap_node();
64 const T&
value()
const;
66 const P& priority()
const;
68 fibonacci_heap_node<P,T> *left()
const;
69 fibonacci_heap_node<P,T> *right()
const;
70 fibonacci_heap_node<P,T> *parent()
const;
71 fibonacci_heap_node<P,T> *child()
const;
78 void set_value(
const T&);
79 void set_left(fibonacci_heap_node<P,T> *node);
80 void set_right(fibonacci_heap_node<P,T> *node);
81 void set_parent(fibonacci_heap_node<P,T> *node);
82 void set_child(fibonacci_heap_node<P,T> *node);
83 void set_degree(
short degree);
84 void set_mark(
short mark);
86 void operator=(fibonacci_heap_node<P,T>& rhs);
87 bool operator==(fibonacci_heap_node<P,T>& rhs);
88 bool operator<(fibonacci_heap_node<P,T>& rhs);
90 void print_(std::ostream& ostr)
const;
95 fibonacci_heap_node<P,T> *left_;
96 fibonacci_heap_node<P,T> *right_;
97 fibonacci_heap_node<P,T> *parent_;
98 fibonacci_heap_node<P,T> *child_;
116 template <
typename P,
typename T>
135 void push(
const P& priority,
const T& value);
142 const T&
front()
const;
167 std::ostream& print_(std::ostream& ostr,
168 internal::fibonacci_heap_node<P,T> *
tree = 0,
169 internal::fibonacci_heap_node<P,T> *parent = 0)
const;
180 int decrease_key(internal::fibonacci_heap_node<P,T> *node,
181 internal::fibonacci_heap_node<P,T>& key);
187 int remove(internal::fibonacci_heap_node<P,T> *node);
190 void insert(internal::fibonacci_heap_node<P,T> *node);
193 void exchange(internal::fibonacci_heap_node<P,T>*& lhs,
194 internal::fibonacci_heap_node<P,T>*& rhs);
215 void link(internal::fibonacci_heap_node<P,T> *lhs,
216 internal::fibonacci_heap_node<P,T> *rhs);
218 void add_to_root_list(internal::fibonacci_heap_node<P,T> *);
221 void cut(internal::fibonacci_heap_node<P,T> *lhs,
222 internal::fibonacci_heap_node<P,T> *rhs);
231 void cascading_cut(internal::fibonacci_heap_node<P,T> *);
238 mutable internal::fibonacci_heap_node<P,T> *min_root;
239 mutable long num_nodes;
240 mutable long num_trees;
241 mutable long num_marked_nodes;
246 template <
typename P,
typename T>
248 operator<<(std::ostream& ostr, const fibonacci_heap<P,T>& heap);
252 # ifndef MLN_INCLUDE_ONLY
264 template <
typename P,
typename T>
266 fibonacci_heap_node<P,T>::fibonacci_heap_node()
267 : left_(0), right_(0), parent_(0), child_(0),
268 degree_(0), mark_(0), priority_(0)
274 template <
typename P,
typename T>
276 fibonacci_heap_node<P,T>::fibonacci_heap_node(
const P& priority,
278 : left_(0), right_(0), parent_(0), child_(0),
279 degree_(0), mark_(0), priority_(priority), value_(new_value)
284 template <
typename P,
typename T>
286 fibonacci_heap_node<P,T>::~fibonacci_heap_node()
291 template <
typename P,
typename T>
294 fibonacci_heap_node<P,T>::value()
const
300 template <
typename P,
typename T>
303 fibonacci_heap_node<P,T>::priority()
const
309 template <
typename P,
typename T>
311 fibonacci_heap_node<P,T> *
312 fibonacci_heap_node<P,T>::left()
const
318 template <
typename P,
typename T>
320 fibonacci_heap_node<P,T> *
321 fibonacci_heap_node<P,T>::right()
const
327 template <
typename P,
typename T>
329 fibonacci_heap_node<P,T> *
330 fibonacci_heap_node<P,T>::parent()
const
336 template <
typename P,
typename T>
338 fibonacci_heap_node<P,T> *
339 fibonacci_heap_node<P,T>::child()
const
345 template <
typename P,
typename T>
348 fibonacci_heap_node<P,T>::degree()
const
354 template <
typename P,
typename T>
357 fibonacci_heap_node<P,T>::mark()
const
363 template <
typename P,
typename T>
366 fibonacci_heap_node<P,T>::set_value(
const T& value)
372 template <
typename P,
typename T>
375 fibonacci_heap_node<P,T>::set_left(fibonacci_heap_node<P,T> *node)
381 template <
typename P,
typename T>
384 fibonacci_heap_node<P,T>::set_right(fibonacci_heap_node<P,T> *node)
390 template <
typename P,
typename T>
393 fibonacci_heap_node<P,T>::set_parent(fibonacci_heap_node<P,T> *node)
399 template <
typename P,
typename T>
402 fibonacci_heap_node<P,T>::set_child(fibonacci_heap_node<P,T> *node)
408 template <
typename P,
typename T>
411 fibonacci_heap_node<P,T>::set_degree(
short degree)
417 template <
typename P,
typename T>
420 fibonacci_heap_node<P,T>::set_mark(
short mark)
426 template <
typename P,
typename T>
428 void fibonacci_heap_node<P,T>::operator=(fibonacci_heap_node<P,T>& rhs)
430 priority_ = rhs.priority();
431 value_ = rhs.value();
435 template <
typename P,
typename T>
438 fibonacci_heap_node<P,T>::operator==(fibonacci_heap_node<P,T>& rhs)
440 return priority_ == rhs.priority() && value_ == rhs.value();
444 template <
typename P,
typename T>
447 fibonacci_heap_node<P,T>::operator<(fibonacci_heap_node<P,T>& rhs)
454 template <
typename P,
typename T>
456 void fibonacci_heap_node<P,T>::print_(std::ostream& ostr)
const
458 ostr << value_ <<
" (" << priority_ <<
")";
470 template <
typename P,
typename T>
478 template <
typename P,
typename T>
483 min_root = rhs.min_root;
484 num_nodes = rhs.num_nodes;
485 num_trees = rhs.num_trees;
486 num_marked_nodes = rhs.num_marked_nodes;
493 rhs.num_marked_nodes = 0;
497 template <
typename P,
typename T>
505 template <
typename P,
typename T>
510 typedef internal::fibonacci_heap_node<P,T> node_t;
511 node_t *new_node =
new node_t(priority, value);
517 template <
typename P,
typename T>
522 if (other_heap.
is_empty() || &other_heap ==
this)
527 internal::fibonacci_heap_node<P,T> *min1, *min2, *next1, *next2;
534 min2 = other_heap.min_root;
535 next1 = min1->right();
536 next2 = min2->right();
542 min1->set_right(next2);
543 next2->set_left(min1);
544 min2->set_right(next1);
545 next1->set_left(min2);
552 min_root = other_heap.min_root;
555 num_nodes += other_heap.num_nodes;
556 num_marked_nodes += other_heap.num_marked_nodes;
557 num_trees += other_heap.num_trees;
560 other_heap.soft_clear_();
562 mln_postcondition(other_heap.
is_empty());
566 template <
typename P,
typename T>
571 return min_root->value();
575 template <
typename P,
typename T>
580 mln_precondition(is_valid());
581 mln_precondition(!is_empty());
583 internal::fibonacci_heap_node<P,T> *result = min_root;
587 min_root = result->right();
588 result->right()->set_left(result->left());
589 result->left()->set_right(result->right());
591 result->set_right(0);
599 result->set_degree(0);
603 if (result->child() == 0)
605 if (min_root == result)
612 else if (min_root == result)
613 min_root = result->child();
621 child_heap->min_root = result->child();
625 if (result->child() != 0)
626 result->child()->set_parent(0);
627 result->set_child(0);
628 result->set_parent(0);
644 T val = result->value();
651 template <
typename P,
typename T>
655 internal::fibonacci_heap_node<P,T>& key)
657 internal::fibonacci_heap_node<P,T> *parent;
659 if (node == 0 || *node < key)
664 parent = node->parent();
665 if (parent != 0 && *node < *parent)
668 cascading_cut(parent);
671 if (*node < *min_root)
678 template <
typename P,
typename T>
681 fibonacci_heap<P,T>::remove(internal::fibonacci_heap_node<P,T> *node)
683 internal::fibonacci_heap_node<P,T> temp;
689 result = decrease_key(node, temp);
692 if (pop_front() == 0)
702 template <
typename P,
typename T>
707 return min_root == 0;
711 template <
typename P,
typename T>
716 return min_root != 0;
720 template <
typename P,
typename T>
725 while (min_root != 0)
730 template <
typename P,
typename T>
738 num_marked_nodes = 0;
742 template <
typename P,
typename T>
751 template <
typename P,
typename T>
758 min_root = rhs.min_root;
759 num_nodes = rhs.num_nodes;
760 num_trees = rhs.num_trees;
761 num_marked_nodes = rhs.num_marked_nodes;
768 template <
typename P,
typename T>
771 internal::fibonacci_heap_node<P,T> *
tree,
772 internal::fibonacci_heap_node<P,T> *parent)
const
774 internal::fibonacci_heap_node<P,T>* temp = 0;
783 if (temp->left() == 0)
784 ostr <<
"(left is 0)";
786 if (temp->parent() != parent)
787 ostr <<
"(parent is incorrect)";
788 if (temp->right() == 0)
789 ostr <<
"(right is 0)";
790 else if (temp->right()->left() != temp)
791 ostr <<
"(Error in left link left) ->";
795 temp = temp->right();
797 }
while (temp != 0 && temp != tree);
800 ostr <<
" <empty>" << std::endl;
807 ostr <<
"children of " << temp->value() <<
": ";
808 if (temp->child() == 0)
809 ostr <<
"NONE" << std::endl;
810 else print_(ostr, temp->child(), temp);
811 temp = temp->right();
812 }
while (temp!=0 && temp != tree);
819 template <
typename P,
typename T>
821 void fibonacci_heap<P,T>::consolidate()
823 internal::fibonacci_heap_node<P,T> *x, *y, *w;
824 internal::fibonacci_heap_node<P,T> *a[1 + 8 *
sizeof (long)];
825 short dn = 1 + 8 *
sizeof (long);
828 for (
int i = 0; i < dn; ++i)
839 min_root->left()->set_right(0);
840 min_root->set_left(0);
856 if (w == y) w = y->right();
870 for (
int i = 0; i < dn; ++i)
872 add_to_root_list(a[i]);
876 template <
typename P,
typename T>
879 fibonacci_heap<P,T>::link(internal::fibonacci_heap_node<P,T> *y,
880 internal::fibonacci_heap_node<P,T> *x)
884 y->right()->set_left(y->left());
886 y->left()->set_right(y->right());
901 y->set_left(x->child());
902 y->set_right(x->child()->right());
903 x->child()->set_right(y);
904 y->right()->set_left(y);
908 x->set_degree(x->degree() + 1);
917 template <
typename P,
typename T>
920 fibonacci_heap<P,T>::add_to_root_list(internal::fibonacci_heap_node<P,T> *x)
931 template <
typename P,
typename T>
934 fibonacci_heap<P,T>::cut(internal::fibonacci_heap_node<P,T> *x,
935 internal::fibonacci_heap_node<P,T> *y)
938 y->child() = x->right();
942 y->set_degree(y->degree() - 1);
944 x->left()->right() = x->right();
945 x->right()->left() = x->left();
951 template <
typename P,
typename T>
954 fibonacci_heap<P,T>::cascading_cut(internal::fibonacci_heap_node<P,T> *y)
956 internal::fibonacci_heap_node<P,T> *z = y->parent();
976 template <
typename P,
typename T>
979 fibonacci_heap<P,T>::insert(internal::fibonacci_heap_node<P,T> *node)
989 node->set_left(node);
990 node->set_right(node);
996 node->set_right(min_root->right());
997 node->set_left(min_root);
1000 node->left()->set_right(node);
1001 node->right()->set_left(node);
1005 if (*node < *min_root)
1012 node->set_parent(0);
1016 template <
typename P,
typename T>
1019 fibonacci_heap<P,T>::exchange(internal::fibonacci_heap_node<P,T>*& n1,
1020 internal::fibonacci_heap_node<P,T>*& n2)
1022 internal::fibonacci_heap_node<P,T> *temp;
1030 template <
typename P,
typename T>
1032 operator<<(std::ostream& ostr, const fibonacci_heap<P,T>& heap)
1034 return heap.print_(ostr);
1037 # endif // ! MLN_INCLUDE_ONLY
1045 #endif // ! MLN_UTIL_FIBONACCI_HEAP_HH