GeeksforGeeks App
Open App
Browser
Continue

# Types of Binary Tree

We have discussed Introduction to Binary Tree in set 1 and the Properties of Binary Tree in Set 2. In this post, common types of Binary Trees are discussed.

## Types of Binary Tree based on the number of children:

Following are the types of Binary Tree based on the number of children:

1. Full Binary Tree
2. Degenerate Binary Tree
3. Skewed Binary Trees

### 1. Full Binary Tree

A Binary Tree is a full binary tree if every node has 0 or 2 children. The following are examples of a full binary tree. We can also say a full binary tree is a binary tree in which all nodes except leaf nodes have two children.

A full Binary tree is a special type of binary tree in which every parent node/internal node has either two or no children. It is also known as a proper binary tree.

Full Binary Tree

## C++

 `#include ` `class` `Node {`` ``public``:``  ``int` `value;``  ``Node* left;``  ``Node* right;``  ``Node(``int` `val) : value(val), left(NULL), right(NULL) {}``};` `class` `FullBinaryTree {`` ``public``:``  ``Node* root;``  ``FullBinaryTree() : root(NULL) {}``  ``void` `insert(``int` `value) {``    ``Node* new_node = ``new` `Node(value);``    ``if` `(!root) {``      ``root = new_node;``    ``} ``else` `{``      ``Node* current_node = root;``      ``while` `(``true``) {``        ``if` `(!current_node->left) {``          ``current_node->left = new_node;``          ``break``;``        ``} ``else` `if` `(!current_node->right) {``          ``current_node->right = new_node;``          ``break``;``        ``} ``else` `{``          ``current_node = current_node->left;``        ``}``      ``}``    ``}``  ``}``};` `int` `main() {``  ``FullBinaryTree tree;``  ``tree.insert(1);``  ``tree.insert(2);``  ``tree.insert(3);``  ``tree.insert(4);``  ``return` `0;``}`

## Java

 `// Java Program for the above approach` `class` `Node {``  ``public` `int` `value;``  ``public` `Node left;``  ``public` `Node right;` `  ``public` `Node(``int` `val) {``    ``value = val;``    ``left = ``null``;``    ``right = ``null``;``  ``}``}` `class` `FullBinaryTree {``  ``public` `Node root;` `  ``public` `FullBinaryTree() {``    ``root = ``null``;``  ``}` `  ``public` `void` `insert(``int` `value) {``    ``Node new_node = ``new` `Node(value);``    ``if` `(root == ``null``) {``      ``root = new_node;``    ``} ``else` `{``      ``Node current_node = root;``      ``while` `(``true``) {``        ``if` `(current_node.left == ``null``) {``          ``current_node.left = new_node;``          ``break``;``        ``} ``else` `if` `(current_node.right == ``null``) {``          ``current_node.right = new_node;``          ``break``;``        ``} ``else` `{``          ``current_node = current_node.left;``        ``}``      ``}``    ``}``  ``}``}` `class` `Main {``  ``public` `static` `void` `main(String[] args) {``    ``FullBinaryTree tree = ``new` `FullBinaryTree();``    ``tree.insert(``1``);``    ``tree.insert(``2``);``    ``tree.insert(``3``);``    ``tree.insert(``4``);``  ``}``}` `// This code is contributed by codebraxnzt`

## Python3

 `# Node class representing a node in a binary tree``class` `Node:``    ``def` `__init__(``self``, val):``        ``self``.value ``=` `val``        ``self``.left ``=` `None``        ``self``.right ``=` `None` `# FullBinaryTree class representing a full binary tree``class` `FullBinaryTree:``    ``def` `__init__(``self``):``        ``self``.root ``=` `None` `    ``# Method to insert a new node with the given value into the tree``    ``def` `insert(``self``, value):``        ``newNode ``=` `Node(value)``        ``if` `not` `self``.root:``            ``self``.root ``=` `newNode``        ``else``:``            ``currentNode ``=` `self``.root``            ``while` `True``:``                ``if` `not` `currentNode.left:``                    ``currentNode.left ``=` `newNode``                    ``break``                ``elif` `not` `currentNode.right:``                    ``currentNode.right ``=` `newNode``                    ``break``                ``else``:``                    ``currentNode ``=` `currentNode.left` `# Main function``tree ``=` `FullBinaryTree()``tree.insert(``1``)``tree.insert(``2``)``tree.insert(``3``)``tree.insert(``4``)`

