- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试拓宽我对递归的有限理解。我一直在研究二叉搜索树,目前正在尝试实现遍历功能。我开始使用预序遍历,没问题,然后转向对我来说似乎更棘手的按序遍历。我无法自己找出递归解决方案,所以我用谷歌搜索并发现了同一答案的许多变体 -
function inOrderHelper(root) {
if (root !== null) {
inOrderHelper(root.left);
console.log(root.data);
inOrderHelper(root.right);
}
}
非常简单的代码和更简单的解释,但都没有帮助我理解这个函数到底在做什么。所以,既然你们之前给了我很大的帮助,我希望你们能帮助我扩展我的知识。
最佳答案
理解代码的最简单方法通常是使用调试器进行尝试。 Chrome 有一个 excellent debugger您可以使用它来逐行单步执行代码,因为它是实时运行的。
下一个最简单的方法是使用控制台日志打印出正在发生的事情,这就是大多数超过一定年龄的程序员在调试器使事情变得更容易之前弄清楚发生了什么的方式。
由于我无法坐在您旁边打开调试器,所以让我们做下一个最好的事情并添加一些控制台日志,以便我们可以看到发生了什么:
function inOrderHelper(root) {
console.group("Entering inOrderHelper with ", root);
if (root !== null && root !== undefined) {
console.log("Root is not null, so continue");
console.group("Traversing down the left node");
inOrderHelper(root.left);
console.groupEnd();
console.log("The root value is ", root.value);
console.group("Traversing down the right node");
inOrderHelper(root.right);
console.groupEnd();
} else {
console.log("Root is null, so back up");
}
console.log("Exiting inOrderHelper");
console.groupEnd();
}
让我们尝试一个 BST 示例:
在 JavaScript 中可以将其构造为如下所示:
{
left: {
left: {
value: 1,
},
value: 2,
right: {
value: 3,
},
},
value: 4,
right: {
value: 5,
},
}
您可以run this code in your browser's dev tools通过粘贴上面的函数(并按 Enter 键),然后像这样调用它:
inOrderHelper({
left: {
left: {
value: 1,
},
value: 2,
right: {
value: 3,
},
},
value: 4,
right: {
value: 5,
},
})
结果应该是这样的:
Entering inOrderHelper with {left: {…}, value: 4, right: {…} }
Root is not null, so continue
Traversing down the left node
Entering inOrderHelper with {left: {…}, value: 2, right: {…}}
Root is not null, so continue
Traversing down the left node
Entering inOrderHelper with { value: 1 }
Root is not null, so continue
Traversing down the left node
Entering inOrderHelper with undefined
Root is null, so back up
Exiting inOrderHelper
The root value is 1
Traversing down the right node
Entering inOrderHelper with undefined
Root is null, so back up
Exiting inOrderHelper
Exiting inOrderHelper
The root value is 2
Traversing down the right node
Entering inOrderHelper with { value: 3 }
Root is not null, so continue
Traversing down the left node
Entering inOrderHelper with undefined
Root is null, so back up
Exiting inOrderHelper
The root value is 3
Traversing down the right node
Entering inOrderHelper with undefined
Root is null, so back up
Exiting inOrderHelper
Exiting inOrderHelper
Exiting inOrderHelper
The root value is 4
Traversing down the right node
Entering inOrderHelper with { value: 5 }
Root is not null, so continue
Traversing down the left node
Entering inOrderHelper with undefined
Root is null, so back up
Exiting inOrderHelper
The root value is 5
Traversing down the right node
Entering inOrderHelper with undefined
Root is null, so back up
Exiting inOrderHelper
Exiting inOrderHelper
Exiting inOrderHelper
您还可以使用在线工具,例如 BinaryTreeVisualizer ,查看动画演示。
How does the program know to stop before the tree is finished? It seems to me that it should continue to go to the runner's left node until it is null, at which point it will skip the console.log
请注意,当函数从左侧向下递归时,当递归函数返回时,控制权返回到父函数,父函数继续从右侧向下延伸。当递归函数返回时,它不会立即结束父函数。父函数像对待任何其他函数一样对待递归函数。它调用它,然后当它返回时,继续下一件事。
How does the program know that a node has already been printed? It seems to me that it would just print the minimum value repeatedly or once before traversing to the maximum value but apparently the nodes are being checked off somehow.
这就是 javascript 有点令人困惑的地方。本质上,该函数尝试从左侧和右侧向下移动,但如果根值是字符串,例如 "B"
,则 root.left
和 root.right
引用不存在的属性。在 javascript 中,它不会抛出错误,而是返回 undefined
。因此,当我们在 root.left
上递归并且该值为 undefined
时,我们什么也不做。
因此,在我们的示例树中:
{
left: {
left: {
value: 1,
},
value: 2,
right: {
value: 3,
},
},
value: 4,
right: {
value: 5,
},
}
我们的第一个根是{ left: { ... }, value: 4, right: { value: 5 } }
当我们向左移动时,根现在是{ left: { value: 1 }, value: 2, right: { value: 3 } }
。
当我们再次向左走时,根现在是{ value: 1 }
。
当我们再次向左走时,根现在未定义
,因此我们什么也不做,并返回到根为{ value: 1 }
的上一个调用。
我们打印1
。
然后我们转到右侧,根现在未定义
,因此我们什么也不做,并返回到根为{ value: 1 }
的上一个调用。
我们已经完成了 { value: 1 }
,因此我们返回到上一个调用,其中根为 { left: { value: 1 }, value: 2, right: { 值:3 } }
我们打印2
。
现在我们向下到右侧,并像向左侧一样重复该过程,打印 3
。
然后我们回到上一个根,{ left: { ... }, value: 4, right: { value: 5 } }
我们打印4
。
我们转到右侧,与前面的示例一样,打印 5
。
我们返回,因为我们已经到达原始函数调用,所以我们返回并结束程序。
最终结果是我们打印了 1
, 2
, 3
, 4
, 5
,按此顺序。
How are all the values printed? For example, if the second smallest value is the right node of the third smallest, value, how is the second smallest value account for?
我不确定你在问什么,但重要的是要注意这个函数不会对树进行排序。它只是报告值。因此,如果 BST 构造不正确(例如,较小的值是较大值的右侧),那么它也会乱序打印这些值。
关于javascript - 关于 javascript 和 BST 递归的初学者问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59885780/
我已经编写了一个 BSTLink 类来将 BST 转换为双向链表,但是在我尝试通过引用传递 BST 的节点指针的类中的构造调用抛出一个错误“没有匹配的函数来调用 BSTLink::construct(
当我使用 xgboost 为 2-cates classification problem 训练我的数据时,我想使用提前停止来获得最佳模型,但我对在我的预测中使用哪一个感到困惑,因为提前停止将返回 3
因为我找不到有用的东西所以我在这里问我的问题: 我们如何在不使用任何额外空间的情况下将 BST 转换为中序链接列表,然后再转换回“相同”的 BST。 到目前为止我已经尝试过的(虽然仍在做):我尝试了
我从我们的教授讲座幻灯片中获得了 BST(二叉搜索树)和随机 BST 的源代码,现在我想通过插入新元素来测试它们是否正常工作,然后我如何才能看到我的结果,如 http://cs.lmu.edu/~ra
给定两棵二叉树 T1 和 T2,您必须找到要在 T1 中完成的最少插入次数,以使其在结构上与 T2 相同。如果不可能则返回 -1。 注意事项 假设插入在 BST 中以正常方式完成。 假设在插入时,如果
我有一个始终将日期存储为 UTC 的网络应用程序,但它们需要分别以 GMT/BST 的形式显示给用户。 我有一个 UTC/GMT 日期(2013 年 3 月 30 日 22:00),我每小时移动一次以
题目地址:https://leetcode-cn.com/problems/largest-bst-subtree/ 题目描述 Given a binary tree, find the larg
注意:BST - 二叉搜索树(缩写) 正如标题所说,这是一项家庭作业,所以我不是在寻找答案。相反,我只需要一个正确方向的点。 对于作业,我应该创建一个 BST 类,它直接定义为最多包含 2 个 BST
我有一个插入方法和一个搜索方法,我正在考虑一种方法来循环二叉搜索树并使用像获取节点这样的方法,然后在另一个二叉搜索树上搜索它,如果它成立,那么我将其插入该元素,但问题是我无法想出一种基于索引获取节点的
function validateBst(root, min=-Infinity, max=Infinity) { if (!root) return true; if (root.value
我有一个问题,我知道如何像这样计算树中的所有节点 return 1 + rightchild(tree->right) + rightchild(tree->left); 现在我的问题是如果一个节点在
给定一个二叉树根,任务是返回 任何子树的所有键的最大总和 这也是 二叉搜索树 (BST) . 假设 BST 定义如下: - 节点的左子树仅包含键小于节点键的节点。 - 节点的右子树仅包含键大于节点键的
我正在尝试使用 ScalaCheck 为 BST 创建一个 Gen,但是当我调用 .sample 方法时,它给了我 java.lang.NullPointerException。我哪里错了? seal
这些是我的领域: public class BSTSet extends AbstractSet { // Data fields private BSTNode root;
我需要在二叉搜索树中执行范围搜索功能,这将给出给定范围内的项目数量。我不明白如何在找到项目时增加计数值。因为,我必须使用递归函数&如果我在递归过程中将计数变量初始化为0,它将始终从0开始计数值,而不是
所以我正在尝试编写一个代码来返回二叉搜索树中的最小值。我知道这是树的最左边的值,并且我知道我需要它递归地向左运行,直到什么都没有为止。但是我的代码不起作用,我不知道为什么。任何帮助将不胜感激。 (de
我想返回一个包含树中所有键的字符串,按照它们的存储顺序。每个子树中的键应包含在括号中。 _7_ / \ _3_ 8 / \ 1
尝试运行递归算法来找出某棵树是否是 BST(二叉搜索树)。 boolean checkBST(Node root) { boolean isBST = true; if(root ==
使用下面的代码,每个时区都正确打印值,除了 BST import java.text.*; def format = "yyyy-MM-dd HH:mm:ssXXX" def dt = new Da
您能帮忙搜索功能吗,它总是返回nil,我不明白为什么 func BTreeSearchItem(root *TreeNode, elem string) *TreeNode { if root
我是一名优秀的程序员,十分优秀!