基数排序
总结:
1)基数排序是以计数排序为基础的一种排序
2)它是从右向左排(所以这就应用到了计数排序的稳定性,可以保证相同的数在相对位置保持不变)
3)其总代价是:O( ( b/r ) * ( n + 2^r ) )
每个关键字可以看作d = (d/r) 个r位数 , 没个数都是 0 ~ 2^r-1 区间内的一个整数
4)那么 r 到底要取多少大呢?
所以对总的代价进行求导,求出最佳的 r 。
5)当 r 趋向于 lgn 时,基数排序的运行时间为O(n)
但是很多时候我们在选择的时候还是会选择比较的排序算法,
因为利用计数排序作为中间稳定排序的基数排序不是原址排序 ,
而很多 O(nlgn) 时间的比较排序是原址排序 , 贮存的容量比较宝贵,所以我们通常会选用像快排这样的原址排序
C++代码:
#include <iostream>
using namespace std;
//基数排序:稳定排序
// 获取data指定位的数
int getBitData(intdata,intexpIndex)
{
while(data != 0 && expIndex > 0){
data /= 10;
expIndex--;
}
returndata % 10;
}
// 利用计数排序对元素的每一位进行排序
void countingSort(int* arr,int expIndex , int size)
{
intk= 10;
intb[size+1];
intc[k];// 这里比较特殊:数的每一位最大数为9
inti;
for(i = 0; i < k; i++){
c[i] = 0;
}
for(i = 0; i < size; i++){
int d = getBitData(arr[i], expIndex);
c[d]++;
}
for(i= 1; i <= k; i++){
c[i] += c[i - 1];
}
for(i = size - 1; i >= 0; i--){
int d = getBitData(arr[i], expIndex);
b[c[d] - 1] = arr[i];// C[d]-1 就代表小于等于元素d的元素个数,就是d在B的位置
c[d]--;
}
for(i = 0; i < size; i++){
arr[i] = b[i];
}
}
// 把每次按位排序的结果打印出来
void print(int* arr,intk, intd,intsize)
{
if(k == d)
cout << "最终排序结果为:" << endl;
else
cout << "按第" << k << "位排序后,结果为:" << endl;
for(inti=0 ; i<size ; i++){
cout << arr[i] << " ";
}
cout << endl;
}
// d为数据长度
void radixSorting(int* arr,int d , int size)
{
for(inti = 0; i < d; i++){
countingSort(arr, i , size); // 依次对各位数字排序(直接用计数排序的变体)
print(arr, i + 1, d , size);
}
}
int main()
{
intarr[] = { 326, 453, 608, 835, 751, 435, 704, 690, 88, 79 ,79};
cout << "基数排序前为:" << endl;
for(inti=0 ; i<11 ; i++){
cout << arr[i] << " " ;
}
cout << endl;
radixSorting(arr, 4 , 11);
return0;
}