bucket_sort.hpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. //=======================================================================
  2. // Copyright 2007 Aaron Windsor
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //=======================================================================
  8. #ifndef __BUCKET_SORT_HPP__
  9. #define __BUCKET_SORT_HPP__
  10. #include <vector>
  11. #include <algorithm>
  12. #include <boost/property_map/property_map.hpp>
  13. namespace boost
  14. {
  15. template < typename ItemToRankMap > struct rank_comparison
  16. {
  17. rank_comparison(ItemToRankMap arg_itrm) : itrm(arg_itrm) {}
  18. template < typename Item > bool operator()(Item x, Item y) const
  19. {
  20. return get(itrm, x) < get(itrm, y);
  21. }
  22. private:
  23. ItemToRankMap itrm;
  24. };
  25. template < typename TupleType, int N,
  26. typename PropertyMapWrapper = identity_property_map >
  27. struct property_map_tuple_adaptor
  28. : public put_get_helper< typename PropertyMapWrapper::value_type,
  29. property_map_tuple_adaptor< TupleType, N, PropertyMapWrapper > >
  30. {
  31. typedef typename PropertyMapWrapper::reference reference;
  32. typedef typename PropertyMapWrapper::value_type value_type;
  33. typedef TupleType key_type;
  34. typedef readable_property_map_tag category;
  35. property_map_tuple_adaptor() {}
  36. property_map_tuple_adaptor(PropertyMapWrapper wrapper_map)
  37. : m_wrapper_map(wrapper_map)
  38. {
  39. }
  40. inline value_type operator[](const key_type& x) const
  41. {
  42. return get(m_wrapper_map, get< n >(x));
  43. }
  44. static const int n = N;
  45. PropertyMapWrapper m_wrapper_map;
  46. };
  47. // This function sorts a sequence of n items by their ranks in linear time,
  48. // given that all ranks are in the range [0, range). This sort is stable.
  49. template < typename ForwardIterator, typename ItemToRankMap, typename SizeType >
  50. void bucket_sort(ForwardIterator begin, ForwardIterator end, ItemToRankMap rank,
  51. SizeType range = 0)
  52. {
  53. #ifdef BOOST_GRAPH_PREFER_STD_LIB
  54. std::stable_sort(begin, end, rank_comparison< ItemToRankMap >(rank));
  55. #else
  56. typedef std::vector<
  57. typename boost::property_traits< ItemToRankMap >::key_type >
  58. vector_of_values_t;
  59. typedef std::vector< vector_of_values_t > vector_of_vectors_t;
  60. if (!range)
  61. {
  62. rank_comparison< ItemToRankMap > cmp(rank);
  63. ForwardIterator max_by_rank = std::max_element(begin, end, cmp);
  64. if (max_by_rank == end)
  65. return;
  66. range = get(rank, *max_by_rank) + 1;
  67. }
  68. vector_of_vectors_t temp_values(range);
  69. for (ForwardIterator itr = begin; itr != end; ++itr)
  70. {
  71. temp_values[get(rank, *itr)].push_back(*itr);
  72. }
  73. ForwardIterator orig_seq_itr = begin;
  74. typename vector_of_vectors_t::iterator itr_end = temp_values.end();
  75. for (typename vector_of_vectors_t::iterator itr = temp_values.begin();
  76. itr != itr_end; ++itr)
  77. {
  78. typename vector_of_values_t::iterator jtr_end = itr->end();
  79. for (typename vector_of_values_t::iterator jtr = itr->begin();
  80. jtr != jtr_end; ++jtr)
  81. {
  82. *orig_seq_itr = *jtr;
  83. ++orig_seq_itr;
  84. }
  85. }
  86. #endif
  87. }
  88. template < typename ForwardIterator, typename ItemToRankMap >
  89. void bucket_sort(ForwardIterator begin, ForwardIterator end, ItemToRankMap rank)
  90. {
  91. bucket_sort(begin, end, rank, 0);
  92. }
  93. template < typename ForwardIterator >
  94. void bucket_sort(ForwardIterator begin, ForwardIterator end)
  95. {
  96. bucket_sort(begin, end, identity_property_map());
  97. }
  98. } // namespace boost
  99. #endif //__BUCKET_SORT_HPP__