Python 合并排序执行缓慢,什么';怎么了?
我从这个mergesort实现中得到了意想不到的(?)结果。与我的三向快速排序(也是用python编写的)相比,它的速度非常慢 我的快速排序在大约0.005s后完成10000个元素,而mergesort需要1.6s!包括两种实现的源代码 合并排序:Python 合并排序执行缓慢,什么';怎么了?,python,sorting,Python,Sorting,我从这个mergesort实现中得到了意想不到的(?)结果。与我的三向快速排序(也是用python编写的)相比,它的速度非常慢 我的快速排序在大约0.005s后完成10000个元素,而mergesort需要1.6s!包括两种实现的源代码 合并排序: #Merges two sorted lists into one sorted list. recursively def merge(left, right): if len(left) == 0 and len(right) == 0:
#Merges two sorted lists into one sorted list. recursively
def merge(left, right):
if len(left) == 0 and len(right) == 0:
return []
elif len(left) == 0:
return right
elif len(right) == 0:
return left
else:
if left[0] <= right[0]:
return left[:1] + merge(left[1:],right)
else:
return right[:1] + merge(left,right[1:])
#Splits a list in half and returns the halves
def halve(list):
return list[:len(list)//2],list[len(list)//2:]
#Mergesort
def mergesort(list):
if len(list) <= 1:
return list
left,right = halve(list)
left,right = mergesort(left),mergesort(right)
return merge(left,right)
#将两个排序列表合并为一个排序列表。递归地
def合并(左、右):
如果len(左)==0且len(右)==0:
返回[]
elif len(左)==0:
返回权
elif len(右)==0:
左转
其他:
如果左[0]解释:
通常,快速排序非常重要
实践中比其他Θ(nlogn)更快
算法,因为它的内部循环可以
在大多数情况下都能有效地实施
体系结构,以及在大多数现实世界中
数据,可以进行设计
最小化概率的选择
需要二次时间
对性能的猜测通常是错误的,但我只会说一次,因为我确实有一些这方面的经验。如果您真的想知道,请配置文件:
您正在添加列表,即left[:1]+merge(left[1:],right)
,这是Python中较慢的操作之一。它从两个列表中创建一个新列表,因此您的mergesort创建的中间列表类似于N**2个。另一方面,快速排序使用非常快的LCs,创建的列表更少(我认为是2N左右)
尝试使用而不是+,可能会有所帮助。递归合并排序并不是最好的方法。使用直接迭代方法应该可以获得更好的性能。我对Python不是很熟悉,所以我将向您介绍类似C的伪代码
ileft = 0 // index into left array
iright = 0 // index into right array
iresult = 0 // index into result array
while (ileft < left.length && iright < right.length)
{
if (left[ileft] <= right[iright])
result[iresult++] = left[ileft++]
else
result[iresult++] = right[iright++]
}
// now clean up the remaining list
while (ileft < left.length)
result[iresult++] = left[ileft++]
while (iright < right.length)
result[iresult++] = right[iright++]
ileft=0//索引到左数组中
iright=0//索引到右数组中
iresult=0//索引到结果数组中
while(ileft 如果(left[ileft]只是出于好奇,我编写了一个使用生成器的快速实现(可能更干净)。这与原始方法中的实现相比如何
def merge(listA,listB):
iterA, iterB = iter(listA), iter(listB)
valA, valB = iterA.next(), iterB.next()
while True:
if valA <= valB:
yield valA
try:
valA = iterA.next()
except StopIteration:
yield valB
try:
while True:
yield iterB.next()
except StopIteration:
return
else:
yield valB
try:
valB = iterB.next()
except StopIteration:
yield valA
try:
while True:
yield iterA.next()
except StopIteration:
return
def合并(列表A、列表B):
iterA,iterB=iter(列表A),iter(列表B)
valA,valB=iterA.next(),iterB.next()
尽管如此:
如果valA可以,我将尝试翻译您的代码,希望得到更好的结果:)谢谢你+1,因为我怀疑你的思路是对的。不过,他的快速排序实现也添加了列表。这可能在一般情况下是正确的,但这次不是。这明显快了。实际上比我的快速排序快。谢谢你!我真的不明白它的作用是什么:p Python不是我的母语。当一个函数包含关键字“yield”时,它是一个生成器函数。当调用生成器函数时,它返回和迭代器对象。当调用迭代器对象的next
方法时,生成器函数运行到并包括第一条yield
语句,next
返回生成的值。当再次调用next
时,该函数返回继续。当生成器函数退出时,next
方法引发一个StopIteration
异常。此生成器表达式迭代两个输入列表。因此在此实现中没有创建或连接列表。
def merge(listA,listB):
iterA, iterB = iter(listA), iter(listB)
valA, valB = iterA.next(), iterB.next()
while True:
if valA <= valB:
yield valA
try:
valA = iterA.next()
except StopIteration:
yield valB
try:
while True:
yield iterB.next()
except StopIteration:
return
else:
yield valB
try:
valB = iterB.next()
except StopIteration:
yield valA
try:
while True:
yield iterA.next()
except StopIteration:
return