## C#

 `using` `System;` `// Node class representing a node in a binary tree``public` `class` `Node {``    ``public` `int` `value;``    ``public` `Node left;``    ``public` `Node right;` `    ``public` `Node(``int` `val)``    ``{``        ``value = val;``        ``left = ``null``;``        ``right = ``null``;``    ``}``}` `// FullBinaryTree class representing a full binary tree``public` `class` `FullBinaryTree {``    ``public` `Node root;` `    ``// Method to insert a new node with the given value into``    ``// the tree``    ``public` `void` `Insert(``int` `value)``    ``{``        ``Node newNode = ``new` `Node(value);``        ``if` `(root == ``null``) {``            ``root = newNode;``        ``}``        ``else` `{``            ``Node currentNode = root;``            ``while` `(``true``) {``                ``if` `(currentNode.left == ``null``) {``                    ``currentNode.left = newNode;``                    ``break``;``                ``}``                ``else` `if` `(currentNode.right == ``null``) {``                    ``currentNode.right = newNode;``                    ``break``;``                ``}``                ``else` `{``                    ``currentNode = currentNode.left;``                ``}``            ``}``        ``}``    ``}``}` `// Main function``class` `Program {``    ``static` `void` `Main(``string``[] args)``    ``{``        ``FullBinaryTree tree = ``new` `FullBinaryTree();``        ``tree.Insert(1);``        ``tree.Insert(2);``        ``tree.Insert(3);``        ``tree.Insert(4);``    ``}``}`

## Javascript

 `// Node class representing a node in a binary tree``class Node {``  ``constructor(val) {``    ``this``.value = val;``    ``this``.left = ``null``;``    ``this``.right = ``null``;``  ``}``}` `// FullBinaryTree class representing a full binary tree``class FullBinaryTree {``  ``constructor() {``    ``this``.root = ``null``;``  ``}` `  ``// Method to insert a new node with the given value into the tree``  ``insert(value) {``    ``const newNode = ``new` `Node(value);``    ``if` `(!``this``.root) {``      ``this``.root = newNode;``    ``} ``else` `{``      ``let currentNode = ``this``.root;``      ``while` `(``true``) {``        ``if` `(!currentNode.left) {``          ``currentNode.left = newNode;``          ``break``;``        ``} ``else` `if` `(!currentNode.right) {``          ``currentNode.right = newNode;``          ``break``;``        ``} ``else` `{``          ``currentNode = currentNode.left;``        ``}``      ``}``    ``}``  ``}``}` `// Main function``const tree = ``new` `FullBinaryTree();``tree.insert(1);``tree.insert(2);``tree.insert(3);``tree.insert(4);`

### 2. Degenerate (or pathological) tree

A Tree where every internal node has one child. Such trees are performance-wise same as linked list. A degenerate or pathological tree is a tree having a single child either left or right.

Degenerate (or pathological) tree

## C++

 `#include ``#include ` `class` `Node {`` ``public``:``  ``int` `value;``  ``Node* next;``  ``Node(``int` `val) : value(val), next(NULL) {}``};` `class` `DegenerateTree {`` ``public``:``  ``std::vector nodes;``  ``DegenerateTree() {}``  ``void` `insert(``int` `value) {``    ``Node* new_node = ``new` `Node(value);``    ``if` `(nodes.empty()) {``      ``nodes.push_back(new_node);``    ``} ``else` `{``      ``Node* last_node = nodes.back();``      ``last_node->next = new_node;``      ``nodes.push_back(new_node);``    ``}``  ``}``};` `int` `main() {``  ``DegenerateTree tree;``  ``tree.insert(1);``  ``tree.insert(2);``  ``tree.insert(3);``  ``tree.insert(4);``  ``return` `0;``}`

