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.

Updated on: 2026-03-15T23:18:59+05:30

586 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements