Radix Sort如何工作?

时间:2013-02-05 21:46:32

标签: algorithm sorting radix-sort

我不知道为什么这对我来说如此困难。我查看了wiki页面和伪代码(以及实际代码),试图理解基数排序算法的工作方式(关于存储桶)。

我在这里看错了吗?我应该考虑一下桶排序吗?有人能给我一个愚蠢的版本吗?作为参考,这里是据称执行基数排序的代码块:

// Sort 'size' number of integers starting at 'input' according to the 'digit'th digit
// For the parameter 'digit', 0 denotes the least significant digit and increases as significance does
void radixSort(int* input, int size, int digit)
{
    if (size == 0)
        return;

    int[10] buckets;    // assuming decimal numbers

    // Sort the array in place while keeping track of bucket starting indices.
    // If bucket[i] is meant to be empty (no numbers with i at the specified digit),
    // then let bucket[i+1] = bucket[i]

    for (int i = 0; i < 10; ++i)
    {
        radixSort(input + buckets[i], buckets[i+1] - buckets[i], digit+1);
    }
}

我也看过非递归解决方案:

void radixsort(int *a, int arraySize)
{
    int i, bucket[sortsize], maxVal = 0, digitPosition =1 ;
    for(i = 0; i < arraySize; i++) {
        if(a[i] > maxVal) maxVal = a[i];
    }

    int pass = 1; 
    while(maxVal/digitPosition > 0) {
        // reset counter 
        int digitCount[10] = {0};

        // count pos-th digits (keys) 
        for(i = 0; i < arraySize; i++)
            digitCount[a[i]/digitPosition%10]++;

        // accumulated count 
        for(i = 1; i < 10; i++)
            digitCount[i] += digitCount[i-1];

        // To keep the order, start from back side
        for(i = arraySize - 1; i >= 0; i--)
            bucket[--digitCount[a[i]/digitPosition%10]] = a[i];

        for(i = 0; i < arraySize; i++)
            a[i] = bucket[i];

        cout << "pass #" << pass++ << ": ";
        digitPosition *= 10;
    } 

}

具体来说,这条线给我带来了麻烦。我试过用笔和纸走过它,但我仍然无法弄清楚这是做什么的:

   // To keep the order, start from back side
        for(i = arraySize - 1; i >= 0; i--)
            bucket[--digitCount[a[i]/digitPosition%10]] = a[i];

4 个答案:

答案 0 :(得分:100)

在数学中,基数表示基数,其中十进制表示基数为10.想象一下,你有一些数字,其中一些数字有多个数字,如

5, 213, 55, 21, 2334, 31, 20, 430

为简单起见,假设您要使用十进制基数(= 10)进行排序。然后你将开始按单位分隔数字,然后再将它们组合在一起;接下来你将数字除以数十,然后再将它们组合在一起;然后是数百个,依此类推,直到所有的数字都被排序。每次循环时,只需从左到右阅读列表。您还可以想象您将数字分成多个桶。以下是使用5, 213, 55, 21, 2334, 31, 20, 430

的插图

按单位分开:

  • 零:20,430

  • :21,31

  • 两两:

  • 三人:213

  • 四人:2334

  • 五:5,55

    回到一起:20,430,21,31,213,2334,5,55

要将它们重新组合在一起,请首先阅读zeroes存储桶,然后阅读ones存储桶,依此类推,直至读取nines存储桶。

分开数十:

  • 零:05

  • :213

  • twos:20,21

  • 三人:430,31,2334,

  • 四肢:

  • 五:55

    回到一起:5,213,20,21,430,31,2334,55

分开数百:

  • 零:005,020,021,031,055

  • 的:

  • twos:213

  • 三人:2334

  • 四肢:430

  • 击掌:

    回到一起:5,20,21,31,55,213,2334,430

千人分开:

  • 零:0005,0020,0021,0031,0055,0213,0430

  • 的:

  • twos:2334

  • 三分:

  • 四肢:

  • 击掌:

    回到一起:5,20,21,31,55,213,430,2334

你现在完成了。我在Javapython

中的Geekviewpoint上看到了一个很好的代码

答案 1 :(得分:2)

想想一副牌。你首先按四个套装排序。然后你把这四个桩放在另一个上面,然后根据等级排成13堆。把它们放在一起,你现在有一个排序的套牌。

答案 2 :(得分:1)

这是quicksort的基本流程。

对于第一遍:我们使用计数排序根据最低有效数字(1s位置)对数组进行排序。请注意,435低于835,因为原始列表中的435低于835。

对于第二遍:我们使用计数排序根据下一个数字(10位)对数组进行排序。请注意,这里608低于704,因为608发生在前一个列表中的704以下,并且类似于(835,435)和(751,453)。

对于第3遍:我们使用计数排序根据最高有效数字(100位)对数组进行排序。请注意,这里435低于453,因为435出现在上一个列表中低于453,同样对于(608,690)和(704,751)。

有关详情you can refer to this blog on codingeek and have clear understanding

答案 3 :(得分:0)

可能是我的代码可以为您提供帮助:)

这是Radix Sort的python代码:

import random,time

from random import randint

A=[random.randint(1,1212) for i in range(23)]


length = len(str(max(A)))

print(length) 

rang = 10

print(A)

start=time.time()

for i in range(length):

B = [[] for k in range(rang)]

for x in A:

    figure =x // (10**i) % 10

    B[figure].append(x)

A = []

for k in range(rang):

    A+=B[k]

end=time.time()

print(end-start)

print(A)