Java基数排序(可负数)

Java基数排序(可负数)

一、基数排序(radix sort)
基本思想:一个待排序的数组,按个十百千等位数,来划分,这个数组中的最大值是多少位数,就需要排序多少次,从个位数开始,如下图。

算法思路

i. 开始排个位数
在这里插入图片描述

放入的结果为:
在这里插入图片描述

取出的结果为:
在这里插入图片描述

Ii .开始排十位数(以个位数排序过的数组为基数组)
在这里插入图片描述

取出的结果为:
在这里插入图片描述

Iii.百位数排序(以十位数排序过的数组为基数组)

在这里插入图片描述

取出的结果为
在这里插入图片描述

那么这个排序的最终结果就为 2,7,34,45,67,76,367,508,897。

算法步骤

1、找到最大值和最小值,如果最小值小于0,将所有数都加上2147483647。

2、计算最大值有几位数,决定比较次数。

3、定义10个桶,用来存放临时排序的数组。

4、把每一个数字分别计算余数,把余数相同的数字放到同一个桶里。

5、遍历每一个桶,把桶里的数字按顺序取出来,放回原数组。

6、重复第4步到第5步,直到所有位数都比较完毕。

7、把排序好的数组重新加上减去的值。

时间复杂度

基数排序的时间复杂度为O(d*(n+k)),其中d为位数,n为待排序数组长度,k为桶的数量。

空间复杂度

基数排序的空间复杂度为O(n+k),其中n为待排序数组长度,k为桶的数量。

稳定性

基数排序是一种稳定性排序算法,因为在同一位数上,相同的数字会被放到同一个桶里,而桶内的排序是稳定的。

注意:
在基数排序的实现中,如Integer.MIN_VALUE,则会出现整数溢出的情况。为了解决这个问题,可以将所有数都加上 2147483647,这样最小的数就是 2147483647 - 2147483648 = -1。在排序完成后,再将所有数都减去2147483647即可,这里并没有做特殊处理,如果需要做处理,可以参考可通过最小值测试

三、代码 :

public static int[] radixSort(int[] arr) {
		// 找到最大值和最小值
		int max = Integer.MIN_VALUE, min = Integer.MAX_VALUE;
		for (int i = 0; i < arr.length; i++) {
			if (arr[i] > max) {
				max = arr[i];
			}
			if (arr[i] < min) {
				min = arr[i];
			}
		}
		// 如果最小值小于0,将所有数都加上 2147483647
		if (min < 0) {
			for (int i = 0; i < arr.length; i++) {
				arr[i] -= min;
			}
			max -=min;
		}
		// 计算最大值有几位数
		int maxLength = (int) Math.log10(max) + 1;
		// 桶的数量
		int bucketCount = 10;
		// 用来存放临时排序的数组
		int[][] bucket = new int[bucketCount][arr.length];
		// 用来存放排序数组在某个值下面的位置
		int[] bucketIndex = new int[bucketCount];
		// 根据最大长度数,决定比较次数
		for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {
			// 把每一个数字分别计算余数
			for (int j = 0; j < arr.length; j++) {
				int digit = Math.abs(arr[j] / n % 10);
				bucket[digit][bucketIndex[digit]] = arr[j];
				bucketIndex[digit]++;
			}
			// 记录arr的位置
			int index = 0;
			// 遍历取出第n次排序的值,等于0的不需要取
			for (int j = 0; j < bucketCount; j++) {
				if (bucketIndex[j] != 0) {
					for (int k = 0; k < bucketIndex[j]; k++) {
						arr[index] = bucket[j][k];
						index++;
					}
				}
				// 把数量置为零,因为还有n轮
				bucketIndex[j] = 0;
			}
		}
		// 把排序好的arr重新加上减去的值
		if (min < 0) {
			for (int i = 0; i < arr.length; i++) {
				arr[i] += min;
			}
		}
		return arr;
	}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值