为什么此代码会引发错误-“ Python停止工作”?

时间:2019-05-29 11:32:31

标签: python sorting quicksort

在这段代码中,我想对一些随机生成的数字进行排序。如果我要对超过2000个元素进行排序,则在通过QuickSort进行排序时(在通过Bubblesort进行排序之后),Python将停止工作,并抛出“进程以退出代码-1073741571(0xC00000FD)完成”。我不知道,为什么会出现这个问题。我的递归深度是扩展,所以我不认为这是问题。有谁知道我该如何解决这个问题?

import time
import random
from sys import setrecursionlimit
setrecursionlimit(1000000)

#------------------------------Sortieralgorithmen-----------------------------------------------
#-----------------------------------------------------------------------------------------------

def bubbleSort(array):

    length = len(array)

    for sorted in range(length):

        for j in range(0, length-sorted-1):
            if array[j] > array[j+1] :
                array[j], array[j+1] = array[j+1], array[j]



def help(array, low, high):
    pivot = array[low]
    fromhigh = high
    fromlow = low
    while True:
        while(array[fromhigh]>pivot):
            fromhigh = fromhigh-1
        while(array[fromlow]<pivot):
            fromlow = fromlow+1
        if(fromlow<fromhigh):
            array[fromlow], array[fromhigh] = array[fromhigh], array[fromlow]
        else:
            return fromhigh


def quickSort(array, low, high):
   if (low<high):
       pivot = help(array, low, high)
       quickSort(array, low, pivot)
       quickSort(array, pivot + 1, high)




#--------------------------------Zeitmessung-----------------------------------------------------
#------------------------------------------------------------------------------------------------

numb_elements = 6000

sortedarray = []
for i in range (0,numb_elements):
    sortedarray.append(i)

notsortedarray = random.sample(range(0,numb_elements),numb_elements)

copy1 = sortedarray.copy()
before = time.time()
bubbleSort(copy1)
after = time.time()
total = after-before
print("Bubblesort sortiertes Array:\t\t" + str(total))

copy2 = notsortedarray.copy()
before = time.time()
bubbleSort(copy2)
after = time.time()
total = after-before
print("Bubblesort nicht sortiertes Array:\t" + str(total))

copy3 = sortedarray.copy()
before = time.time()
quickSort(copy3, 0, len(copy3)-1)
after = time.time()
total = after-before
print("QuickSort sortiertes Array:\t\t\t" + str(total))

copy4 = notsortedarray.copy()
before = time.time()
quickSort(copy4, 0, len(copy4)-1)
after = time.time()
total = after-before
print("QuickSort nicht sortiertes Array:\t" + str(total)+"\t (Worst Case)")

进程结束,退出代码为-1073741571(0xC00000FD)

2 个答案:

答案 0 :(得分:0)

您最初遇到了递归限制,并且(通常)明智地提高了递归限制。

def quickSort(array, low, high):
   if (low<high):
       pivot = help(array, low, high)
       quickSort(array, low, pivot)
       quickSort(array, pivot + 1, high)

您要排序的数组有6000个元素。在递归的第一级,您调用quicksort(array(low, pivot)),它将拆分您的数组,然后在具有约3000个元素的数组上再次调用它。这一直进行到对数组[0:2]进行排序,堆栈上有大约3000帧。最后一次调用返回,从堆栈中释放了一帧,然后发生了对quicksort(array, pivot + 1, high)的第二次调用,再次填充了它。

如果到目前为止我们已经正确地推理过,那么看来堆栈会增长到大约3k帧深,然后来回弹跳到那里(对help()的+/-调用),最后才将所有返回排序后的数组时返回的方式。

如果是这种情况,那么似乎实际的递归限制(小于您可以在堆栈中容纳的帧数)将小于3000。

理论上,任何递归算法都可以迭代求解,因此您可以尝试重写quicksort。如果您对计算机和操作系统上的最大递归深度感到好奇,则可以传递一个整数参数,您可以在每次调用中递增并打印。炸毁后,打印的最大数字将是您实际的递归深度限制。

setrecursionlimit()使您可以将事务自动处理。强大的力量带来巨大的责任。

答案 1 :(得分:0)

通过在较小(或相等)部分上使用递归,然后迭代以处理较大部分,可以避免Quicksort中的堆栈溢出:

def quickSort(array, low, high):
   while (low<high):
       pivot = help(array, low, high)
       if(pivot - low < high - pivot):
           quickSort(array, low, pivot)
           low = pivot+1
       else:
           quickSort(array, pivot + 1, high)
           high = pivot

对于已经排序的数据,在帮助中最好选择中间值作为枢轴:

    pivot = array[(low+high)//2]