排序之基数排序

基数排序也是一种不基于比较的排序方法,它的思想是这样的:假设有m个数据,先根据个位数大小对这m个数据进行排序,得到一个新的序列;然后根据十位数大小对这m个数据进行排序,又得到一个新的序列;然后再根据百位、千位,依次类推,直至最高位,最后得到的序列就是有序的序列。那么对每一位的排序是如何进行的呢?位排序的思想是这样的:假设每位数据的范围是0到9,那么就创建10个桶(可用数组表示),如果该位数是0,那么就放到0号桶内,是1就放到1号桶内.....,最后从0号桶到9号桶,依次取出桶内的数据,就可以得到一个序列,这里同一个桶内的数据顺序任意,处于同一个桶内的数据,说明它们这一位的数是相同的。先用图示举一个例子:

基数排序的算法描述如下:

radix_sort(A,d)//1是最低位,d是最高位

1、for i=1 to d

2、  do use a stable sort to sort array A on digit i

算法描述很简单,但是里面的细节还是挺多的,首先,我们要创建桶,这里桶是用一个数组表示,桶内元素类型是一个自定义的类,类可以存储数组A中的数据,而为了取“位”的方便,这里将数组A中的数据均用String类型表示,对图中序列进行基数排序的代码示例图下:

class stableNode{
    String val=null;
    stableNode next=null;
    public stableNode(String val){
        this.val=val;
    }
}
public class Test{
    public static void main(String[] args)throws InterruptedException{
        String[] value={"329","457","657","839","436","720","355"};
        radix_sort(value);
        System.out.println();
    }
    static void radix_sort(String[] value){
        //创建一个盒子,用于存放数据
        stableNode[] stable=new stableNode[10];//0 to 9
        int i=0;
        //因为要从最低位开始排序,所以要对数据进行翻转,使其高低位交换位置
        for(i=0;i<value.length;i++){
            value[i]=(new StringBuilder(value[i]).reverse()).toString();
        }
        for(String str:value){
            System.out.print(str+" ");
        }
        System.out.println();
        //注意这里,为了演示方便,将所有数据的位数都设成一样的
        int maxLen=value[0].length();
        int index=0;
        int k=0;
        for(k=0;k<maxLen;k++){//进行数字位的遍历
            for(i=0;i<value.length;i++){//遍历待排序的数组
                //为了演示方便,这里假定所有数据的位数是相同的!!!
                //也就是说,如果是百位数,那么全是百位数
                //如果数的位数不同,则需要进一步修改排序细节,但是思想是相同的
                index=Integer.valueOf(value[i].substring(k,k+1));
                build_stable(stable,index,value[i]);
            }
            sort_result(stable,value);
        }
        for(i=0;i<value.length;i++){
            value[i]=(new StringBuilder(value[i]).reverse()).toString();
        }
        for(String str:value){
            System.out.print(str+" ");
        }
    }
    //将桶内的数据从新放到数组里面,从而得到一个新的序列
    static void sort_result(stableNode[] stable,String[] value){
        int k=0,i=0;
        stableNode root=null;
        for(i=0;i<stable.length;i++){//其实是i<10即可
            root=stable[i];
            while(root!=null){
                value[k++]=root.val;
                root=root.next;
            }
        }
        //全部赋值为空,以待下次使用
        for(i=0;i<stable.length;i++){
            stable[i]=null;
        }
    }
    //创建桶,根据基数,将数据放到何时的桶里面
    static void build_stable(stableNode[] stable,int index,String value){
        if(stable[index]==null){
            stable[index]=new stableNode(value);
        }else{
            stableNode list=stable[index];
            while(list.next!=null){
                list=list.next;
            }
            list.next=new stableNode(value);
        }

    }
    static void printArray(int[] array){
        for(int val:array){
            System.out.print(val+" ");
        }
        System.out.println();
    }
}

基数排序分析:时间复杂度是O(max_digit*(radix_size+n)),其中max_digit是每位中的最大数值,在这里是9,radix_size是0到k之间的k中可能取值这里是0到9共10中可能取值。由于需要建立桶,且要盛放序列A中的所有数据,所以空间复杂度是O(n)

时间: 2024-10-29 03:33:00

排序之基数排序的相关文章

【数据结构】非比较排序算法(实现计数排序和基数排序)

