`

基数排序

J# 
阅读更多
基数排序
基数排序的主要思路是,将所有待比较数值(注意,必须是正整数)统一为同样的数位长度,数位较短的数前面补零. 然后, 从最低位开始, 依次进行一次稳定排序.这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列.

它的理论比较容易理解,但实现却有一点绕。




Java代码
package sort;  
 
import java.util.Arrays;  
 
public class RadixSort {  
 
    /** 
     * 取数x上的第d位数字 
     * @param x 数 
     * @param d 第几位,从低位到高位 
     * @return 
     */ 
    public int digit(long x, long d) {  
 
        long pow = 1;  
        while (--d > 0) {  
            pow *= 10;  
        }  
        return (int) (x / pow % 10);  
    }  
 
    /** 
     * 基数排序实现,以升序排序(下面程序中的位记录器count中,从第0个元素到第9个元素依次用来 
     * 记录当前比较位是0的有多少个..是9的有多少个数,而降序时则从第0个元素到第9个元素依次用来 
     * 记录当前比较位是9的有多少个..是0的有多少个数) 
     * @param arr 待排序数组 
     * @param digit 数组中最大数的位数 
     * @return 
     */ 
    public long[] radixSortAsc(long[] arr) {  
        //从低位往高位循环  
        for (int d = 1; d <= getMax(arr); d++) {  
            //临时数组,用来存放排序过程中的数据  
            long[] tmpArray = new long[arr.length];  
            //位记数器,从第0个元素到第9个元素依次用来记录当前比较位是0的有多少个..是9的有多少个数  
            int[] count = new int[10];  
            //开始统计0有多少个,并存储在第0位,再统计1有多少个,并存储在第1位..依次统计到9有多少个  
            for (int i = 0; i < arr.length; i++) {  
                count[digit(arr[i], d)] += 1;  
            }  
            /* 
             * 比如某次经过上面统计后结果为:[0, 2, 3, 3, 0, 0, 0, 0, 0, 0]则经过下面计算后 结果为: 
             * [0, 2, 5, 8, 8, 8, 8, 8, 8, 8]但实质上只有如下[0, 2, 5, 8, 0, 0, 0, 0, 0, 0]中 
             * 非零数才用到,因为其他位不存在,它们分别表示如下:2表示比较位为1的元素可以存放在索引为1、0的 
             * 位置,5表示比较位为2的元素可以存放在4、3、2三个(5-2=3)位置,8表示比较位为3的元素可以存放在 
             * 7、6、5三个(8-5=3)位置 
             */ 
            for (int i = 1; i < 10; i++) {  
                count[i] += count[i - 1];  
            }  
 
            /* 
             * 注,这里只能从数组后往前循环,因为排序时还需保持以前的已排序好的 顺序,不应该打 
             * 乱原来已排好的序,如果从前往后处理,则会把原来在前面会摆到后面去,因为在处理某个 
             * 元素的位置时,位记数器是从大到到小(count[digit(arr[i], d)]--)的方式来处 
             * 理的,即先存放索引大的元素,再存放索引小的元素,所以需从最后一个元素开始处理。 
             * 如有这样的一个序列[212,213,312],如果按照从第一个元素开始循环的话,经过第一轮 
             * 后(个位)排序后,得到这样一个序列[312,212,213],第一次好像没什么问题,但问题会 
             * 从第二轮开始出现,第二轮排序后,会得到[213,212,312],这样个位为3的元素本应该 
             * 放在最后,但经过第二轮后却排在了前面了,所以出现了问题 
             */ 
            for (int i = arr.length - 1; i >= 0; i--) {//只能从最后一个元素往前处理  
                //for (int i = 0; i < arr.length; i++) {//不能从第一个元素开始循环  
                tmpArray[count[digit(arr[i], d)] - 1] = arr[i];  
                count[digit(arr[i], d)]--;  
            }  
 
            System.arraycopy(tmpArray, 0, arr, 0, tmpArray.length);  
        }  
        return arr;  
    }  
 
    /** 
     * 基数排序实现,以降序排序(下面程序中的位记录器count中,从第0个元素到第9个元素依次用来 
     * 记录当前比较位是0的有多少个..是9的有多少个数,而降序时则从第0个元素到第9个元素依次用来 
     * 记录当前比较位是9的有多少个..是0的有多少个数) 
     * @param arr 待排序数组 
     * @return 
     */ 
    public long[] radixSortDesc(long[] arr) {  
        for (int d = 1; d <= getMax(arr); d++) {  
            long[] tmpArray = new long[arr.length];  
            //位记数器,从第0个元素到第9个元素依次用来记录当前比较位是9的有多少个..是0的有多少个数  
            int[] count = new int[10];  
            //开始统计0有多少个,并存储在第9位,再统计1有多少个,并存储在第8位..依次统计  
            //到9有多少个,并存储在第0位  
            for (int i = 0; i < arr.length; i++) {  
                count[9 - digit(arr[i], d)] += 1;  
            }  
 
            for (int i = 1; i < 10; i++) {  
                count[i] += count[i - 1];  
            }  
 
            for (int i = arr.length - 1; i >= 0; i--) {  
                tmpArray[count[9 - digit(arr[i], d)] - 1] = arr[i];  
                count[9 - digit(arr[i], d)]--;  
            }  
 
            System.arraycopy(tmpArray, 0, arr, 0, tmpArray.length);  
        }  
        return arr;  
    }  
 
    private int getMax(long[] array) {  
        int maxlIndex = 0;  
        for (int j = 1; j < array.length; j++) {  
            if (array[j] > array[maxlIndex]) {  
                maxlIndex = j;  
            }  
        }  
        return String.valueOf(array[maxlIndex]).length();  
    }  
 
    public static void main(String[] args) {  
        long[] ary = new long[] { 123, 321, 132, 212, 213, 312, 21, 223 };  
        RadixSort rs = new RadixSort();  
        System.out.println("升 - " + Arrays.toString(rs.radixSortAsc(ary)));  
 
        ary = new long[] { 123, 321, 132, 212, 213, 312, 21, 223 };  
        System.out.println("降 - " + Arrays.toString(rs.radixSortDesc(ary)));  
    }  

分享到:
评论

相关推荐

    基数排序及流程图

    包括了基数排序的实现代码和流程图。 先对个位数字进行统计,然后根据个位进行排序,然后对十位进行统计,然后根据十位进行排序,即可获得最终结果。 时间效率:待排序列为n个记录,10个关键码,关键码的取值范围为0...

    数据结构基数排序数据结构基数排序

    数据结构中的基数排序是一种非比较型整数排序算法,它基于数字的位宽进行排序,尤其适用于处理大量相同数字的情况。基数排序的核心思想是将数字按照位数从低位到高位分别进行桶排序,最终得到完全有序的序列。下面将...

    基数排序过程及程序基数排序过程及程序

    基数排序(Radix Sort)是一种非比较型的整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表示字符串、卡片等数据(当成是整数即可),所以基数排序并不限于整数。它是...

    数据结构实验报告--链式基数排序算法.doc

    链式基数排序是一种非比较型整数排序算法,它的原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。在描述中提到的实验报告中,主要目标是实现一个链式基数排序算法,用于对一组数据进行最低位优先的排序...

    基数排序、堆排序、希尔排序、直接插入排序

    这里我们将深入探讨四种常见的排序算法:基数排序、堆排序、希尔排序和直接插入排序。 首先,基数排序是一种非比较型整数排序算法,它的基本思想是将整数按位数切割成不同的数字,然后按每个位数分别比较。基数排序...

    C++写基数排序算法

    基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。在C++中实现基数排序,主要涉及到数组、计数排序以及位操作等技术。以下是关于基数排序及其C++实现的详细解释...

    基于双向链表的基数排序

    基数排序(radix sort)又称桶排序(bucket sort),相对于常见的比较排序,基数排序是一种分配式排序,需要将关键字拆分成数字位。并且按照数字位的值对数据项进行排序,这种方法不需要进行比较操作。 为了尽可能少的...

    基数排序链表法

    基数排序法用链表完成使用C语言适用于刚入门的学者

    基数排序基数排序基数排序

    基数排序是一种非比较型整数排序算法,它的原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。这种排序方法不需要进行记录关键字间的比较,而是通过“分配”和“收集”操作对单逻辑关键字进行排序。 1....

    Radix Sort (基数排序)排序算法

    ### Radix Sort (基数排序) 排序算法详解 #### 一、算法介绍与应用场景 基数排序(Radix Sort)是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达...

    基数排序-radix sort

    基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。这种排序方法对于大数据量的处理非常有效,尤其适合于数据范围远大于内存大小的情况。以下是基数排序的详细...

    基数排序C语言实现

    基数排序是一种非比较型整数排序算法,它的原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。这种排序方法非常适合处理大量整数的排序,尤其在数字位数相同或者相差不大的情况下,效率较高。本文将深入...

    数据结构之基数排序数据结构之基数排序数据结构之基数排序

    基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。这种排序方法适用于处理大量数据,且数据的范围不超过10的某个幂次方的情况。基数排序是基于多关键字排序的一...

    基数排序算法 java实现

    基数排序是一种非比较型整数排序算法,它的原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。这种算法对于大数据量的排序尤其有效,因为其时间复杂度为线性,即O(n*k),其中n是待排序的元素数量,k是每...

    基数排序_C语言_源码_数据结构

    基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。这种算法对于大数据量的排序非常有效,尤其是在数据范围不超过0-9的情况下。接下来,我们将深入探讨基数排序...

    C经典算法之基数排序法

    ### C经典算法之基数排序法 #### 知识点概览 1. **排序算法的基础概念** - 排序算法的基本定义与分类 - 比较性排序与非比较性排序的区别 - 稳定排序与不稳定排序的概念 2. **基数排序的原理** - 分配式排序的...

    基数排序课程设计.rar

    基数排序是一种非比较型整数排序算法,它的原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。这个课程设计主要涵盖了基数排序的基本概念、实现方式以及C++编程技术。在本课程设计中,你将学习到如何用...

    用stl实现基数排序算法

    基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。它不是基于比较的排序,而是通过创建额外的数据结构,比如计数器或者桶,来达到排序的目的。在处理大量数据时...

    简单的基数排序算法,STL实现

    基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。这种算法对于大数据量的排序尤其有效,因为它是线性时间复杂度的,即O(nk),其中n是元素数量,k是数字的最大...

Global site tag (gtag.js) - Google Analytics