逸帅 发表于 2021-3-23 23:15

排序算法----基数排序

# 排序算法----基数排序

## 1.基本思想

> 基数排序的基本思想:将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。 这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。

## 2.基数排序的代码实现

```java
package com.yishuai.sort;

import java.util.Arrays;

/**
* @AuThor yishuai
* @description 基数排序算法
* @date 2021/3/23 10:02 下午
*/
public class Radix {
    public static void main(String[] args) {
      int[] initial = {15, 159, 552, 328, 976, 333, 312, 4, 799};
      radixSort(initial);
      System.out.println(Arrays.toString(initial));
    }

    /**
   * 基数排序(经典的用空间换时间的算法,速度非常快):
   * 第一步:确定数组中最大数的位数
   * 第二步:定义二维数组,十个一维数组作为十个桶,桶的大小是数组的长度
   * 第三步:定义一个大小为10的一位数组,用来记录每个桶里面数个数
   * 第四步:分别取个位、十位、百位...,分别放入对应序号的桶内
   * 第五步:从小到大遍历每一个桶,依次把桶里的数据放入到原来数组中
   * 遍历完最后一位时,则代表排序完成。
   */
    public static void radixSort(int[] initial) {
      //假设第一位就是最大的,然后循环遍历所有的数,把最大数找出来
      int maxSize = initial;
      for (int i = 1; i < initial.length; i++) {
            if (maxSize < initial) {
                maxSize = initial;
            }
      }
      //确定最大数后,通过转换成字符串,然后取字符串长度,就知道最大有几位数
      int maxLength = (maxSize + "").length();

      //第二步:定义桶的个数和大小,、
      // 取到数组的长度,是为了防止所以元素都在一个桶里,导致数组越界
      int[][] bucket = new int;

      //第三步:定义记录每个桶里元素个数的一维数组
      int[] count = new int;

      //第四步:分别取个、十、百...的数据,放入桶里,开始排序
      //i为0代表各位,1代表十位,直到遍历到最大位数
      //n是用来表示个位数、十位数等... 取10的倍数
      for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {
            //把数组里面的每个数都遍历出来,然后放到桶子里面
            for (int j = 0; j < initial.length; j++) {
                /**
               * digit:位数
               * /1代表是数本身,%10表示取10的余数,代表取出个位数
               * /10代表取出数除以10的商,然后%10,代表取出了十位数
               * /100代表取出数除以100的商,就是百位数本身,百位数是一位数,一位数再%10还是本身
               * 这是为了找规律,凑出来的数据
               */
                int digit = initial / n % 10;
                //取出digit号桶子,然后往里面添加数据,同时count对应的记录数据+1
                //count是代表桶里本来的数据已经到了多少位,往上面添加即可
                bucket++] = initial;
            }
            int num = 0;
            //第五步:把桶里的每个元素,一次放到数组中去
            for (int k = 0; k < 10; k++) {
                //通过计数的数组,把不为0的数组里面的数一次遍历出来
                if (count != 0) {
                  for (int j = 0; j < count; j++) {
                        //把第i个不为空的桶里的,第j个数据,放到数组中
                        initial = bucket;
                  }
                }
                //每次把个位、十位...数据取出来后,把桶子里面的计数清空
                // 也就代表着清空了桶子里的数,这样下次又会从第0个开始
                count = 0;
            }
            System.out.println(Arrays.toString(initial));
      }
    }
}

```

## 3.基数排序存在的问题

1. 基数排序是对传统桶排序的扩展,速度很快.

2. 基数排序是经典的空间换时间的方式,占用内存很大, 当对海量数据排序时,容易造成 OutOfMemoryError 。

3. 基数排序是稳定的。

    [注:假定在待排序的记录序列中, 存在多个具有相同的关键字的记录,若经过排序,这些 记录的相对次序保持不变,即在原序列中, r=r, 且 r在 r之前, 而在排序后的序列中, r仍在 r之前, 则称这种排序算法是稳定的;否则称为不稳定的]

4. 有负数的数组,我们一般不用基数排序来进行排序,如果要支持负数,还要进行进一步的改善

PhoebeCLS 发表于 2021-3-24 00:14

很好的技术帖刚好用到,谢谢楼主

Masterlinnn 发表于 2021-3-24 01:39

小白还是不懂{:1_937:},慢慢学习:lol

704473288 发表于 2021-3-24 08:34

谢谢分享
页: [1]
查看完整版本: 排序算法----基数排序