桶排序

a的班级有5个同学,5个同学分别考了5分、3分、5分、2分和8分,按照从小到大进行排序,排序后的数据是8-5-5-3-2,使用程序让计算机随机输入5个数据然后将5个数从大到小输出。

通过一个一维数组,申请大小为11的数组int a[11]。申请好以后就有了11个变量,编号从a[0]-a[10]。刚开始将a[0]-a[10]都初始化为0,表示这些分数没有人得过。例如a[0]等于0表示还没有人得过0分,a[1]等于0表示目前还没有人得过1分……a[10]等于0表示没有得过10分。

数组a[0]-a[10]表示0-10分,不同的分数所对应单元格存储得此分数的人数 

首先处理第一个人的分数,第一个人是5分,在对应的a[5]的值在原来的基础上增加1,将a[5]对应的值从0变为1。

第二个人的分数是3分,把对应的a[3]的值增加1,表示3分出现了1次。

第三个人的分数也是5分,所以在此基础上再增加1,将a[5]的值从1改为2,表示5分出现过了2次。

第四个人的分数是2分,在a[2]对应的值加1,结果如下

第五个人的分数是8分,所以需要在a[8]对应的值加1,结果如下

从这个得出规律a[0]-a[10]就是0分到10分每个分数出现的次数,最后只需要打印出现过分数的就行了,出现几次打印几次:

a[0]为0,表示“0”分没有出现过,不进行打印

a[1]为0,表示“1”分没有出现过,不进行打印

a[2]为1,表示“2”分出现过1次,打印1次

a[3]为1,表示“3”分出现过1次,打印1次

a[4]为0,表示“4”分出现过0次,不打印

a[5]为2,表示“5”分出现过2次,打印2次

a[6]为0,表示“6”分出现过0次,不打印

a[7]为0,表示“7”分出现过0次,不打印

a[8]为1,表示“8”分出现过1次,打印1次

a[9]为0,表示“9”分出现过0次,不打印

a[10]为0,表示“10”分出现过0次,不打印

所以最后屏幕应该打印的数字是:“2 3 5 5 8”

【从小到大排序】

 1 package day08;
 2 
 3  
 4 
 5 import java.util.Scanner;
 6 
 7  
 8 
 9 public class BarrelTest {
10 
11     public static void main(String[] args) {
12 
13  
14 
15         int[] scores = new int[11];//定义一个空间大小为11的变量 0-10即11个
16 
17         Scanner input = new Scanner(System.in);
18 
19         for (int i = 0; i <= 10; i++) {    //初始化scores值为0
20 
21             scores[i] = 0;
22 
23         }
24 
25  
26 
27         for (int j = 1; j <= 5; j++) {    //循环输入5名学生成绩
28 
29             System.out.println("请输入第" + j + "名学生成绩");
30 
31             int t = input.nextInt();
32 
33             scores[t]++;//计数
34 
35         }
36 
37         System.out.println("-----------");
38 
39         for (int a = 0; a <= 10; a++) {   //依次判断每个成绩
40 
41             for (int b = 1; b <= scores[a]; b++) {   //依次判断每个成绩的人数
42 
43                 System.out.print(a + "	");
44 
45             }
46 
47         }
48 
49     }
50 
51 }

运行结果:

 

 【从大到小排序】

 1 package day08;
 2 
 3  
 4 
 5 import java.util.Scanner;
 6 
 7  
 8 
 9 public class Barrel {
10 
11     public static void main(String[] args) {
12 
13  
14 
15         int[] scores = new int[11];//定义一个空间大小为11的变量 0-10即11个
16 
17         Scanner input = new Scanner(System.in);
18 
19         for (int i = 0; i <= 10; i++) {    //初始化scores值为0
20 
21             scores[i] = 0;
22 
23         }
24 
25  
26 
27         for (int j = 1; j <= 5; j++) {    //循环输入5名学生成绩
28 
29             System.out.println("请输入第" + j + "名学生成绩");
30 
31             int t = input.nextInt();
32 
33             scores[t]++;//计数
34 
35         }
36 
37         System.out.println("-----------");
38 
39         for (int a = 10; a >= 0; a--) {   //依次判断每个成绩
40 
41             for (int b = 1; b <= scores[a]; b++) {   //依次判断每个成绩的人数
42 
43                 System.out.print(a + "	");
44 
45             }
46 
47         }
48 
49     }
50 
51 }

运行结果:

 

这种排序方法类似“桶排序”,因为真正的桶排序会比这个复杂点。这种算法好比有11个桶,编号是0-10。每出现一个数,就在对应编号的桶中放一个小旗子,最后只要数数每个桶中有几个小旗子就可以了。比如2号桶有1个小旗子,表示2出现了1次。3号桶有1个旗子,表示3出现了1次。5号桶有2个旗子,表示5出现了2次。8号桶有1个旗子,表示8出现了1次。

如果需要对数据范围在0-1000之间的整数进行排序就需要n+1即1001个桶,表示0-1000范围内每个数出现的次数。每一个桶的作用就是标记每个数出现的次数。

去除常量,桶排序的时间复杂度为O(M+N),M表示桶的个数,N表示待排序的个数。如果需要将分数和人数对应起来该方法就不能解决了。桶排序的优点是非常快,缺点是浪费空间,如果需要0-20000000之间的数就需要申请20000001个变量,即使只对5个数进行排序也需要20000001个桶。

欢迎批评指正,提出问题,谢谢!
原文地址:https://www.cnblogs.com/xxeleanor/p/14405725.html