数据结构——基数排序

简介

基数排序和其他一般的排序算法不同,一般的排序算法主要是通过关键字之间的比较和移动记录这两种操作,而实现基数排序则不需要进行记录关键字间的比较。
基数排序是一种借助多关键字排序的思想,对单逻辑关键字进行排序的方法。

代码实现

/*
基数排序
算法思想

假设我有数据
11 23 45 29 31 67 59 32
假设我拥有10个桶,编号分别为0-9
一开始,我将个位数相应的数据都放入桶当中
0
1   11 31
2   32
3   23
4   
5   45
6   
7   67
8
9   29 59

之后,将数据依次拿出来
得到数组
11 31 32 23 45 67 29 59

之后,我将十位数相应的数据放入桶当中
0  11
1
2  23 29
3  31 32
4  45
5  59
6  67
7
8
9

然后将数据拿出来,得
11 23 29 31 32 45 58 67 排序完成

实现原理则是
我们可以将所有数的数位补齐使所有数的数位都相同(数位不足的补0)
然后,按照数位进行排序,直到所有数位都排序完成之后,排序结束

因此,此算法的时间复杂度为
O (d(n+rd)),其中d为所采取的基数,因此基数排序适合d很小但n很大的数据
*/
void radixSoft(int *arr, int length) {

    int bit = findMaxBit(arr, length); //数组的最大为位数
    int *temp = new int[length];       //临时记录的数组
    int *count = new int[10];          //计数器

    int radix = 1;//基数
    int k;

    for (int i = 0; i < bit; i++) {

        //清空计数器
        for (int j = 0; j < 10; j++) {
            count[j] = 0;
        }
        //记录在每个桶当中的数据的个数
        for (int j = 0; j < length; j++) {
            k = (arr[j] / radix) % 10;
            count[k]++;
        }
        //为数组temp分配空间
        for (int j = 1; j < 10; j++) {
            count[j] = count[j - 1] + count[j];
        }
        //将数据依次加入到桶当中
        //之所以是倒着插入,是因为,当radix大于10之后,之前的排序已经是按照个位数排好了
        //而count[k]当中分配的内存空间是从后往前开始插入的,因此,插入到当前桶的数据也
        //必须是从后开始插入才能不打乱之前所进行排序所得出的结果
        for (int j = length-1; j >= 0; j--) {
            k = (arr[j] / radix) % 10;
            temp[count[k] - 1] = arr[j];
            count[k]--;
        }
        //将桶中的数据依次放回数组当中
        for (int j = 0; j < length; j++) {
            arr[j] = temp[j];
        }
        //下一波桶
        radix *= 10;
    }

    delete[] temp;
    delete[] count;
}

int findMaxBit(int *arr, int length) {

    int bit = 1; //记录最大位数
    int number = 10;

    //遍历数组
    for (int i = 0; i < length; i++) {

        //找出最大的位数
        while (arr[i] >= number) {
            number *= 10;
            bit++;
        }
    }

    return bit;

}

猜你喜欢

转载自blog.csdn.net/a591243801/article/details/72585536
今日推荐