基数排序详解以及java实现这篇讲的很清楚,附上本人自己写的代码,将空间位n*10减为了n;
package suanfa; import java.util.Arrays; import java.util.Scanner;import java.util.concurrent.CountDownLatch; public class Main { public static void main (String[] args) { int[] arr = {34,52,33,45,35}; // int[] arr1 = {1,2,3,4,5}; radixSort(arr,getDigit(arr)); System.out.println(Arrays.toString(arr)); } public static void radixSort(int [] arr ,int digit) { int[] count = new int[10];//记录每个桶的下标; int k; int[] bucket = new int [arr.length];//辅助排序数组 for(int i=1;i<=digit;i++) { for(int j=0;j<count.length;j++) {//初始化计算桶下标数组 count[j] = 0; } for(int j=0;j<arr.length;j++) { count[getDigitNum(arr[j], i)]++;//记录第i位数值位bitNum的数量; } System.out.println(Arrays.toString(count)); for(k=1;k<count.length;k++) {//记录第k个桶的下标 count[k] = count[k]+count[k-1]; } System.out.println(Arrays.toString(count)); for(int j = arr.length-1;j>=0;j--) { bucket[count[getDigitNum(arr[j], i)]-1] = arr[j]; count[getDigitNum(arr[j], i)]--; } for(int j=0;j<arr.length;j++) { arr[j] = bucket[j]; } } } public static int getDigitNum(int bitNum,int i) {//求第i位的数值bitNum; //System.out.println(((int)Math.pow(10, i-1))%10); return bitNum/((int)Math.pow(10, i-1))%10; } public static int getDigit(int[] arr) { int maxNum = 0; int digit = 0; for(int i =0 ;i< arr.length;i++) {//寻找最大数; if(arr[i] > maxNum) { maxNum = arr[i]; } } while(maxNum>0) {//求最大数的位数 digit++; maxNum /= 10; } System.out.println(digit); return digit; } }
桶排序思想解决一道编程题:有n个数,求相邻两位数的最大差值,时间复杂度位O(n)。显然这题如果先排序再比较的话时间最少要nO(logn),所以使用桶排序的思想,即找到最大值与最小值,将这部分差值空间分位n+1份,然后建立n+1个桶,将这些数分到这些桶里,显然可知必然存在一个空桶,所以相邻两数的差值必然不在同一一个桶中(因为在同一桶中的差值必然小于桶的区间值),如
34,38,33,31,43
最大与最小差值位12,分成六分,
(1)【31-33) :31;
(2)【33-35): 33,34;
(3)【35-37): 空;
(4)【37-39):38;
(5)【39-41):空;
(6)【41-43】:43
显然可知,同一桶的值最大差值小于2,相邻桶的最小差值>=2;所以问题转化位求相邻非空桶的最大值与最小值的差之间的比较。即 33-31,38-34;43-38,之间值得比较可得最大差值位5.。
public static int maxGap(int[] nums) { if (nums == null || nums.length < 2) { return 0; } int len = nums.length; int min = Integer.MAX_VALUE; int max = Integer.MIN_VALUE; for (int i = 0; i < len; i++) { min = Math.min(min, nums[i]); max = Math.max(max, nums[i]); } if (min == max) { return 0; } boolean[] hasNum = new boolean[len + 1]; int[] maxs = new int[len + 1]; int[] mins = new int[len + 1]; int bid = 0; for (int i = 0; i < len; i++) { bid = bucket(nums[i], len, min, max); mins[bid] = hasNum[bid] ? Math.min(mins[bid], nums[i]) : nums[i]; maxs[bid] = hasNum[bid] ? Math.max(maxs[bid], nums[i]) : nums[i]; hasNum[bid] = true; } int res = 0; int lastMax = maxs[0]; int i = 1; for (; i <= len; i++) { if (hasNum[i]) { res = Math.max(res, mins[i] - lastMax); lastMax = maxs[i]; } } return res; } public static int bucket(long num, long len, long min, long max) { return (int) ((num - min) * len / (max - min)); }