BST Insert Method JS Getting an Infinite Loop - javascript

class Node {
constructor(val) {
this.value = val;
this.left = null;
this.right = null;
}
}
class BinarySearchTree {
constructor() {
this.root = null;
}
insert(val) {
var node = new Node(val);
if(!this.root) {
this.root = node;
return this;
} else{
var root = this.root;
while(root) {
if(val === root.value) return undefined;
if(val < root.value) {
if(!root.left) {
root.left = node;
return this;
} else{
root = root.left;
}
} else if(val > root.value) {
if(!root.right) {
root.right = node;
return this;
} else{
root = root.right;
}
}
}
}
}
}
var bts = new BinarySearchTree();
bts.insert(100);
I get an infinite loop most of the time with this method, I have no idea why, can anybody please help me to find the error in my code, Sometime this methods works fine, but other times an infinite loop. Thank you

Related

Can you spot a mistake in this construction of a Binary Search Tree?

I am going through AlgoExpert and learning about Binary Search trees and their construction for the first time. The below implementation seems to be working locally for me as expected but I am getting errors for most test cases on AlgoExpert. This is my implementation:
class BST {
constructor(value) {
this.value = value;
this.left = null;
this.right = null;
}
insert(value) {
const searchTree = (node) => {
if (value < node.value) {
if (!node.left) {
node.left = new BST(value);
} else {
searchTree(node.left);
}
} else {
if (!node.right) {
node.right = new BST(value);
} else {
searchTree(node.right);
}
}
};
searchTree(this);
// Write your code here.
// Do not edit the return statement of this method.
return this;
}
contains(value) {
let currentNode = this;
while (currentNode) {
if (currentNode.value === value) {
return true;
}
if (value < currentNode.value) {
currentNode = currentNode.left;
} else {
currentNode = currentNode.right;
}
}
return false;
// Write your code here.
}
min() {
let currentNode = this;
while (currentNode.left) {
currentNode = currentNode.left;
}
return {
value: currentNode.value,
node: currentNode
};
}
remove(value) {
let nodeToBeRemoved = this;
while (nodeToBeRemoved.value !== value) {
if (value < nodeToBeRemoved.value) {
nodeToBeRemoved = nodeToBeRemoved.left;
} else {
nodeToBeRemoved = nodeToBeRemoved.right;
}
}
if (!nodeToBeRemoved.right) {
nodeToBeRemoved.value = null;
} else {
const {
value: minValue,
node
} = nodeToBeRemoved.right.min();
node.value = null;
nodeToBeRemoved.value = minValue;
}
// Write your code here.
// Do not edit the return statement of this method.
return this;
}
}
Can you see any mistake that could cause this error on Algo Expert? I don't see where the mistake is. This is the error I am getting:
Cannot read property 'toString' of null
TypeError: Cannot read property 'toString' of null
at constructBinaryTreeWithUniqueIds
at constructBinaryTreeWithUniqueIds
...
The remove method has some issues:
After the first while loop, nodeToBeRemoved could be null. In that case the next if statement will make an invalid reference with nodeToBeRemoved.right.
nodeToBeRemoved.value = null does not remove a node. It just modifies the value of a node to null. But it is still part of the tree, and could even have a left child.
The same is true for node.value = null. This remains part of the tree and could have a right child.
remove(value) {
let nodeToBeRemoved = this;
if (value < this.value) {
if (this.left) this.left = this.left.remove(value);
} else if (value > this.value) {
if (this.right) this.right = this.right.remove(value);
} else if (!this.right) {
return this.left;
} else if (!this.left) {
return this.right;
} else {
const minValue = this.right.min().value;
this.right.remove(minValue); // use recursion to delete that min-node
this.value = minValue;
}
return this;
}

who does the method call it self again after the return?

