Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 合并排序执行缓慢,什么';怎么了?_Python_Sorting - Fatal编程技术网

Python 合并排序执行缓慢,什么';怎么了?

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:

我从这个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:
        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