基数排序
基数排序(Radix Sort)是对桶排序的改进和推广。
单关键字和多关键字
文件中任一记录R[i]的关键字均由d个分量
k0ik1i...kd−1i
构成。
若这
d
个分量中每个分量都是一个独立的关键字,则文件是多个关键字的(如扑克牌有两个关键字:点数和花色);否则文件是单关键字的
多关键字中的每个关键字的取值范围一般不同。如扑克牌的花色取值只有4种,而点数则有13种。单关键字中每位一般取值范围相同。
基数
设单关键字的每个分量的取值范围均是: C0≤kj≤Crd−1(0≤j<d) 可能的取值个数rd称为基数。
基数的选择和关键字的分解因关键字的类型而异:
(1). 若关键字是十进制数,则按个、十等位进行分解,基数
rd=10,C0=0,C9=9
,
d
为最长整数的位数
(2). 若关键字是小写的英文字母,则
基数排序的基本思想
从低位到高位依次对
基数排序的排序过程
算法分析
时间是线性的(即
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 )))