如果递归函数返回到开头,该如何操作?

法哈德·塔玛塞比

我是新手程序员

我正在查找使用递归函数的问题。尽管我可以理解要点,但是有一个不清楚的问题,在调试过程中无法立即解密。感谢您在我的问题上的帮助。

问题的概念(合并排序)非常简单,但是我对递归函数的一般工作方式感到困惑。贝娄是我正在处理的程序(来自佐治亚理工学院的Python课程):

def mergesort(lst):

    if len(lst) <= 1:
        return lst

    else:

        midpoint = len(lst) // 2
        left = mergesort(lst[:midpoint])

        right = mergesort(lst[midpoint:])

        newlist = []
        while len(left) and len(right) > 0:
            if left[0] < right[0]:
                newlist.append(left[0])
            else:
                newlist.append(right[0])
                del right[0]

        newlist.extend(left)
        newlist.extend(right)

        return newlist

print(mergesort([2, 5, 3, 8, 6, 9, 1, 4, 7]))

问题:当程序到达此行时会发生什么left = mergesort( lst[:midpoint])

根据我的理解,它返回到程序的第一行,然后再次下降到同一行(就像这样for做)。

因此它不断返回!但是,这使我无法读取该程序。总的来说,程序如何处理递归函数是我的主要问题。我不明白它的工作方式。

谢谢

程序到达这一行会发生什么left = mergesort(lst[:midpoint])根据我的理解,它返回到程序的第一行,然后再次下降到同一行...

程序每次重复执行时,都会mergesort较小的列表进行调用我们称其为“子问题”-

def mergesort(lst):
    if len(lst) <= 1:
        # ...
    else:
        midpoint = len(lst) // 2           # find midpoint
        left = mergesort(lst[:midpoint])   # solve sub-problem one
        right = mergesort(lst[midpoint:])  # solve sub-problem two
        # ...

例如,如果我们首先mergesort用4个元素的列表进行调用-

mergesort([5,2,4,7])

输入列表,lst不符合基本情况,因此我们转到else分支-

def mergesort(lst):                       # lst = [5,2,4,7]
    if len(lst) <= 1:
        # ...
    else:
        midpoint = len(lst) // 2          # midpoint = 2
        left = mergesort(lst[:midpoint])  # left = mergesort([5,2])
        right = mergesort(lst[midpoint:]) # right = mergesort([4,7])
        # ...

通知mergesort被称为with[5,2][4,7]sub-problems。让我们对第一个子问题重复这些步骤-

left = mergesort([5,2])
def mergesort(lst):                       # lst = [5,2]
    if len(lst) <= 1:
        # ...
    else:
        midpoint = len(lst) // 2          # midpoint = 1
        left = mergesort(lst[:midpoint])  # left = mergesort([5])
        right = mergesort(lst[midpoint:]) # right = mergesort([2])
        # ...

因此它不断返回!

不完全是。当我们在此步骤中解决子问题时,情况似乎有所不同。如果输入是一个元素或更少,则满足基本情况,并且函数退出-

left = mergesort([5])
def mergesort(lst):     # lst = [5]
    if len(lst) <= 1:   # base case condition satisfied
        return lst      # return [5]
    else:
        ...             # no more recursion

left子问题递归停止,[5]返回的答案这同样适用于right子问题-

right = mergesort([2])
def mergesort(lst):     # lst = [2]
    if len(lst) <= 1:   # base case condition satisfied
        return lst      # return [2]
    else:
        ...             # no more recursion

接下来,我们返回第一left个子问题-

left = mergesort([5,2])
def mergesort(lst):                       # lst = [5,2]
    if len(lst) <= 1:
        # ...
    else:
        midpoint = len(lst) // 2          # midpoint = 1
        left = mergesort(lst[:midpoint])  # left = [5]        <-
        right = mergesort(lst[midpoint:]) # right = [2]       <-
        # ...
        return newlist                    # newlist = [2,5]

现在,您将对第一right个子问题重复这些步骤-

right = mergesort([4,7])
def mergesort(lst):                       # lst = [4,7]
    if len(lst) <= 1:
        # ...
    else:
        midpoint = len(lst) // 2          # midpoint = 1
        left = mergesort(lst[:midpoint])  # left = mergesort([4])
        right = mergesort(lst[midpoint:]) # right = mergesort([7])
        # ...

同样,由于新问题leftright子问题是一个单元素列表,因此递归停止了,它满足了基本情况-

right = mergesort([4,7])
def mergesort(lst):                       # lst = [4,7]
    if len(lst) <= 1:
        # ...
    else:
        midpoint = len(lst) // 2          # midpoint = 1
        left = mergesort(lst[:midpoint])  # left = [4]       <-
        right = mergesort(lst[midpoint:]) # right = [7]      <-
        # ...
        return newlist                    # newlist = [4,7]

最后,最外层的mergesort调用可以返回-

