算法学习笔记--基数排序

基数排序

基数排序(Radix Sort)是对桶排序的改进和推广。

单关键字和多关键字

文件中任一记录R[i]的关键字均由d个分量 k0ik1i...kd1i 构成。
若这 d 个分量中每个分量都是一个独立的关键字,则文件是多个关键字的(如扑克牌有两个关键字:点数和花色);否则文件是单关键字的kji(0j<d)只不过是关键字中其中的一位(如字符串、十进制整数等)。
多关键字中的每个关键字的取值范围一般不同。如扑克牌的花色取值只有4种,而点数则有13种。单关键字中每位一般取值范围相同。

基数

设单关键字的每个分量的取值范围均是: C0kjCrd1(0j<d) 可能的取值个数rd称为基数。

基数的选择和关键字的分解因关键字的类型而异:
(1). 若关键字是十进制数,则按个、十等位进行分解,基数 rd=10C0=0,C9=9 d 为最长整数的位数
(2). 若关键字是小写的英文字母,则rd=26,C0=a,C9=z, d 为字符串最大长度。

基数排序的基本思想

从低位到高位依次对Kj(j=d1,d2,...,0)进行桶排序。在d趟桶中,所需的桶子数就是基数 rd ,这就是“基数排序”名称的由来。

基数排序的排序过程

算法分析

时间是线性的(即 O(n)
所需的辅助存储空间为( O(n+rd)
基数排序是稳定的

代码实现

python
# -- coding: utf-8 --

import math;
import random
import sys
import io

# 解决 atom-script中文乱码问题
sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding = 'utf-8')
sys.stderr = io.TextIOWrapper(sys.stderr.detach(), encoding = 'utf-8')


def radixsort(data):
    maxNumber = max(data)
    d = math.floor(math.log10(maxNumber))
    buckets = list(map(lambda x:[], range(0,10)))
    j,m = 0,1
    while j <= d:
        for num in data:
            i = num // m % 10
            buckets[i].append(num)

        dataIndex = 0
        for bucket in buckets:
            for bnum in bucket:
                data[dataIndex] = bnum
                dataIndex = dataIndex + 1
            bucket.clear()
        j,m = j+1, m * 10
    return data

rand = lambda minval=0,maxval=1:minval + random.random() * (maxval-minval)

arr = list(map(lambda x: int(rand(1, math.pow(10,rand(1,8)))), range(1,20)))
print("排序前:%s"%arr)
radixsort(arr)
print("排序后:%s"%arr)
scheme(⊙﹏⊙)

(define  digits (lambda (number)
                    (if (< number 10) 1
                        (+ 1 (digits (/ number 10)))
                    )
                )
)
(define list-get!
    (lambda (data index)
        (cond ( (or (null? data) (< index 0)) #f )
              ( (zero? index) (car data) )
              (else (list-get! (cdr data) (- index 1)) )
        )
    )
)
(define list-set!
    (lambda (listv index value)
        (if (zero? index)
            (cons value (cdr listv))
            (cons (car listv) (list-set! (cdr listv) (- index 1) value))
        )
    )
)
(define modulo
    (lambda ( divident divider)
        (- divident (* (floor (/ divident divider)) divider))
    )
)
(define (list-reverse l)
  (if (null? l)
     (list)
     (append (list-reverse (cdr l)) (list (car l)))
  )
)
(define radix-sort
    (lambda (arr)
        (begin
            (define zip-buckets
                (lambda (data m buckets) (if (null? data) buckets (let ( (index (modulo (floor (/ (car data) m)) 10) ) ) (zip-buckets (cdr data) m (list-set! buckets index (cons (car data) (list-get! buckets index) ) ) ) ) ) )
            )
            (define unzip-buckets
                (lambda (buckets data) (if (not (null? buckets)) (unzip-buckets (cdr buckets) (append data (list-reverse (car buckets)))) data ) )
            )
            (define r-sort
                (lambda (data d j m) (if (< j d) (r-sort (unzip-buckets (zip-buckets data m (list (list) (list) (list) (list) (list) (list) (list) (list) (list) (list))) (list) ) d (+ j 1) (* m 10) ) data ) )
            )
            (r-sort arr (digits (apply max arr)) 0 1)
        )
    )
)

(display (radix-sort (list 1048 79 276 158 31 15 23 2 0 345 )))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值