简单的基数排序——桶式排序

桶式排序是一种简单的基数排序。桶式排序(这里以对若干个正整数的排序为例描述求解过程):待排序的正整数存放在一维数组中,此外还有一个整型的二维数组,其中
行下标从0~9,列下标从0~n – 1。在这里,n是待排序的数组中元素的数目。二维数组的每行称为一个桶。编写一个程序,读入15个正整数,并按从小到大的顺序排序
。桶式排序的算法如下:

遍历一维数组中的每个元素,并根据它的个位将每个值安排在桶数组的某行中。例如,97安排在行7,3安排在行3,而100安排在行0——这个过程叫分桶。在桶数组内循环
,并将值复制回到最初的数组——这个过程叫收集。上面的数值在一维数组中的新顺序是100、3和97。接下来依次取一维数组中所有数字的十位,百位,千位等等,并按取
出的十位,百位,千位等位上的数字不断分桶和放回原数组;重复这个过程(分桶---收集),当处理完了一维数组中最大数字的最高位时,就停止这个过程。例如,在对
数组进行第2轮处理时,100安排在行0,3安排在行0(它仅有一个数位),而97安排在行9。一维数组中值的顺序是100、3和97。在第3轮处理时,100安排在行1,3安
排在行0,而97安排在行0(在3之后)。桶式排序可以确保在处理了最大数字的最高位之后正确排列所有值的顺序。

注意,桶的二维数组的大小是要排序的整数数组大小的10倍。这种排序方法的性能比冒泡排序方法要高,但需要更多的存储空间。冒泡排序仅仅需要为待排序的数据配置内
存空间,整个排序过程中不再需要额外的空间;然而,桶式排序中待排数据需要存放空间,此外排序过程中用到的桶也需要内存空间。桶式排序使用更多的内存,但性能更
好,这是一种以空间换时间的做法。本题目源自重庆科技学院的伍建全老师,在此特向伍老师致谢!!!

输入格式:
输入为15个不超出int数值范围的非负整数。

输出格式:
运用上面介绍的桶排序规则编制程序,输出每次分派收集之后得到的一维数组,每个整数之间以空格隔开。每次输出占一行。(注意每行末尾有1个空格)

输入样例:
在这里给出一组输入。例如:

6634 9796 435 1405 6123 10001 11459 12018 10372 19874 12860 11326 7096 30205 27010
输出样例:
在这里给出相应的输出。例如:

12860 27010 10001 10372 6123 6634 19874 435 1405 30205 9796 11326 7096 12018 11459
10001 1405 30205 27010 12018 6123 11326 6634 435 11459 12860 10372 19874 9796 7096
10001 27010 12018 7096 6123 30205 11326 10372 1405 435 11459 6634 9796 12860 19874
10001 30205 10372 435 11326 1405 11459 12018 12860 6123 6634 27010 7096 9796 19874
435 1405 6123 6634 7096 9796 10001 10372 11326 11459 12018 12860 19874 27010 30205

从题目要求分析,首先我们要进行存入:这种排序方法就是先按照每个数的个位数大小分行排序,然后存入每行之中,重复的数就往后排,相当于排到同一行的第二第三列去。所以定义一个二位数组bucket[][]代表存储空间,一维数组a[]就用来表示要进行存储的那十五个数。

在存放过程中,因为每行存入数字的数量不同嘛,因此我们要记录每行数字的多少,这里我用数组b[]来进行存储每行放了多少个元素,每次存放就该位数b[hang]++;

接下来是就是提取了,加入第一行存了3个,第二行存了1个,所以我们就用两个for循环,第一个for就0~9,代表遍历每一行,第二个for就用该行存了多少个元素表示,也就是b[hang].然后重新提取出来放到原来的一维数组a[]当中,接下来遍历输出。

接下来就开始进行第二次第三次循环了,这里要注意清空原来的数组,因此我将数组初始化放在了循环里面。要知道一共循环多少次,所以我们要知道最大的数有几位,这里我构造了一个max()方法,然后用除以e的方式来表示往十位百位那边方向遍历。一直这样重复下去,直到最大那个数也变成0为止。

具体代码如下,本代码仅代表个人思路,欢迎纠正改进。

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        int a[] = new int[15];
        Scanner sc = new Scanner(System.in);
        for (int i = 0; i < a.length; i++) {
            a[i] = sc.nextInt();
        }
//        最大数有几位则执行几次
        int e = 1;
        for (int num = 0; num < max(a); num++) {
//            每次执行刷新一次
            int [][] bucket = new int[10][15];
//            代表某一行存了几个数
            int[] b = new int[10];
//            存入
            for (int j = 0; j < a.length; j++) {
                int hang = a[j]/e%10;
                bucket[hang][b[hang]] = a[j];
//                那一行下次存在后一个
                b[hang]++;
            }
//            读取重新放回
            int index = 0;
            for (int i = 0; i < b.length; i++) {
                for (int j = 0; j < b[i]; j++) {
                    a[index] = bucket[i][j];
                    index++;
                }
            }
            e = e*10;
//            遍历输出
            for (int i = 0; i < a.length; i++) {
                System.out.print(a[i]+" ");
            }
            System.out.println();
        }
    }


    //    求出数组中最大的数有几位
    public static int max(int[] Arry) {
        int num = 0;
        int max = 0;
        for (int i = 0; i < Arry.length; i++) {
            if (Arry[i] > num)
                num = Arry[i];
        }
        while (num > 0) {
            num /= 10;
            max++;
        }
        return max;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值