# Recursive implementation of Binary Tree


class Node:
    def __init__(self, data):
        self.l = None
        self.r = None
        self.val = data


class BinaryTree:
    def __init__(self):
        self.root = None

    def get_root(self):
        return self.root

    def add(self, data):
        if self.root is None:
            self.root = Node(data)
        else:
            self._add(data, self.root)

    def _add(self, data, node):
        if data < node.val:  # Adds smaller val to left child
            if node.l is not None:
                self._add(data, node.l)
            else:
                node.l = Node(data)
        else:
            if node.r is not None:  # Adds bigger val to right child
                self._add(data, node.r)
            else:
                node.r = Node(data)

    def find(self, data):
        if self.root is not None:
            return self._find(data, self.root)
        else:
            return None

    def _find(self, data, node):
        if data is node.val:
            return node
        elif data < node.val and node.l is not None:
            self._find(data, node.l)
        elif data > node.val and node.r is not None:
            self._find(data, node.r)

    def delete_tree(self):
        # garbage collector will do this for us
        self.root = None

    def print_tree(self):
        if self.root is not None:
            self._print_tree(self.root)

    def _print_tree(self, node):
        if node is not None:
            self._print_tree(node.l)
            print(str(node.val) + ' ')
            self._print_tree(node.r)


#     3
# 0     4
#   2      8
tree = BinaryTree()
tree.add(3)
tree.add(4)
tree.add(0)
tree.add(8)
tree.add(2)
tree.print_tree()
#print((tree.find(3)).val)
#print(tree.find(10))
#tree.delete_tree()
#tree.print_tree()

