废话不说直接看
'''
计数排序
'''
def CountSort(datalist):
#最终排好序的数组
B=[0]*len(datalist)
#计算用来存储计数的数组C的长度
maxNum=max(datalist)
minNum=min(datalist)
cLength=maxNum-minNum+1
C=[0]*cLength
#将原数组中数字出现的次数存储到C中
for i in range(len(datalist)):
#datalist[i]-min表示datalist中下标为i的值应该放到C中哪个位置去
C[datalist[i]-minNum]+=1
#将C中数组元素的值(每个值出现的次数)加上前一个数字出现的次数
for i in range(1,cLength):
C[i]+=C[i-1]
#遍历A中元素,将它放入B中最终应该在的位置
for i in range(len(datalist)):
#C[datalist[i]-minNum]表示截止datalist[i],小于等于datalist[i]的有多少
B[C[datalist[i]-minNum]-1]=datalist[i]
#c中记录的值得数量应该减1,因为那个对应的元素已经到B里面了
C[datalist[i]-minNum]-=1
return B
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
3.基数排序
基数排序理解起来也是比较容易的,不过不要被“基数”这个名词给整蒙了,说白了,基数排序就是先将个位相同的放到一个桶里面(此时共有10个桶,分为0,1,2,3,4,5,6,7,8,9,放进桶里的都是有序的,因为拿出来的时候回先从标号为0的桶开始拿,),桶清空,然后把十位相同的放进一个桶里面,以此类推,最终得到有序的序列。
直接先来个简单的例子,假设我们要排序的数组为: a=[10 , 23, 56 ,78 ,42 ,12, 58 , 46 ,1 ,4 , 65 ]
第一次放进桶里面的是个位相同的,也就是:
第二次放进桶里面的十位数相同,也就是:
(1,4的十位数都是0)
那么将上述数组小段合并起来组成的数组就是有序的了。
但是现在有一些细节问题需要解决:
Q:怎么知道最大的数字是多少位的呢?
K = int(math.ceil(math.log(max(a)+1, radix))) # 最大的数用几位数表示,如91用两位数表示
- 1
其中radix表示进制,默认就是采用10进制表达radix=10
得到K表示=2表示用个位和十位可以表示所有的数,即不超过三位数
Q:怎么知道个位数十位数是多少呢?
temp=int(val%(radix**i)/(radix**(i-1)))
- 1
其中i就是上面K的遍历,算个位是多少就令i=1
一个简单的例子:
import math
"""a为整数列表, radix为基数"""
a=[10,23,56,78,42,12,58,46,1,4,65]
radix=10
K = int(math.ceil(math.log(max(a)+1, radix))) # 最大的数用几位数表示,如91用两位数表示
bucket = [[] for i in range(radix)] # 不能用 [[]]*radix
bucketBack = [] #桶的缓存,便于观察桶中元素的变化
for i in range(1, K+1): # K次循环,如两次循环的话,先将个位排序,在排序10位数
for val in a:
temp=int(val%(radix**i)/(radix**(i-1)))
print(temp,end=' ')
bucket[temp].append(val) # 获得整數第K位數字 (從低到高),如91,先看个位数是1
print()
del a[:]
for each in bucket:
a.extend(each) # 桶合并,第一次合并后个位有序,然后十位有序····
bucketBack.append(bucket)#将目前桶中元素存储起来
bucket = [[] for i in range(radix)]#清空当前桶,便于下一次入桶
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
但上面的代码有一个bug,就是没法排序负数,那怎么办呢?
一种方法就是先把负数和正数分开,分别排序后合并,这种思路的实现代码在文章末尾。