1. 桶排序

1.1 范围为1-M的桶排序

如果有一个数组A,包含N个整数,值从1到M,我们可以得到一种非常快速的排序,桶排序(bucket sort)。留置一个数组S,里面含有M个桶,初始化为0。然后遍历数组A,读入Ai时,S[Ai]增一。所有输入被读进后,扫描数组S得出排好序的表。该算法时间花费O(M+N),空间上不能原地排序。

初始化序列S

遍历A修改序列S的项

举个例子,排序一个数组[5,3,6,1,2,7,5,10]

值都在1-10之间,建立10个桶:

[0 0 0 0 0 0 0 0 0 0]    桶

[1 2 3 4 5 6 7 8 9 10]   桶代表的值

遍历数组,第一个数字5,第五个桶加1

[0 0 0 0 1 0 0 0 0 0]

第二个数字3,第三个桶加1

[0 0 1 0 1 0 0 0 0 0]

遍历后

[1 1 1 0 2 1 1 0 0 1]

输出

[1 2 3 5 5 6 7 10]

代码

import random
class bucketSort(object):
def _max(self,oldlist):
_max=oldlist[0]
for i in oldlist:
if i>_max:
_max=i
return _max
def _min(self,oldlist):
_min=oldlist[0]
for i in oldlist:
if i<_min:
_min=i
return _min
def sort(self,oldlist):
_max=self._max(oldlist)
_min=self._min(oldlist)
s=[0 for i in xrange(_min,_max+1)]
for i in oldlist:
s[i-_min]+=1
current=_min
n=0
for i in s:
while i>0:
oldlist[n]=current
i-=1
n+=1
current+=1
def __call__(self,oldlist):
self.sort(oldlist)
return oldlist
if __name__=='__main__':
a=[random.randint(0,100) for i in xrange(10)]
bucketSort()(a)
print a

1.2 区间[0,1)均匀分布的桶排序

当输入符合均匀分布时,例如,元素均匀的分布在区间[0,1)上,可以将桶排序与其它排序方法结合使用。

如果序列的大小为n,就将[0,1)划分成n个相同大小的子区间(桶),然后将n个输入数分布到各个桶中。先对各个桶中的数进行排序,然后按照次序把各桶中的元素列出来即可。

《算法导论》的描述图:

代码:

class bucketSort(object):
def insertSort(self,a):
n=len(a)
if n<=1:
pass
for i in range(1,n):
key=a[i]
j=i-1
while key<a[j] and j>=0:
a[j+1]=a[j]
j-=1
a[j+1]=key
def sort(self,a):
n=len(a)
s=[[] for i in xrange(n)]
for i in a:
s[int(i*n)].append(i)
for i in s:
self.insertSort(i)
return [i for j in s for i in j]
def __call__(self,a):
return self.sort(a) if __name__=='__main__':
from random import random
from timeit import Timer
a=[random() for i in xrange(10000)]
def test_bucket_sort():
bucketSort()(a)
def test_builtin_sort():
sorted(a)
tests=[test_bucket_sort,test_builtin_sort]
for test in tests:
name=test.__name__
t=Timer(name+'()','from __main__ import '+name)
print t.timeit(1)

2. 基数排序

基数排序一般用于长度相同的元素组成的数组。首先按照最低有效数字进行排序,然后由低位向高位进行。

329                720                720                329

457                355                329                355

657                436                436                436

839====≯ 457====≯ 839====≯ 457

436                657                355                657

720                329                457                720

355                839                657                839

基数排序可以看做是进行多趟桶排序。每个有效数字都在0-9之间,很适合桶排序,建10个桶很方便。

排序数组 64,8,216,512,27,729,0,1,343,125

第一趟排序:

0     1    512   343   64   125   216   27    8   729

0     1      2      3      4      5      6      7     8     9

第二趟排序:

8            729

1    216   27

0    512   125         343           64

0     1      2      3      4      5      6      7     8     9

第三趟排序:

64

27

8

1

0    125   216  343         512          729

0     1      2      3      4      5      6      7     8     9

输出:1  8  27  64  125  216  343  512  729

代码:

import random
def radixSort():
A=[random.randint(1,9999) for i in xrange(10000)]
for k in xrange(4): #4轮排序
s=[[] for i in xrange(10)]
for i in A:
s[i/(10**k)%10].append(i)
A=[a for b in s for a in b]
return A

 1.3 计数排序

假设n个输入元素中每一个都是介于0到k之间的整数,此处k为某个整数。当k=O(n)时,计数排序的运行时间为Θ(n)。

对每一个数的元素x,确定出小于x的元素个数。有了这一信息就可以把x直接放到最终输出数组中的位置上。

def countingSort(alist,k):
n=len(alist)
b=[0 for i in xrange(n)]
c=[0 for i in xrange(k+1)]
for i in alist:
c[i]+=1
for i in xrange(1,len(c)):
c[i]=c[i-1]+c[i]
for i in alist:
b[c[i]-1]=i
c[i]-=1
return b
if __name__=='__main__':
a=[random.randint(0,100) for i in xrange(100)]
print countingSort(a,100)

  

