排序-基数排序

版权声明:有一些内容粘贴之后变成图片如果需要原文原视频 可以联系我 https://blog.csdn.net/wodemale/article/details/90112301

基数排序(Radix Sort)
基数排序也是非比较的排序算法,对每一位进行排序,从最低位开始排序,复杂度为O(kn),为数组长度,k为数组中的数的最大的位数;
基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。基数排序基于分别排序,分别收集,所以是稳定的。

算法描述
取得数组中的最大数,并取得位数;
arr为原始数组,从最低位开始取每个位组成radix数组;
对radix进行计数排序(利用计数排序适用于小范围数的特点);

算法分析
最佳情况:T(n) = O(n * k)
最差情况:T(n) = O(n * k)
平均情况:T(n) = O(n * k)
基数排序有两种方法:
MSD 从高位开始进行排序
LSD 从低位开始进行排序

public static void radixSort(int[] arr) {
	if (arr == null || arr.length < 2) {
		return;
	}
	radixSort(arr, 0, arr.length - 1, maxbits(arr));
}

public static int maxbits(int[] arr) {
	int max = Integer.MIN_VALUE;
	for (int i = 0; i < arr.length; i++) {
		max = Math.max(max, arr[i]);
	}
	int res = 0;
	while (max != 0) {
		res++;
		max /= 10;
	}
	return res;
}

public static void radixSort(int[] arr, int begin, int end, int digit) {
	final int radix = 10;
	int i = 0, j = 0;
	int[] count = new int[radix];
	int[] bucket = new int[end - begin + 1];
	for (int d = 1; d <= digit; d++) {
		for (i = 0; i < radix; i++) {
			count[i] = 0;
		}
		for (i = begin; i <= end; i++) {
			j = getDigit(arr[i], d);
			count[j]++;
		}
		for (i = 1; i < radix; i++) {
			count[i] = count[i] + count[i - 1];
		}
		for (i = end; i >= begin; i--) {
			j = getDigit(arr[i], d);
			bucket[count[j] - 1] = arr[i];
			count[j]--;
		}
		for (i = begin, j = 0; i <= end; i++, j++) {
			arr[i] = bucket[j];
		}
	}
}

public static int getDigit(int x, int d) {
	return ((x / ((int) Math.pow(10, d - 1))) % 10);
}

图文讲解可以参考博文:
https://blog.csdn.net/hellozhxy/article/details/79911867

猜你喜欢

转载自blog.csdn.net/wodemale/article/details/90112301