• 桶排序


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

    欢迎批评指正,提出问题,谢谢!
  • 相关阅读:
    java多线程之happens-before
    三次握手和四次挥手
    数据库操作事物的四大特性以及MySQL数据库的四种隔离级别
    网易云易盾中标浙报反作弊服务 助力浙江新闻App健康发展
    值得细读!如何系统有效地提升Android代码的安全性?
    逻辑编程入门--clojure.core.logic
    React server rendering —— 网易美学主站同构实录
    致传统企业朋友:不够痛就别微服务,有坑 (1)
    致传统企业朋友:不够痛就别微服务,有坑 (2)
    亲近用户—回归本质
  • 原文地址:https://www.cnblogs.com/xxeleanor/p/14405725.html
Copyright © 2020-2023  润新知