基数排序(桶排序)
核心思想:
- 相比其他排序而言,基数排序不用将两个数字直接对比,而是根据一些关键字进行排序
- 如【108,521,367】,关键字有个位,十位,百位。
- 然后初始化一个桶,桶的个数由每个关键字的范围给出,这里个位,十位,百位关键字范围都为10(数字0——9).所以桶的个数10个
- 开始分配,由个位开始,遍历原序列,根据每个数字的个位数字放入对应桶中,如108 放入8号桶中。此时排完序后【521,367,108】,每次排完序后将桶中序列收集(更换原始序列顺序为桶中的顺序)
- 重复4步骤,将个位换位十位【108,521,367】,百位【108,367,521】。最后结束.
时间复杂度:
- O(K*(n+m))
- K为关键字个数;n为元素个数;m为桶的个数
空间效率:
- O(kn+m)-------桶使用二维数组存
- O(n+m)--------桶使用动态数组
- K为关键字个数;n为元素个数;m为桶的个数
稳定性:
适用场景:
- 优点:可用于多因子排序,时间复杂度低
- 缺点:关键字范围需知道且关键字范围不能太大,对空间有要求
示例展示:
java源码:
public class RadixSort {
public static void radixSort(int[]a,int range){
int cur=1;//除数,方便取数字每个位上的数字,每次乘以10,
int curRange=1;//表示当前在依据第几个关键字排序
ArrayList<Integer> []tong=new ArrayList[10];//10表示10个桶,依次放入0到9的数字
while(curRange<=range){
//初始化动态数组
for(int i=0;i<tong.length;i++){
tong[i]=new ArrayList<Integer>();
}
//分配
for(int i=0;i<a.length;i++){
int temp=a[i]/cur%10;//获得依据排序位子的数
tong[temp].add(a[i]);
}
//收集
for(int i=0,k=0;i<tong.length;i++){
for(int j=0;j<tong[i].size();j++){
a[k]=tong[i].get(j);
k++;
}
}
cur*=10;
curRange++;
}
}
public static void main(String[] args) {
//测试
int []a={617,738,921,485,637,101,215,530,790,306};
radixSort(a,3);//这里关键字范围为3(个位,十位,百位)
for(int t:a)System.out.println(t);
}
}