00001 #ifndef GIM_RADIXSORT_H_INCLUDED
00002 #define GIM_RADIXSORT_H_INCLUDED
00003
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "gim_memory.h"
00038
00041 class less_comparator
00042 {
00043 public:
00044
00045 template<class T,class Z>
00046 inline int operator() ( const T& a, const Z& b )
00047 {
00048 return ( a<b?-1:(a>b?1:0));
00049 }
00050 };
00051
00053 class integer_comparator
00054 {
00055 public:
00056
00057 template<class T>
00058 inline int operator() ( const T& a, const T& b )
00059 {
00060 return (int)(a-b);
00061 }
00062 };
00063
00065 class uint_key_func
00066 {
00067 public:
00068 template<class T>
00069 inline GUINT operator()( const T& a)
00070 {
00071 return (GUINT)a;
00072 }
00073 };
00074
00075
00077 class copy_elements_func
00078 {
00079 public:
00080 template<class T>
00081 inline void operator()(T& a,T& b)
00082 {
00083 a = b;
00084 }
00085 };
00086
00088 class memcopy_elements_func
00089 {
00090 public:
00091 template<class T>
00092 inline void operator()(T& a,T& b)
00093 {
00094 gim_simd_memcpy(&a,&b,sizeof(T));
00095 }
00096 };
00097
00098
00100 struct GIM_RSORT_TOKEN
00101 {
00102 GUINT m_key;
00103 GUINT m_value;
00104 GIM_RSORT_TOKEN()
00105 {
00106 }
00107 GIM_RSORT_TOKEN(const GIM_RSORT_TOKEN& rtoken)
00108 {
00109 m_key = rtoken.m_key;
00110 m_value = rtoken.m_value;
00111 }
00112
00113 inline bool operator <(const GIM_RSORT_TOKEN& other) const
00114 {
00115 return (m_key < other.m_key);
00116 }
00117
00118 inline bool operator >(const GIM_RSORT_TOKEN& other) const
00119 {
00120 return (m_key > other.m_key);
00121 }
00122 };
00123
00125 class GIM_RSORT_TOKEN_COMPARATOR
00126 {
00127 public:
00128
00129 inline int operator()( const GIM_RSORT_TOKEN& a, const GIM_RSORT_TOKEN& b )
00130 {
00131 return (int)((a.m_key) - (b.m_key));
00132 }
00133 };
00134
00135
00136
00137 #define kHist 2048
00138
00139 #define D11_0(x) (x & 0x7FF)
00140 #define D11_1(x) (x >> 11 & 0x7FF)
00141 #define D11_2(x) (x >> 22 )
00142
00143
00144
00146 inline void gim_radix_sort_rtokens(
00147 GIM_RSORT_TOKEN * array,
00148 GIM_RSORT_TOKEN * sorted, GUINT element_count)
00149 {
00150 GUINT i;
00151 GUINT b0[kHist * 3];
00152 GUINT *b1 = b0 + kHist;
00153 GUINT *b2 = b1 + kHist;
00154 for (i = 0; i < kHist * 3; ++i)
00155 {
00156 b0[i] = 0;
00157 }
00158 GUINT fi;
00159 GUINT pos;
00160 for (i = 0; i < element_count; ++i)
00161 {
00162 fi = array[i].m_key;
00163 b0[D11_0(fi)] ++;
00164 b1[D11_1(fi)] ++;
00165 b2[D11_2(fi)] ++;
00166 }
00167 {
00168 GUINT sum0 = 0, sum1 = 0, sum2 = 0;
00169 GUINT tsum;
00170 for (i = 0; i < kHist; ++i)
00171 {
00172 tsum = b0[i] + sum0;
00173 b0[i] = sum0 - 1;
00174 sum0 = tsum;
00175 tsum = b1[i] + sum1;
00176 b1[i] = sum1 - 1;
00177 sum1 = tsum;
00178 tsum = b2[i] + sum2;
00179 b2[i] = sum2 - 1;
00180 sum2 = tsum;
00181 }
00182 }
00183 for (i = 0; i < element_count; ++i)
00184 {
00185 fi = array[i].m_key;
00186 pos = D11_0(fi);
00187 pos = ++b0[pos];
00188 sorted[pos].m_key = array[i].m_key;
00189 sorted[pos].m_value = array[i].m_value;
00190 }
00191 for (i = 0; i < element_count; ++i)
00192 {
00193 fi = sorted[i].m_key;
00194 pos = D11_1(fi);
00195 pos = ++b1[pos];
00196 array[pos].m_key = sorted[i].m_key;
00197 array[pos].m_value = sorted[i].m_value;
00198 }
00199 for (i = 0; i < element_count; ++i)
00200 {
00201 fi = array[i].m_key;
00202 pos = D11_2(fi);
00203 pos = ++b2[pos];
00204 sorted[pos].m_key = array[i].m_key;
00205 sorted[pos].m_value = array[i].m_value;
00206 }
00207 }
00208
00209
00210
00211
00213
00219 template<typename T, class GETKEY_CLASS>
00220 void gim_radix_sort_array_tokens(
00221 T* array ,
00222 GIM_RSORT_TOKEN * sorted_tokens,
00223 GUINT element_count,GETKEY_CLASS uintkey_macro)
00224 {
00225 GIM_RSORT_TOKEN * _unsorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*element_count);
00226 for (GUINT _i=0;_i<element_count;++_i)
00227 {
00228 _unsorted[_i].m_key = uintkey_macro(array[_i]);
00229 _unsorted[_i].m_value = _i;
00230 }
00231 gim_radix_sort_rtokens(_unsorted,sorted_tokens,element_count);
00232 gim_free(_unsorted);
00233 gim_free(_unsorted);
00234 }
00235
00237
00244 template<typename T, class GETKEY_CLASS, class COPY_CLASS>
00245 void gim_radix_sort(
00246 T * array, GUINT element_count,
00247 GETKEY_CLASS get_uintkey_macro, COPY_CLASS copy_elements_macro)
00248 {
00249 GIM_RSORT_TOKEN * _sorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*element_count);
00250 gim_radix_sort_array_tokens(array,_sorted,element_count,get_uintkey_macro);
00251 T * _original_array = (T *) gim_alloc(sizeof(T)*element_count);
00252 gim_simd_memcpy(_original_array,array,sizeof(T)*element_count);
00253 for (GUINT _i=0;_i<element_count;++_i)
00254 {
00255 copy_elements_macro(array[_i],_original_array[_sorted[_i].m_value]);
00256 }
00257 gim_free(_original_array);
00258 gim_free(_sorted);
00259 }
00260
00262
00272 template<class T, typename KEYCLASS, typename COMP_CLASS>
00273 bool gim_binary_search_ex(
00274 const T* _array, GUINT _start_i,
00275 GUINT _end_i,GUINT & _result_index,
00276 const KEYCLASS & _search_key,
00277 COMP_CLASS _comp_macro)
00278 {
00279 GUINT _k;
00280 int _comp_result;
00281 GUINT _i = _start_i;
00282 GUINT _j = _end_i+1;
00283 while (_i < _j)
00284 {
00285 _k = (_j+_i-1)/2;
00286 _comp_result = _comp_macro(_array[_k], _search_key);
00287 if (_comp_result == 0)
00288 {
00289 _result_index = _k;
00290 return true;
00291 }
00292 else if (_comp_result < 0)
00293 {
00294 _i = _k+1;
00295 }
00296 else
00297 {
00298 _j = _k;
00299 }
00300 }
00301 _result_index = _i;
00302 return false;
00303 }
00304
00305
00306
00308
00317 template<class T>
00318 bool gim_binary_search(
00319 const T*_array,GUINT _start_i,
00320 GUINT _end_i,const T & _search_key,
00321 GUINT & _result_index)
00322 {
00323 GUINT _i = _start_i;
00324 GUINT _j = _end_i+1;
00325 GUINT _k;
00326 while(_i < _j)
00327 {
00328 _k = (_j+_i-1)/2;
00329 if(_array[_k]==_search_key)
00330 {
00331 _result_index = _k;
00332 return true;
00333 }
00334 else if (_array[_k]<_search_key)
00335 {
00336 _i = _k+1;
00337 }
00338 else
00339 {
00340 _j = _k;
00341 }
00342 }
00343 _result_index = _i;
00344 return false;
00345 }
00346
00347
00348
00350 template <typename T, typename COMP_CLASS>
00351 void gim_down_heap(T *pArr, GUINT k, GUINT n,COMP_CLASS CompareFunc)
00352 {
00353
00354
00355
00356 T temp = pArr[k - 1];
00357
00358 while (k <= n/2)
00359 {
00360 int child = 2*k;
00361
00362 if ((child < (int)n) && CompareFunc(pArr[child - 1] , pArr[child])<0)
00363 {
00364 child++;
00365 }
00366
00367 if (CompareFunc(temp , pArr[child - 1])<0)
00368 {
00369
00370 pArr[k - 1] = pArr[child - 1];
00371 k = child;
00372 }
00373 else
00374 {
00375 break;
00376 }
00377 }
00378 pArr[k - 1] = temp;
00379 }
00380
00381
00382 template <typename T, typename COMP_CLASS>
00383 void gim_heap_sort(T *pArr, GUINT element_count, COMP_CLASS CompareFunc)
00384 {
00385
00386 GUINT k;
00387 GUINT n = element_count;
00388 for (k = n/2; k > 0; k--)
00389 {
00390 gim_down_heap(pArr, k, n, CompareFunc);
00391 }
00392
00393
00394 while ( n>=2 )
00395 {
00396 gim_swap_elements(pArr,0,n-1);
00397 --n;
00398
00399 gim_down_heap(pArr, 1, n, CompareFunc);
00400 }
00401 }
00402
00403
00404
00405
00406 #endif // GIM_RADIXSORT_H_INCLUDED