基数排序
基数排序
1)基本思想: 不通过直接比较数值大小,而是将整数按位分开(个,十,百),从低位到高位,依次排序
2)实现方法: 基数排序通常采用 LSD (Least Significant Digit first) 策略,即从最低有效位(个位)开始排序。我们以数组 [170, 45, 75, 90, 802, 24, 2, 66] 为例,看看它是如何一步步完成的:
2.1)找出最大值:首先找到数组中的最大数 802,它有3位数。这意味着我们需要进行3轮排序(分别处理个位、十位、百位)。
2.2)第一轮:按个位数排序
我们将每个数字根据其个位数分配到0-9的“桶”中。
桶0: [170, 90]
桶2: [802, 2]
桶4: [24]
桶5: [45, 75]
桶6: [66]
然后,按桶的顺序(0到9)收集所有数字,得到新序列:[170, 90, 802, 2, 24, 45, 75, 66]。
2.3)第二轮:按十位数排序
对上一轮得到的新序列,根据十位数再次分配到桶中(没有十位数的看作0)。
桶0: [802, 2]
桶2: [24]
桶4: [45]
桶6: [66]
桶7: [170, 75]
桶9: [90]
收集后得到:[802, 2, 24, 45, 66, 170, 75, 90]。
2.4)第三轮:按百位数排序
继续对上一轮的序列,根据百位数分配。
桶0: [2, 24, 45, 66, 75, 90]
桶1: [170]
桶8: [802]
最后收集起来,就得到了完全有序的数组:[2, 24, 45, 66, 75, 90, 170, 802]
3)代码实现:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
// 基数排序
const int maxx = 1000;
int help[maxx] = {0};
//Base 代表进制
#define Base 10
//求位数
int bitss(int num){
int res = 0;
while(num > 0){
res++;
num/=Base;
}
return res;
}
void Radixsort(int arr[],int n,int bits){
//表示指向的位置,从个位开始
int offset = 1;
for(int i = 0;i<bits;i++,offset *= Base){
//cnt 记录每个数字出现次数
vector<int>cnt(Base,0);
//求出每个数字的数量
for(int j = 0;j<n;j++){
cnt[(arr[j]/offset) % Base]++;
}
//计算前缀和
for(int j = 1;j<Base;j++){
cnt[j] = cnt[j] + cnt[j-1];
}
for(int j = n-1;j>=0;j--){
//按照当前位的数字大小排序
help[--cnt[(arr[j]/offset) % Base]] = arr[j];
}
for(int j = 0;j<n;j++){
arr[j] = help[j];
}
}
}
int main(){
int n;
cin >> n;
int a[100];
int max_num = 0;
for(int i = 0;i<n;i++){
cin >> a[i];
max_num = max(max_num,a[i]);
}
Radixsort(a,n,bitss(max_num));
for(int i = 0;i<n;i++){
cout << a[i] << " ";
}
cout << endl;
return 0;
}
浙公网安备 33010602011771号