简体   繁体   English

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

[英]Remove operation on binary search tree with only 1 node (the root)

Started writing the removal function for an unbalanced BST structure. 开始为不平衡的BST结构编写删除功能。 Manually running some tests for the first case (node has no children). 为第一种情况手动运行一些测试(节点没有子节点)。 Decided to run it on a tree of size 1 (just the root), and for some reason it does not seem to be reassigning the root to null the way I'm expecting it to on line 3 of this statement: 决定在大小为1(仅是根)的树上运行它,由于某种原因,它似乎并没有像我期望的那样在此语句的第3行上将根重新分配为null

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

Then when I run inOrderTraversal on the single node tree, which should just console.log each node, and return undefined for a null tree (what I'm expecting) it simply prints the 55 as it does before the removal. 然后,当我在单节点树上运行inOrderTraversal时,应该在每个节点上进行console.log ,并为空树返回undefined(我期望如此),它只像删除前一样打印55。

It seems to be working for all other cases where the node to remove has no children. 对于要删除的节点没有子节点的所有其他情况,它似乎都起作用。

Here's the fiddle: https://jsfiddle.net/uvdrmwh0/6/ 这是小提琴: https : //jsfiddle.net/uvdrmwh0/6/

And the code: 和代码:

"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);

Update: 更新:

I've noticed things like this work: 我注意到这样的事情:

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

But this doesn't: 但这不是:

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

It seems you can reassign properties of an object (pointers within an object) and it will change the outside reference, but reassigning the reference to the object itself doesn't? 看来您可以重新分配对象的属性(对象内的指针),并且它会更改外部引用,但不会将引用重新分配给对象本身吗?

The following change should make it work: 以下更改应使其起作用:

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

The changes to node happen locally in remove function. node的更改在remove功能中本地发生。 So you should set the bst to whatever is received back from remove function. 因此,您应该将bst设置为从remove函数收到的任何内容。

The important thing to understand here is how does javascript pass the arguments . 这里要了解的重要一点是javascript如何传递参数 I hope this helps. 我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM