排序算法Python

废话不说直接看

'''
计数排序
'''
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,就是没法排序负数,那怎么办呢?

一种方法就是先把负数和正数分开,分别排序后合并,这种思路的实现代码在文章末尾。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值