当前位置: 首页 > news >正文

基数排序的理解和实现(Java)

基数排序是桶排序的扩展算法,其思想是:将整数按位数切割成不同的数字,然后按每个位数分别比较排序。

算法流程:

  1. 将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。
  2. 从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。

通过基数排序对数组{53, 3, 542, 748, 14, 214, 154, 63, 616},它的示意图如下:
在这里插入图片描述
在上图中,首先将所有待比较数字统一为统一位数长度,接着从最低位开始,依次进行排序。

  1. 按照个位数进行排序。
  2. 按照十位数进行排序。
  3. 按照百位数进行排序。
    排序后,数列就变成了一个有序序列。
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个桶中最后一个元素在数组中第七个位置。

转载于:https://www.cnblogs.com/lishanlei/p/10707653.html

相关文章:

  • P1962 斐波那契数列-题解(矩阵乘法扩展)
  • DotNetNuke模块开发(一)
  • LOJ104 普通平衡树
  • Airport Simulation (数据结构与算法 – 队列 / Queue 的应用)
  • 掌握 Dojo 工具包
  • js中用变量作为$()内id的值、动态获取id,及获取其下面的class元素
  • 读Google三大论文后感
  • 数据展现DataList控件(26)
  • [转帖] 使用 InstallShield 安装和卸载SQL Server 数据库
  • Spring Cloud微服务如何设计异常处理机制?
  • SpringCloud 之 Bus消息总线
  • 26步打造高访问量网站[经典]
  • Silverlight 4中把DataGrid数据导出Excel—附源码下载
  • 类加载、反射
  • Ubuntu 中的编程语言(上)
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • Apache的基本使用
  • CSS中外联样式表代表的含义
  • JS题目及答案整理
  • js写一个简单的选项卡
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • Objective-C 中关联引用的概念
  • open-falcon 开发笔记(一):从零开始搭建虚拟服务器和监测环境
  • passportjs 源码分析
  • SpringCloud集成分布式事务LCN (一)
  • Travix是如何部署应用程序到Kubernetes上的
  • 搞机器学习要哪些技能
  • 入职第二天:使用koa搭建node server是种怎样的体验
  • 在Docker Swarm上部署Apache Storm:第1部分
  • 终端用户监控:真实用户监控还是模拟监控?
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • #图像处理
  • (70min)字节暑假实习二面(已挂)
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (附源码)计算机毕业设计大学生兼职系统
  • (九十四)函数和二维数组
  • (一)Java算法:二分查找
  • (一)Thymeleaf用法——Thymeleaf简介
  • (一)基于IDEA的JAVA基础12
  • .NET delegate 委托 、 Event 事件,接口回调
  • .net oracle 连接超时_Mysql连接数据库异常汇总【必收藏】
  • .net 流——流的类型体系简单介绍
  • .NET框架设计—常被忽视的C#设计技巧
  • .NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数
  • .NET下的多线程编程—1-线程机制概述
  • :O)修改linux硬件时间
  • @RequestBody的使用
  • [ C++ ] STL_vector -- 迭代器失效问题
  • []串口通信 零星笔记
  • [2021]Zookeeper getAcl命令未授权访问漏洞概述与解决
  • [ai笔记9] openAI Sora技术文档引用文献汇总
  • [APIO2015]巴厘岛的雕塑
  • [C#]C# OpenVINO部署yolov8图像分类模型
  • [C#]OpenCvSharp使用帧差法或者三帧差法检测移动物体