基数排序

基数排序是桶式排序的推广。——《数据结构与算法分析: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

原文地址:https://www.cnblogs.com/nufangrensheng/p/3593282.html