## Java

 `import` `java.util.ArrayList;``import` `java.util.List;``// Node class to represent a node in the tree``class` `Node {``    ``int` `value; ``// value of the node``    ``Node next; ``// reference to the next node` `    ``// constructor to initialize the node``    ``public` `Node(``int` `val)``    ``{``        ``value = val;``        ``next = ``null``;``    ``}``}` `// DegenerateTree class to represent a degenerate tree``class` `DegenerateTree {``    ``List nodes; ``// list of nodes in the tree` `    ``// constructor to initialize the tree``    ``public` `DegenerateTree() { nodes = ``new` `ArrayList<>(); }` `    ``// method to insert a new node into the tree``    ``public` `void` `insert(``int` `value)``    ``{``        ``Node newNode``            ``= ``new` `Node(value); ``// create a new node with the``                               ``// given value` `        ``if` `(nodes.isEmpty()) { ``// if the list is empty, add``                               ``// the new node as the first``                               ``// node``            ``nodes.add(newNode);``        ``}``        ``else` `{ ``// otherwise, add the new node as the next``               ``// node of the last node in the list``            ``Node lastNode = nodes.get(nodes.size() - ``1``);``            ``lastNode.next = newNode;``            ``nodes.add(newNode);``        ``}``    ``}``}` `// Main class to test the DegenerateTree class``public` `class` `Main {``    ``public` `static` `void` `main(String[] args)``    ``{``        ``DegenerateTree tree``            ``= ``new` `DegenerateTree(); ``// create a new``                                    ``// degenerate tree` `        ``// insert some values into the tree``        ``tree.insert(``1``);``        ``tree.insert(``2``);``        ``tree.insert(``3``);``        ``tree.insert(``4``);``    ``}``}`

## Python3

 `class` `Node:``    ``def` `__init__(``self``, val):``        ``self``.value ``=` `val``        ``self``.``next` `=` `None` `class` `DegenerateTree:``    ``def` `__init__(``self``):``        ``self``.nodes ``=` `[]` `    ``def` `insert(``self``, value):``        ``new_node ``=` `Node(value)``        ``if` `not` `self``.nodes:``            ``self``.nodes.append(new_node)``        ``else``:``            ``last_node ``=` `self``.nodes[``-``1``]``            ``last_node.``next` `=` `new_node``            ``self``.nodes.append(new_node)` `# Driver code``if` `__name__ ``=``=` `'__main__'``:``    ``tree ``=` `DegenerateTree()``    ``tree.insert(``1``)``    ``tree.insert(``2``)``    ``tree.insert(``3``)``    ``tree.insert(``4``)`

### 3. Skewed Binary Tree

A skewed binary tree is a pathological/degenerate tree in which the tree is either dominated by the left nodes or the right nodes. Thus, there are two types of skewed binary tree: left-skewed binary tree and right-skewed binary tree.

Skewed Binary Tree

## C++

 `#include ` `class` `Node {`` ``public``:``  ``int` `value;``  ``Node* right;``  ``Node(``int` `val) : value(val), right(NULL) {}``};` `class` `SkewedTree {`` ``public``:``  ``Node* root;``  ``SkewedTree() : root(NULL) {}``  ``void` `insert(``int` `value) {``    ``Node* new_node = ``new` `Node(value);``    ``if` `(!root) {``      ``root = new_node;``    ``} ``else` `{``      ``Node* current_node = root;``      ``while` `(current_node->right) {``        ``current_node = current_node->right;``      ``}``      ``current_node->right = new_node;``    ``}``  ``}``};` `int` `main() {``  ``SkewedTree tree;``  ``tree.insert(1);``  ``tree.insert(2);``  ``tree.insert(3);``  ``tree.insert(4);``  ``return` `0;``}`

## Types of Binary Tree On the basis of the completion of levels:

1. Complete Binary Tree
2. Perfect Binary Tree
3. Balanced Binary Tree

### 1. Complete Binary Tree

A Binary Tree is a Complete Binary Tree if all the levels are completely filled except possibly the last level and the last level has all keys as left as possible.

