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

时间:2018-02-20 03:37:46

标签: javascript algorithm pointers binary-search-tree

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

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

然后当我在单个节点树上运行inOrderTraversal时,每个节点应该console.log,并且对于空树(我期待的那样)返回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 个答案:

答案 0 :(得分:2)

以下更改应使其有效:

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

node的更改发生在remove函数的本地。因此,您应该将bst设置为从remove函数收到的任何内容。

这里要理解的重要事项是how does javascript pass the arguments。我希望这会有所帮助。