In the last method dfs(), after the node will be '1' the two if statement will not go into and it will go until the return statement without any line that call the method again, !!!but it call it self again!!!
who does that come?
I'm using JS.
Here is the code with online compiler: https://repl.it/repls/EnchantingSpanishBlockchain
class Node {
constructor(value) {
this.left = null;
this.right = null;
this.value = value;
}
}
class BinarySearchTree {
constructor() {
this.root = null;
}
insert(value) {
const newNode = new Node(value);
if (this.root === null) {
this.root = newNode;
} else {
let currentNode = this.root;
while (true) {
if (value < currentNode.value) {
//Left
if (!currentNode.left) {
currentNode.left = newNode;
return this;
}
currentNode = currentNode.left;
} else {
//Right
if (!currentNode.right) {
currentNode.right = newNode;
return this;
}
currentNode = currentNode.right;
}
}
}
}
}
function dfs(node, list) {
if (node.left) {
dfs(node.left, list);
}
if (node.right) {
dfs(node.right, list);
}
list.push(node.value);
return list;
}
// 9
// 4 20
//1 6 15 170
const tree = new BinarySearchTree();
tree.insert(9)
tree.insert(4)
tree.insert(6)
tree.insert(20)
tree.insert(170)
tree.insert(15)
tree.insert(1)
//DFTPostOrder
console.log(dfs(tree.root, []));

How to use recursion function to traverse tree in Javascript