mergesort([5,2,4,7])
def mergesort(lst):                       # lst = [5,2,4,7]
    if len(lst) <= 1:
        # ...
    else:
        midpoint = len(lst) // 2          # midpoint = 2
        left = mergesort(lst[:midpoint])  # left = [2,5]
        right = mergesort(lst[midpoint:]) # right = [4,7]
        # ...
        return newlist                    # newlist = [2,4,5,7]
# => [2,4,5,7]

综上所述,递归是一种功能性遗产,因此将其与功能性样式一起使用可产生最佳效果。这意味着避免诸如突变,变量重新分配和其他副作用之类的事情。考虑这种替代方案,它可以通过明确区分程序的关注点来降低概念上的开销-

def mergesort(lst):
  def split(lst):
    m = len(lst) // 2
    return (lst[:m], lst[m:])

  def merge(l, r):
    if not l:
      return r
    elif not r:
      return l
    elif l[0] < r[0]:
      return [l[0]] + merge(l[1:], r)
    else:
      return [r[0]] + merge(l, r[1:])

  if len(lst) <= 1:
    return lst
  else:
    (left, right) = split(lst)
    return merge(mergesort(left), mergesort(right))

mergesort([5,2,4,7])
# => [2,4,5,7]

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何修改此代码,使它不返回到函数的开头,而是返回到函数的开头呢?

来自分类Dev

如何将值从递归函数返回到数组

来自分类Dev

如何返回到随机文本生成器函数的开头?

来自分类Dev

该递归函数如何工作?

来自分类Dev

如何将多个列表从控制器操作返回到ajax成功回调函数

来自分类Dev

变为假后如何返回到代码的开头?

来自分类Dev

变为假后如何返回到代码的开头?

来自分类Dev

Scala递归函数否则如果返回Unit

来自分类Dev

如何从一个方法中退出,即我如何从这个递归中的函数返回到 java 中?

来自分类Dev

如何从递归LISP函数返回?

来自分类Dev

如何使该程序被视为递归函数

来自分类Dev

该交错递归函数如何工作?

来自分类Dev

递归函数陷入无限循环。即使在返回语句评估之后,控制也会返回到函数调用

来自分类Dev

如果每秒调用100次以上,该如何实现不会执行其操作的C函数呢?

来自分类Dev

我如何回到kcachegrind的开头?

来自分类Dev

Java:如何回到循环的开头

来自分类Dev

如果到达 else 语句,如何返回到循环的顶部

来自分类Dev

在Windows上,如果函数将int返回到返回BOOL的函数有关系吗?

来自分类Dev

将读取光标返回到文件的开头

来自分类Dev

如何终止递归函数并返回值

来自分类Dev

如何中断和从递归函数返回?

来自分类Dev

递归函数如何返回某些内容?

来自分类Dev

如何使用递归函数返回ArrayList

来自分类Dev

此递归函数如何返回正确答案?

来自分类Dev

如何使用递归函数返回ArrayList

来自分类Dev

如何从Python的递归函数返回列表?

来自分类Dev

递归函数如何返回某些内容?

来自分类Dev

为什么递归返回到第一个函数?

来自分类Dev

为什么递归返回到第一个函数?

Related 相关文章

  1. 1

    如何修改此代码,使它不返回到函数的开头,而是返回到函数的开头呢?

  2. 2

    如何将值从递归函数返回到数组

  3. 3

    如何返回到随机文本生成器函数的开头?

  4. 4

    该递归函数如何工作?

  5. 5

    如何将多个列表从控制器操作返回到ajax成功回调函数

  6. 6

    变为假后如何返回到代码的开头?

  7. 7

    变为假后如何返回到代码的开头?

  8. 8

    Scala递归函数否则如果返回Unit

  9. 9

    如何从一个方法中退出,即我如何从这个递归中的函数返回到 java 中?

  10. 10

    如何从递归LISP函数返回?

  11. 11

    如何使该程序被视为递归函数

  12. 12

    该交错递归函数如何工作?

  13. 13

    递归函数陷入无限循环。即使在返回语句评估之后,控制也会返回到函数调用

  14. 14

    如果每秒调用100次以上,该如何实现不会执行其操作的C函数呢?

  15. 15

    我如何回到kcachegrind的开头?

  16. 16

    Java:如何回到循环的开头

  17. 17

    如果到达 else 语句,如何返回到循环的顶部

  18. 18

    在Windows上,如果函数将int返回到返回BOOL的函数有关系吗?

  19. 19

    将读取光标返回到文件的开头

  20. 20

    如何终止递归函数并返回值

  21. 21

    如何中断和从递归函数返回?

  22. 22

    递归函数如何返回某些内容?

  23. 23

    如何使用递归函数返回ArrayList

  24. 24

    此递归函数如何返回正确答案?

  25. 25

    如何使用递归函数返回ArrayList

  26. 26

    如何从Python的递归函数返回列表?

  27. 27

    递归函数如何返回某些内容?

  28. 28

    为什么递归返回到第一个函数?

  29. 29

    为什么递归返回到第一个函数?

热门标签

归档