Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 非常基本的基数排序_Algorithm_Sorting_Radix Sort - Fatal编程技术网

Algorithm 非常基本的基数排序

Algorithm 非常基本的基数排序,algorithm,sorting,radix-sort,Algorithm,Sorting,Radix Sort,我刚刚写了一个简单的迭代基数排序,我想知道我的想法是否正确。 递归实现似乎更为常见 我对4字节整数进行排序(无符号以保持简单)。 我使用1字节作为“数字”。所以我有2^8=256个桶。 我首先对最高有效位(MSD)进行排序。 每次排序后,我都会按照它们在桶中的顺序将它们放回数组,然后执行下一次排序。 所以我最后做了4次桶排序。 它似乎适用于一小部分数据。因为我在做MSD,我猜这是不稳定的,可能会因为不同的数据而失败 我错过了什么重要的课程吗 #include <iostream> #

我刚刚写了一个简单的迭代基数排序,我想知道我的想法是否正确。
递归实现似乎更为常见

我对4字节整数进行排序(无符号以保持简单)。
我使用1字节作为“数字”。所以我有2^8=256个桶。
我首先对最高有效位(MSD)进行排序。
每次排序后,我都会按照它们在桶中的顺序将它们放回数组,然后执行下一次排序。
所以我最后做了4次桶排序。
它似乎适用于一小部分数据。因为我在做MSD,我猜这是不稳定的,可能会因为不同的数据而失败

我错过了什么重要的课程吗

#include <iostream>
#include <vector>
#include <list>

using namespace std;

void radix(vector<unsigned>&);
void print(const vector<list<unsigned> >& listBuckets);
unsigned getMaxForBytes(unsigned bytes);
void merge(vector<unsigned>& data, vector<list<unsigned> >& listBuckets);

int main()
{
    unsigned d[] = {5,3,6,9,2,11,9, 65534, 4,10,17,13, 268435455, 4294967294,4294967293, 268435454,65537};
    vector<unsigned> v(d,d+17);

    radix(v);
    return 0;
}

void radix(vector<unsigned>& data)
{
    int bytes = 1;                                  //  How many bytes to compare at a time
    unsigned numOfBuckets = getMaxForBytes(bytes) + 1;
    cout << "Numbuckets" << numOfBuckets << endl;
    int chunks = sizeof(unsigned) / bytes;

    for(int i = chunks - 1; i >= 0; --i) 
    {
        vector<list<unsigned> > buckets;            // lazy, wasteful allocation
        buckets.resize(numOfBuckets);

        unsigned mask = getMaxForBytes(bytes);
        unsigned shift = i * bytes * 8;
        mask = mask << shift;

        for(unsigned j = 0; j < data.size(); ++j)
        {
            unsigned bucket = data[j] & mask;       //  isolate bits of current chunk
            bucket = bucket >> shift;               //  bring bits down to least significant

            buckets[bucket].push_back(data[j]); 
        }

        print(buckets);

        merge(data,buckets);
    }
}

unsigned getMaxForBytes(unsigned bytes)
{
    unsigned max = 0;
    for(unsigned i = 1; i <= bytes; ++i)
    {
        max = max << 8;
        max |= 0xFF;
    }

    return max;
}

void merge(vector<unsigned>& data, vector<list<unsigned> >& listBuckets)
{
    int index = 0;
    for(unsigned i = 0; i < listBuckets.size(); ++i)
    {
        list<unsigned>& list = listBuckets[i];
        std::list<unsigned>::const_iterator it = list.begin();

        for(; it != list.end(); ++it)
        {
            data[index] = *it;
            ++index;
        }
    }
}

void print(const vector<list<unsigned> >& listBuckets)
{
    cout << "Printing listBuckets: " << endl;
    for(unsigned i = 0; i < listBuckets.size(); ++i)
    {
        const list<unsigned>& list = listBuckets[i];

        if(list.size() == 0) continue;

        std::list<unsigned>::const_iterator it = list.begin();  //  Why do I need std here!?
        for(; it != list.end(); ++it)
        {
            cout << *it << ", ";
        }

        cout << endl;
    }
}

让我们看一看带有两位十进制数字的en示例:

49, 25, 19, 27, 87, 67, 22, 90, 47, 91
按第一位数字排序产生

19, 25, 27, 22, 49, 47, 67, 87, 90, 91
接下来,按第二个数字排序,得到

90, 91, 22, 25, 27, 47, 67, 87, 19, 49
似乎不对,不是吗?或者这不是你正在做的吗?如果我弄错了,也许你可以给我们看看密码


如果您对具有相同第一位数字的所有组执行第二个桶排序,那么您的算法将等同于递归版本。它也将是稳定的。唯一的区别是,您要先对桶进行宽度排序,而不是深度排序。

您还需要确保在重新组装之前对每个桶进行从MSD到LSD的排序。 例子: 19,76,90,34,84,12,72,38 在MSD上分为10个桶[0-9] B0=[];B1=[19,12];B2=[];B3=[34,38];B4=[];B5=[];B6=[];B7=[76,72];B8=[84];B9=[90]; 如果你要重新组装,然后再分类,那就行不通了。而是递归地对每个bucket排序。 B1被分类为B1B2=[12];B1B9=[19]
一旦所有内容都被分类,您就可以正确地重新组装。

我认为MSD表单需要额外的递归步骤,而LSD则不需要。只要我将“空”数字视为0(即1=01),我就应该得到一个严格递增的结果。我不应该看到像1,10,2,3,4这样的东西。对吧?如果你像你提到的那样预先设定零,一切都应该正常。
90, 91, 22, 25, 27, 47, 67, 87, 19, 49