在我的比较中超出了最大递归深度

时间:2017-08-06 23:04:49

标签: python algorithm recursion insertion-sort

我目前正在阅读算法导论(CLRS)。在尝试解决练习2.3-4时,通过递归排序A [:n-1]来编写A的插入排序。我已经编写了一个代码,我将在下面显示我生成一个随机数列表并尝试对其进行排序,它可以在列表中使用多达一定数量的项目,但是当我将它提高到一千个时我得到一个错误,相比之下,超过最大递归深度,从在线检查我注意到有一种方法可以将递归深度增加到某个值,但我不确定这是好的做法还是我应该以某种方式改进我的代码。任何帮助,将不胜感激。谢谢

import random
numlist = []
for i in range(1000):
    numlist.append(i)
random.shuffle(numlist)

def rec_ins_sort(L):
    if(len(L) == 1):
        return L
    else:
        step = rec_ins_sort(L[:len(L)-1])
        return insert(L[len(L)-1], step)

def insert(a, inp_list):
    inp_list.append(a)
    i = len(inp_list) - 2
    while(i > 0 and inp_list[i] > a):
        inp_list[i+1] = inp_list[i]
        i -= 1
    inp_list[i+1] = a
    return inp_list

1 个答案:

答案 0 :(得分:1)

  

但我不确定这是不是很好的做法,或者我应该以某种方式改进我的代码。

在输入的 size 中递归线性(或超线性)的算法通常不是一个好主意,除非是编程语言支持尾调用优化(TCO)(Python没有),程序是尾递归。在这种情况下,调用堆栈不会增长,因为最后一个调用帧被覆盖。

例如,

MergeSort 是一种在 O(log n)中递归的算法,其输入大小为 n 。因此,调用堆栈不会增长太多:如果列表具有1' 073&#3941' 824个元素,则调用堆栈将增长~30个深度。

插入排序。我真的没有看到一种优雅的方式让它在 O(log n)中递归,所以你最好不要使用递归:你可以在这里简单地使用迭代:

def rec_ins_sort(L):
    iflen(L) < 1:
        return L
    else:
        R = []
        for l in L:
            R = insert(l,R)
        return R

def insert(a, inp_list):
    inp_list.append(a)
    i = len(inp_list) - 2
    while(i > 0 and inp_list[i] > a):
        inp_list[i+1] = inp_list[i]
        i -= 1
    inp_list[i+1] = a
    return inp_list

据说构建新列表等不是非常有效,要么使这个算法慢于严格必要的速度。

总结一下:你最好不要在Python中构造算法来递归(超)线性输入的大小。在这种情况下,您最好将其转换为迭代方法。