Python线性时间排序——桶排序、基数排序与计数排序的更多相关文章

  1. 排序算法<No.1> 【计数排序】

    继上篇博文,今天我将先介绍一下什么是计数排序,将计数排序描述清楚后,再进行后续的桶排序方法解决这个问题. 通常情况下,一提到排序,大家第一反应就是比较,其实,今天我要说的这个计数排序,不是基于比较的排 ...

  2. 排序算法的c++实现——计数排序

    任何比较排序算法的时间复杂度的上限为O(NlogN), 不存在比o(nlgN)更少的比较排序算法.如果想要在时间复杂度上超过O(NlogN)的时间复杂度,肯定需要加入其它条件.计数排序就加入了限制条件 ...

  3. 排序算法的C语言实现(下 线性时间排序:计数排序与基数排序)

    计数排序 计数排序是一种高效的线性排序. 它通过计算一个集合中元素出现的次数来确定集合如何排序.不同于插入排序.快速排序等基于元素比较的排序,计数排序是不需要进行元素比较的,而且它的运行效率要比效率为 ...

  4. JavaScript 数据结构与算法之美 - 桶排序、计数排序、基数排序

    1. 前言 算法为王. 想学好前端,先练好内功,只有内功深厚者,前端之路才会走得更远. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScript ,旨在入门数据结构与算 ...

  5. 排序基础之非比较的计数排序、桶排序、基数排序(Java实现)

    转载请注明原文地址: http://www.cnblogs.com/ygj0930/p/6639353.html  比较和非比较排序 快速排序.归并排序.堆排序.冒泡排序等比较排序,每个数都必须和其他 ...

  6. 由Maximum Gap,对话桶排序,基数排序和统计排序

    一些非比较排序 在LeetCode中有个题目叫Maximum Gap.是求一个非排序的正数数列中按顺序排列后的最大间隔.这个题用桶排序和基数排序都能够实现.以下说一下桶排序.基数排序和计数排序这三种非 ...

  7. 计数排序和桶排序(Java实现)

    目录 比较和非比较的区别 计数排序 计数排序适用数据范围 过程分析 桶排序 网络流传桶排序算法勘误 桶排序适用数据范围 过程分析 比较和非比较的区别 常见的快速排序.归并排序.堆排序.冒泡排序等属于比 ...

  8. 计数排序(counting-sort)——算法导论(9)

    1. 比较排序算法的下界 (1) 比较排序     到目前为止,我们已经介绍了几种能在O(nlgn)时间内排序n个数的算法:归并排序和堆排序达到了最坏情况下的上界:快速排序在平均情况下达到该上界.   ...

  9. 计数排序算法——时间复杂度O(n+k)

    计数排序 计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出.它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于 ...

随机推荐

  1. CentOS6.5 64bit 运行Mono程序

    前几日和一技术友聊天,认为转Java好,java可以在Linux下运行,貌似c#不可以哦,就做了个尝试,运行控制台程序和窗口程序(界面编程,Linux下Java好像也比较烦吧) 现在贴环境: 参考:C ...

  2. iOS - 混合开发

    5.oc 与 js 混合开发 PhoneGap 专门做混合开发的,已经被另一个公司收购. WebViewJavascriptBridge 国内用的比较多 混合开发的好处:跨平台性.H5开发的时间成本, ...

  3. UICollectionView 简单应用和实际操作

    1.网格视图   UICollectionView      网格布局 UICollectionViewFlowLayout系统图自带网格布局 系统自带的网格布局 UICollectionViewFl ...

  4. JavaScript中的window.close在FireFox和Chrome上不能正常动作的解决方法

    JS中关闭窗口的方法window.close()在IE上能够正常动作,而在FireFox和Chrome上无法动作. (当时,在Chrome35.0上的时候还是可以的,Chrome36.0上就无法动作了 ...

  5. java 解析XML文档

    Java 解析XML文档 一.解析XML文档方式: 1.DOM方式:将整个XML文档读取到内存中,按照XML文件的树状结构图进行解析. 2.SAX方式:基于事件的解析,只需要加载XML中的部分数据,优 ...

  6. jquery plugins —— datatables 增加行号

    table = $("#Table").DataTable({ "rowCallback": function (row, data, dataIndex) { ...

  7. Mail搭建

    Mail搭建 一.本章结构 1.postfix概念与原理 2.postfix配置文件解析 3.邮件服务器端配置与客户端使用 4.垃圾邮件过滤 5.邮件自动回复 二.邮件服务器概述 1.邮件服务器概念 ...

  8. Linux 进程管理子系统

    一.进程管理子系统 1.进程要素 (1). 程序与进程 程序:存放在磁盘上的一系列代码和数据的可执行映像,是一个静止的实体 进程:是一个执行中的程序,他是一个动态的实体. (2). 进程4要素 1.有 ...

  9. 基于Qt的Tcp协议的流程图

    TCP(Transmission Control Protocol传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议.在qt中,Tcp协议主要是用QTcpServer和QTcpSock ...

  10. 查看Nodejs 占用的端口

    查看 Nodejs 占用的端口 ps -ef | grep node强制关闭端口 kill