![]() |
Template class
|
#include "boost/r_heap.hpp" template <typename T, int b = 32> class boost::radix_traits { static int const bits = b; static unsigned long value(T val); static int radix(T val, unsigned long offset); }; template <typename T, typename traits = boost::radix_traits<T> > class boost::radix_heap { public: class iterator { public: iterator(); T const& operator* () const; T const* operator->() const; iterator& operator++(); iterator operator++(int); bool operator== (iterator const& it); bool operator!= (iterator const& it); }; typedef T value_type; typedef T& reference; typedef T const& const_reference; typedef iterator const_iterator; typedef int size_type; typedef node* pointer; radix_heap(); ~radix_heap(); void remove(pointer); // sorry, not yet implemented void change(pointer, T const&); // sorry, not yet implemented void change_top(T const&); // sorry, not yet implemented void decrease(pointer, T const&); // sorry, not yet implemented void increase(pointer, T const&); // sorry, not yet implemented bool empty() const; size_type size() const; pointer push(T const&); T const& top() const; void pop(); iterator begin() const; iterator end() const; private: radix_heap(radix_heap const&); // deliberately not implemented void operator= (radix_heap const&); // deliberately not implemented }; |
Apart from the restriction on integral types, there is another restriction for the Radix heap, namely that elements cannot be decreased beyond the minimum value currently stored in the heap. A priority queue like this is suitable only in very specific cases but eg. Dijkstra's algorithm to find the shortest paths in a graph is one such application. In turn a radix heap seems to be significantly faster (however, I can't really tell because the current implementation has to be changed to implement the missing operations).
The Radix heap maintains a set of buckets and objects with different priority can end up in different buckets. To avoid excessive search for the minimum element, elements are redistributed into unused buckets. Each bucket is assigned a range of elements stored in the bucket where the smaller elements end up in buckets with narrow ranges: Initially, the ranges for the buckets are 0..0, 1..1, 2..3, 4..7, 8..15, and so on. Thus, the correct bucket can be found by determining the radix of the integral value. Now, when elements are removed from the heap, the first buckets become unused and the heap has to search larger buckets for the minium element. If it has found a bucket with multiple different elements, the heap knows that the smaller buckets are not used. Thus, the elements in the found bucket are redistributed into the unused buckets.
The only description of the Radix heap I have currently available (from Network Flows, Ahuja, Magnanti, Orlin, Prentice Hall) is somewhat silent about the details of the operation. Thus, I haven't implemented some of the operations. Also, it probably does not work to insert an element after there are elements extracted from the heap...
This class does not use a comparator function. Instead, it uses a traits class which is used to determine the radix of the elements. Actually, the traits class has three members:
For a description of the methods of Bugs
Some of the methods are not yet implemented and other methods are
probably buggy. However, I have to work on other stuff and need to
get the priority queue off my desk. If you really want to use this
class or if you have an idea how to implement the missing methods
please contact me. Maybe we can work out how to implement the missing
stuff. A paper describing Radix heaps would probably also help...
See Also
heap(3),
heap-common(3)