当前位置: 首页 > 知识库问答 >
问题:

基于递归的合并排序逻辑的替代方案

金慈
2023-03-14

这是python中的合并排序逻辑:(这是第一部分,忽略函数merge())问题的关键是将递归逻辑转换为while循环。代码礼貌:Rosettacode合并排序

def merge_sort(m):
    if len(m) <= 1:
        return m

    middle = len(m) / 2
    left = m[:middle]
    right = m[middle:]

    left = merge_sort(left)
    right = merge_sort(right)
    return list(merge(left, right))

是否有可能使其成为一种动态的在同时循环,而每个左和右数组分成两个,一种指针根据左和右数组的数量不断增加并打破它们,直到只剩下单个长度大小的列表?因为每次在左和右侧进行下一次拆分时,数组都会不断分解,直到只剩下单个长度列表,因此左侧(左-左,左-右)和右侧(右-左,右-右)中断的数量将增加,直到它达到所有大小为1的列表。

共有3个答案

尉迟安民
2023-03-14

据说,每个递归函数都可以用非递归的方式编写,所以简单的回答是:是的,这是可能的。我能想到的唯一解决方案是使用基于堆栈的方法。当递归函数调用自身时,它会在内部堆栈上放置一些上下文(其参数和返回地址),这对您不可用。基本上,为了消除递归,您需要做的是编写自己的堆栈,每次进行递归调用时,都将参数放入这个堆栈。

欲了解更多信息,您可以阅读本文,或参考Robert Laver的“Java中的数据结构和算法”中名为“消除递归”的部分(尽管本书中的所有示例都是Java给出的,但很容易掌握主要思想)。

茅慈
2023-03-14

根据读者的要求,从替代方案重新发布到基于递归的合并排序逻辑:

消除递归的一种方法是使用队列来管理未完成的工作。例如,使用内置的collections.deque

from collections import deque
from heapq import merge

def merge_sorted(iterable):
    """Return a list consisting of the sorted elements of 'iterable'."""
    queue = deque([i] for i in iterable)
    if not queue:
        return []
    while len(queue) > 1:
        queue.append(list(merge(queue.popleft(), queue.popleft())))
    return queue[0]
云卓
2023-03-14

一种可能的实现方式可能是:

def merge_sort(m):
    l = [[x] for x in m]                  # split each element to its own list
    while len(l) > 1:                     # while there's merging to be done 
        for x in range(len(l) >> 1):      # take the first len/2 lists
            l[x] = merge(l[x], l.pop())   # and merge with the last len/2 lists
    return l[0] if len(l) else []

递归版本中的堆栈帧用于存储需要合并的较小列表。您正确地识别出,在堆栈的底部,无论您排序什么,每个元素都有一个元素列表。因此,通过从一系列单元素列表开始,我们可以迭代地建立更大的合并列表,直到我们有一个单独的排序列表。

 类似资料:
  • 我正在尝试编写一个ruby方法,它可以递归地执行合并排序。我有这个方法,但这是一次我偶然得到它的工作,所以我不知道它为什么工作,并很想了解我写的代码是如何工作的。在psuedocode中,我遵循的步骤如下所示。 拆分长度为n的原始数组,直到我拥有长度为1的n个数组 一次合并和排序长度为m的2个数组,以返回长度为m*2的数组 重复上述步骤,直到我有一个长度为n的当前排序数组 基本上,在我看来,这是一

  • 我在我的应用程序中有以下合并排序代码。我对递归方法在不满足if条件时从if块中出来后如何再次调用感到非常困惑。 我调试了我的代码,但我仍然没有得到它。调用mergesort(0,号-1)的排序方法首先从mergesort(0,5)开始。低小于高,中间是2,所以接下来运行mergesort(0,2)。这一直持续到我们有mergesort(0,0),在这种情况下,低不小于高,所以它来自if块。但是当我

  • 我有个小问题。我尝试实现合并排序算法递归。 现在我的问题: 左=合并排序(rrays.copyOfRange(iv_sort_list,0,iv_sort_list.length));右=合并排序(rrays.copyOfRange(iv_sort_list,iv_sort_list.length,iv_sort_list.length)); 如果我尝试分配我的左/右数组“mergeSort(..

  • 我试图实现一个递归合并排序算法来排序一个简单的整数数组,但我得到奇怪的值为索引在我的数组的后半部分。前半部分似乎排序精细,这是令人困惑的,因为它是递归实现的。随机整数数组在我的main方法中初始化。 } 这会产生以下输出: 未排序数组={15,9,12,19,49,43,57,70,78,87}对于第1轮:第一个=0中间=4最后=9第1轮中的数组={15,9、12,19、49,43、57,70、7

  • 我正在尝试理解递归排序函数,它是mergesort算法的一部分。下面是我的代码,我几乎可以肯定它是正确的(通过在线课程)。 我理解合并的作用——它将每个子数组分解成两个较小的子数组,重复这个过程,直到子数组的长度为1(根据定义排序),然后合并。然而,这个排序函数用来完成这个任务的实际方法对我来说很难理解。也许是因为我不习惯递归函数,但是我想知道是否有人可以在第一次合并发生时阐明操作的顺序和参数是什

  • 我写了3个方法来实现递归合并排序,参数数量有限(没有aux、lo、mid、hi)。我认为我的工作是这样的,但它并没有返回一个排序数组,尽管它在运行时没有任何编译错误。我已经摆弄了4个小时,似乎无法弄清楚我做错了什么,没有合并一个有序数组。我只从我的助教那里得到了非常模糊的输入,并且能够修复我正在遇到的一些问题,但是该方法仍然没有对项数组进行排序。欢迎任何关于我在这里做错了什么的建议。谢谢!