跳转至

基数排序

把数据从数组里一个个复制到链表里,然后从链表里一个个复制到数组里。不断的重复,来回复制。

优点:算法简单 数组复制到链表 链表复制到数组,来来回回复制。效率很高。速度很高。

缺点:需要多一倍的存储空间(需要二倍的空间,数组和链表的空间)。

基数

十进制的基数是10,二进制的基数是2。扑克牌排序:四种花色基数是4,13种牌基数是13。

排序

  • 示例

未排数组:421 240 035 532 305 430 124

按个位排:(240 430)(421)(532)(124)(035 305)

按十位排:(305)(421 124) (430 532 035) (240)

按百位排:(035)(124)(240)(305)(421 430)(532)

  • MSD(先排最高位,最高位优先)、LSD(最低位优先)

设计算法的时候用链表去做。

十进制 所以需要10个链表。基数是几就需要几个链表。

  1. 首先按照个位排 放到链表里 然后从链表里拿出来

个位是0的排前面 个位是1的在后面,越大越在后面。并且个位是0的是一组。

  1. 然后按照十位 放到链表里 再拿出来

  2. 最后按照百位 放到链表里 再拿出来

  3. 等等 以此类推。

原始数据从数组里 拿出来, 放到链表里,从链表里复制出来,再放到数组里。

数组到链表,链表到数组,反复进行。排序就完成了。

代码示例

1、先判断最大的数有几位

int maxdigit(int data[], int n)
{
    int d = 1;
    int p = 10;
    for (int i = 0; i < n; ++i) {
        while (data[i] >= p) { //大于10有2位,大于100有3位。等等
            p*=10;
            ++d;
        }
    }
    return d;
}

2、最大数有几位就循环几次(按照个位排,按照十位排,...)。

排序算法:(按照最低位优先,先排最低位。个位、十位、百位...)

  1. 再有一个循环所有的数,进行排序 判断放哪个链表(桶)内:

把一个个数从数组里放到链表里。

判断个位的话,根据个位数是几,放到哪个链表里。如果是9就放到9的链表里。如果是8就放到8的链表里。

判断十位的话,根据十位数是几,放到哪个链表里。

  1. 再循环所有的链表(桶),把链表里的数再放回数组里。

把每一个链表里的数依次拿出来,放到数组里:如果链表不是空的,就一直取数据,取了再把它删除。

void radixsort(int data[], int n)
{
    //n:数组里有多少数
    int digits = maxdigit(data, n);
    //基数是几就需要几个链表
    list<int> lists[10];
    int d,j,k,factor;
    //最大的数有几位 就循环几次 factor提取个位十位百位
    for (d = 1, factor = 1; d <= digits; factor*=10, d++) {
        for (j = 0; j < n; j++) {
            //把所有的数循环一遍,然后放到对应的链表里
            lists[(data[j] / factor) % 10].push_back(data[j]);
        }
        for (j = k = 0; j < 10; j++) {
            //把每一个数从各个链表里放回到数组里
            while (!lists[j].empty()) {
                data[k++] = lists[j].front();//取链表开头的数据
                lists[j].pop_front();//取完就把数据从链表删除
            }
        }


//        //查看中间结果 按个位排序 按十位排序 等等
//        for (int m = 0; m < n; m++) {
//            cout << data[m] << " ";
//        }
//        cout << endl;
    }
}

调试

//测试
void test()
{
    int data[10] = {179, 208, 306, 93, 859, 984, 55, 9, 271, 33};
    radixsort(data, 10);
    //排序后的结果
    for (int i = 0; i < 10; i++) {
        cout << data[i] << " ";
    }
    cout << endl;
}