Data Structure Unit-5-Tree-Data-Structure
Data Structure Unit-5-Tree-Data-Structure
A tree is also one of the data structures that represent hierarchical data. Suppose we want
to show the employees and their positions in the hierarchical form then it can be
represented as shown below:
The above tree shows the organization hierarchy of some company. In the above
structure, john is the CEO of the company, and John has two direct reports named
as Steve and Rohan. Steve has three direct reports named Lee, Bob, Ella where Steve is
a manager. Bob has two direct reports named Sal and Emma. Emma has two direct
reports named Tom and Raj. Tom has one direct report named Bill. This particular logical
structure is known as a Tree. Its structure is similar to the real tree, so it is named a Tree.
In this structure, the root is at the top, and its branches are moving in a downward
direction. Therefore, we can say that the Tree data structure is an efficient way of storing
the data in a hierarchical way.
In the above structure, each node is labeled with some number. Each arrow shown in the
above figure is known as a link between the two nodes.
o Root: The root node is the topmost node in the tree hierarchy. In other words, the
root node is the one that doesn't have any parent. In the above structure, node
numbered 1 is the root node of the tree. If a node is directly linked to some other
node, it would be called a parent-child relationship.
o Child node: If the node is a descendant of any node, then the node is known as a
child node.
o Parent: If the node contains any sub-node, then that node is said to be the parent
of that sub-node.
o Sibling: The nodes that have the same parent are known as siblings.
o Leaf Node:- The node of the tree, which doesn't have any child node, is called a
leaf node. A leaf node is the bottom-most node of the tree. There can be any
number of leaf nodes present in a general tree. Leaf nodes can also be called
external nodes.
o Internal nodes: A node has atleast one child node known as an internal
o Ancestor node:- An ancestor of a node is any predecessor node on a path from
the root to that node. The root node doesn't have any ancestors. In the tree shown
in the above image, nodes 1, 2, and 5 are the ancestors of node 10.
o Descendant: The immediate successor of the given node is known as a descendant
of a node. In the above figure, 10 is the descendant of node 5.
o Number of edges: If there are n nodes, then there would n-1 edges. Each arrow
in the structure represents the link or path. Each node, except the root node, will
have atleast one incoming link known as an edge. There would be one link for the
parent-child relationship.
o Depth of node x: The depth of node x can be defined as the length of the path
from the root to the node x. One edge contributes one-unit length in the path. So,
the depth of node x can also be defined as the number of edges between the root
node and the node x. The root node has 0 depth.
o Height of node x: The height of node x can be defined as the longest path from
the node x to the leaf node.
Based on the properties of the Tree data structure, trees are classified into various
categories.
Implementation of Tree
The tree data structure can be created by creating the nodes dynamically with the help of
the pointers. The tree in the memory can be represented as shown below:
The above figure shows the representation of the tree data structure in the memory. In
the above structure, the node contains three fields. The second field stores the data; the
first field stores the address of the left child, and the third field stores the address of the
right child.
The above structure can only be defined for the binary trees because the binary tree can
have utmost two children, and generic trees can have more than two children. The
structure of the node for generic trees would be different as compared to the binary tree.
Applications of trees
The following are the applications of trees:
o Storing naturally hierarchical data: Trees are used to store the data in the
hierarchical structure. For example, the file system. The file system stored on the
disc drive, the file and folder are in the form of the naturally hierarchical data and
stored in the form of trees.
o Organize data: It is used to organize data for efficient insertion, deletion and
searching. For example, a binary tree has a logN time for searching an element.
o Trie: It is a special kind of tree that is used to store the dictionary. It is a fast and
efficient way for dynamic spell checking.
o Heap: It is also a tree data structure implemented using arrays. It is used to
implement priority queues.
o B-Tree and B+Tree: B-Tree and B+Tree are the tree data structures used to
implement indexing in databases.
o Routing table: The tree data structure is also used to store the data in routing
tables in the routers.
o There can be n number of subtrees in a general tree. In the general tree, the
subtrees are unordered as the nodes in the subtree cannot be ordered.
Every non-empty tree has a downward edge, and these edges are connected to
the nodes known as child nodes. The root node is labeled with level 0. The nodes
that have the same parent are known as siblings.
o Binary tree: Here, binary name itself suggests two numbers, i.e., 0 and 1. In a binary
tree, each node in a tree can have utmost two child nodes. Here, utmost means
whether the node has 0 nodes, 1 node or 2 nodes.
Binary Search tree: Binary search tree is a non-linear data structure in which one
node is connected to n number of nodes. It is a node-based data structure. A node
can be represented in a binary search tree with three fields, i.e., data part, left-child,
and right-child. A node can be connected to the utmost two child nodes in a binary
search tree, so the node contains two pointers (left child and right child pointer).
Every node in the left subtree must contain a value less than the value of the root
node, and the value of each node in the right subtree must be bigger than the
value of the root node.
A node can be created with the help of a user-defined data type known as struct, as
shown below:
struct node
{
int data;
struct node *left;
struct node *right;
}
The above is the node structure with three fields: data field, the second field is the left
pointer of the node type, and the third field is the right pointer of the node type.
Binary Tree
The Binary tree means that the node can have maximum two children. Here, binary name
itself suggests that 'two'; therefore, each node can have either 0, 1 or 2 children.
Let's understand the binary tree through an example.
The above tree is a binary tree because each node contains the utmost two children. The
logical representation of the above tree is given below:
In the above tree, node 1 contains two pointers, i.e., left and a right pointer pointing to
the left and right node respectively. The node 2 contains both the nodes (left and right
node); therefore, it has two pointers (left and right). The nodes 3, 5 and 6 are the leaf
nodes, so all these nodes contain NULL pointer on both left and right parts.
In the above tree, we can observe that each node is either containing zero or two children;
therefore, it is a Full Binary tree.
Properties of Full Binary Tree
o The number of leaf nodes is equal to the number of internal nodes plus 1. In the
above example, the number of internal nodes is 5; therefore, the number of leaf
nodes is equal to 6.
o The maximum number of nodes is the same as the number of nodes in the binary
tree, i.e., 2h+1 -1.
o The minimum number of nodes in the full binary tree is 2*h-1.
o The minimum height of the full binary tree is log2(n+1) - 1.
o The maximum height of the full binary tree can be computed as:
n= 2*h - 1
n+1 = 2*h
h = n+1/2
The above tree is a complete binary tree because all the nodes are completely filled, and
all the nodes in the last level are added at the left first.
Note: All the perfect binary trees are the complete binary trees as well as the full binary tree, but vice
versa is not true, i.e., all complete binary trees and full binary trees are the perfect binary trees.
The above tree is also a degenerate binary tree because all the nodes have only one child.
It is also known as a left-skewed tree as all the nodes have a left child only.
The above tree is not a balanced binary tree because the difference between the left
subtree and the right subtree is greater than 1.
#include <iostream>
using namespace std;
struct Node {
int data;
Node *left;
Node *right;
};
Node* create(int item)
{
Node* node = new Node;
node->data = item;
node->left = node->right = NULL;
return node;
}
/*Inorder traversal of the tree formed*/
void inorder(Node *root)
{
if (root == NULL)
return;
inorder(root->left); //traverse left subtree
cout<< root->data << " "; //traverse root node
inorder(root->right); //traverse right subtree
}
Node* findMinimum(Node* cur) /*To find the inorder successor*/
{
while(cur->left != NULL) {
cur = cur->left;
}
return cur;
}
Node* insertion(Node* root, int item) /*Insert a node*/
{
if (root == NULL)
return create(item); /*return new node if tree is empty*/
if (item < root->data)
root->left = insertion(root->left, item);
else
root->right = insertion(root->right, item);
return root;
}
void search(Node* &cur, int item, Node* &parent)
{
while (cur != NULL && cur->data != item)
{
parent = cur;
if (item < cur->data)
cur = cur->left;
else
cur = cur->right;
}
}
void deletion(Node*& root, int item) /*function to delete a node*/
{
Node* parent = NULL;
Node* cur = root;
search(cur, item, parent); /*find the node to be deleted*/
if (cur == NULL)
return;
if (cur->left == NULL && cur->right == NULL) /*When node has no children*/
{
if (cur != root)
{
if (parent->left == cur)
parent->left = NULL;
else
parent->right = NULL;
}
else
root = NULL;
free(cur);
}
else if (cur->left && cur->right)
{
Node* succ = findMinimum(cur->right);
int val = succ->data;
deletion(root, succ->data);
cur->data = val;
}
else
{
Node* child = (cur->left)? cur->left: cur->right;
if (cur != root)
{
if (cur == parent->left)
parent->left = child;
else
parent->right = child;
}
else
root = child;
free(cur);
}
}
int main()
{
Node* root = NULL;
root = insertion(root, 45);
root = insertion(root, 30);
root = insertion(root, 50);
root = insertion(root, 25);
root = insertion(root, 35);
root = insertion(root, 45);
root = insertion(root, 60);
root = insertion(root, 4);
printf("The inorder traversal of the given binary tree is - \n");
inorder(root);
deletion(root, 25);
printf("\nAfter deleting node 25, the inorder traversal of the given binary tree is - \n
");
inorder(root);
insertion(root, 2);
printf("\nAfter inserting node 2, the inorder traversal of the given binary tree is - \n"
);
inorder(root);
return 0;
}
Output
After the execution of the above code, the output will be -