排序九 基数排序

基数排序(Radix Sort)

  • 基数排序类似于桶排序,是一种借助多关键字排序的思想对单逻辑关键字进行排序的方法。

  • 最高位优先(Most Significant Digit first)法,简称MSD法:依次元素的高位到低位为关键字进行分桶排序。

  • 最低位优先(Least Significant Digit first)法,简称LSD法:依次元素的低位到高位为关键字进行分桶排序。

  • 基数排序是一种稳定的排序方式

效率分析
时间效率:设待排序列为n个记录,d个关键码,关键码的取值范围为radix,则进行链式基数排序的时间复杂度为O(d(n+radix)),其中,一趟分配时间复杂度为O(n),一趟收集时间复杂度为O(radix),共进行d趟分配和收集。
空间效率:需要2*radix个指向队列的辅助空间,以及用于静态链表的n个指针。—百度百科

排序示例:

假设有一个序列:S[143,275,257,102,347,562,264,786,715,913]

以10为基数截取关键字,并以LSD法排序:
1. 对原数组以个位为关键字进行排序

个位序号元素元素
0
1
2102562
3143913
4264
5275715
6786
7257347
8
9

个位排位结果为:[102,562,143,913,264,275,715,786,257,347]

  1. 根据个位排序的结果再以十位为关键字进行排序
十位序号元素元素
0102
1913715
2
3
4143347
5257
6562264
7275
8786
9

十位排位结果为:[102,913,715,143,347,257,562,264,275,786]

  1. 根据十位排序的结果再以百位为关键字进行排序
百位序号元素元素元素
0
1102143
2257264275
3347
4
5562
6
7715786
8
9913

百位排位结果为:[102,143,257,264,275,347,562,715,786,913]

示例代码:

public static void RadixLSDSort(int[] S, int radix = 16) {
    //int digit = S.Max().ToString().Length; //10进制可以用这种方式取位数
    //列表中最大数按radix进位制的位数
    int digit = (int)Math.Ceiling(Math.Log(S.Max(), radix));
    int i = 0;
    int j = 0;
    List<int>[] buckets = new List<int>[radix];
    for(i = 0; i < radix; i++) {
        buckets[i] = new List<int>(); //初始化桶
    }

    for (i = 1; i <= digit; i++) {
        foreach (var item in S) {
            //元素入桶
            buckets[item / (int)Math.Pow(radix, i - 1) % radix].Add(item);
        }
        j = 0;
        foreach(var bucket in buckets) {
            foreach(var item in bucket) {
                S[j++] = item; //将桶中元素倒回原数组
            }
        }
        for (i = 0; i < radix; i++) {
            buckets[i].Clear();//清空桶
        }
    }
}

public static void RadixMSDSort(int[] S, int radix = 16) {
    int digit = (int)Math.Ceiling(Math.Log(S.Max(), radix));
    RadixMSDSort(S, S.ToList(), radix, 0, digit);
}
private static void RadixMSDSort(int[] S, List<int> sub, int radix, int start, int digit) {
    if (sub.Count <= 1 || digit < 1) {
        return;
    }
    int i;
    List<int>[] bucket = new List<int>[radix];
    for (i = 0; i < radix; i++) {
        bucket[i] = new List<int>(); //初始化桶
    }
    foreach (var item in sub) {
        //元素入桶
        bucket[item / (int)Math.Pow(radix, digit - 1) % radix].Add(item);
    }
    i = start;
    foreach (var data in bucket) {
        foreach (var item in data) {
            S[i++] = item;//将桶中元素倒回原数组
        }
    }
    i = 0;
    foreach (var data in bucket) {
        //对下一位进行递归基数排序
        RadixMSD2Sort(S, data, radix, start + i, digit - 1);
        i += data.Count;
    }
}
def radix_lsd_sort(s, radix = 16):  #Python
    digit = int(math.ceil(math.log(max(s), radix)))
    buckets = [[] for i in range(radix)]
    for i in range(1, digit+1):
        for item in s:
            buckets[int(item // (radix ** (i-1)) % radix)].append(item)
        del s[:]
        for bucket in buckets:
            s.extend(bucket)
        buckets = [[] for i in range(radix)]

def radix_msd_sort(s, radix = 16):
    def inner_radix_msd_sort(s, sub, radix, start, digit):
        if len(sub) <= 1 or digit < 1:
            return
        buckets = [[] for i in range(radix)]
        for item in sub:
            buckets[int(item // (radix ** (digit-1)) % radix)].append(item)
        i = start
        for bucket in buckets:
            for item in bucket:
                s[i] = item
                i += 1
        i = 0
        for bucket in buckets:
            inner_radix_msd_sort(s, bucket, radix, start+i, digit-1)
            i += len(bucket)

    digit = int(math.ceil(math.log(max(s), radix)))
    inner_radix_msd_sort(s, s, radix, 0, digit)

文中若有什么错误,欢迎留言指正。

转载请保留出处:http://blog.csdn.net/x1060549/article/details/78927021

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值