diff --git a/lemon/kary_heap.h b/lemon/kary_heap.h --- a/lemon/kary_heap.h +++ b/lemon/kary_heap.h @@ -1,8 +1,8 @@ -/* -*- C++ -*- +/* -*- mode: C++; indent-tabs-mode: nil; -*- * - * This file is a part of LEMON, a generic C++ optimization library + * This file is a part of LEMON, a generic C++ optimization library. * - * Copyright (C) 2003-2008 + * Copyright (C) 2003-2009 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport * (Egervary Research Group on Combinatorial Optimization, EGRES). * @@ -19,152 +19,151 @@ #ifndef LEMON_KARY_HEAP_H #define LEMON_KARY_HEAP_H -///\ingroup auxdat +///\ingroup heaps ///\file -///\brief Kary Heap implementation. +///\brief Fourary heap implementation. -#include #include #include #include namespace lemon { - ///\ingroup auxdat + /// \ingroup heaps /// - ///\brief A Kary Heap implementation. + ///\brief K-ary heap data structure. /// - ///This class implements the \e Kary \e heap data structure. A \e heap - ///is a data structure for storing items with specified values called \e - ///priorities in such a way that finding the item with minimum priority is - ///efficient. \c Compare specifies the ordering of the priorities. In a heap - ///one can change the priority of an item, add or erase an item, etc. + /// This class implements the \e K-ary \e heap data structure. + /// It fully conforms to the \ref concepts::Heap "heap concept". /// - ///\param _Prio Type of the priority of the items. - ///\param _ItemIntMap A read and writable Item int map, used internally - ///to handle the cross references. - ///\param _Compare A class for the ordering of the priorities. The - ///default is \c std::less<_Prio>. + /// The \ref KaryHeap "K-ary heap" is a generalization of the + /// \ref BinHeap "binary heap" structure, its nodes have at most + /// \c K children, instead of two. + /// \ref BinHeap and \ref FouraryHeap are specialized implementations + /// of this structure for K=2 and K=4, respectively. /// - ///\sa FibHeap - ///\sa Dijkstra - ///\author Dorian Batha + /// \tparam PR Type of the priorities of the items. + /// \tparam IM A read-writable item map with \c int values, used + /// internally to handle the cross references. + /// \tparam CMP A functor class for comparing the priorities. + /// The default is \c std::less. + /// + ///\sa BinHeap + ///\sa FouraryHeap +#ifdef DOXYGEN + template +#else + template > +#endif + class KaryHeap { + public: + /// Type of the item-int map. + typedef IM ItemIntMap; + /// Type of the priorities. + typedef PR Prio; + /// Type of the items stored in the heap. + typedef typename ItemIntMap::Key Item; + /// Type of the item-priority pairs. + typedef std::pair Pair; + /// Functor type for comparing the priorities. + typedef CMP Compare; - template > - - class KaryHeap { - - public: - ///\e - typedef _ItemIntMap ItemIntMap; - ///\e - typedef _Prio Prio; - ///\e - typedef typename ItemIntMap::Key Item; - ///\e - typedef std::pair Pair; - ///\e - typedef _Compare Compare; - ///\e - - /// \brief Type to represent the items states. + /// \brief Type to represent the states of the items. /// - /// Each Item element have a state associated to it. It may be "in heap", - /// "pre heap" or "post heap". The latter two are indifferent from the + /// Each item has a state associated to it. It can be "in heap", + /// "pre-heap" or "post-heap". The latter two are indifferent from the /// heap's point of view, but may be useful to the user. /// - /// The ItemIntMap \e should be initialized in such way that it maps - /// PRE_HEAP (-1) to any element to be put in the heap... + /// The item-int map must be initialized in such way that it assigns + /// \c PRE_HEAP (-1) to any element to be put in the heap. enum State { - IN_HEAP = 0, - PRE_HEAP = -1, - POST_HEAP = -2 + IN_HEAP = 0, ///< = 0. + PRE_HEAP = -1, ///< = -1. + POST_HEAP = -2 ///< = -2. }; private: - std::vector data; - Compare comp; - ItemIntMap &iim; - int K; + std::vector _data; + Compare _comp; + ItemIntMap &_iim; + int _K; public: - /// \brief The constructor. + /// \brief Constructor. /// - /// The constructor. - /// \param _iim should be given to the constructor, since it is used - /// internally to handle the cross references. The value of the map - /// should be PRE_HEAP (-1) for each element. - explicit KaryHeap(ItemIntMap &_iim, const int &_K=32) : iim(_iim), K(_K) {} + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + explicit KaryHeap(ItemIntMap &map, int K=32) : _iim(map), _K(K) {} - /// \brief The constructor. + /// \brief Constructor. /// - /// The constructor. - /// \param _iim should be given to the constructor, since it is used - /// internally to handle the cross references. The value of the map - /// should be PRE_HEAP (-1) for each element. + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + /// \param comp The function object used for comparing the priorities. + KaryHeap(ItemIntMap &map, const Compare &comp, int K=32) + : _iim(map), _comp(comp), _K(K) {} + + /// \brief The number of items stored in the heap. /// - /// \param _comp The comparator function object. - KaryHeap(ItemIntMap &_iim, const Compare &_comp, const int &_K=32) - : iim(_iim), comp(_comp), K(_K) {} + /// This function returns the number of items stored in the heap. + int size() const { return _data.size(); } + /// \brief Check if the heap is empty. + /// + /// This function returns \c true if the heap is empty. + bool empty() const { return _data.empty(); } - /// The number of items stored in the heap. + /// \brief Make the heap empty. /// - /// \brief Returns the number of items stored in the heap. - int size() const { return data.size(); } - - /// \brief Checks if the heap stores no items. - /// - /// Returns \c true if and only if the heap stores no items. - bool empty() const { return data.empty(); } - - /// \brief Make empty this heap. - /// - /// Make empty this heap. It does not change the cross reference map. - /// If you want to reuse what is not surely empty you should first clear - /// the heap and after that you should set the cross reference map for - /// each item to \c PRE_HEAP. - void clear() { data.clear(); } + /// This functon makes the heap empty. + /// It does not change the cross reference map. If you want to reuse + /// a heap that is not surely empty, you should first clear it and + /// then you should set the cross reference map to \c PRE_HEAP + /// for each item. + void clear() { _data.clear(); } private: - int parent(int i) { return (i-1)/K; } - int first_child(int i) { return K*i+1; } + int parent(int i) { return (i-1)/_K; } + int firstChild(int i) { return _K*i+1; } bool less(const Pair &p1, const Pair &p2) const { - return comp(p1.second, p2.second); + return _comp(p1.second, p2.second); } - int find_min(const int child, const int length) { + int findMin(const int child, const int length) { int min=child, i=1; - while( i0 && less(p,data[par]) ) { - move(data[par],hole); + while( hole>0 && less(p,_data[par]) ) { + move(_data[par],hole); hole = par; par = parent(hole); } move(p, hole); } - void bubble_down(int hole, Pair p, int length) { + void bubbleDown(int hole, Pair p, int length) { if( length>1 ) { - int child = first_child(hole); + int child = firstChild(hole); while( child0) bubble_down(0, data[n], n); - data.pop_back(); + int n = _data.size()-1; + _iim.set(_data[0].first, POST_HEAP); + if (n>0) bubbleDown(0, _data[n], n); + _data.pop_back(); } - /// \brief Deletes \c i from the heap. + /// \brief Remove the given item from the heap. /// - /// This method deletes item \c i from the heap. - /// \param i The item to erase. - /// \pre The item should be in the heap. + /// This function removes the given item from the heap if it is + /// already stored. + /// \param i The item to delete. + /// \pre \e i must be in the heap. void erase(const Item &i) { - int h = iim[i]; - int n = data.size()-1; - iim.set(data[h].first, POST_HEAP); + int h = _iim[i]; + int n = _data.size()-1; + _iim.set(_data[h].first, POST_HEAP); if( h=0) s=0; return State(s); } - /// \brief Sets the state of the \c item in the heap. + /// \brief Set the state of an item in the heap. /// - /// Sets the state of the \c item in the heap. It can be used to - /// manually clear the heap when it is important to achive the - /// better time complexity. + /// This function sets the state of the given item in the heap. + /// It can be used to manually clear the heap when it is important + /// to achive better time complexity. /// \param i The item. /// \param st The state. It should not be \c IN_HEAP. void state(const Item& i, State st) { switch (st) { - case POST_HEAP: - case PRE_HEAP: - if (state(i) == IN_HEAP) erase(i); - iim[i] = st; - break; - case IN_HEAP: - break; + case POST_HEAP: + case PRE_HEAP: + if (state(i) == IN_HEAP) erase(i); + _iim[i] = st; + break; + case IN_HEAP: + break; } } - /// \brief Replaces an item in the heap. + /// \brief Replace an item in the heap. /// - /// The \c i item is replaced with \c j item. The \c i item should - /// be in the heap, while the \c j should be out of the heap. The - /// \c i item will out of the heap and \c j will be in the heap - /// with the same prioriority as prevoiusly the \c i item. + /// This function replaces item \c i with item \c j. + /// Item \c i must be in the heap, while \c j must be out of the heap. + /// After calling this method, item \c i will be out of the + /// heap and \c j will be in the heap with the same prioriority + /// as item \c i had before. void replace(const Item& i, const Item& j) { - int idx=iim[i]; - iim.set(i, iim[j]); - iim.set(j, idx); - data[idx].first=j; + int idx=_iim[i]; + _iim.set(i, _iim[j]); + _iim.set(j, idx); + _data[idx].first=j; } }; // class KaryHeap