我正在做一个AlgoExpert挑战,我已经花时间自己解决它,看了关于它的视频讲座,我觉得我有一个很好的理解,但我在递归和树遍历方面的技能现在很低(这就是我工作的原因)。
这是提示
编写一个函数,该函数接受二进制搜索树(BST)和目标整数值,并返回与BST中包含的目标值最接近的值。每个BST节点都有一个整数值、一个左子节点和一个右子节点。其子节点本身是有效的BST节点或无/空
目标:12
这是我目前为止的解决方案:
function findClosestValueInBst(tree, target) {
let closest = tree.value;
const traverse = (inputTree) => {
if (inputTree === null) return;
if (Math.abs(target - closest) > Math.abs(target - inputTree.value)) {
closest = inputTree.value;
}
if (target < tree.value) {
console.log('left')
traverse(inputTree.left)
} else {
console.log('right')
traverse(inputTree.right)
}
}
traverse(tree)
return closest;
}
// This is the class of the input tree. Do not edit.
class BST {
constructor(value) {
this.value = value;
this.left = null;
this.right = null;
}
}
到目前为止的行为是,遍历到节点 15,但随后,它不是转到 13,而是转到 22,因此它返回 10 作为接近可能的值,而不是绝对值接近 12 而不是 10 的 13。
使用 Nina Scholz 的测试用例,但我认为这是一个更简单的递归,我们可以这样做:
const closer = (v) => (x, y) =>
Math.abs (x - v) < Math .abs (y - v) ? x : y
const findClosestValueInBst = (node, target) =>
node == null
? Infinity
: target == node .value
? node .value
: target < node .value
? closer (target) (findClosestValueInBst (node .left, target), node .value)
: closer (target) (findClosestValueInBst (node .right, target), node .value)
const tree = { value: 10, left: { value: 7, left: { value: 5, left: null, right: null }, right: { value: 8, left: null, right: null } }, right: { value: 13, left: { value: 11, left: null, right: null }, right: { value: 15, left: null, right: null } } };
console .log (findClosestValueInBst (tree, 11))
console .log (findClosestValueInBst (tree, 12))
console .log (findClosestValueInBst (tree, 13))
console .log (findClosestValueInBst (tree, 14))
console .log (findClosestValueInBst (tree, 15))
console .log (findClosestValueInBst (tree, 16))
console .log (tree)
.as-console-wrapper {max-height: 100% !important; top: 0}
也许这行得通。
它检查单个函数中的节点,并使用具有较大值的初始值的最后一个值。
然后它发现是否找到目标并返回目标。
否则,检查目标是否在内部
function findClosestValue(tree, target, last = tree.value) {
if (tree === null) return last;
if (tree.value === target) return target;
if (
last < target && target < tree.value ||
tree.value < target && target < last
) return Math.abs(target - this.value) < Math.abs(target - last)
? this.value
: last;
return target < tree.value
? findClosestValue(tree.left, target, tree.value)
: findClosestValue(tree.right, target, tree.value);
}
const
tree = { value: 10, left: { value: 7, left: { value: 5, left: null, right: null }, right: { value: 8, left: null, right: null } }, right: { value: 13, left: { value: 11, left: null, right: null }, right: { value: 15, left: null, right: null } } };
console.log(findClosestValue(tree, 11));
console.log(findClosestValue(tree, 12));
console.log(findClosestValue(tree, 13));
console.log(findClosestValue(tree, 14));
console.log(findClosestValue(tree, 15));
console.log(findClosestValue(tree, 16));
console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
function findClosestValueInBst(tree, target) {
let closest = tree.value;
const traverse = (inputTree) => {
if (inputTree === null) return;
if (Math.abs(target - closest) > Math.abs(target - inputTree.value)) {
closest = inputTree.value;
}
// As you can see below this line you are checking target < tree.value
// problem is that tree is the root that your surrounding function gets
// not the argument that your recursive function gets.
// both your condition and your parameter to traverse
// need to be inputTree, not tree
if (target < tree.value) {
console.log('left')
traverse(inputTree.left)
} else {
console.log('right')
traverse(inputTree.right)
}
}
traverse(tree)
return closest;
}
现在看看下面的代码:
function findClosestValueInBst(root, target) {
let closest = root.value;
const traverse = (node) => {
if (node === null) return;
if (Math.abs(target - closest) > Math.abs(target - node.value)) {
closest = node.value;
}
if (target < node.value) {
console.log('left')
traverse(node.left)
} else {
console.log('right')
traverse(node.right)
}
}
traverse(root)
return closest;
}
在这种情况下,将参数命名得更清楚是有帮助的,这样就不会产生混淆。
我试图使用队列的链表实现实现二叉搜索树的级别顺序遍历。 我已经检查了二叉查找树的实现,它是好的。队列的链表实现也是正确的。在这里,我试图访问节点并将其子节点排队。然后使用弹出函数实际访问节点。 这最终是通过递归调用完成的。当我运行以下代码时,我以不同的顺序获得输出。
我正在努力实现二叉搜索树。完成实现所需的功能之一是重新平衡功能。 根据规范,该功能的工作方式如下: rebalance() 方法应创建一个平衡树,从而将偏度降低为零。平衡树是指在整个树中,左子树和右子树的大小相差不超过1(即,每个子树也是平衡的)。 为了平衡树,rebalance() 方法应反复将根值移动到较小的子树,并将最小/最大值从较大的子树移动到根,直到树平衡。然后,它应该以递归方式平衡两个
主要内容:什么是二叉排序树?,使用二叉排序树查找关键字,二叉排序树中插入关键字,二叉排序树中删除关键字,总结前几节介绍的都是有关静态 查找表的相关知识,从本节开始介绍另外一种查找表—— 动态查找表。 动态查找表中做查找操作时,若查找成功可以对其进行删除;如果查找失败,即表中无该关键字,可以将该关键字插入到表中。 动态查找表的表示方式有多种,本节介绍一种使用树结构表示动态查找表的实现方法—— 二叉排序树(又称为 “二叉查找树”)。 什么是二叉排序树? 二叉排序树要么是空 二叉树,要么具有如下特点:
我们已经看到了两种不同的方法来获取集合中的键值对。回想一下,这些集合实现了 map 抽象数据类型。我们讨论的 map ADT 的两个实现是在列表和哈希表上的二分搜索。在本节中,我们将研究二叉查找树作为从键映射到值的另一种方法。 在这种情况下,我们对树中项的确切位置不感兴趣,但我们有兴趣使用二叉树结构来提供高效的搜索。
我试图编写一个Prolog谓词,为给定的遍历提供一个可能的二叉搜索树。我选择将树表示为,叶子就是,当子树不存在时,它的值是。 这是我到目前为止所做的(仅适用于本例中的后序遍历): 这在一个方面很好,但在另一个方面却很好: 我意识到不需要二叉搜索树,也就是说,不需要左子树中的所有节点都小于根节点,右子树中的所有节点都大于根节点,所以我还写了以下内容: 我想我可以做使Prolog只返回实际的二进制搜索
我试图从BST中删除最小节点,所以我在树中搜索,直到得到最小值(当root.leftnode为None时),然后将root.rightnode设置为根本身,以继续BST。 问题是,当我这样做之后检查树时,它不会显示曾经发生过的删除。 有人可以指出我正确的方向吗,任何建议都值得赞赏。