分配排序之基数排序(Java语言描述)

分配排序之基数排序

基数排序是在计数排序上的应用扩展,是分配排序的一个特例,我们已经知道计数排序(桶排序)适用于小数范围内的排序,对于大数则效率不高,而今天要说的基数排序,利用了进制基数的特点,将大数拆解为进制内范围的小数,多次执行计数或其他稳定排序,实现了大数范围内的排序功能。

例如对于两位数之间的排序问题,我们一般从十位开始比较,十位相同的数,再比较个位,最终得出想要的结果,基数排序的过程大致如此,不同之处在于对于十位或个位相同的数,我们采用计数排序的处理,中间不需要进行元素之间的比较。

基数排序分为高位优先法(most significant digit first, MSD)与低位优先法(least significant digit first, LSD),计算机在实现高位优先法时,需要进行嵌套分配桶空间,是一个递归分治的算法,执行起来比较复杂,因此LSD的实现则更为常见。

LSD基于数组的实现代码如下:

import java.util.Arrays;

public class RadixSort {

    public static void main(String[] args) {
        int[] arr = new int[] { 97, 53, 88, 59, 26, 41, 88, 31, 22 };
        arr = radixSort(arr, 9, 2, 10);
        System.out.println(Arrays.toString(arr));
    }

    /**
     * 
     * @param array 排序序列
     * @param n     排序序列元素数
     * @param d     排序位数(两位数传入2)
     * @param r     基
     */
    public static int[] radixSort(int[] array, int n, int d, int r) {
        // 内部桶排序时用以保存各桶中的元素数
        int[] count = new int[r];
        // 按照不同基位进行桶排序时存放元素
        int[] tmpArray = new int[n];
        // 模除数,计算桶位
        int radix = 1;

        // 临时变量,用于计算每个元素的桶位,避免重复声明
        int k = 0;

        // 进行d轮计数排序(/桶排序)
        for (int i = 0; i < d; i++) {
            // 每轮循环,须重新初始化count数组
            for (int j = 0; j < r; j++) {
                count[j] = 0;
            }

            // 遍历原始数组,计算每个桶位的元素数,存储于count数组
            for (int j = 0; j < n; j++) {
                k = (array[j] / radix) % r;
                count[k]++;
            }
            // 计数器对应位数值修改为下一位的开始位置
            for (int j = 1; j < r; j++) {
                count[j] = count[j] + count[j - 1];
            }
            
            // 进行桶排序过程
            for (int j = n - 1; j >= 0; j--) {
                // 计算元素桶位
                k = (array[j] / radix) % r;
                count[k]--;
                tmpArray[count[k]] = array[j];
            }
            
            // 回写到原数组
            for (int j = 0; j < n; j++) {
                array[j] = tmpArray[j];
            }

            // 基位递增
            radix *= r;
        }
        return array;
    }
}

小结

基数排序的主要思想是按照基数对排序元素进行拆分,拆分后的每个值都属于进制内的数值,在此基础上,按照每一位进行桶排序,与直观的理解不同,由于计算机在处理递归分治算法时较为复杂,因此一般实现方式是LSD–低位优先的算法,稍微考虑下,高位优先MSD与低位LSD之间的直观区别仅仅是排序时处理的方向不一样。

推荐资料:
Radix sort - Wikiwand

欢迎关注我的公众号,了解更多内容:
我的公众号

发布了159 篇原创文章 · 获赞 225 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/lyg673770712/article/details/88047572
今日推荐