# Binary Tree

Data Structures: Binary Tree Data Structure

## The Definition of a Binary Tree​

Creating a Binary tree data structure usually involves first defining the basic building block: the node. Then you define the tree itself and its methods. Here's a step-by-step guide to create a simple binary tree in JavaScript:

## Binary Tree Creation Instructions​

### 1. Define the Node​

The node will have a `value`, a reference to the left child (`left`), and a reference to the right child (`right`).

``class TreeNode {    constructor(value) {        this.value = value;        this.left = null;        this.right = null;    }}``

### 2. Define the Binary Tree​

For simplicity, this tree will have methods to insert and check for a value.

``class BinaryTree {    constructor() {        this.root = null;    }    // Add a method to insert a value    insert(value) {        const newNode = new TreeNode(value);        if (!this.root) {            this.root = newNode;            return;        }        let current = this.root;        while (true) {            if (value < current.value) {                if (!current.left) {                    current.left = newNode;                    return;                }                current = current.left;            } else {                if (!current.right) {                    current.right = newNode;                    return;                }                current = current.right;            }        }    }    // Add a method to check if the tree contains a value    contains(value) {        let current = this.root;        while (current) {            if (value === current.value) {                return true;            }            if (value < current.value) {                current = current.left;            } else {                current = current.right;            }        }        return false;    }}``

### 3. Use the Binary Tree​

With the binary tree now defined, you can create an instance of it and use its methods.

``const myTree = new BinaryTree();myTree.insert(10);myTree.insert(5);myTree.insert(20);myTree.insert(3);myTree.insert(7);console.log(myTree.contains(7));  // trueconsole.log(myTree.contains(25)); // false``

### 4. Optional Enhancements​

• Traversal Methods: You can add methods to traverse the tree in different orders: in-order, pre-order, post-order, level-order, etc.
• Balancing: For performance reasons, binary trees might be balanced. Balancing ensures that the tree remains efficient for operations like add, delete, and find. Balanced trees like AVL trees or Red-Black trees have additional rules and rotations to keep the tree balanced.
• Deletion: Implement a method to remove a node from the tree.

Note: Remember, the tree structure mentioned above is a binary search tree (BST) where for each node, all elements in the left subtree are less than the node and all the elements in the right subtree are greater than the node. Trees can have many variations, and based on use-cases, you might need different types of trees or methods.

### 5. Enhancements for Balanced Trees​

For a more efficient tree in terms of operations, consider implementing self-balancing trees such as:

AVL Trees: These trees perform rotations to ensure that the tree remains balanced after every insert or delete operation.

Red-Black Trees: These trees maintain balance by coloring each node either red or black and ensuring that a few structural properties are maintained after every insert or delete operation.

The provided steps offer a basic overview of binary tree creation in JavaScript. Depending on your needs, you might want to expand upon this foundation with advanced features and optimization techniques.

### Complexity​

A binary tree is a tree data structure in which each node has at most two children, typically distinguished as "left" and "right". Unlike a binary search tree, there's no specific order among the sibling nodes.

Here's a table for the time and space complexities of common operations on a binary tree:

OperationAverage Time ComplexityWorst Case Time ComplexitySpace Complexity
InsertionO(1)*O(1)*O(1)
DeletionO(n)O(n)O(n)
SearchO(n)O(n)O(n)
Traversal (in, pre, post, level)O(n)O(n)O(n)
Maximum DepthO(n)O(n)O(n)

Notes:

1. Insertion: This assumes you know where you're inserting, e.g., in a complete binary tree where you insert at the next available position. Otherwise, the insertion position might need to be located first.

2. Deletion: This complexity arises because you need to search for the node to be deleted. Post finding, the deletion itself is O(1), but replacing the deleted node (if not a leaf) requires more operations.

3. Search: You might need to traverse all nodes in the worst case, thus O(n).

4. Traversal: Whether you're doing an inorder, preorder, postorder, or level order (breadth-first) traversal, you'll touch each node once.

5. Maximum Depth: This requires traversing down from the root to each leaf, thus O(n) in the worst case.

For Space Complexity, operations that require a stack or a queue, such as traversals or the maximum depth calculation (in the case of recursive implementations), will use space proportional to the height or breadth of the tree. In the worst case, where the tree is completely unbalanced and resembles a linked list, the height could be n, making the space complexity O(n).

It's worth mentioning that for balanced binary trees, the height is O(log n), and some operations can be more efficient. However, since this is a general binary tree without any balance guarantees, we consider the worst case.