基数排序的理解和实现(Java)
基数排序是桶排序的扩展算法,其思想是:将整数按位数切割成不同的数字,然后按每个位数分别比较排序。
算法流程:
- 将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。
- 从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。
通过基数排序对数组{53, 3, 542, 748, 14, 214, 154, 63, 616},它的示意图如下:
在上图中,首先将所有待比较数字统一为统一位数长度,接着从最低位开始,依次进行排序。
- 按照个位数进行排序。
- 按照十位数进行排序。
- 按照百位数进行排序。
排序后,数列就变成了一个有序序列。
public class RadixSort {
/*
* 获取数组a中最大值
*
* 参数说明:
* a -- 数组
* n -- 数组长度
*/
private static int getMax(int[] a) {
int max;
max = a[0];
for (int i = 1; i < a.length; i++)
if (a[i] > max)
max = a[i];
return max;
}
/*
* 对数组按照"某个位数"进行排序(桶排序)
*
* 参数说明:
* a -- 数组
* exp -- 指数。对数组a按照该指数进行排序。
*
* 例如,对于数组a={50, 3, 542, 745, 2014, 154, 63, 616};
* (01) 当exp=1表示按照"个位"对数组a进行排序
* (02) 当exp=10表示按照"十位"对数组a进行排序
* (03) 当exp=100表示按照"百位"对数组a进行排序
* ...
*/
private static void countSort(int[] a, int exp) {
//int output[a.length]; // 存储"被排序数据"的临时数组
int[] output = new int[a.length]; // 存储"被排序数据"的临时数组
int[] buckets = new int[10];
// 将数据出现的次数存储在buckets[]中
for (int i = 0; i < a.length; i++)
buckets[ (a[i]/exp)%10 ]++;
for (int i = 0; i < buckets.length; i++) {
System.out.print(buckets[i] + ",");
}
System.out.println();
// 更改buckets[i]。目的是让更改后的buckets[i]的值,是该数据在output[]中的位置。
for (int i = 1; i < 10; i++)
buckets[i] += buckets[i - 1];
for (int i = 0; i < buckets.length; i++) {
System.out.print(buckets[i] + ",");
}
System.out.println();
// 将数据存储到临时数组output[]中
for (int i = a.length - 1; i >= 0; i--) {
output[buckets[ (a[i]/exp)%10 ] - 1] = a[i];
buckets[ (a[i]/exp)%10 ]--;
}
for (int i = 0; i < output.length; i++) {
System.out.print(output[i] + ",");
}
System.out.println();
System.out.println();
// 将排序好的数据赋值给a[]
for (int i = 0; i < a.length; i++)
a[i] = output[i];
output = null;
buckets = null;
}
/*
* 基数排序
*
* 参数说明:
* a -- 数组
*/
public static void radixSort(int[] a) {
int exp; // 指数。当对数组按各位进行排序时,exp=1;按十位进行排序时,exp=10;...
int max = getMax(a); // 数组a中的最大值
// System.out.println(max);
// 从个位开始,对数组a按"指数"进行排序
for (exp = 1; max/exp > 0; exp *= 10)
countSort(a, exp);
}
public static void main(String[] args) {
int i;
int a[] = {53, 3, 542, 748, 14, 214, 154, 63, 616};
radixSort(a); // 基数排序
}
}
在上面的代码中,用了两个数组:output和buckets。output用来存储每次按位数排序的数字。而buckets则是一个桶,因为位数在0-9之间,所以buckets的长度为10。在第一次循环中,buckets[i]表示表示第i个桶中装了几个数据;而第二次for循环中则是为了标记在每个桶中最后一个数据在整个数组中的右边界。
以{53, 3, 542, 748, 14, 214, 154, 63, 616}的个位数排序举例:
在上例中,第一个for循环结束后,buckets[2]=1,buckets[3]=buckets[4]=3;在第二个for循环后,buckets[2]=1,buckets[3]=4,buckets[4]=7,表示第4个桶中最后一个元素在数组中第七个位置。
基数排序的理解和实现(Java)的更多相关文章
- Atitit 深入理解命名空间namespace java c# php js
Atitit 深入理解命名空间namespace java c# php js 1.1. Namespace还是package1 1.2. import同时解决了令人头疼的include1 1.3 ...
- 理解和解决Java并发修改异常ConcurrentModificationException(转载)
原文地址:https://www.jianshu.com/p/f3f6b12330c1 理解和解决Java并发修改异常ConcurrentModificationException 不知读者在Java ...
- 深入理解和探究Java类加载机制
深入理解和探究Java类加载机制---- 1.java.lang.ClassLoader类介绍 java.lang.ClassLoader类的基本职责就是根据一个指定的类的名称,找到或者生成其对应的字 ...
- 深入理解什么是Java泛型?泛型怎么使用?【纯转】
本篇文章给大家带来的内容是介绍深入理解什么是Java泛型?泛型怎么使用?有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所助. 一.什么是泛型 “泛型” 意味着编写的代码可以被不同类型的对象所 ...
- [转载] 深入理解Android之Java虚拟机Dalvik
本文转载自: http://blog.csdn.net/innost/article/details/50377905 一.背景 这个选题很大,但并不是一开始就有这么高大上的追求.最初之时,只是源于对 ...
- 如何理解和使用Java package包
Java中的一个包就是一个类库单元,包内包含有一组类,它们在单一的名称空间之下被组织在了一起.这个名称空间就是包名.可以使用import关键字来导入一个包.例如使用import java.util.* ...
- 深入理解JVM(6)——Java内存模型和线程
Java虚拟机规范中定义了Java内存模型(Java Memory Model,JMM)用来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果(“即Ja ...
- 理解JVM之Java内存区域
Java虚拟机运行时数据区分为以下几个部分: 方法区.虚拟机栈.本地方法栈.堆.程序计数器.如下图所示: 一.程序计数器 程序计数器可看作当前线程所执行的字节码行号指示器,字节码解释器工作时就是通过改 ...
- 平衡二叉树(AVL)的理解和实现(Java)
AVL的定义 平衡二叉树:是一种特殊的二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1.从平衡二叉树的名字中可以看出来,它是一种高度平衡的二叉排序树.那么什么叫做高度平衡呢?意思就是要么它 ...
随机推荐
- netty(一) netty有哪几部分构成
netty netty是一个支持高并发的非阻塞I/O框架. Channel Channel 是 NIO 基本的结构.它代表了一个用于连接到实体如硬件设备.文件.网络套接字或程序组件,能够执行一个或多个 ...
- ucore-lab1-练习5report
实验5--实现函数调用堆栈跟踪函数 需要完成kdebug.c中函数print_stackframe的实现,可以通过函数print_stackframe来跟踪函数调用堆栈中记录的返回地址. 一.函数堆栈 ...
- 20175314 《Java程序设计》第一周学习总结
20175314 <Java程序设计>第一周学习总结 教材学习内容总结 除了学院统一购买的<Java 2 实用教程(第5版)>我还在网上买了一本<Head ...
- SSM框架整合过程总结
-----------------------siwuxie095 SSM 框架整合过程总结 1.导入相关 jar 包( ...
- 三、putty工具常见设置
转载自:https://www.cnblogs.com/hdk1993/p/4769072.html Putty是一个免费小巧的Win32平台下的telnet,rlogin和ssh客户端. 它的主程序 ...
- 将VSCode设置成中文语言环境
VSCode是一款轻量级的好用的编译软件,今天小编来将软件默认的英文语言环境变为我们熟悉的中文语言环境. 工具/原料 电脑一台 安装有VSCode 方法/步骤 首先打开VSCode软件,可 ...
- Eclipse Golang 开发环境搭建 GoClipse 插件
Windows平台 下载完成后,直接双击安装即可 默认情况下,.msi文件会安装在 C:\Go 目录下.可以将 C:\Go\bin 目录添加到环境变量 PATH 中,方便调用命令. Go 里面有两个非 ...
- SpringMvc在返回数据之前进行统一处理
这里其实有多种解决方案 如果你不需要获取request对象 可以采用aop(环绕通知)的方式来统一修改 如果你需要获取request对象,那么就需要采用下面的方式 0自己定义一个注解,内容如下 @Ta ...
- 解决win10系统无法安装.NET Framework 3.5
方法1:“我的电脑”,单击右键选择“管理” 在打开的“计算机管理”窗口中依路径“服务和应用程序—服务”打开,在列表中找到“Windows Update”并双击打开. 启动类型:自动. 服务状态下面点击 ...
- ABP框架系列之十七:(Data-Filters-数据过滤)
Introduction It's common to use the soft-deletepattern which is used to not delete an entity from da ...