【问题标题】:Merge sort, the recursion part归并排序,递归部分
【发布时间】:2015-06-17 17:25:43
【问题描述】:

在研究了几天归并排序之后,我从概念上理解了它,但是有一点我没有理解。

我得到了什么:

1.) 它接受一个列表,例如一个数字数组,并将其分成两半并对两半进行排序,最后将它们合并在一起。

2.) 因为它是一种递归算法,所以它使用递归来做到这一点。 因此,上述数组的拆分如下所示:

它,拆分数组,直到每个列表中只有一个项目,并且它被认为是排序的。到那时,合并就介入了。 应该是这样的:

我不明白的是,在将所有列表拆分为列表中的一项后,递归如何“知道”以恢复递归树?有左右两边的东西合并后怎么变成左边?

困扰我的是这个。我已经从 interactivepython 页面截取了代码的快照

在我们得到 lefthalf = 2 和 righthalf = 1 之后,代码是如何到达重点的?回到将我们合并的内容划分的递归?

Tnx, 汤姆

【问题讨论】:

    标签: recursion merge


    【解决方案1】:

    一旦列表只包含一个元素,就会对每一对叶子进行排序和连接。然后您可以遍历列表并找出下一对应该插入的位置。递归对返回递归树一无所知,而是排序和连接的行为具有这种效果。

    【讨论】:

    • 所以遍历递归树(向后)不依赖于递归,而是依赖于合并?
    • 没错。另一种思考方式:要“向前”,您将列表分成更小的部分,因此要“向后”,您必须重新加入它们。
    • 但是,如何将两个元素(例如 [3] 和 [4])合并到一个新列表 [3,4] 中时不会再次回调递归?
    • 确实如此 - 有两个级别的递归,一个迭代对列表,另一个迭代直到没有其他东西可以加入。即,一旦将单个元素连接成对,然后将这些对连接成四个等,直到只剩下一个大列表。
    • 是的,那部分真的让我很烦!我就是想不通!
    【解决方案2】:

    “递归”当然不知道这种情况。它是使用递归的代码,看起来像这样(有点简化):

    sort list = merge (sort left_half) (sort right_half)
        where
             (left_half, right_half) = split list
    

    在这里你看到“递归”(即sort 的递归调用)不需要“知道”任何东西。他们唯一的工作就是提供排序列表、数组或其他任何东西。

    换一种说法:如果我们有merge满足以下不变量:

    1. `merge`, given two sorted lists, will return a sorted list.
    

    然后我们可以像上面概述的那样轻松编写合并排序。在排序中剩下要做的是处理简单的情况:空列表、单例和具有两个元素的列表。

    【讨论】:

      【解决方案3】:

      如果您谈论的是奇数子列表,那么它取决于实现。

      它要么每次都将较大的子列表放在左侧,要么每次都将其放在右侧。

      【讨论】:

        猜你喜欢
        • 2014-04-08
        • 2014-08-12
        • 2016-04-14
        • 2010-12-08
        • 1970-01-01
        • 2015-01-21
        • 2013-10-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多