一、基数排序
稳定排序
按位排序:从低位(个位)到高位,取序列中元素相应位数字计数排序
c++代码:
//供RadixSort用的计数排序
void CountSort1(vector<int>& sequence, vector<int> vec_digit, int max_k=9);
void RadixSort(vector<int>& sequence, int n_digit)
{
const int c_len = sequence.size();
int i,j;
for(i=0; i<n_digit; ++i)
{
vector<int> vec_digit(c_len);
for(j=0; j<c_len; ++j)
vec_digit[j] = sequence[j] / int(pow(10,i)) % 10;
CountSort1(sequence, vec_digit);
}
}
void CountSort1(vector<int>& sequence, vector<int> vec_digit, int max_k)
{
vector<int> count(max_k+1,0); // 计数数组,max_k为vec_digit元素的最大值
const int c_len = sequence.size();
vector<int> sort_seq(c_len);
for(int i=0; i<c_len; ++i)
++count[vec_digit[i]];
for(int i=1; i<=max_k; ++i)
count[i] += count[i-1];
for(int i=c_len-1; i>=0; --i) //c_len->0维持稳定排序
{
sort_seq[count[vec_digit[i]]-1] = sequence[i]; //-1是因为下标从0开始
--count[vec_digit[i]]; //使得后续与vec_digit[i]相同的元素的位置往前挪1
}
sequence = sort_seq;
}
空间复杂度:k0为进制数,即代码中的max_k+1
S(n) = θ(n+k0)
时间复杂度:外层for循环次数 x 计数排序时间复杂度
由于基数排序中所用的计数排序max_k=9,所以其时间复杂度为θ(n+k0)=θ(n+10)
令k为位数,即代码中的n_digit
T(n) = n_digit x θ(n+k0) = θ(k*n + k*k0) = θ(k*n)
扩展:这里取位数的方式为十进制,可以根据实际情况取其他进制以使得效果更好(k越小,计数排序的k0越大,即计数排序的时间复杂度越大) ;最大的进制数应小于等于lgn(以2为底)。