【问题标题】:Activation record trace by a recursion method通过递归方法跟踪激活记录
【发布时间】:2017-09-05 16:02:09
【问题描述】:

因为要很好地学习递归思想背后的逻辑,所以我在使用调试器学习数据结构的同时进行练习。这个问题可能看起来很简单,但它只是引起轰动。该方法在二叉搜索树中找到最大元素。 - 通常,二叉搜索树(完整实现为click here)是一棵树,其中左孩子的元素少于根元素,右孩子的元素比根元素多。 - 在找到它之前,该方法会进入新的激活帧并将其推送到堆栈顶部。找到后,它们会以相反的顺序 (LIFO) 弹出。我的问题是,为什么该方法返回第二条语句(return findMax(node.right))?如果调试器显示激活帧被弹出,为什么它只显示一次?我希望图片也有助于更好地理解我的问题。

/* bST.add(1),bST.add(3),bST.add(7),bST.add(6),bST.add(4),
   bST.add(13),bST.add(14),bST.add(10),bST.add(8); */

/**
 * Find max element in the BST
 * @param node local node being given
 * @return max element
 */
public E findMax(Node<E> node) {
        if (node.right == null)
            return node.data;
        return findMax(node.right);
}

【问题讨论】:

  • 最后一张截图node 是 13,之前是 14。您需要检查调用堆栈。你很可能不在同一个方法调用中
  • 查看您的堆栈跟踪。在node.right 为空之后,您只会倒退。不知道为什么调试器会跳过堆栈跟踪的其余部分。不与 IntelliJ 合作也许“强制步入”会对您有所帮助。或者当你倒退时“走出去”

标签: java recursion data-structures binary-search-tree


【解决方案1】:

代码沿着树的右侧向下运行,直到遇到最大的元素:没有右孩子的那个。然后它返回那个节点的数据值——给调用它的实例。那是从节点 13 调用的实例。

特定语句 return node.data 是此递归的基本情况。第二个,return findMax(node.right),是递归的情况。当您达到值 14 时,您已将其中的四个 回报 堆积起来,等待结果。

来自节点 13 的那个会将值 14 传递回来自节点 7 的调用,继续向下堆栈直到来自节点 1 的调用返回值 14到任何称为 findMax 的东西。

我不知道为什么您的调试器仅显示第一次激活“pop”的证据。不知道你用的是什么设置。如果您是单步执行,或者在 return 处设置了断点(以及 findMax 调用),您应该会看到两端:向下另一个水平,然后按 LIFO 顺序返回。

这对你有好处吗?

【讨论】:

  • 感谢您的关注。但是,我知道并同意您对最后一段的疑惑。您可以从the link. 中看到“步入”转发和其他内容,调试属性是标准的 IntelliJ IDE。顺便说一句,我认为它与IDE有关,所以像你这样有经验的人的帮助可以帮助我确定我的想法是正确的。
  • 是的。那是“步入”,但是当它退出时,它的返回需要一个很大的飞跃。我记得当我使用 IntelliJ 时。我认为我们通过在汇编代码中设置断点来阻止大飞跃。
猜你喜欢
  • 2010-11-16
  • 2016-04-13
  • 2019-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-27
  • 1970-01-01
  • 2022-01-23
相关资源
最近更新 更多