[英]Binary Search Tree - remove function not changing the original tree
我正在嘗試刪除二叉搜索樹中的根節點。
bst.remove(1) 給出了正確的 output 但它不會改變樹本身。
因此,如果我在調用 bst.remove(1) 后檢查 bst,則 output 是不同的。 為什么會這樣?
如果我運行bst=bst.left||bst.right;
,我得到了正確的 output,這讓我相信我的 function 沒有改變原樹。
remove(key) {
return this.removeImpl(key, this);
}
removeImpl(key, node){
if (node != null) {
if (key < node.value) {
// Key might be in the left subtree.
node.left = this.removeImpl(key, node.left);
} else if (key > node.value) {
node.right = this.removeImpl(key, node.right);
} else {
// Node found.
// Let's see if it has two children.
if (node.left && node.right) {
// Replace current node with
// predecessor data
node.value = this.minimum(node.right);
node.right = this.removeImpl(node.value, node.right);
} else {
// Only 1 child.
// Let's return the child that's valid.
node = node.left || node.right; //node to be removed becomes it's right or left child
}
}
}
return node;
}
var bst=new BST(1);
bst.insert(2);
bst.insert(3);
bst.insert(4);
bst.remove(1);
bst.remove(1)
給出了正確的 output 但它不會改變樹本身。
這是有意的。 你所說的“樹本身”,實際上是根節點。 您的代碼沒有單獨的 class 形式的樹的概念——樹(僅)由根節點隱含。 由於刪除節點不是刪除節點的突變,而是其他引用的突變,並且對該根節點的唯一引用是bst
變量,因此您需要對bst
進行賦值。 在刪除樹的最后一個節點的極端情況下,您會期望bst
變為null
,因此再次需要對bst
進行分配。 由於此bst
變量不是某些 class 實例的屬性,因此您需要在主代碼中“自己”管理此分配。
下面是分析這種情況的另一種方法:
removeImpl
function依賴調用者將返回的節點附加到正確的位置。 您可以在removeImpl
進行的每個遞歸調用中看到這種情況……例如:
node.left = this.removeImpl(key, node.left);
node.right = this.removeImpl(key, node.right);
所以我們可以說調用者改變了樹。 如果removeImpl
本身就是調用者(遞歸調用),那么它自己執行突變,但removeImpl
的初始調用者(即remove
)也會這樣做:
return this.removeImpl(key, this);
在這里,我們看到對返回的節點做某事的責任被級聯到了remove
的調用者。 那個調用者應該應用這個原則,那就是你當前的代碼是缺乏的。 我們在這里看到了remove
的調用:
bst.remove(1)
但是該調用忽略了返回的節點。 這不是應該調用remove
的方式。 它應該這樣調用:
bst = bst.remove(1)
通過該更改,代碼始終使用remove
和removeImpl
方法返回的節點來捕獲更改。
以上內容可能看起來過於冗長。 如果您希望bst.remove(1)
完成這項工作而無需為bst
分配任何東西,那么您應該考慮使用二類系統而不是當前的一類實現。
然后,您將當前的BST
class 重命名為Node
,並創建第二個 class ,它將成為容器 class,並且可以命名為BST
。 當您將BST
重命名為Node
時,不要忘記在創建節點的地方也使用該名稱(如在insert
方法中, new BST
應該成為new Node
)。
然后加:
class BST {
constructor() {
self.root = null; // Now the root is a property, not a global variable
}
insert(key) {
if (self.root == null) self.root = new Node(key);
else self.root.insert(key);
}
remove(key) {
if (self.root) {
// Now we mutate the container instance:
self.root = self.root.remove(key);
}
}
}
var bst = new BST();
for (let value of [1, 2, 3, 4]) bst.insert(value);
bst.remove(1);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.