【问题标题】:Understanding how stack frames work in recursive function了解堆栈帧如何在递归函数中工作
【发布时间】:2015-08-17 01:56:16
【问题描述】:

这里是 Python/CS 新手,试图了解特定递归函数是如何“在后台”工作的,即函数的堆栈帧如何操作以及它们“持有”什么值。

我知道这里有很多关于递归函数的文章/发布,并且有说明它们如何工作的示例,但是递归的概念以及堆栈如何工作/它们在递归函数中的作用有点棘手,并且我没有找到任何清晰简洁的解释。

假设我们有以下递归函数可以反转字符串中的字符:

text = "hello"
def reverse_string(text):
        if len(text) <= 1:
            return text
        return reverse_string(text[1:]) + text[0]

哪个输出:olleh

我认为reverse_string(text[1:]) 的框架如下工作:

Global frame
text    "hello"
reverse_string  

reverse_string
text    "hello"

reverse_string
text    "ello"

reverse_string
text    "llo"

reverse_string
text    "lo"

reverse_string
text    "o"

Return
value   "o"

但是在返回值"o" 并且满足终止基本条件之后会发生什么? text[0] 在函数中是如何工作最终到达"olleh" 的?

【问题讨论】:

    标签: python function recursion stack frame


    【解决方案1】:

    只是以你的例子来散步。

    一旦我们达到终止条件,剩余的帧就会以相反的顺序弹出。

    假设我们达到了终止条件,在这种情况下return text 是“命中”并且text = "o" 被返回。然后在前一帧中我们有reverse_string(text[1:]) + text[0],但这只是reverse_string("o") + "l" = "o" + "l" = "ol" = reverse_string(text[1:]),其中reverse_string(text[1:]) 是来自前一帧的调用(text 等于“llo”的调用)。继续这个逻辑,reverse_string("lo") + "l" = "ol" + "l" = "oll"。

    我们继续同样的想法,直到我们到达最终返回“olleh”的“顶部”框架。

    【讨论】:

    • 感谢您的回复。这可能是一个愚蠢的问题,但你能解释为什么帧以相反的顺序弹出吗?这是如何/为什么会发生的?查看pythontutor.com/visualize.html 中的代码时,看起来在“o”最终返回(并且满足基本条件)之后,它通过帧“备份”,但我不明白为什么。
    • 它返回帧的原因是由于return 语句。返回的函数“返回”到调用它的位置,无论结果如何(除非它是无效的)。在reverse_string(str) 的情况下,您将在最后一个“pop”中返回反转的字符串:reverse_string("ello") + "h"。请记住,reverse_string("ello") 返回值 "olle"。
    • 所以当基本条件满足时,函数实际上并没有结束,对吧?似乎在条件基本条件语句中,只返回 text,而不是 reverse_string 函数。为什么当返回文本是“命中”并且text = "o" 时,函数会向下移动到return reverse_string(text[1:]) + text[0]?
    • 最后一点,发生这种情况是因为它实际上是从 return text 被“命中”的帧返回并转到 reverse_string("o") 被调用的行:return reverse_string("o") + text[0]
    • 谢谢。我认为这里缺少的部分是用递归函数阐明 Winding 和 Unwinding 的概念。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-14
    • 2017-11-27
    • 2015-11-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    相关资源
    最近更新 更多