二叉搜索树 JavaScript 实现 - 删除功能
Binary Search Tree JavaScript implementation - remove function
这是我在 JavaScript 中实现的二叉搜索树。除了 remove
函数外,所有函数似乎都正常工作。具体来说,它似乎正在正确删除节点,直到树中剩下 2 个节点:
var binaryTreeNode = function (value) {
return {
value : value,
left : null,
right : null
};
};
var binarySearchTree = function () {
var tree = Object.create( binarySearchTreeMethods );
tree.root = null;
return tree;
};
var binarySearchTreeMethods = {
insert: function (value, node) {
var newNode = binaryTreeNode( value );
// check if tree is empty
if ( this.isEmpty() ) {
this.root = newNode;
return;
}
// initialize node
if ( node === void 0 ) node = this.root;
// compare value with node.value
if ( value <= node.value ) {
// check if left exists
if ( node.left ) {
this.insert( value, node.left );
} else {
node.left = newNode;
}
} else {
if ( node.right ) {
this.insert( value, node.right );
} else {
node.right = newNode;
}
}
},
remove: function (value, node) {
var nextRightValue, nextLeftValue, minRight;
if ( !this.isEmpty() ) {
// initialize node
if ( node === void 0 ) node = this.root;
// compare the node's value with the value
if ( value < node.value ) {
// check if there is a left node
if ( node.left ) {
node.left = this.remove( value, node.left );
}
} else if ( value > node.value ) {
// check if there is a right node
if ( node.right ) {
node.right = this.remove( value, node.right );
}
} else {
// at this point, value === node.value
// check if node is a leaf node
if ( node.left === null && node.right === null ) {
// edge case of single node in tree (i.e. root node)
if ( this.getHeight() === 0 ) {
this.root = null;
return this.root;
} else {
node = null;
}
} else if ( node.left === null ) {
node = node.right;
} else if ( node.right === null ) {
node = node.left;
} else {
// node has both left and right
minRight = this.findMinValue( node.right );
node.value = minRight;
node.right = this.remove( minRight, node.right );
}
}
return node;
}
},
contains: function (value, node) {
if ( this.isEmpty() ) return false;
// tree is not empty - initialize node
if ( node === void 0 ) node = this.root;
// check if node's value is the value
if ( value === node.value ) return true;
if ( value < node.value ) {
// check if left node exists
return node.left ? this.contains( value, node.left ) : false;
} else {
// check if right node exists
return node.right ? this.contains( value, node.right ) : false;
}
},
findMaxValue: function (node) {
if ( !this.isEmpty() ) {
if ( node === void 0 ) node = this.root;
while ( node.right ) {
node = node.right;
}
return node.value;
}
},
findMinValue: function (node) {
if ( !this.isEmpty() ) {
if ( node === void 0 ) node = this.root;
while ( node.left ) {
node = node.left;
}
return node.value;
}
},
getHeight: function (node) {
if ( !this.isEmpty() ) {
// initialize node
if ( node === void 0 ) node = this.root;
// base case
if ( node.left === null && node.right === null ) return 0;
if ( node.left === null ) return 1 + this.getHeight( node.right );
if ( node.right === null ) return 1 + this.getHeight( node.left );
return 1 + Math.max( this.getHeight( node.left ), this.getHeight( node.right ) );
}
},
isEmpty: function () {
return this.root === null;
}
};
将值插入二叉搜索树工作正常:
var bst = binarySearchTree();
bst.insert(10);
bst.insert(5);
bst.insert(20);
bst.insert(30);
bst.insert(22);
bst.insert(18);
我每次开始删除 root
值时遇到问题:
bst.remove(10); // this works fine and the resulting bst tree is structurally correct
bst.remove(18); // this works fine and the resulting bst tree is structurally correct
bst.remove(20); // this works fine and the resulting bst tree is structurally correct
bst.remove(22); // this works fine and the resulting bst tree is structurally correct
bst.remove(30); // THIS IS WHERE THE ISSUE OCCURS
在删除 30 之前,树只有两个值:30 作为根值,5 作为 root.left 值。我希望删除 30 会给我一棵以 5 为根的树。但是,删除 30 对树没有任何影响;它保持不变。
进一步测试表明,如果我先删除 5 个,然后删除 30 个,那么一切也都正常:
bst.remove(10); // this works fine and the resulting bst tree is structurally correct
bst.remove(18); // this works fine and the resulting bst tree is structurally correct
bst.remove(20); // this works fine and the resulting bst tree is structurally correct
bst.remove(22); // this works fine and the resulting bst tree is structurally correct
bst.remove(5); // Results in a tree with 30 as the root value
bst.remove(30); // Results in the empty tree where root === null
谁能帮我理解为什么最初删除 30 不起作用?
当找到的节点是根并且它是树中唯一的节点时,你的代码有一个规定,如果一个节点既有左节点又有右节点 child,你覆盖它价值。但是当要删除的节点是根并且它只有一个 child 时,您的代码中没有任何内容可以覆盖 this.root
,并且您不会覆盖根的值,因此它不会被删除并且树保持不变。
您可以通过更改以下内容来解决此问题:
if ( node === void 0 ) node = this.root;
// compare the node's value with the value
if ( value < node.value ) {
对此:
if ( node === void 0 ) {
this.root = this.remove(value, this.root);
// compare the node's value with the value
} else if ( value < node.value ) {
修复后,您可以稍微简化一下逻辑:
remove: function (value, node) {
if (!this.isEmpty()) {
// initialize node
if (!node) {
this.root = this.remove(value, this.root);
} else if (value < node.value && node.left) {
node.left = this.remove(value, node.left);
} else if (value > node.value && node.right) {
node.right = this.remove(value, node.right);
} else if (value === node.value) {
// check if node is a leaf node
if (node.left && node.right) {
// node has two children. change its value to the min
// right value and remove the min right node
node.value = this.findMinValue(node.right);
node.right = this.remove(node.value, node.right);
} else {
// replace the node with whichever child it has
node = node.left || node.right;
}
}
return node;
}
},
然后您可以通过将其分为两种方法来进一步简化它:
remove: function (value) {
this.root = this._removeInner(value, this.root);
},
_removeInner: function (value, node) {
if (node) {
if (value < node.value) {
node.left = this._removeInner(value, node.left);
} else if (value > node.value) {
node.right = this._removeInner(value, node.right);
} else if (node.left && node.right) {
node.value = this.findMinValue(node.right);
node.right = this._removeInner(node.value, node.right);
} else {
node = node.left || node.right;
}
}
return node;
},
@wmock 问过我是如何解决这个问题的,所以我会详细说明一下。
我做的第一件事是在调试器中遍历代码,重点放在 bst.remove(30)
部分。我注意到那时 30 是根,并且在 remove()
完成后它仍然存在。这让我注意到在那个特定情况下,代码从不修改根。
然后我查看了 this.remove()
的 return 值是如何分配给 node.left
和 node.right
的,并且回忆了一些 BST 算法,认为它会对根进行模拟也是有意义的。这确实是答案。
有一些因素促使将该方法分为两种方法:
- 我注意到该方法具有相当多的 special-case 功能,这些功能仅与
bst.remove()
的初始调用相关
- 正在检查
this.isEmpty()
- 如果
node
为 null ,则对 node
的值使用 this.root
- 在树高为 0 的某些情况下,将
this.root
重置为 null
每次通过时都做所有这些似乎很马虎remove()
- 我也反复发现自己想使用
if (!node)
来检查我是否已经到达树的边缘,但我做不到,因为有那种特殊情况逻辑可以使用 this.root
当node
为空。
将方法分成两部分解决了上述所有问题。
请注意,在许多 BST 实现中,_removeInner()
中的功能将是 binaryTreeNode
类型上的一个方法,树将只与根节点交互。这消除了将节点从一个方法调用传递到下一个方法调用的需要:
在binarySearchTree
中:
remove: function (value) {
this.root && this.root.remove(value);
},
在binaryTreeNode
中:
remove: function (value) {
if (value < this.value) {
this.left = this.left && this.left.remove(value);
} else if (value > this.value) {
this.right = this.right && this.right.remove(value);
} else if (this.left && this.right) {
this.value = this.right.findMinValue();
this.right = this.right.remove(this.value);
} else {
return this.left || this.right;
}
return this;
},
findMinValue: function () {
return this.left ? this.left.findMinValue() : this.value;
}
这是具有 插入 和 删除 功能
的二叉树的完整示例
function Node(val) {
this.data = val;
this.right = null;
this.left = null;
}
function BST() {
this.root = null;
this.insert = insert;
this.inOrder = inOrder;
this.remove = remove;
this.removeNode = removeNode;
this.kthSmallestNode = kthSmallestNode;
}
function insert(val) {
if (val == null || val == undefined)
return;
if (this.root == null) {
this.root = new Node(val);
return;
}
var current = this.root
var newNode = new Node(val);
while (true) {
if (val < current.data) {
if (current.left == null) {
current.left = newNode;
return;
}
current = current.left;
} else {
if (current.right == null) {
current.right = newNode;
return;
}
current = current.right;
}
}
}
function remove(val) {
this.root = removeNode(this.root, val);
}
function removeNode(current, value) {
if (value == null || value == undefined)
return;
if (value == current.data) {
if (current.left == null && current.right == null) {
return null;
} else if (current.left == null)
return current.right;
else if (current.right == null)
return current.left;
else {
var tempNode = kthSmallestNode(current.right);
current.data = tempNode.data;
current.right = removeNode(current.right, tempNode.data);
return current;
}
} else if (value < current.data) {
current.left = removeNode(current.left, value);
return current;
} else {
current.right = removeNode(current.right, value);
return current;
}
}
function kthSmallestNode(node) {
while (!(node.left == null))
node = node.left;
return node;
}
function inOrder(node) {
if (!(node == null)) {
inOrder(node.left);
console.log(node.data + " ");
inOrder(node.right);
}
}
var tree = new BST();
tree.insert(25);
tree.insert(20);
tree.insert(30);
tree.insert(27);
tree.insert(21);
tree.insert(16);
tree.insert(26);
tree.insert(35);
tree.remove(30)
console.log("Inorder : ")
console.log(tree.inOrder(tree.root))
祝你好运!!!
我有一个我认为大多数人都能理解的非常简单的答案,它考虑了子节点。关键是,如果你要删除一个有左右子节点的值,你首先要向左移动,然后一直向右移动,因为这可以确保它没有子节点并且更容易更新。
removeNode(val) {
let currentNode, parentNode, nextBiggestParentNode=null, found=false, base=[this.root];
while(base.length > 0 && !found) {
currentNode = base.pop();
if(currentNode.value === val) {
found=true;
if(!currentNode.left && !currentNode.right) {
parentNode.right === currentNode ? parentNode.right = null : parentNode.left = null;
}
else if(!currentNode.right && currentNode.left) {
parentNode.right === currentNode ? parentNode.right = currentNode.left : parentNode.left = currentNode.left;
}
else if(!currentNode.left && currentNode.right) {
parentNode.right === currentNode ? parentNode.right = currentNode.right : parentNode.left = currentNode.right;
}
else {
let _traverse = node => {
if (node.right) {
nextBiggestParentNode = node;
_traverse(node.right);
}
else {
currentNode.value = node.value;
nextBiggestParentNode ? nextBiggestParentNode.right = null : currentNode.left = null;
}
}
_traverse(currentNode.left);
}
}
else {
parentNode = currentNode;
val > currentNode.value && currentNode.right ? base.unshift(currentNode.right) : base.unshift(currentNode.left);
}
}
return this;
}
该代码是 class 的一部分,如果有人感兴趣,这里是我的构造函数代码的其余部分
let TreeNode = class {
constructor(value, left=null, right=null) {
this.value = value;
this.left = left;
this.right = right;
}
}
let BST = class {
constructor(root=null) {
this.root = root;
}
insert(nodeToInsert) {
if (this.root === null) {
this.root = nodeToInsert;
} else {
this._insert(this.root, nodeToInsert);
}
}
_insert(root, nodeToInsert) {
if (nodeToInsert.value < root.value) {
if (!root.left) {
root.left = nodeToInsert;
} else {
this._insert(root.left, nodeToInsert);
}
} else {
if (!root.right) {
root.right = nodeToInsert;
} else {
this._insert(root.right, nodeToInsert);
}
}
}
这里有一些创建 bst 和删除值的演示代码
let bst = new BST();
const nums = [20,10,5,15,3,7,13,17,30,35,25,23,27,37,36,38];
function createBst() {
for (let i of nums) {
bst.insert(new TreeNode(i));
}
console.log(JSON.stringify(bst, null, 2));
bst.removeNode(35);
}
createBst();
console.log(JSON.stringify(bst, null, 2));
这是我在 JavaScript 中实现的二叉搜索树。除了 remove
函数外,所有函数似乎都正常工作。具体来说,它似乎正在正确删除节点,直到树中剩下 2 个节点:
var binaryTreeNode = function (value) {
return {
value : value,
left : null,
right : null
};
};
var binarySearchTree = function () {
var tree = Object.create( binarySearchTreeMethods );
tree.root = null;
return tree;
};
var binarySearchTreeMethods = {
insert: function (value, node) {
var newNode = binaryTreeNode( value );
// check if tree is empty
if ( this.isEmpty() ) {
this.root = newNode;
return;
}
// initialize node
if ( node === void 0 ) node = this.root;
// compare value with node.value
if ( value <= node.value ) {
// check if left exists
if ( node.left ) {
this.insert( value, node.left );
} else {
node.left = newNode;
}
} else {
if ( node.right ) {
this.insert( value, node.right );
} else {
node.right = newNode;
}
}
},
remove: function (value, node) {
var nextRightValue, nextLeftValue, minRight;
if ( !this.isEmpty() ) {
// initialize node
if ( node === void 0 ) node = this.root;
// compare the node's value with the value
if ( value < node.value ) {
// check if there is a left node
if ( node.left ) {
node.left = this.remove( value, node.left );
}
} else if ( value > node.value ) {
// check if there is a right node
if ( node.right ) {
node.right = this.remove( value, node.right );
}
} else {
// at this point, value === node.value
// check if node is a leaf node
if ( node.left === null && node.right === null ) {
// edge case of single node in tree (i.e. root node)
if ( this.getHeight() === 0 ) {
this.root = null;
return this.root;
} else {
node = null;
}
} else if ( node.left === null ) {
node = node.right;
} else if ( node.right === null ) {
node = node.left;
} else {
// node has both left and right
minRight = this.findMinValue( node.right );
node.value = minRight;
node.right = this.remove( minRight, node.right );
}
}
return node;
}
},
contains: function (value, node) {
if ( this.isEmpty() ) return false;
// tree is not empty - initialize node
if ( node === void 0 ) node = this.root;
// check if node's value is the value
if ( value === node.value ) return true;
if ( value < node.value ) {
// check if left node exists
return node.left ? this.contains( value, node.left ) : false;
} else {
// check if right node exists
return node.right ? this.contains( value, node.right ) : false;
}
},
findMaxValue: function (node) {
if ( !this.isEmpty() ) {
if ( node === void 0 ) node = this.root;
while ( node.right ) {
node = node.right;
}
return node.value;
}
},
findMinValue: function (node) {
if ( !this.isEmpty() ) {
if ( node === void 0 ) node = this.root;
while ( node.left ) {
node = node.left;
}
return node.value;
}
},
getHeight: function (node) {
if ( !this.isEmpty() ) {
// initialize node
if ( node === void 0 ) node = this.root;
// base case
if ( node.left === null && node.right === null ) return 0;
if ( node.left === null ) return 1 + this.getHeight( node.right );
if ( node.right === null ) return 1 + this.getHeight( node.left );
return 1 + Math.max( this.getHeight( node.left ), this.getHeight( node.right ) );
}
},
isEmpty: function () {
return this.root === null;
}
};
将值插入二叉搜索树工作正常:
var bst = binarySearchTree();
bst.insert(10);
bst.insert(5);
bst.insert(20);
bst.insert(30);
bst.insert(22);
bst.insert(18);
我每次开始删除 root
值时遇到问题:
bst.remove(10); // this works fine and the resulting bst tree is structurally correct
bst.remove(18); // this works fine and the resulting bst tree is structurally correct
bst.remove(20); // this works fine and the resulting bst tree is structurally correct
bst.remove(22); // this works fine and the resulting bst tree is structurally correct
bst.remove(30); // THIS IS WHERE THE ISSUE OCCURS
在删除 30 之前,树只有两个值:30 作为根值,5 作为 root.left 值。我希望删除 30 会给我一棵以 5 为根的树。但是,删除 30 对树没有任何影响;它保持不变。
进一步测试表明,如果我先删除 5 个,然后删除 30 个,那么一切也都正常:
bst.remove(10); // this works fine and the resulting bst tree is structurally correct
bst.remove(18); // this works fine and the resulting bst tree is structurally correct
bst.remove(20); // this works fine and the resulting bst tree is structurally correct
bst.remove(22); // this works fine and the resulting bst tree is structurally correct
bst.remove(5); // Results in a tree with 30 as the root value
bst.remove(30); // Results in the empty tree where root === null
谁能帮我理解为什么最初删除 30 不起作用?
当找到的节点是根并且它是树中唯一的节点时,你的代码有一个规定,如果一个节点既有左节点又有右节点 child,你覆盖它价值。但是当要删除的节点是根并且它只有一个 child 时,您的代码中没有任何内容可以覆盖 this.root
,并且您不会覆盖根的值,因此它不会被删除并且树保持不变。
您可以通过更改以下内容来解决此问题:
if ( node === void 0 ) node = this.root;
// compare the node's value with the value
if ( value < node.value ) {
对此:
if ( node === void 0 ) {
this.root = this.remove(value, this.root);
// compare the node's value with the value
} else if ( value < node.value ) {
修复后,您可以稍微简化一下逻辑:
remove: function (value, node) {
if (!this.isEmpty()) {
// initialize node
if (!node) {
this.root = this.remove(value, this.root);
} else if (value < node.value && node.left) {
node.left = this.remove(value, node.left);
} else if (value > node.value && node.right) {
node.right = this.remove(value, node.right);
} else if (value === node.value) {
// check if node is a leaf node
if (node.left && node.right) {
// node has two children. change its value to the min
// right value and remove the min right node
node.value = this.findMinValue(node.right);
node.right = this.remove(node.value, node.right);
} else {
// replace the node with whichever child it has
node = node.left || node.right;
}
}
return node;
}
},
然后您可以通过将其分为两种方法来进一步简化它:
remove: function (value) {
this.root = this._removeInner(value, this.root);
},
_removeInner: function (value, node) {
if (node) {
if (value < node.value) {
node.left = this._removeInner(value, node.left);
} else if (value > node.value) {
node.right = this._removeInner(value, node.right);
} else if (node.left && node.right) {
node.value = this.findMinValue(node.right);
node.right = this._removeInner(node.value, node.right);
} else {
node = node.left || node.right;
}
}
return node;
},
@wmock 问过我是如何解决这个问题的,所以我会详细说明一下。
我做的第一件事是在调试器中遍历代码,重点放在 bst.remove(30)
部分。我注意到那时 30 是根,并且在 remove()
完成后它仍然存在。这让我注意到在那个特定情况下,代码从不修改根。
然后我查看了 this.remove()
的 return 值是如何分配给 node.left
和 node.right
的,并且回忆了一些 BST 算法,认为它会对根进行模拟也是有意义的。这确实是答案。
有一些因素促使将该方法分为两种方法:
- 我注意到该方法具有相当多的 special-case 功能,这些功能仅与
bst.remove()
的初始调用相关- 正在检查
this.isEmpty()
- 如果
node
为 null ,则对 - 在树高为 0 的某些情况下,将
this.root
重置为 null
node
的值使用this.root
- 正在检查
每次通过时都做所有这些似乎很马虎remove()
- 我也反复发现自己想使用
if (!node)
来检查我是否已经到达树的边缘,但我做不到,因为有那种特殊情况逻辑可以使用this.root
当node
为空。
将方法分成两部分解决了上述所有问题。
请注意,在许多 BST 实现中,_removeInner()
中的功能将是 binaryTreeNode
类型上的一个方法,树将只与根节点交互。这消除了将节点从一个方法调用传递到下一个方法调用的需要:
在binarySearchTree
中:
remove: function (value) {
this.root && this.root.remove(value);
},
在binaryTreeNode
中:
remove: function (value) {
if (value < this.value) {
this.left = this.left && this.left.remove(value);
} else if (value > this.value) {
this.right = this.right && this.right.remove(value);
} else if (this.left && this.right) {
this.value = this.right.findMinValue();
this.right = this.right.remove(this.value);
} else {
return this.left || this.right;
}
return this;
},
findMinValue: function () {
return this.left ? this.left.findMinValue() : this.value;
}
这是具有 插入 和 删除 功能
的二叉树的完整示例function Node(val) {
this.data = val;
this.right = null;
this.left = null;
}
function BST() {
this.root = null;
this.insert = insert;
this.inOrder = inOrder;
this.remove = remove;
this.removeNode = removeNode;
this.kthSmallestNode = kthSmallestNode;
}
function insert(val) {
if (val == null || val == undefined)
return;
if (this.root == null) {
this.root = new Node(val);
return;
}
var current = this.root
var newNode = new Node(val);
while (true) {
if (val < current.data) {
if (current.left == null) {
current.left = newNode;
return;
}
current = current.left;
} else {
if (current.right == null) {
current.right = newNode;
return;
}
current = current.right;
}
}
}
function remove(val) {
this.root = removeNode(this.root, val);
}
function removeNode(current, value) {
if (value == null || value == undefined)
return;
if (value == current.data) {
if (current.left == null && current.right == null) {
return null;
} else if (current.left == null)
return current.right;
else if (current.right == null)
return current.left;
else {
var tempNode = kthSmallestNode(current.right);
current.data = tempNode.data;
current.right = removeNode(current.right, tempNode.data);
return current;
}
} else if (value < current.data) {
current.left = removeNode(current.left, value);
return current;
} else {
current.right = removeNode(current.right, value);
return current;
}
}
function kthSmallestNode(node) {
while (!(node.left == null))
node = node.left;
return node;
}
function inOrder(node) {
if (!(node == null)) {
inOrder(node.left);
console.log(node.data + " ");
inOrder(node.right);
}
}
var tree = new BST();
tree.insert(25);
tree.insert(20);
tree.insert(30);
tree.insert(27);
tree.insert(21);
tree.insert(16);
tree.insert(26);
tree.insert(35);
tree.remove(30)
console.log("Inorder : ")
console.log(tree.inOrder(tree.root))
祝你好运!!!
我有一个我认为大多数人都能理解的非常简单的答案,它考虑了子节点。关键是,如果你要删除一个有左右子节点的值,你首先要向左移动,然后一直向右移动,因为这可以确保它没有子节点并且更容易更新。
removeNode(val) {
let currentNode, parentNode, nextBiggestParentNode=null, found=false, base=[this.root];
while(base.length > 0 && !found) {
currentNode = base.pop();
if(currentNode.value === val) {
found=true;
if(!currentNode.left && !currentNode.right) {
parentNode.right === currentNode ? parentNode.right = null : parentNode.left = null;
}
else if(!currentNode.right && currentNode.left) {
parentNode.right === currentNode ? parentNode.right = currentNode.left : parentNode.left = currentNode.left;
}
else if(!currentNode.left && currentNode.right) {
parentNode.right === currentNode ? parentNode.right = currentNode.right : parentNode.left = currentNode.right;
}
else {
let _traverse = node => {
if (node.right) {
nextBiggestParentNode = node;
_traverse(node.right);
}
else {
currentNode.value = node.value;
nextBiggestParentNode ? nextBiggestParentNode.right = null : currentNode.left = null;
}
}
_traverse(currentNode.left);
}
}
else {
parentNode = currentNode;
val > currentNode.value && currentNode.right ? base.unshift(currentNode.right) : base.unshift(currentNode.left);
}
}
return this;
}
该代码是 class 的一部分,如果有人感兴趣,这里是我的构造函数代码的其余部分
let TreeNode = class {
constructor(value, left=null, right=null) {
this.value = value;
this.left = left;
this.right = right;
}
}
let BST = class {
constructor(root=null) {
this.root = root;
}
insert(nodeToInsert) {
if (this.root === null) {
this.root = nodeToInsert;
} else {
this._insert(this.root, nodeToInsert);
}
}
_insert(root, nodeToInsert) {
if (nodeToInsert.value < root.value) {
if (!root.left) {
root.left = nodeToInsert;
} else {
this._insert(root.left, nodeToInsert);
}
} else {
if (!root.right) {
root.right = nodeToInsert;
} else {
this._insert(root.right, nodeToInsert);
}
}
}
这里有一些创建 bst 和删除值的演示代码
let bst = new BST();
const nums = [20,10,5,15,3,7,13,17,30,35,25,23,27,37,36,38];
function createBst() {
for (let i of nums) {
bst.insert(new TreeNode(i));
}
console.log(JSON.stringify(bst, null, 2));
bst.removeNode(35);
}
createBst();
console.log(JSON.stringify(bst, null, 2));