用于反转列表项的算法?

时间:2015-12-18 00:20:37

标签: python reverse

我现在正在学习CS类中的数据结构和算法效率,并且我已经创建了一个算法来返回一个新的项目列表,它们与原始列表的顺序相反。我正在试图弄清楚如何使用递归的Python列表来实现这一点,但解决方案是在逃避我。这是我的代码:

def reverse_list(in_list):
    n = len(in_list)
    print('List is: ', in_list)
    if n <= 2:
        in_list[0], in_list[-1] = in_list[-1], in_list[0]
        return in_list
    else:
        first = [in_list[0]]
        last = [in_list[-1]]
        temp = reverse_list(in_list[1:-1])
        in_list = last + temp + first
        print('Now list is: ', in_list)
        return in_list

if __name__ == '__main__':
    list1 = list(range(1, 12))
    list2 = reverse_list(list1)
    print(list2)

作为旁注,这是平均情况下的O(n),因为它是n / 2对吗?

2 个答案:

答案 0 :(得分:3)

你真的不想在这里使用递归,因为它并没有真正简化函数调用所涉及的额外开销的问题:

list3 = list(range(1, 10))
for i in range(len(list3)/2):
    list3[i], list3[len(list3)-i-1] = list3[len(list3)-i-1], list3[i]
print(list3)

如果你想使用递归来接近它,你会在你的函数的每次调用中传入一个索引计数器,直到你在列表的一半处。这将为您提供O(n / 2)运行时。

答案 1 :(得分:2)

你的n <= 2案件很好。这是&#34;就地&#34;在两种常见的感官中。它修改了传入的相同列表,除了传入的列表外,它只使用一定量的内存。

您的一般情况是您遇到问题的地方。它使用了大量的额外内存(n / 2级别的递归,每个递归调用都有两个列表,因此所有级别的所有列表必须同时存在),并且它不会修改传入的列表(相反,它返回一个新列表。)

我不想为你做太多,但解决这个问题的关键是将一个(或两个,如果你愿意的话)额外的参数传递给递归步骤。要么是函数的可选参数,要么是定义具有它们的递归助手函数。使用此选项指示列表的哪个区域可以就地撤消。

正如评论中提到的那样,CPython没有尾递归优化。这意味着没有像这样使用调用递归的算法永远是真正的&#34;就地&#34;,因为它将使用线性数量的堆栈。但是&#34;就地&#34;在&#34;意义上修改原始列表而不是返回一个新列表&#34;当然可行。