在Python中对大于0且小于100000的整数数组进行排序的最快方法是什么?但不使用像sort这样的内置函数。
我正在考虑根据输入大小组合2种运动功能的可能性。
答案 0 :(得分:15)
如果您对渐近时间感兴趣,那么计算排序或基数排序可以提供良好的性能。
但是,如果您对挂钟时间感兴趣,则需要使用您的特定数据集来比较不同算法之间的性能,因为不同的算法对不同的数据集执行不同的操作。在这种情况下,它总是值得尝试快速排序:
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
来源:http://rosettacode.org/wiki/Sorting_algorithms/Quicksort#Python
答案 1 :(得分:7)
由于你知道数字的范围,你可以使用Counting Sort,它将是及时的线性。
答案 2 :(得分:3)
如果你想快速进行快速排序,可以在数组大小变小时使用插入排序。
理解算法复杂性和Big-O表示法的概念可能会有所帮助。
答案 3 :(得分:2)
早期版本的Python使用samplesort
(具有大样本大小的快速排序的变体)和二进制插入排序的混合作为内置排序算法。事实证明这有点不稳定。 S0,从python 2.3开始使用adaptive mergesort
算法。
mergesort顺序(平均值)= O(nlogn)
。
mergesort的顺序(最差)= O(nlogn)
。
但是快速排序(最差)= n * 2
如果您使用list=[ .............. ]
list.sort()
使用mergesort algorithm.
为了比较排序算法,您可以阅读wiki
详细比较comp
答案 4 :(得分:1)
我们可以使用字典来计算排序,以最大限度地减少额外的空间使用量,同时保持较低的运行时间。由于python与C的实现开销,对于小尺寸的输入数组,count排序要慢得多。当数组大小(COUNT)约为100万时,计数排序开始超过常规排序。
如果你真的想要小尺寸输入的大幅加速,请在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
答案 5 :(得分:1)
我可能会稍微迟到一下,但是有一篇有趣的文章可以比较https://www.linkedin.com/pulse/sorting-efficiently-python-lakshmi-prakash
的不同种类。主要的一点是,虽然默认排序很好,但我们可以使用quicksort的编译版本做得更好。这需要Numba包。
这里是Github回购的链接: https://github.com/lprakash/Sorting-Algorithms/blob/master/sorts.ipynb
答案 6 :(得分:0)
内置函数是最好的,但由于你不能使用它们看看:
答案 7 :(得分:0)
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
这是我创建的算法,但速度非常快。只做排序(l) l是您要排序的列表。
答案 8 :(得分:0)
@fmark 我对http://rosettacode.org/wiki/Sorting_algorithms/Quicksort#Python的python quicksorts写的python merge-sort实现的一些基准测试 并从最佳答案。
合并排序获胜,但它使用内置的int()到底层
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))