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