基数排序 (桶排序)(含负数)

  1. 基数排序(radixsort) 属于“分配式排序”(distributionsort) ,又称“桶子法”(bucket sort) 或binsort, 顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用
    2)基数排序法是属于稳定 性的排序,基数排序法的是效率高的稳定性排序法
    3)基数排序(Radix Sort)是桶排序的扩展
    4)基数排序是 1887年赫尔曼●何乐礼发明的。它是这样实现的:将整数按位数切割成不同的数字,然后按每个位数分别比较。

  2. 基数排序是对传统桶排序的扩展,速度很快
    2)基数排序是经典的空间换时间的方式,占用内存很大,当对海量数据排序时,容易造成OutOfMemoryError。
    3)基数排序时稳定的。 [注:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些
    记录的相对次序保持不变,即在原序列中,r[j]=([j], 且[i]在r(i]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的
    有负数时处理思路:先判断有无负数 有则找到最小值 数组所有数据都减去该值 也就是数组最小值会变为0 接下来按正整数排序 最后数组所有数据加上原最小数 变为原有数据值

import java.util.Arrays;

public class RadixSort {
	//800W1s内
	public static void main (String[] args) {
		int a[] = {97,-80,-20,0,13,2};
		radixSort(a);
//		int a1[] = new int[8000000];
//		for(int i=0;i<8000000;i++) {
//			a1[i] = (int)(Math.random()*8000000);
//			
//		}
//		
//		System.out.println(System.currentTimeMillis()/1000);
//		radixSort(a1);
//
//		System.out.println(System.currentTimeMillis()/1000);

	

	}
	public static void radixSort(int[] arr) {
		int max = arr[0];//假定最大数为第一个
		int min = 0;
		for(int m = 1;m<arr.length;m++) {
			if(arr[m]>max) {
				max = arr[m];
			}
			if(arr[m]<min) {	
				min = arr[m];//找到负数最小值			
			}
		}
		if(min<0) {
			for(int mi = 0;mi<arr.length;mi++) {
				arr[mi] -= min;
				max -= min;
			}
		}
		System.out.println(Arrays.toString(arr)+"==");
		int maxLength = (max+"").length();//获取是几位数
		
		//定义一个二维数组,表示10个桶,每个桶就是一 个一维数组
		//说明
		//1.二维数组包含10个一维数组
		//2.为了防止在放入数的时候,数据溢出,则每个一维数组(桶),大小定为arr . length
		//3.名明确,基数排序是使用空间换时间的经典算法
		int[][] bucket = new int[10][arr.length];//以防所有数据个位数都是同一个数
		//为了记录每个桶中,实际存放了多少个数据,我们定义一一个-维数组来记录各个桶的每次放入的数据个数
		//可以这里理解
		//比如: bucketElementCounts[0] ,记录的就是bucket[0] 桶的放入数据个数
		int[] bucketElementCounts = new int[10];
		for (int n = 0, g=1; n < maxLength; n++,g*=10) {
			for (int i = 0; i < arr.length; i++) {
				int digitOfElement = arr[i]/g % 10;// 求各位数的数值
				bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[i];// [个位数值][该数存放的第几个]
				bucketElementCounts[digitOfElement]++;
			}
			// 存放完毕后再取回原数组
			int index = 0;
			for (int j = 0; j < bucketElementCounts.length; j++) {
				if (bucketElementCounts[j] != 0) {
					// 表示存储的有数据
					for (int k = 0; k < bucketElementCounts[j]; k++) {
						arr[index] = bucket[j][k];
						index++;
					}
				}
				bucketElementCounts[j] = 0;//为下一轮初始化
			}
			System.out.println(Arrays.toString(arr));

		}
		if(min<0) {
			for(int mi = 0;mi<arr.length;mi++) {
				arr[mi] += min;
			}
		}
		System.out.println(Arrays.toString(arr));

	}
}

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值