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个桶。