当前位置: 首页 > 知识库问答 >
问题:

仅具有1个节点(根节点)的二叉搜索树上的删除操作

翟柏
2023-03-14

开始为不平衡的BST结构编写删除函数。为第一种情况手动运行一些测试(节点没有子节点)。决定在大小为1的树上运行它(仅在根上),出于某种原因,它似乎没有按照我在本语句第3行期望的方式将根重新分配到null

return direction ?
  parent[direction] :
  node = null;

然后,当我在单节点树上运行inOrderTraversal时,它应该只是控制台。记录每个节点,并为空树返回undefined(我所期望的),它只是像删除之前一样打印55。

它似乎适用于要删除的节点没有子节点的所有其他情况。

这是小提琴:https://jsfiddle.net/uvdrmwh0/6/

和代码:

"use strict";

function Node(value, left = null, right = null) {
  return {
    value,
    left,
    right
  };
}

function insert(x, root) {
  let currNode = root;
  while (currNode) {
    if (x < currNode.value) {
      if (currNode.left) {
        currNode = currNode.left;
      } else {
        currNode.left = Node(x);
        return;
      }
    } else if (x > currNode.value) {
      if (currNode.right) {
        currNode = currNode.right;
      } else {
        currNode.right = Node(x);
        return;
      }
    } else if (x === currNode.value) {
      throw new Error("cannot insert node with the same value as an existing node");
    } else {
      throw new Error("undefined behavior in insert");
    }
  }
  throw new Error("failed to insert");
}

function remove(x, node, parent = null, direction = null) {
  if (node === null) return;
  if (node.value === x) {
    if (!node.left && !node.right) {
      return direction ?
        parent[direction] = null :
        node = null;
    } else if (node.left && !node.right) {
        //TODO
    }
    //TODO
  }
  direction = x < node.value ? "left" : "right";
  remove(x, node[direction], node, direction);
}

function inOrderTraversal(node) {
  if (node === null) return;
  inOrderTraversal(node.left);
  console.log(node.value);
  inOrderTraversal(node.right);
}

function BinarySearchTree(seed) {
  if (!Array.isArray(seed)) {
    throw new Error("BinarySearchTree must be seeded with an array");
  }
  let root = Node(seed[0]);
  seed.slice(1).forEach(x => {
    insert(x, root);
  });
  return root;
}

let bst = BinarySearchTree([55]);
inOrderTraversal(bst);
console.log("---------after removal---------");
remove(55, bst);
inOrderTraversal(bst);

我注意到像这样的工作:

let x = { a: 1 };
function changeProperty(obj, key, newValue) {
  obj[key] = newValue;
}
changeProperty(x, "a", "hello");
console.log(x.a); //prints hello

但这并没有:

function reassignObject(obj) {
    obj = { a: "some new value" };
}
reassignObject(x);
console.log(x.a); //still prints hello

似乎您可以重新分配对象的属性(对象中的指针),它将更改外部引用,但将引用重新分配到对象本身却不会?


共有1个答案

贝研
2023-03-14

以下更改将使其正常工作:

console.log("---------after removal---------");
bst = remove(55, bst); //change here

节点的更改在remove函数中本地发生。因此,您应该将bst设置为从remove函数返回的内容。

这里需要了解的重要一点是javascript如何传递参数。我希望这有帮助。

 类似资料:
  • 当删除具有两个子节点的节点时,如果指示使用标准的二叉搜索树节点删除算法,我们应该将其替换为右子树的最小节点还是左子树的最大节点?

  • 我的删除方法由4个if语句组成,用于处理二叉查找树中的4种不同类型的删除。不确定哪里错了,但当我检查它时,它没有删除任何节点。如果赞赏,任何帮助。提前感谢' 我怀疑问题在于我试图将节点删除替换为空 }

  • 主要内容:src/runoob/binary/BSTRemove.java 文件代码:本小节介绍二分搜索树节点的删除之前,先介绍如何查找最小值和最大值,以及删除最小值和最大值。 以最小值为例(最大值同理): 查找最小 key 值代码逻辑,往左子节点递归查找下去: ... // 返回以node为根的二分搜索树的最小键值所在的节点 private Node minimum (Node node ) {     if ( node. left == null )         retu

  • 目前,我在理解如何在没有传递节点时从二进制搜索树中删除节点时遇到了一个问题。我有两个类,BSTSet和BSTNode,每个类都有一个remove方法。。 当我被传递一个节点时,我理解删除方法,但当我在根上调用remove方法并试图从node类中删除节点时,我不知道从何处开始。有人能告诉我吗?谢谢如果您想了解更多信息,请询问。

  • 我有一个名为TreeNode的结构,它有一个int键、左键、右键和父键。我正试图用DeleteNode函数从树中删除一个节点,但它不起作用。我应该用左边子树中的最大值替换DeleteNode函数中已删除的节点。我的移植和max函数是deletenode的助手函数。我的问题是,我不确定在DeleteNode函数中,我应该将我所在的节点值与通过函数传入的值进行比较。我在代码中有一个注释,我不知道该怎么

  • 我正在尝试删除我的二叉查找树的根,以便我可以更新它的值,但这种方法不能做到这一点。我的想法是删除根,然后将其再次插入二叉查找树中,但使用另一个值。它适用于树中的每个节点,但不是我无法删除它的根本原因。有人知道为什么会发生这种情况吗?谢谢。 这是我调用方法删除任何节点的主代码,在这种情况下,我想删除根。