● 计数排序 1.算法思想: 计数排序是直接定址法的变形.通过开辟一定大小的空间,统计相同数据出现的次数,然后回写到原序列中. 2.步骤: 1)找到序列中的最大和最小数据,确定开辟的空间大小. 2)开辟空间,利用开辟的空间存放各数据的个数. 3)将排好序的序列回写到原序列中. 具体实现如下: void CountSort(int *arr, int size) {  assert(arr);  int min = arr[0];  int max = arr[0];  int num = 0;

有Leetcode中一道题,谈桶排序,基数排序和计数排序

几种非比较排序 在LeetCode中有个题目叫Maximum Gap,是求一个非排序的正数数列中按顺序排列后的最大间隔.这个题用桶排序和基数排序都可以实现.下面说一下桶排序.基数排序和计数排序这三种非比较排序. 桶排序 这种排序的主要思想是,把数列分配到多个桶中,然后再在各个桶中使用排序算法进行排序,当然也可以继续使用桶排序. 假设数组的最大值是A,最小值是B,长度是L,则每个桶的大小可以是S=Max(1,(A-B)/(L-1))则可以分为(A-B)/S+1个桶. 对于数列中的数字x,用(x-B

桶式排序和基数排序

之前总结了基于比较模型的常见排序算法,它们中最快的也要消耗O(nlogn)时间.但是我们应该知道的是,在一定条件下以线性时间进行排序依然是可能的.桶式排序和基数排序在合适的条件下就是以线性时间执行的算法. 桶式排序(bucket sort): 思想:如果我们限制需要排序的整数的范围,比如说我们有n个整数,范围从0到m-1,我们可以利用这个信息得到一种快速的排序算法.我们留置一个数组,称之为t,大小为m,并初始化为0.于是t有m个单元(桶),开始时它们都是空的.当i被读入时t[i]加一.在所有的输

常见的五类排序算法图解和实现(多关键字排序:基数排序以及各个排序算法的总结)

基数排序思想 完全不同于以前的排序算法,可以说,基数排序也叫做多关键字排序,基数排序是一种借助“多关键字排序”的思想来实现“单关键字排序”的内部排序算法. 两种方式: 1.最高位优先,先按照最高位排成若干子序列,再对子序列按照次高位排序 2.最低位优先:不必分子序列,每次排序全体元素都参与,不比较,而是通过分配+收集的方式. 多关键字排序 例:将下表所示的学生成绩单按数学成绩的等级由高到低排序,数学成绩相同的学生再按英语成绩的高低等级排序.        第一个关键字是数学成绩,第二个关键字是英

算法——排序之基数排序

基数排序也是稳定的内排序. 因为它的实现是基于内部使用了稳定的排序实现的所以基数排序整体是稳定的,而且时间复杂度为O(n). 举个例子: 现在我们将一些3(多)位数排序,如果你说直接判断就好的话,那你就太天真了,因为那就又变成看O(nlgn)或者O(n2). 如何能降低时间复杂度变成O(n) 呢? 那就要使用线性时间的排序了,正如上篇的计数排序. 基数排序 利用的是计数排序进行排序的.因为计数排序是稳定的排序,即排序后的大小顺序 会与 上一轮的排序顺序结果一致. 再举个例子: 排序前 第一遍排序

桶排序和基数排序

桶排序的基本思想 假设有一组长度为N的待排关键字序列K[1....n].首先将这个序列划分成M个的子区间(桶) .然后基于某种映射函数 ,将待排序列的关键字k映射到第i个桶中(即桶数组B的下标 i) ,那么该关键字k就作为B[i]中的元素(每个桶B[i]都是一组大小为N/M的序列).接着对每个桶B[i]中的所有元素进行比较排序(可以使用快排).然后依次枚举输出B[0]....B[M]中的全部内容即是一个有序序列. 假如待排序列K= {49. 38 . 35. 97 . 76. 73 . 27.

排序八 基数排序

要点 基数排序又称桶排序. 基数排序与本系列前面讲解的七种排序方法都不同,它不需要比较关键字的大小. 它是根据关键字中各位的值,通过对排序的N个元素进行若干趟“分配”与“收集”来实现排序的. 不妨通过一个具体的实例来展示一下,基数排序是如何进行的. 设有一个初始序列为: R {50, 123, 543, 187, 49, 30, 0, 2, 11, 100}. 我们知道,任何一个阿拉伯数,它的各个位数上的基数都是以0~9来表示的. 所以我们不妨把0~9视为10个桶. 我们先根据序列的个位数的数字

计数排序、基数排序与桶排序

一.计数排序 稳定. 当输入的元素是n 个小区间(0到k)内整数时,它的运行时间是 O(n + k),空间复杂度是O(n). const int K = 100; //计数排序:假设输入数据都属于一个小区间内的整数,可用于解决如年龄排序类的问题 //Input:A[0, ..., n-1], 0 <= A[i] < K //Output:B[0, ..., n-1], sorting of A //Aux storage C[0, ..., K) void CountSort(int A[],

经典排序算法 - 基数排序Radix sort

经典排序算法 - 基数排序Radix sort 原理类似桶排序,这里总是需要10个桶,多次使用 首先以个位数的值进行装桶,即个位数为1则放入1号桶,为9则放入9号桶,暂时忽视十位数 例如 待排序数组[62,14,59,88,16]简单点五个数字 分配10个桶,桶编号为0-9,以个位数数字为桶编号依次入桶,变成下边这样 |  0  |  0  | 62 |  0  | 14 |  0  | 16 |  0  |  88 | 59 | |  0  |  1  |  2  |  3  |  4 | 

线性排序算法---- 计数排序, 基数排序, 桶排序

排序算法里,除了比较排序算法(堆排序,归并排序,快速排序),还有一类经典的排序算法-------线性时间排序算法.听名字就让人兴奋! 线性时间排序,顾名思义,算法复杂度为线性时间O(n) , 非常快,比快速排序还要快的存在,简直逆天.下面我们来仔细看看三种逆天的线性排序算法, 计数排序,基数排序和桶排序. 1计数排序  counting Sort 计数排序 假设 n个 输入元素中的每一个都是在 0 到 k 区间内的一个整数,当 k= O(N) 时,排序运行的时间为 O(N). 计数排序的基本思想