文章目录
- 基数排序
- 一、基数排序
- 概念
- 1.LSD排序法(最低位优先法)
- 2.MSD排序法(最高位优先法)
基数排序
一、基数排序
概念
-
基数排序是一种非比较型整数排序算法
-
将整数按位数切割成不同的数字,然后按每个位数分别比较
-
使用场景:按位分割进行排序,适用于大数据范围排序,打破了计数排序的限制
-
稳定性:稳定
-
按位分割技巧:arr[i] / digit % 10,其中digit为10^n。
1.LSD排序法(最低位优先法)
-
从最低位向最高位依次按位进行计数排序。
-
进出的次数和最大值的位数有关
-
桶可以用队列来表示
-
数组的每个元素都是队列
- 1.先遍历找到最大值
- 2.求出最高位
public static void radixSortR(int[] array) {//10进制数,有10个桶,每个桶最多存array.length个数int[][] bucket = new int[10][array.length];//桶里面要存的具体数值int[] bucketElementCounts = new int[10];//用来计算,统计每个桶所存的元素的个数,每个桶对应一个元素//1.求出最大数int MAX = array[0];for (int i = 1; i < array.length; i++) {if (array[i] > MAX) {MAX = array[i];}}//求最大值的位数,先变成字符串,求字符串长度int MAXCount = (MAX + "").length();//最大位数的个数,进行几次计数排序for (int i = 0; i < MAXCount; i++) {//i代表第几次排序//放进桶中for (int k = 0; k < array.length; k++) {//k相当于遍历待排数值//array[k] /(int) Math.pow(10, i)%10 求出每次要比较位的数//求的是个位,并且是对应趟数的个位int value = (array[k] / (int) Math.pow(10, i)) % 10;//根据求出的位数,找到对应桶,放到对应桶的位置bucket[value][bucketElementCounts[value]] = array[k];//不管value 为多少,bucketElementCounts[value]的值都为0//相当于存到对应桶的0位bucket[value][0]bucketElementCounts[value]++; //从0->1//对应桶的技术数组开始计数}//取出每个桶中的元素,赋值给数组int index = 0;//array新的下标for (int k = 0; k < bucketElementCounts.length; k++) {//遍历每个桶if (bucketElementCounts[k] != 0) {//桶里有元素for (int j = 0; j < bucketElementCounts[k]; j++) {//比那里每个桶的元素array[index] = bucket[k][j];index++;}}bucketElementCounts[k] =0;//每个桶遍历完后,清空每个桶的元素;}}}
2.MSD排序法(最高位优先法)
- 从最高位向最低位依次按位进行排序。
- 按位递归分组收集
- 1.查询最大值,获取最高位的基数
- 2.按位分组,存入桶中
- 3.组内元素数量>1,下一位递归分组
- 4.组内元素数量=1.收集元素
/*** 基数排序--MSD--递归* @param array*/public static void radixSortMSD(int[] array) {//1.求出最大数int MAX = array[0];for (int i = 1; i < array.length; i++) {if (array[i] > MAX) {MAX = array[i];}}//求最大值的位数,先变成字符串,求字符串长度int MAXCount = (MAX + "").length();// 计算最大值的基数int radix = new Double(Math.pow(10, MAXCount - 1)).intValue();int[] arr = msdSort(array, radix);System.out.println(Arrays.toString(arr));}public static int[] msdSort(int[] arr, int radix){// 递归分组到个位,退出if (radix <= 0) {return arr;}// 分组计数器int[] groupCounter = new int[10];// 分组桶int[][] groupBucket = new int[10][arr.length];for (int i = 0; i < arr.length; i++) {// 找分组桶位置int position = arr[i] / radix % 10;// 将元素存入分组groupBucket[position][groupCounter[position]] = arr[i];// 当前分组计数加1groupCounter[position]++;}int index = 0;int[] sortArr = new int[arr.length];// 遍历分组计数器for (int i = 0; i < groupCounter.length; i++) {// 组内元素数量>1,递归分组if (groupCounter[i] > 1) {int[] copyArr = Arrays.copyOf(groupBucket[i], groupCounter[i]);// 递归分组int[] tmp = msdSort(copyArr, radix / 10);// 收集递归分组后的元素for (int j = 0; j < tmp.length; j++) {sortArr[index++] = tmp[j];}} else if (groupCounter[i] == 1) {// 收集组内元素数量=1的元素sortArr[index++] = groupBucket[i][0];}}return sortArr;}
点击移步博客主页,欢迎光临~