【问题标题】:Simple Merge Sort bug in PythonPython中的简单合并排序错误
【发布时间】:2015-03-31 07:26:57
【问题描述】:

我正在 Python 中执行合并排序分配,但我一直有 RuntimeError: maximum recursion depth exceeded 的错误 这是我的代码:

def merge_sort(list):
    left_num = len(list) // 2
    left_sorted = merge_sort(list[:left_num])
    right_sorted = merge_sort(list[left_num:])
    final_sort = merge(left_sorted, right_sorted)
    return final_sort

def merge(left_sorted, right_sorted):
    final_sort = []
    while left_sorted and right_sorted:
        if left_sorted[0] <= right_sorted[0]:
            final_sort.append(left_sorted[0])
            left_sorted.pop(0)
        else:
            final_sort.append(right_sorted[0])
            right_sorted.pop(0)
    final_sort = final_sort + left_sorted + right_sorted
    return final_sort

if __name__ == "__main__":
    list = [4, 2]
    print(merge_sort(list))

谁能告诉我为什么?为了使问题对其他人更有用,请随时编辑问题以使其更有意义。 ^_^

【问题讨论】:

    标签: python list python-3.x recursion mergesort


    【解决方案1】:

    在编写递归函数时,应注意基本情况,它决定递归何时结束。

    在您的情况下,缺少基本情况。例如,如果列表只有一个元素,那么您不必再次递归排序。所以,这是你的基本条件。

    def merge_sort(list):
        if len(list) == 1:
            return list
        ...
        ...
    

    注意:变量名list 会影响内置函数list。所以最好避免使用内置名称。


    由于你做了很多pop(0)s,值得注意的是它在列表上效率不高。引用Python's official documentation

    虽然list 对象支持类似的操作,但它们针对快速固定长度操作进行了优化,并且对于pop(0)insert(0, v) 操作会产生 O(n) 内存移动成本,这些操作会改变基础数据的大小和位置表示。

    因此,如果弹出很多内容,更好的选择是使用collections.deque,而不是list。从deque is done with popleft method 实际弹出。

    >>> from collections import deque
    >>> d = deque([4, 2])
    >>> d.popleft()
    4
    >>> d
    deque([2])
    

    【讨论】:

    • 对不起,dequepopleft() 之后的“列表”的其余部分?
    【解决方案2】:

    merge_sort 中没有退出点。您需要执行以下操作:

    left_num = len(list) // 2
    if left_num <= 1:
        return list
    

    你总是需要在递归函数中有一个条件退出:if COND then EXIT else RECURSION_CALL

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-28
      • 1970-01-01
      • 2018-10-13
      • 2016-02-05
      • 2016-06-16
      相关资源
      最近更新 更多