基数排序(Radix Sort)也是非比较的排序算法,对每一位进行排序,从最低位开始排序,复杂度为O(kn),为数组长度,k为数组中的数的最大的位数;
基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。基数排序基于分别排序,分别收集,所以是稳定的。
算法描述
- 取得数组中的最大数,并取得位数;
- arr为原始数组,从最低位开始取每个位组成radix数组;
- 对radix进行计数排序(利用计数排序适用于小范围数的特点);
算法图示
算法分析
时间复杂度: 最佳情况:T(n) = O(n * k) 最差情况:T(n) = O(n * k) 平均情况:T(n) = O(n * k)
空间复杂度:O(N+K)
稳定
非比较
占用额外内存
基数排序有两种方法:
MSD 从高位开始进行排序 LSD 从低位开始进行排序
基数排序 vs 计数排序 vs 桶排序
这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异:
- 基数排序:根据键值的每位数字来分配桶
- 计数排序:每个桶只存储单一键值
- 桶排序:每个桶存储一定范围的数值
算法实现
#include<iostream>
#include<vector>
#include<list>
using namespace std;
#define TEN 10
int insert(list<int> &li, int val){
list<int>::iterator iter=li.begin();
while(iter!=li.end() && val>=*iter) iter++;
li.insert(iter, val);
return 0;
}
int radix_sort(vector<int> &nums){
int length=nums.size();
if(length<=1) return 0;
int min=nums[0], max=nums[0];
for(int i=1; i<length;i++) {
if(nums[i]<min) min=nums[i];
if(nums[i]>max) max=nums[i];
}
int base = (max-min)/TEN+1;
vector<list <int> > radix(base);
for(int i=0; i<length;i++){
insert(radix[nums[i]/TEN], nums[i]);
}
int index=0;
for(int i=0;i<base;i++){
if(radix[i].size()) {
for(list<int>::iterator iter=radix[i].begin(); iter!=radix[i].end(); iter++)
nums[index++]=*iter;
}
}
return 0;
}
int main() {
int arr[]={19,56,78,23,54,85,32,12,34,56,76,87,34,2,24,75,53,23,52,62};//,123,321,121};
int length = sizeof(arr)/sizeof(arr[0]);
vector<int> nums(arr, arr+length);
for (vector<int>::iterator iter=nums.begin(); iter!=nums.end(); iter++)
cout<<*iter<<" ";
cout<<endl;
radix_sort(nums);
for(int i=0;i<length;i++)
cout<<nums[i]<<" ";
cout<<endl;
return 0;
}