简易桶排序(Java版本)
一、算法步骤
Step1.为要排序的这列数申请一个数组,数组大小由这列数的区间范围决定,如这列数都在0~10之间,则申请一个大小为11的数组int a[11]。
Step2.将数组的值都初始化为0,表示这些数在要排序的这列数中还未出现过。
Step3.读取要排序的这列数,将出现过的数字在数组上标记,如第一个数为5,则将相对应的a[5]的值在原来的基础增加1,即将a[5]的值从0 改为1,表示5出现过了一次。最终a[0]~a[10]中的数值其实就是0~10 每个数出现的次数。
Step4.将出现过的数组输出,出现几次就输出几次。
二、算法代码
题目描述:
期末考试完了老师要将同学们的分数按照从高到低排序。小哼的班上只有5 个同学,这5 个同学分别考了5 分、3 分、5 分、2 分和8 分,哎考得真是惨不忍睹(满分是10 分)。接下来将分数进行从大到小排序,排序后是8 5 5 3 2。
实现代码:
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args) { 5 // TODO Auto-generated method stub 6 Scanner reader = new Scanner(System.in); 7 int a[] = new int[11]; 8 int t; 9 for(int i=0;i<5;i++){ 10 t=reader.nextInt(); 11 a[t]++; 12 } 13 for(int i=0;i<11;i++){ 14 for(int j=0;j<a[i];j++){ 15 System.out.printf("%d ", i); 16 } 17 } 18 } 19 }
题目描述:
输入n 个0~1000 之间的整数,将它们从大到小排序。(tips:如果需要对数据范围在0~1000 之间的整数进行排序,我们需要1001 个桶,来表示0~1000之间每一个数出现的次数)
实现代码:
1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String[] args) { 5 // TODO Auto-generated method stub 6 Scanner reader = new Scanner(System.in); 7 int book[] = new int[1001]; 8 int n = reader.nextInt(); 9 int t; 10 for(int i=0;i<n;i++){ 11 t=reader.nextInt(); 12 book[t]++; 13 } 14 for(int i=1000;i>=0;i--){ 15 for(int j=0;j<book[i];j++){ 16 System.out.printf("%d ", i); 17 } 18 } 19 } 20 }
时间复杂度:桶排序的时间复杂度为O(m+n)。
三、算法缺点
1、最终输出的也仅仅是分数,但没有对人本身进行排序。也就是说,我们现在并不知道排序后的分数原本对应着哪一个人。
2、浪费空间。例如需要排序数的范围是0~2100000000 之间,那你则需要申请2100000001 个变量,也就是说要写成int a[2100000001]。因为我们需要用2100000001 个“桶”来存储0~2100000000 之间每一个数出现的次数。即便只给你5 个数进行排序(例如这5 个数是1、1912345678、2100000000、18000000 和912345678),你也仍然需要2100000001 个“桶”。
3、只能对整数进行排序,小数负数等则不可以使用此方法进行排序。