Learn Simpli

Free Online Tutorial For Programmers, Contains a Solution For Question in Programming. Quizzes and Practice / Company / Test interview Questions.

Binary Search Tree

data structure - binary search tree

Definition:

  1. Is an ordered tree
  2. Is a binary tree where nodes with lesser values are placed to the left of the root node and nodes with equal or greater values are placed to the right
Rules
  1. Rule 1: All child node in the tree to the right of the root node must be greater or equal to the current or left node
  2. “Rule 2: Node can only have at most 2 children
Advantages
  1. Searching the is very easy and fast
Tree Traversal
  1. Pre-order: The node is visited before its children
  2. In order: The left child is visited before the node and then the roght child
  3. Postorder: The left and Right child are visited before the node
Write a code
Now let’s write a code in javascript for the binary search tree
class Node {
    constructor(data) {
        this.left = null;
        this.right = null;
        this.data = data;
    }
}

class BinarySearchTree {
    constructor() {
        this.root = null;
    }
    insert(data) {
        const newNode = new Node(data);
        if (this.root === null) {
            this.root = newNode;
        } else {
            let currentNode = this.root;
            while (true) {
                if (data < currentNode.data) {
                    //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;
                }
            }
        }
    }
    lookup(data) {
        if (!this.root) {
            return false;
        }
        let currentNode = this.root;
        while (currentNode) {
            if (data < currentNode.data) {
                currentNode = currentNode.left;
            } else if (data > currentNode.data) {
                currentNode = currentNode.right;
            } else if (currentNode.data === data) {
                return currentNode;
            }
        }
        return null
    }
    remove(data) {
        if (!this.root) {
            return false;
        }
        let currentNode = this.root;
        let parentNode = null;
        while (currentNode) {
            if (data < currentNode.data) {
                parentNode = currentNode;
                currentNode = currentNode.left;
            } else if (data > currentNode.data) {
                parentNode = currentNode;
                currentNode = currentNode.right;
            } else if (currentNode.data === data) {
                if (currentNode.right === null) {
                    if (parentNode === null) {
                        this.root = currentNode.left;
                    } else {
                        if (currentNode.data < parentNode.data) {
                            parentNode.left = currentNode.left;
                        } else if (currentNode.data > parentNode.data) {
                            parentNode.right = currentNode.left;
                        }
                    }
                } else if (currentNode.right.left === null) {
                    currentNode.right.left = currentNode.left;
                    if (parentNode === null) {
                        this.root = currentNode.right;
                    } else {
                        if (currentNode.data < parentNode.data) {
                            parentNode.left = currentNode.right;
                        } else if (currentNode.data > parentNode.data) {
                            parentNode.right = currentNode.right;
                        }
                    }
                } else {
                    let leftmost = currentNode.right.left;
                    let leftmostParent = currentNode.right;
                    while (leftmost.left !== null) {
                        leftmostParent = leftmost;
                        leftmost = leftmost.left;
                    }
                    leftmostParent.left = leftmost.right;
                    leftmost.left = currentNode.left;
                    leftmost.right = currentNode.right;

                    if (parentNode === null) {
                        this.root = leftmost;
                    } else {
                        if (currentNode.data < parentNode.data) {
                            parentNode.left = leftmost;
                        } else if (currentNode.data > parentNode.data) {
                            parentNode.right = leftmost;
                        }
                    }
                }
                return true;
            }
        }
    }
}

function treeTraversal(node) {
    const tree = { data: node.data };
    tree.left = node.left === null ? null : treeTraversal(node.left);
    tree.right = node.right === null ? null : treeTraversal(node.right);
    return tree;
}

const treeInstance = new BinarySearchTree();
treeInstance.insert(20)
treeInstance.insert(50)
treeInstance.insert(30)
console.log(JSON.stringify(treeTraversal(treeInstance.root)))
treeInstance.remove(30)
console.log(JSON.stringify(treeTraversal(treeInstance.root)))
// Output
// {"data":20,"left":null,"right":{"data":50,"left":{"data":30,"left":null,"right":null},"right":null}}
// {"data":20,"left":null,"right":{"data":50,"left":null,"right":null}}