排序 8

来源:互联网 发布:js获取file绝对路径 编辑:程序博客网 时间:2024/06/06 00:48

参考:

排序 0 - 前言

百度百科:基数排序


基数排序(radix sort)

工作原理

针对 基数 进行排序,找出待排序列表的最大值,判断它的位数,比如 123 的位数为 3,先对个位数进行排序,遍历待排序列表,将个位数相同的值放在一起,即放在编号 0-9 中,排序完成后,按顺序连接 0-9 桶中的值;再对十位数的值进行排序,同样放入 0-9 中;依此类推,遍历所有位数

基数排序又称为 桶子法(bucket sort)

算法思想

有两种不同的排序方式

  • 最低位优先(LSD,least significant digit first)。先从低位数开始,遍历到最高位,每次遍历后都将所有桶中数据连接在一起,最后一次合并所有桶中的数字就是排序结果

    • 问题:用 Python 实现时考虑如何创建 0-910 个桶,如何将数据放入这些桶中
    • 思路:创建一个下标列表,长度为 10,初始化为 0,表示每个桶的数据个数,同时创建一个辅助列表,保存排序结果
  • 最高位优先(MSD,most significant digit first)。先从最高位数开始,遍历到最低位。和 LSD 不同的是,每次遍历后不再连接所有桶中的数据,而是针对单独桶中的数据进行低位排序,最后再合并所有桶中的数据

    • 问题:如何针对桶中数据进行排序
    • 思路:采用递归方法,输入待排序数据和位数

Python 算法实现

# -*- coding: utf-8 -*-"""基数排序实现"""import random__author__ = 'zj'def create_data(leng, min, max):    """    创建待排序序列    :param leng: 序列长度    :param min: 最小值    :param max: 最大值    :return: 列表    """    li = range(min, max)    return random.sample(li, leng)def radix_sort(li):    """    基数排序实现 lsd(least significant digit first) 从小到大排序    :param li: 待排序列表    :return: 已排序列表    """    m = max(li)  # 获取最大值    digits = len(str(m))  # 获取位数    target = 0    while target < digits:        idxs = [x * 0 for x in xrange(10)]        te = []        for item in li:            radix = item / 10 ** target % 10            idxs[radix] += 1            te.insert(sum(idxs[:radix + 1]) - 1, item)        target += 1        li = te    return lidef radix_sort_v2(li, d=None):    """    基数排序实现 msd(most significant digit first)    :param li: 待排序列表    :param d:基数,默认为 None    :return: 已排序列表    """    if len(li) == 1:        return li    if d is None:        m = max(li)  # 获取最大值        d = len(str(m))  # 获取位数    if d <= 0:        return li    idxs = [x * 0 for x in xrange(10)]    te = []    for item in li:        radix = item / 10 ** (d - 1) % 10        idxs[radix] += 1        te.insert(sum(idxs[:radix + 1]) - 1, item)    res = []    for i in xrange(len(idxs)):        if idxs[i] != 0:            sub = te[sum(idxs[:i]): sum(idxs[:i + 1])]            # print sub            res.extend(radix_sort_v2(sub, d - 1))    return resif __name__ == '__main__':    da = create_data(20, 0, 160)    print da    res = radix_sort(da)    print res

性能分析

稳定性

基数排序是稳定排序算法

不论是 LSD 还是 MSD,每次遍历不涉及数据交换,所以相同大小的数据的相对位置不会发生改变

时间复杂度

其时间复杂度为 O(d(r+n)),其中 r 为所采取的基数,而 n 为堆数(关键字的个数),d 代表长度

空间复杂度

空间复杂度为 O(rd+n)

原创粉丝点击