问题描述
我正在尝试在JavaScript中创建二进制搜索树(BST)类。在JS中,对象是通过引用传递/分配的,但看起来在remove方法中存在一些问题。 remove方法不是删除我要删除的节点。任何帮助表示赞赏。这是代码
class Node {
constructor(value) {
this.value = value;
this.left = null;
this.right = null;
}
}
class BST {
constructor() {
this.root = null;
}
add(value){
if(!this.root){
this.root = new Node(value);
return this;
}
addNode(this.root);
return this;
function addNode(node) {
if(value < node.value){
if(!node.left){
node.left = new Node(value);
}else{
addNode(node.left);
}
}
if(node.value < value){
if(!node.right){
node.right = new Node(value);
}else{
addNode(node.right);
}
}
}
}
find(value){
if(!this.root){
return;
}
return findNode(this.root);
function findNode(node) {
if(node.value === value){
return node;
}
if(value < node.value){
if(!node.left){
return;
}else{
return findNode(node.left);
}
}else{
if(!node.right){
return;
}else{
return findNode(node.right);
}
}
}
}
remove(value){
if(!this.root){
return this;
}
return removeNode(this.root);
function removeNode(node) {
if(node.value === value){
return actualRemoval(node);
}
if(value < node.value){
if(!node.left){
return;
}else{
return removeNode(node.left);
}
}else{
if(!node.right){
return;
}else{
return removeNode(node.right);
}
}
}
function actualRemoval(node) {
let tmp = Object.assign(node);
if(!node.left && !node.right){
node = null;
return tmp;
}
if(!node.left){
node = node.right;
return tmp;
}
if(!node.right){
node = node.left;
return tmp;
}
//if the node has both the children.
node.value = popMin(node.right).value;
return tmp;
}
function popMin(node) {
if(!node.left){
let tmp = Object.assign(node);
node = node.right;
return tmp;
}
return popMin(node.left);
}
}//end of function remove()
}//end of class BST
let myBST = new BST();
myBST.add(5).add(6).add(3).add(4).add(7).add(5.5)
// console.log(myBST.add(5).add(6).add(3).add(4).add(7).add(5.5));
// console.log(myBST.find(6));
console.log(myBST.remove(3));
console.log(myBST);
在第二行中,我试图删除一个值为3的节点。但是最后一行显示了其中有节点3的树。
解决方法
remove(value){
if(!this.root){
return this;
}
return removeNode(this.root,null);//second argument is the
function removeNode(node,parent,leftOrRight) {
if(node.value === value){
return actualRemoval(node,leftOrRight);
}
if(value < node.value){
if(!node.left){
return;
}else{
return removeNode(node.left,node,"l");
}
}else{
if(!node.right){
return;
}else{
return removeNode(node.right,"r");
}
}
}
function actualRemoval(node,leftOrRight) {
let tmp = Object.assign(node);
if(!node.left && !node.right){
if(parent){
if(leftOrRight === "l"){
parent.left = null;
}else{
parent.right = null;
}
}else{
node = null;
}
return tmp;
}
if(!node.left){
if(parent){
if(leftOrRight === "l"){
parent.left = node.right;
}else{
parent.right = node.right;
}
}else{
node = node.right; //this case runs once node is root
}
return tmp;
}
if(!node.right){
if(parent){
if(leftOrRight === "l"){
parent.left = node.leftt;
}else{
parent.right = node.left;
}
}else{
node = node.left; //this case runs once node is root
}
return tmp;
}
//if the node has both the children.
node.value = popMin(node.right,"r").value;//it is always called for right side with popMin
return tmp;
}
function popMin(node,leftOrRight) {
if(!node.left){
let tmp = Object.assign(node);
if(leftOrRight == "l"){
parent.left = node.right;
}else{
parent.right = node.right;
}
return tmp;
}
return popMin(node.left,"l");
}
}