用Python进行排序的最快方法
在Python中,对大于0小于100000的整数数组进行排序的最快方法是什么?但不使用诸如sort之类的内置函数用Python进行排序的最快方法,python,arrays,performance,sorting,Python,Arrays,Performance,Sorting,在Python中,对大于0小于100000的整数数组进行排序的最快方法是什么?但不使用诸如sort之类的内置函数 我正在考虑根据输入大小组合两个运动功能的可能性。因为您知道数字的范围,所以可以使用时间上是线性的。内置功能是最好的,但是因为您不能使用它们,请看一下: 如果您对渐近时间感兴趣,那么计数排序或基数排序可以提供良好的性能 但是,如果您对挂钟时间感兴趣,则需要使用特定数据集比较不同算法之间的性能,因为不同算法对不同数据集的性能不同。在这种情况下,尝试快速排序总是值得的: def qsort
我正在考虑根据输入大小组合两个运动功能的可能性。因为您知道数字的范围,所以可以使用时间上是线性的。内置功能是最好的,但是因为您不能使用它们,请看一下:
如果您对渐近时间感兴趣,那么计数排序或基数排序可以提供良好的性能 但是,如果您对挂钟时间感兴趣,则需要使用特定数据集比较不同算法之间的性能,因为不同算法对不同数据集的性能不同。在这种情况下,尝试快速排序总是值得的:
def qsort(inlist):
if inlist == []:
return []
else:
pivot = inlist[0]
lesser = qsort([x for x in inlist[1:] if x < pivot])
greater = qsort([x for x in inlist[1:] if x >= pivot])
return lesser + [pivot] + greater
def qsort(内部列表):
如果inlist=[]:
返回[]
其他:
pivot=inlist[0]
lesser=qsort([x代表inlist[1:]中的x,如果x=pivot])
返回较小值+[枢轴]+较大值
来源:早期版本的Python使用了
samplesort
(大样本快速排序的变体)和二进制插入排序的混合作为内置排序算法。这证明有点不稳定。S0,从python 2.3开始使用自适应合并排序
算法
合并排序顺序(平均)=O(nlogn)
。
合并排序顺序(最差)=O(nlogn)
。
但快速排序顺序(最差)=n*2
如果您使用list=[………]
list.sort()
使用mergesort算法。
对于排序算法之间的比较,您可以阅读
对于细节比较我们可以使用字典进行计数排序,以最大限度地减少额外的空间使用,并保持较低的运行时间。对于小尺寸的输入数组,计数排序要慢得多,这是因为python与C实现开销的关系。当数组(count)的大小约为100万时,count排序开始超过常规排序 如果您真的想为较小的输入带来巨大的加速,那么可以在C中实现计数排序,并从Python中调用它 (修复了Aaron(+1)帮助捕获的错误…) 下面的纯python实现比较了这两种方法
import random
import time
COUNT = 3000000
array = [random.randint(1,100000) for i in range(COUNT)]
random.shuffle(array)
array1 = array[:]
start = time.time()
array1.sort()
end = time.time()
time1 = (end-start)
print 'Time to sort = ', time1*1000, 'ms'
array2 = array[:]
start = time.time()
ardict = {}
for a in array2:
try:
ardict[a] += 1
except:
ardict[a] = 1
indx = 0
for a in sorted(ardict.keys()):
b = ardict[a]
array2[indx:indx+b] = [a for i in xrange(b)]
indx += b
end = time.time()
time2 = (end-start)
print 'Time to count sort = ', time2*1000, 'ms'
print 'Ratio =', time2/time1
基数排序理论上是以线性时间运行的(排序时间大致与数组大小成正比),但在实践中,快速排序可能更适合,除非您对绝对庞大的数组进行排序 如果要使快速排序更快一些,可以在数组大小变小时使用插入排序] 理解算法复杂性和大O表示法的概念可能也会有所帮助。
def sort(l):
def sort(l):
p = 0
while(p<len(l)-1):
if(l[p]>l[p+1]):
l[p],l[p+1] = l[p+1],l[p]
if(not(p==0)):
p = p-1
else:
p += 1
return l
p=0
而(pl[p+1]):
l[p],l[p+1]=l[p+1],l[p]
如果(不是(p==0)):
p=p-1
其他:
p+=1
返回l
这是我创建的一个算法,但速度非常快。只需排序(l)
l是要排序的列表。@fmark
我在上一篇文章中针对python快速排序编写了python合并排序实现的一些基准测试
从上面回答
将numpy导入为np
x=列表(np.random.rand(100))
#测试1,合并\排序
def合并(l、p、q、r):
n1=q-p+1
n2=r-q
左=l[p:p+n1]
右=l[q+1:q+1+n2]
i=0
j=0
k=p
当k
我可能会迟到一点,但是有一篇有趣的文章比较了不同的种类
一个主要的收获是,虽然默认排序做得很好,但我们可以使用编译版的quicksort做得更好。这需要Numba包
以下是Github回购协议的链接:
为什么不使用内置功能?在路上最快的方式是什么,但不驾驶保时捷?安德斯:不要重新发明车轮。内置的sort()应该足以满足您的情况。我很好奇:为什么需要实现自己的排序例程?对我来说,这闻起来像是一个家庭作业:-)@Aaron-或者更确切地说-不使用任何类型的预制车辆,在路上走最快的路是什么;)timsort比mergesortTimsort更具适应性。timsort是一种自适应、稳定、自然的mergesort。除了选择变量列表外,还有一些好的建议,这可能会导致很好的错误。我发布了另一个更快的版本。在同一组变量上运行两次列表理解可能也不太理想。@Tony Veijalainen“计算机科学中只有两件困难的事情:缓存失效和命名”——我更改了变量名(我没有否决)。请注意,如果整数数组明显小于100000,则这不是一个好的算法,因为在我的机器上构建100000元素列表将浪费内存(从而浪费时间)。+1
Ratio=1.16710428623
。巧妙地使用了口述。尽管如此,值得注意的是
import numpy as np
x = list(np.random.rand(100))
# TEST 1, merge_sort
def merge(l, p, q, r):
n1 = q - p + 1
n2 = r - q
left = l[p : p + n1]
right = l[q + 1 : q + 1 + n2]
i = 0
j = 0
k = p
while k < r + 1:
if i == n1:
l[k] = right[j]
j += 1
elif j == n2:
l[k] = left[i]
i += 1
elif left[i] <= right[j]:
l[k] = left[i]
i += 1
else:
l[k] = right[j]
j += 1
k += 1
def _merge_sort(l, p, r):
if p < r:
q = int((p + r)/2)
_merge_sort(l, p, q)
_merge_sort(l, q+1, r)
merge(l, p, q, r)
def merge_sort(l):
_merge_sort(l, 0, len(l)-1)
# TEST 2
def quicksort(array):
_quicksort(array, 0, len(array) - 1)
def _quicksort(array, start, stop):
if stop - start > 0:
pivot, left, right = array[start], start, stop
while left <= right:
while array[left] < pivot:
left += 1
while array[right] > pivot:
right -= 1
if left <= right:
array[left], array[right] = array[right], array[left]
left += 1
right -= 1
_quicksort(array, start, right)
_quicksort(array, left, stop)
# TEST 3
def qsort(inlist):
if inlist == []:
return []
else:
pivot = inlist[0]
lesser = qsort([x for x in inlist[1:] if x < pivot])
greater = qsort([x for x in inlist[1:] if x >= pivot])
return lesser + [pivot] + greater
def test1():
merge_sort(x)
def test2():
quicksort(x)
def test3():
qsort(x)
if __name__ == '__main__':
import timeit
print('merge_sort:', timeit.timeit("test1()", setup="from __main__ import test1, x;", number=10000))
print('quicksort:', timeit.timeit("test2()", setup="from __main__ import test2, x;", number=10000))
print('qsort:', timeit.timeit("test3()", setup="from __main__ import test3, x;", number=10000))