Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Searching for values in an Javascript Binary Search Tree
We're going to use the property of a BST to look up elements in it. In a Binary Search Tree, values smaller than the current node are in the left subtree, and values larger are in the right subtree, making search operations efficient.
Iterative Search Implementation
The iterative approach uses a loop to traverse the tree:
searchIter(data) {
let currNode = this.root;
while (currNode !== null) {
if (currNode.data === data) {
// Found the element!
return true;
} else if (data < currNode.data) {
// Go Left as data is smaller than parent
currNode = currNode.left;
} else {
// Go right as data is greater than parent
currNode = currNode.right;
}
}
return false;
}
In this function, we start with the root as currNode and check our data compared to the currNode's data. If we find a match we return true, else we continue to iterate in either left or right according to data's relation to currNode's data till we either reach a leaf or find our element.
Testing Iterative Search
// Assuming BinarySearchTree class and insertIter method exist
class Node {
constructor(data) {
this.data = data;
this.left = null;
this.right = null;
}
}
class BinarySearchTree {
constructor() {
this.root = null;
}
insertIter(data) {
const newNode = new Node(data);
if (this.root === null) {
this.root = newNode;
return;
}
let currNode = this.root;
while (true) {
if (data < currNode.data) {
if (currNode.left === null) {
currNode.left = newNode;
break;
}
currNode = currNode.left;
} else {
if (currNode.right === null) {
currNode.right = newNode;
break;
}
currNode = currNode.right;
}
}
}
searchIter(data) {
let currNode = this.root;
while (currNode !== null) {
if (currNode.data === data) {
return true;
} else if (data < currNode.data) {
currNode = currNode.left;
} else {
currNode = currNode.right;
}
}
return false;
}
}
let BST = new BinarySearchTree();
BST.insertIter(10);
BST.insertIter(15);
BST.insertIter(5);
BST.insertIter(50);
BST.insertIter(3);
BST.insertIter(7);
BST.insertIter(12);
console.log(BST.searchIter(2));
console.log(BST.searchIter(12));
console.log(BST.searchIter(50));
console.log(BST.searchIter(-22));
console.log(BST.searchIter(200));
false true true false false
Recursive Search Implementation
Similar to the insert function, the search can be implemented recursively as well:
searchRec(data) {
return searchRecHelper(data, this.root);
}
Again, we're going to need to create a helper function that we don't want as a part of the class, so we'll create this function outside of class definition:
function searchRecHelper(data, root) {
if (root === null) {
// Reached leaf but didn't find it.
return false;
}
if (data < root.data) {
return searchRecHelper(data, root.left);
} else if (data > root.data) {
return searchRecHelper(data, root.right);
}
// This means element is found
return true;
}
Testing Recursive Search
function searchRecHelper(data, root) {
if (root === null) {
return false;
}
if (data < root.data) {
return searchRecHelper(data, root.left);
} else if (data > root.data) {
return searchRecHelper(data, root.right);
}
return true;
}
// Add recursive search to our BST class
BinarySearchTree.prototype.searchRec = function(data) {
return searchRecHelper(data, this.root);
};
let BST2 = new BinarySearchTree();
BST2.insertIter(10);
BST2.insertIter(15);
BST2.insertIter(5);
BST2.insertIter(50);
BST2.insertIter(3);
BST2.insertIter(7);
BST2.insertIter(12);
console.log(BST2.searchRec(2));
console.log(BST2.searchRec(12));
console.log(BST2.searchRec(50));
console.log(BST2.searchRec(-22));
console.log(BST2.searchRec(200));
false true true false false
Time Complexity
Both iterative and recursive search operations have O(log n) time complexity in a balanced BST, where n is the number of nodes. In the worst case of a completely unbalanced tree, it becomes O(n).
Conclusion
Binary Search Tree search operations leverage the BST property for efficient lookups. Both iterative and recursive approaches work equally well, with iterative using less memory and recursive being more intuitive to understand.
