00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef NL_RADIX_SORT_H
00027 #define NL_RADIX_SORT_H
00028
00029 #include "nel/misc/types_nl.h"
00030 #include "nel/misc/common.h"
00031
00032
00033 namespace NL3D {
00034
00035
00036
00049 template<class T> class CRadixSort
00050 {
00051 public:
00052
00062 CRadixSort(uint keyDepth= 32, uint digitDepth= 8)
00063 {
00064
00065 _KeyDepth= keyDepth;
00066 NLMISC::clamp(_KeyDepth, 1U, 32U);
00067 _DigitDepth= digitDepth;
00068 NLMISC::clamp(_DigitDepth, 1U, 16U);
00069 _DigitDepth= std::min(_DigitDepth, _KeyDepth);
00070
00071
00072 _DigitSize= 1<<_DigitDepth;
00073 _SortDigits.resize(_DigitSize);
00074 }
00075
00084 T *sort(T *array0, T *array1, uint size) {return doSort(array0, array1, size, true);}
00085
00086
00090 T *reverse_sort(T *array0, T *array1, uint size) {return doSort(array0, array1, size, false);}
00091
00092
00093
00094 private:
00095
00096 struct CSortDigit
00097 {
00098
00099 uint Count;
00100
00101 T *Ptr;
00102 };
00103
00104
00105 uint _KeyDepth;
00106 uint _DigitDepth;
00107 uint _DigitSize;
00108
00109 std::vector<CSortDigit> _SortDigits;
00110
00111
00113 T *doSort(T *arraySrc, T *arrayDst, uint size, bool increasingOrder)
00114 {
00115 if(size==0)
00116 return arraySrc;
00117
00118
00119 for(uint digit=0; digit< _KeyDepth; digit+=_DigitDepth )
00120 {
00121 sint i;
00122
00123 uint digitShift= digit;
00124 uint digitMask= _DigitSize - 1;
00125
00126
00127 for(i=0; i<(sint)_DigitSize; i++)
00128 {
00129 _SortDigits[i].Count= 0;
00130 }
00131
00132
00133 T *srcPtr= arraySrc;
00134 for(i=0; i<(sint)size; i++, srcPtr++)
00135 {
00136
00137 uint32 key= srcPtr->getRadixKey();
00138
00139 key>>= digitShift;
00140 key&= digitMask;
00141
00142 _SortDigits[key].Count++;
00143 }
00144
00145
00146 T *dstPtr= arrayDst;
00147 if(increasingOrder)
00148 {
00149 for(i=0; i<(sint)_DigitSize; i++)
00150 {
00151
00152 _SortDigits[i].Ptr= dstPtr;
00153
00154 dstPtr+= _SortDigits[i].Count;
00155 }
00156 }
00157 else
00158 {
00159
00160
00161 for(i=_DigitSize-1; i>=0; i--)
00162 {
00163
00164 _SortDigits[i].Ptr= dstPtr;
00165
00166 dstPtr+= _SortDigits[i].Count;
00167 }
00168 }
00169
00170
00171 srcPtr= arraySrc;
00172 for(i=0; i<(sint)size; i++, srcPtr++)
00173 {
00174
00175 uint32 key= srcPtr->getRadixKey();
00176
00177 key>>= digitShift;
00178 key&= digitMask;
00179
00180 *(_SortDigits[key].Ptr++)= *srcPtr;
00181 }
00182
00183
00184
00185 std::swap(arraySrc, arrayDst);
00186 }
00187
00188
00189 return arraySrc;
00190 }
00191
00192 };
00193
00194
00195 }
00196
00197
00198 #endif // NL_RADIX_SORT_H
00199
00200