A complete binary tree is just like a full binary tree, but with two major differences:

• Every level must be completely filled
• All the leaf elements must lean towards the left.
• The last leaf element might not have a right sibling i.e. a complete binary tree doesn’t have to be a full binary tree.

Complete Binary Tree

### 2. Perfect Binary Tree

A Binary tree is a Perfect Binary Tree in which all the internal nodes have two children and all leaf nodes are at the same level.
The following are examples of Perfect Binary Trees.

A perfect binary tree is a type of binary tree in which every internal node has exactly two child nodes and all the leaf nodes are at the same level.

Perfect Binary Tree

In a Perfect Binary Tree, the number of leaf nodes is the number of internal nodes plus 1

L = I + 1 Where L = Number of leaf nodes, I = Number of internal nodes.

A Perfect Binary Tree of height h (where the height of the binary tree is the number of edges in the longest path from the root node to any leaf node in the tree, height of root node is 0) has 2h+1 – 1 node.
An example of a Perfect binary tree is ancestors in the family. Keep a person at root, parents as children, parents of parents as their children.

### 3. Balanced Binary Tree

A binary tree is balanced if the height of the tree is O(Log n) where n is the number of nodes. For Example, the AVL tree maintains O(Log n) height by making sure that the difference between the heights of the left and right subtrees is at most 1. Red-Black trees maintain O(Log n) height by making sure that the number of Black nodes on every root to leaf paths is the same and that there are no adjacent red nodes. Balanced Binary Search trees are performance-wise good as they provide O(log n) time for search, insert and delete.

Example of Balanced and Unbalanced Binary Tree

It is a type of binary tree in which the difference between the height of the left and the right subtree for each node is either 0 or 1. In the figure above, the root node having a value 0 is unbalanced with a depth of 2 units.

## Some Special Types of Trees:

On the basis of node values, the Binary Tree can be classified into the following special types:

1. Binary Search Tree
2. AVL Tree
3. Red Black Tree
4. B Tree
5. B+ Tree
6. Segment Tree

Below Image Shows Important Special cases of binary Trees:

Binary Tree Special cases

### 1. Binary Search Tree

Binary Search Tree is a node-based binary tree data structure that has the following properties:

• The left subtree of a node contains only nodes with keys lesser than the node’s key.
• The right subtree of a node contains only nodes with keys greater than the node’s key.
• The left and right subtree each must also be a binary search tree.

Binary Search Tree

### 2. AVL Tree

AVL tree is a self-balancing Binary Search Tree (BST) where the difference between heights of left and right subtrees cannot be more than one for all nodes.

Example of AVL Tree shown below:
The below tree is AVL because the differences between the heights of left and right subtrees for every node are less than or equal to 1

AVL Tree

### 3. Red Black Tree

A red-black tree is a kind of self-balancing binary search tree where each node has an extra bit, and that bit is often interpreted as the color (red or black). These colors are used to ensure that the tree remains balanced during insertions and deletions. Although the balance of the tree is not perfect, it is good enough to reduce the searching time and maintain it around O(log n) time, where n is the total number of elements in the tree. This tree was invented in 1972 by Rudolf Bayer.

Red Black Tree

### 4. B – Tree

A B-tree is a type of self-balancing tree data structure that allows efficient access, insertion, and deletion of data items. B-trees are commonly used in databases and file systems, where they can efficiently store and retrieve large amounts of data. A B-tree is characterized by a fixed maximum degree (or order), which determines the maximum number of child nodes that a parent node can have. Each node in a B-tree can have multiple child nodes and multiple keys, and the keys are used to index and locate data items.

### 5. B+ Tree

A B+ tree is a variation of the B-tree that is optimized for use in file systems and databases. Like a B-tree, a B+ tree also has a fixed maximum degree and allows efficient access, insertion, and deletion of data items. However, in a B+ tree, all data items are stored in the leaf nodes, while the internal nodes only contain keys for indexing and locating the data items. This design allows for faster searches and sequential access of the data items, as all the leaf nodes are linked together in a linked list.