[Java] java基数排序算法 →→→→→进入此内容的聊天室

来自 , 2021-02-27, 写在 Java, 查看 141 次.
URL http://www.code666.cn/view/598b3e71
  1. /**
  2.  * 基数排序:
  3.  */
  4. import java.util.Arrays;
  5.  
  6. public class RadixSort {
  7.  
  8.         /**
  9.          * 取数x上的第d位数字
  10.          *
  11.          * @param x
  12.          *            数
  13.          * @param d
  14.          *            第几位,从低位到高位
  15.          * @return
  16.          */
  17.         public int digit(long x, long d) {
  18.  
  19.                 long pow = 1;
  20.                 while (--d > 0) {
  21.                         pow *= 10;
  22.                 }
  23.                 return (int) (x / pow % 10);
  24.         }
  25.  
  26.         /**
  27.          * 基数排序实现,以升序排序(下面程序中的位记录器count中,从第0个元素到第9个元素依次用来
  28.          * 记录当前比较位是0的有多少个..是9的有多少个数,而降序时则从第0个元素到第9个元素依次用来 记录当前比较位是9的有多少个..是0的有多少个数)
  29.          *
  30.          * @param arr
  31.          *            待排序数组
  32.          * @param digit
  33.          *            数组中最大数的位数
  34.          * @return
  35.          */
  36.         public long[] radixSortAsc(long[] arr) {
  37.                 // 从低位往高位循环
  38.                 for (int d = 1; d <= getMax(arr); d++) {
  39.                         // 临时数组,用来存放排序过程中的数据
  40.                         long[] tmpArray = new long[arr.length];
  41.                         // 位记数器,从第0个元素到第9个元素依次用来记录当前比较位是0的有多少个..是9的有多少个数
  42.                         int[] count = new int[10];
  43.                         // 开始统计0有多少个,并存储在第0位,再统计1有多少个,并存储在第1位..依次统计到9有多少个
  44.                         for (int i = 0; i < arr.length; i++) {
  45.                                 count[digit(arr[i], d)] += 1;
  46.                         }
  47.                         /*
  48.                          * 比如某次经过上面统计后结果为:[0, 2, 3, 3, 0, 0, 0, 0, 0, 0]则经过下面计算后 结果为: [0, 2,
  49.                          * 5, 8, 8, 8, 8, 8, 8, 8]但实质上只有如下[0, 2, 5, 8, 0, 0, 0, 0, 0, 0]中
  50.                          * 非零数才用到,因为其他位不存在,它们分别表示如下:2表示比较位为1的元素可以存放在索引为1、0的
  51.                          * 位置,5表示比较位为2的元素可以存放在4、3、2三个(5-2=3)位置,8表示比较位为3的元素可以存放在
  52.                          * 7、6、5三个(8-5=3)位置
  53.                          */
  54.                         for (int i = 1; i < 10; i++) {
  55.                                 count[i] += count[i - 1];
  56.                         }
  57.  
  58.                         /*
  59.                          * 注,这里只能从数组后往前循环,因为排序时还需保持以前的已排序好的 顺序,不应该打
  60.                          * 乱原来已排好的序,如果从前往后处理,则会把原来在前面会摆到后面去,因为在处理某个
  61.                          * 元素的位置时,位记数器是从大到到小(count[digit(arr[i], d)]--)的方式来处
  62.                          * 理的,即先存放索引大的元素,再存放索引小的元素,所以需从最后一个元素开始处理。
  63.                          * 如有这样的一个序列[212,213,312],如果按照从第一个元素开始循环的话,经过第一轮
  64.                          * 后(个位)排序后,得到这样一个序列[312,212,213],第一次好像没什么问题,但问题会
  65.                          * 从第二轮开始出现,第二轮排序后,会得到[213,212,312],这样个位为3的元素本应该
  66.                          * 放在最后,但经过第二轮后却排在了前面了,所以出现了问题
  67.                          */
  68.                         for (int i = arr.length - 1; i >= 0; i--) {// 只能从最后一个元素往前处理
  69.                                 // for (int i = 0; i < arr.length; i++) {//不能从第一个元素开始循环
  70.                                 tmpArray[count[digit(arr[i], d)] - 1] = arr[i];
  71.                                 count[digit(arr[i], d)]--;
  72.                         }
  73.  
  74.                         System.arraycopy(tmpArray, 0, arr, 0, tmpArray.length);
  75.                 }
  76.                 return arr;
  77.         }
  78.  
  79.         /**
  80.          * 基数排序实现,以降序排序(下面程序中的位记录器count中,从第0个元素到第9个元素依次用来
  81.          * 记录当前比较位是0的有多少个..是9的有多少个数,而降序时则从第0个元素到第9个元素依次用来 记录当前比较位是9的有多少个..是0的有多少个数)
  82.          *
  83.          * @param arr
  84.          *            待排序数组
  85.          * @return
  86.          */
  87.         public long[] radixSortDesc(long[] arr) {
  88.                 for (int d = 1; d <= getMax(arr); d++) {
  89.                         long[] tmpArray = new long[arr.length];
  90.                         // 位记数器,从第0个元素到第9个元素依次用来记录当前比较位是9的有多少个..是0的有多少个数
  91.                         int[] count = new int[10];
  92.                         // 开始统计0有多少个,并存储在第9位,再统计1有多少个,并存储在第8位..依次统计
  93.                         // 到9有多少个,并存储在第0位
  94.                         for (int i = 0; i < arr.length; i++) {
  95.                                 count[9 - digit(arr[i], d)] += 1;
  96.                         }
  97.  
  98.                         for (int i = 1; i < 10; i++) {
  99.                                 count[i] += count[i - 1];
  100.                         }
  101.  
  102.                         for (int i = arr.length - 1; i >= 0; i--) {
  103.                                 tmpArray[count[9 - digit(arr[i], d)] - 1] = arr[i];
  104.                                 count[9 - digit(arr[i], d)]--;
  105.                         }
  106.  
  107.                         System.arraycopy(tmpArray, 0, arr, 0, tmpArray.length);
  108.                 }
  109.                 return arr;
  110.         }
  111.  
  112.         private int getMax(long[] array) {
  113.                 int maxlIndex = 0;
  114.                 for (int j = 1; j < array.length; j++) {
  115.                         if (array[j] > array[maxlIndex]) {
  116.                                 maxlIndex = j;
  117.                         }
  118.                 }
  119.                 return String.valueOf(array[maxlIndex]).length();
  120.         }
  121.  
  122.         public static void main(String[] args) {
  123.                 long[] ary = new long[] { 123, 321, 132, 212, 213, 312, 21, 223 };
  124.                 RadixSort rs = new RadixSort();
  125.                 System.out.println("升 - " + Arrays.toString(rs.radixSortAsc(ary)));
  126.  
  127.                 ary = new long[] { 123, 321, 132, 212, 213, 312, 21, 223 };
  128.                 System.out.println("降 - " + Arrays.toString(rs.radixSortDesc(ary)));
  129.         }
  130. }
  131.  

回复 "java基数排序算法"

这儿你可以回复上面这条便签

captcha