Skip to content

Latest commit

 

History

History
132 lines (110 loc) · 4.55 KB

bst_implementation.md

File metadata and controls

132 lines (110 loc) · 4.55 KB

BST implementation

A node is said to be a BST node if and only if it satisfies the BST property:

  • its value is greater than all the node values to its left;
  • its values is less than the values of every node to its right,
  • and all its children nodes are either BST nodes themselves or null values.

The BST should support insertion, searching and removal of values. The removal method should only remove the first instance of the target value.

class BST:
    """
    We'll use the iterative approach (due to constant space).
    Recursive approach creates a call stack in memory -> O(n) space.
    """

    def __init__(self, value: int):
        self.value = value
        self.left = None
        self.right = None

    def insert(self, value: int):
        """Average Case: O(log(N)) time | O(1) space
        Worst Case: (Where the tree is unbalanced 
        and has only one branch to the left)
            O(n) time, where n = number of nodes in the tree
            O(1) space
        """
        current_node = self
        while True:
            if value < current_node.value:
                if current_node.left is None:
                    current_node.left = BST(value)
                    break
                else:
                    current_node = current_node.left
            else:
                # value is greater than current node's value
                if current_node.right is None:
                    current_node.right = BST(value)
                    break
                else:
                    current_node = current_node.right
        return self

    def contains(self, value):
        """Average Case: O(log(N)) time |  O(1) space
        Worst Case: O(n) time | O(1) space
        """
        current_node = self
        while current_node is not None:
            if value < current_node.value:
                current_node = current_node.left
            elif value > current_node.value:
                current_node = current_node.right
            else:
                # found it!
                return True
        return False

    def remove(self, value, parent_node=None):
        """Average Case: O(log(N)) time | O(1) space
        Worst Case: O(n) time, O(1) space
        """
        current_node = self
        while current_node is not None:
            if value < current_node.value:
                parent_node = current_node
                current_node = current_node.left
            elif value > current_node.value:
                parent_node = current_node
                current_node = current_node.right
            else:
                # we've found the node, time to delete it
                if current_node.left is not None and current_node.right is not None:
                    # set current node value = smallest value of right subtree.
                    current_node.value = current_node.right.get_min_value()
                    current_node.right.remove(current_node.value, current_node)
                elif parent_node is None:
                    # if we are removing the root node (it does not have a parent node)
                    if current_node.left is not None:
                        current_node.value = current_node.left.value
                        current_node.right = current_node.left.right
                        current_node.left = current_node.left.left
                    elif current_node.right is not None:
                        current_node.value = current_node.right.value
                        current_node.left = current_node.right.left
                        current_node.right = current_node.right.right
                    else:
                        # no child nodes exist for this BST, so do nothing
                        pass
                elif parent_node.left == current_node:
                    parent_node.left = (
                        current_node.left if current_node.left is not None else
                        current_node.right)
                elif parent_node.right == current_node:
                    parent_node.right = (
                        current_node.left if current_node.left is not None else
                        current_node.right)
                break
        return self

    def get_min_value(self):
        """Finds the smallest value in a sub-tree."""
        current_node = self
        while current_node.left is not None:
            current_node = current_node.left
        return current_node.value
bst = BST(10).insert(5).insert(15).insert(
        7).insert(2).insert(14).insert(22)

bst.contains(22)
True