I was building a tree traverse function and it has to use recursion.
What I want the output to be is
'{"value":9,"left":{"value":4,"left":{"value":1},"right":{"value":6}},"right":{"value":20,"left":{"value":15},"right":{"value":170}}}'
Could someone figure out how to use recursion in the traverse function to get the output?
Here is my JS:
class Node {
constructor(value){
this.left = null;
this.right = null;
this.value = value;
}
}
class BinarySearchTree {
constructor(){
this.root = null;
}
insert(value){
const newNode = new Node(value);
if (this.root === null) {
this.root = newNode;
} else {
let currentNode = this.root;
while(true){
if(value < currentNode.value){
//Left
if(!currentNode.left){
currentNode.left = newNode;
return this;
}
currentNode = currentNode.left;
} else {
//Right
if(!currentNode.right){
currentNode.right = newNode;
return this;
}
currentNode = currentNode.right;
}
}
}
}
}
const tree = new BinarySearchTree();
tree.insert(9)
tree.insert(4)
tree.insert(6)
tree.insert(20)
tree.insert(170)
tree.insert(15)
tree.insert(1)
JSON.stringify(traverse(tree.root))
// 9
// 4 20
//1 6 15 170
function traverse(node) {
const tree = { value: node.value };
tree.left=node.left
if(node.left===null) {
return null
}else{
traverse(node.left);
}
tree.right=node.right
if(node.right===null) {
return null
}else{
traverse(node.right);
}
}
You're on the right track; I see that you need specially-formatted objects in your result string. I recommend starting by checking whether the current node is null; if so, return nothing (this key will be ignored by the calling function). Otherwise, create a node object to prepare for return and traverse left and right children. After traversing both subtrees recursively, return the root node. This will build the result structure up from the leaves and end with the root.
In your code,
if(node.left===null) {
return null
is a bit premature, for example. If node has a right subtree, we don't want to abandon traversing it. It's also necessary to return something to the caller in all cases except for empty children.
Also, you may consider putting traverse in the BinaryTree class and have it operate on its member field; I left it as-is in the below example.
Lastly, this is a pre-order traversal; visit the root first, then the left and right subtrees.
function traverse(node) {
if (node) {
const left = traverse(node.left);
const right = traverse(node.right);
return {
value: node.value,
[left&&"left"]: left,
[right&&"right"]: right
};
}
}
class Node {
constructor(value, left=null, right=null) {
this.value = value;
this.left = left;
this.right = right;
}
}
class BinarySearchTree {
constructor() {
this.root = null;
}
insert(value) {
const newNode = new Node(value);
if (this.root === null) {
this.root = newNode;
}
else {
let currentNode = this.root;
while (true) {
if (value < currentNode.value) {
if (!currentNode.left) {
currentNode.left = newNode;
return this;
}
currentNode = currentNode.left;
}
else {
if (!currentNode.right) {
currentNode.right = newNode;
return this;
}
currentNode = currentNode.right;
}
}
}
}
}
const tree = new BinarySearchTree();
tree.insert(9);
tree.insert(4);
tree.insert(6);
tree.insert(20);
tree.insert(170);
tree.insert(15);
tree.insert(1);
console.log(JSON.stringify(traverse(tree.root)));
console.log(traverse(tree.root));
// 9
// 4 20
// 1 6 15 170

BinarySearchTree's insert function in javascript

I was building a BinarySearchTree by using javascript
but the insert function in my code deoesn't run what i want
my ideal result is
{"value":9,"left":{"value":4,"left":{"value":1,"left":null,"right":null},"right":{"value":6,"left":null,"right":null}},"right":{"value":20,"left":{"value":15,"left":null,"right":null},"right":{"value":170,"left":null,"right":null}}}
but my result is
'{"value":9,"left":null,"right":{"left":null,"right":{"left":null,"right":{"left":null,"right":{"left":null,"right":{"left":null,"right":{"left":null,"right":null}}}}}}}'
I think the problem is in my insert function
Here is my JS:
class Node {
constructor(value){
this.left = null;
this.right = null;
this.value = value;
}
}
class BinarySearchTree {
constructor(){
this.root = null;
}
insert(value){
var root=this.root
if(!root){
this.root=new Node(value)
}else{
var currentNode=root;
var newNode=new Node(value)
while(currentNode){
if(value<currentNode.value){
if(!currentNode.left){
currentNode.left=new Node;
break;
}
else{
currentNode=currentNode.left;
}
}else{
if(!currentNode.right){
currentNode.right=new Node;
break;
}else{
currentNode=currentNode.right
}
}
}
}
}
lookup(value){
var root=this.root
var searchNode = new Node(value)
if(!this.root){
return null;
}
if(searchNode===root){
return root
}else{
if(searchNode.value>root){
return root.right.value
}else{
return root.left.value
}
}
}
}
const tree = new BinarySearchTree();
tree.insert(9)
tree.insert(4)
tree.insert(6)
tree.insert(20)
tree.insert(170)
tree.insert(15)
tree.insert(1)
JSON.stringify(traverse(tree.root))
// 9
// 4 20
//1 6 15 170
function traverse(node) {
const tree = { value: node.value };
tree.left = node.left === null ? null : traverse(node.left);
tree.right = node.right === null ? null : traverse(node.right);
return tree;
}
Your Node class was instantiated as newNode so change all new Node into newNode *except for the first instance of new Node of course.
var newNode=new Node(value) // Leave this one alone and fix the rest
var searchNode = new Node(value) // Leave this one alone as well
var insertNode = function(node, newNode) {
if (newNode.key < node.key) {
if (node.left === null) {
node.left = newNode;
} else {
insertNode(node.left, newNode);
}
} else {
if (node.right === null) {
node.right = newNode;
} else {
insertNode(node.right, newNode);
}
}
};

TypeError: 'addNode' is not a function

I wrote a simple JavaScript p5 app (with p5.js) to create a BST data structure. When running this with Firefox, it's showing me TypeError: this.root.addNode is not a function
Can anyone please help? This is the full code (error is in line 20)
var tree;
function setup() {
noCanvas();
tree = new Tree();
tree.addValue(5);
tree.addValue(3);
console.log(tree);
}
function Tree() {
this.root = null;
}
Tree.prototype.addValue = function (val) {
var n = new Node(val);
if (this.root == null) {
this.root = n;
} else {
this.root.addNode(n);
}
}
Tree.prototype.addNode = function (n) {
if (n.value < this.value)
if (this.left == null) {
this.left = n;
} else {
this.left.addNode(n);
}
} else if (n.value > this.value) {
if (this.right == null) {
this.right = n;
} else {
this.right.addNode(n);
}
}
}
function Node(val) {
this.value = val;
this.left = null;
this.right = null;
}
root is simply a property that you later assign to be a Node. You assign the prototype function addNode to Tree, Node doesn't have that. Either set
this.root = new Tree();
or assign the prototype method addNode to Node instead.
If you are interested, this is how you might implement it using class keyword which handles a lot of manual prototype stuff handling for you so it is a little less error prone.
class Node {
constructor(key) {
this.key = key;
this.left = null;
this.right = null;
}
}
class Tree {
constructor() {
this.root = null;
}
_insert(target, key) {
if (target.key > key) {
if (!target.left) {
target.left = new Node(key);
} else {
this._insert(target.left, key);
}
} else {
if (!target.right) {
target.right = new Node(key);
} else {
this._insert(target.right, key);
}
}
}
insert(key) {
if (!this.root) {
this.root = new Node(key);
} else {
this._insert(this.root, key);
}
}
}

Categories