基数排序原理
基数排序是一种非比较型整数排序算法,通过将整数按位数切割成不同的数字,然后按每个位数分别比较。排序过程从最低位(LSD)或最高位(MSD)开始,依次对每一位进行稳定排序(如计数排序)。
基数排序步骤
1. 确定最大数的位数 找到数组中最大元素的位数,决定需要多少轮排序。
2. 按位排序 从最低位到最高位(或相反),对每一位进行稳定排序(常用计数排序)。每次排序后,数组会基于当前位有序。
3. 合并结果 所有位处理完成后,数组整体有序。
C++实现示例
cpp
//基数排序
//求出数组arr里面的最大值的位数:例如最大值是12345->5,123456->6
int Get_Arr_MaxNum_Figure(int arr[], int len){
assert(arr != NULL);
int max_num = arr[0];
for (int i = 1; i < len; i++)if (arr[i] > max_num)max_num = arr[i];
if (max_num == 0)return 1;
int count = 0;//2.获取这个最大值的位数
while (max_num != 0){
max_num /= 10;
count++;
}return count;
}
int Get_Num_BucketNum(int num, int figure){//取每个数字的个位
for (int i = 0; i < figure; i++)num /= 10;
return num % 10;
}
void Radix(int arr[], int len, int figure){
std::queue<int> Bucket[10];//0.十个桶(队列)//1.将所有的值放到对应的桶内(放进去操作)
for (int i = 0; i < len; i++){
//先确定一下,此时i指向的这个值arr[i],它应该放到对应的几号队列中
int index = Get_Num_BucketNum(arr[i], figure);
Bucket[index].push(arr[i]);//确定好之后,直接放
}
//2.将0->9号队列中的值,依次取出(取出来操作)
int k = 0;//k指向当前arr的插入位置
for (int j = 0; j <= 9; j++){
while (!Bucket[j].empty()){
arr[k++] = Bucket[j].front();
Bucket[j].pop();
}
}
}
复杂度分析
- 时间复杂度 :O(d*(n+k)),其中
d
为最大位数,n
为元素数量,k
为基数(如10)。 - 空间复杂度:O(n+k),需要额外的计数数组和输出数组。
- 稳定性:基数排序是稳定的,因依赖的计数排序是稳定的。
适用场景
- 整数或字符串排序(需调整位数处理逻辑)。
- 数据范围广但位数较少时效率高。
- 不适用于浮点数或非均匀分布数据。