如何使用基数排序对可变长度字符串数组进行排序?

时间:2015-06-12 03:08:30

标签: string algorithm sorting radix-sort

我知道基数排序可以对相同长度的字符串数组进行排序,但是可以使用可变长度字符串来实现。如果是,那么实现这个的C系列代码或伪代码是什么?

对于可变长度字符串,它可能不是一种快速算法,但它很容易实现基数排序,因此如果需要快速编码排序,它会很有用。

2 个答案:

答案 0 :(得分:1)

我不太确定“变长字符串”是什么意思,但你可以就地执行二进制MSB基数排序,因此字符串的长度无关紧要,因为没有中间存储桶。

#include <stdio.h>
#include <algorithm>

static void display(char *str, int *data, int size)
{
    printf("%s: ", str);

    for(int v=0;v<size;v++) {
        printf("%d ", data[v]);
    }

    printf("\n");
}

static void sort(int *data, int size, int bit)
{
    if (bit == 0)
        return;

    int b = 0;
    int e = size;

    if (size > 0) {
        while (b != e) {
            if (data[b] & (1 << bit)) {
                std::swap(data[b], data[--e]);
            }
            else {
                b++;
            }
        }

        sort(data, e, bit - 1);
        sort(data + b, size - b, bit - 1);
    }
}

int main()
{
    int data[] = { 13, 12, 22, 20, 3, 4, 14, 92, 11 };
    int size = sizeof(data) / sizeof(data[0]);

    display("Before", data, size);
    sort(data, size, sizeof(int)*8 - 1);
    display("After", data, size);
}

答案 1 :(得分:0)

您可以对可变长度字符串执行MSB优先基数排序。 有几个非明显的细节:

根据strvec [i] [N],Pass #N会将输入向量中的字符串分割(分散)为256个分区。然后它将按顺序扫描分区,并将(重新插入)字符串放回输入向量中。

现在稍微复杂一点......

当你到达字符串的末尾时,它处于最终位置,不应该再次触摸。将字符串前后分成单独的RANGES。每次传递的结果是一组尚未排序的行。

这意味着在第一个之后传递#N扫描每个范围中的字符串,并将源范围id(索引)与字符串一起存储在分区中。在&#34;重新插入&#34;步骤,它将字符串放回其源范围;再次,它生成一组新的未排序行范围。

如果向前扫描输入范围然后向后扫描分区并从每个源范围的后面重新开始重新插入,则保持基数排序的稳定类别加值。

你也可以使用递归(在任何子范围内从头开始做一个完整的排序),但上面的设置节省了更快。

还有更多详细信息......快速排序可用于对小范围进行插入排序(例如,最多16个);基数排序也可以从中获益。 使用多个字节作为分区索引是可能的。其中一种方法是:Radix Sort-Mischa Sandberg-2010还有其他方法。 抱歉,我无法发布代码;它现在是专有的。