• 基数排序


    基数排序是桶式排序的推广。——《数据结构与算法分析:C语言描述》

    红心实例分析基数排序算法思想:

    假设我们有10个数,范围在0-999之间,我们要将其排序。显然,我们不能使用桶式排序,考虑最坏的情况下我们将需要使用1000个桶,这样桶就太多了。我们的策略是使用多趟桶式排序(对于十进制数来说,其基数为10,对每位(个、十、百)进行桶式排序最多只需要10个桶)。我们用最低有效位(LSB)优先的方式进行桶式排序,也就是说首先对这10个数按照个位上的数字进行一次桶式排序,再对这10个数按照十位上的数字进行一次桶式排序,最后对这10个数按照百位上的数字进行一次桶式排序。这样经过三趟桶式排序后,这10个数也就排好序了。(注:对于一位数,其十位、百位均为0;对于两位数,其百位为0)

    红心实例解析基数排序实现步骤:

    假设10个数为:64、8、216、512、27、729、0、1、343、125,为方便起见我们将不足三位的数以高位补零的方式全部补为三位数。

    高位补零后这10个数为:064、008、216、512、027、729、000、001、343、125.

    第一趟桶式排序(个位):

    000 001 512 343 064 125 216 027 008 729
    0 1 2 3 4 5 6 7 8 9

    第二趟桶式排序(十位):

    008
    001
    000

    216
    512
    729
    027
    125
     

    343
     

    064
         
    0 1 2 3 4 5 6 7 8 9

    第三趟桶式排序(百位):

    064
    027
    008
    001
    000




    125




    216




    343
     



    512
     



    729
       
    0 1 2 3 4 5 6 7 8 9

    红心基数排序算法时间复杂度分析:

    我们已知桶式排序的时间复杂度为O(N+B),其中N为待排序元素个数,而B是桶数。我们又知道基数排序是以多趟桶式排序来实现的,所以基数排序的运行时间是O(P(N+B)),其中P是排序的趟数。

    红心C语言实现,基于链表

    #include "list.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    void
    radix_sort(int A[], int N, int M)  /* A[]为待排序数组,N为数组A中元素个数,M为数组A中最大值的位数 */
    {                                  /* 假设待排序的数全部是正整数 */
        int i, j, k, l, m, n;
        list bucket[10];
        ptr_to_node ptr;
        
        for(k = 0; k < 10; k++)
            bucket[k] = create_list();   /* 分配10个桶(链表) */ 
    
        for(i = 0; i < M; i++)           /* i=0(按个位上的数字排序);i=1(按十位上的数字排序)… */
        {
            l = 0;
            for(j = 0; j < N; j++)
            {
                n = A[j] / pow(10, i) ;
                m = n % 10;
                insert_to_tail(A[j], bucket[m]);  /* 按位(个、十、百…)排序,放入对应的桶中 */
            }
            for(k = 0; k < 10; k++)
            {
                ptr = bucket[k]->next;
                while(ptr != NULL)
                {
                    A[l] = ptr->data;          /* 把本次(比如按照个位数排序)排序后的数按照顺序重新装入数组A,以待下次(按照下个数位的)桶排序使用 */
                    l++;
                    ptr = ptr->next;
                }
                //bucket[k]->next = NULL;
                make_empty(bucket[k]);         /* 把桶置空,为下一个数位排序做准备,可以用bucket[k]->next = NULL;实现此语句的功能,但未释放资源 */
            }
        }
    }
    
    int 
    main(void)
    {
        int i;
        int A[] = {64, 8, 216, 512, 27, 729, 0, 1, 343, 125};    
        
        printf("unsorted: ");
        for(i = 0; i < 10; i++)
            printf("%d ", A[i]);
        printf("
    ");
    
        radix_sort(A, 10, 3);
        printf("sorted  : ");
        for(i = 0; i < 10; i++)
            printf("%d ", A[i]);
        printf("
    ");
    
    }

    其中list.c和list.h源码参考:http://www.cnblogs.com/nufangrensheng/p/3579993.html

    编译运行结果如下:

    image

  • 相关阅读:
    Spinner使用
    5.5 easypoi模板导出excel测试Demo > 我的程序猿之路:第四十五章
    5.4 SpringCloud配置中心搭建以及问题解决 > 我的程序猿之路:第四十四章
    5.3 Spring事物管理详解 > 我的程序猿之路:第四十二章
    5.2 SpringBoot实现断点续传功能 > 我的程序猿之路:第四十二章
    5.1 java实现doc文档转pdf文件 > 我的程序猿之路:第四一章
    5.0 SpringBoot普通上传功能 > 我的程序猿之路:第四十章
    4.8 数字金额大写转换 插件 > 我的程序猿之路:第三十八章
    4.7 基于Spring注解的定时任务(@Schedule) > 我的程序猿之路:第三十七章
    4.6 基于Spring-Boot的Mysql+jpa的增删改查学习记录 > 我的程序猿之路:第三十六章
  • 原文地址:https://www.cnblogs.com/nufangrensheng/p/3593282.html
Copyright © 2020-2023  润新知