Data Structures: Binary Trees

Download as pdf or txt
Download as pdf or txt
You are on page 1of 26

CS-2001 Data Structures

Binary Trees
Topics
• Binary trees
– properties
– Full Binary Tree
– Complete Binary Tree
• Binary Search Trees
– operations and applications
– skewness and issues
• Multi-way Trees/Tries
Tree Data Structure
• A tree is a non linear data structure that simulates a hierarchical
tree structure with a root value and sub trees of children with parent
node, represented as set of linked nodes.

• Root – Root is a special node in a tree. The entire tree is referenced


through it. It does not have a parent.
• Parent Node – Parent node is an immediate predecessor of a node.
• Child Node – All immediate successors of a node are its children.
• Siblings – Nodes with the same parent are called Siblings.
• Leaf – Last node in the tree. There is no node after this node.
• Edge – Edge is a connection between one node to another. It is a
line between two nodes or a node and a leaf.
• Path – Path is a number of successive edges from source node to
destination node.
Terminologies
Examples of trees
Tree Properties
• Tree can be termed as a RECURSIVE data structure.
• In a valid tree for N Nodes we have N-1
Edges/Links
• Depth of Node – Depth of a node represents the
number of edges from the tree’s root node to the node.
• Height of Node – Height of a node is the number of
edges on the longest path between that node & a leaf.
• Height of Tree – Height of tree represents the height
of its root node.
Binary Tree
• A binary tree is a tree data structure in which each node has at
most two children, which are referred to as the left
child(LC) and the right child(RC).
• Binary Tree Terms & Properties
– A binary tree is called STRICT/PROPER/Full binary tree when each
node has 2 or 0 children.
– A binary tree is called COMPLETE binary tree if all levels except the
last are completely filled and all nodes are as left as possible.
– Max number of nodes at a given level ‘x’ = 2^x
– For a binary tree, maximum number of nodes with height ‘h’ =
2^(h+1) – 1
– A binary tree is called BALANCE binary tree, if the difference
between the height of left subtree and right subtree for every node is
not more than k(usually k=1)
Binary SEARCH Tree (BST)
Binary search tree (BST) is a binary tree data structure, in which the values
in the left sub-trees of every node are smaller and the values in the right
sub-trees of every node are larger.
• bool isTreeEmpty() check if empty
• void insertNode(TreeNode *new_node) insertion
• depth first traversal approach
– void printPreorder (TreeNode* r) print & traverse
– void printInorder (TreeNode* r) print & traverse
– void printPostorder (TreeNode* r) print & traverse
– void print2D(TreeNode *r, int space) print & traverse
• breadth first traversal approach
– void printLevelOrder (TreeNode *r) print & traverse
– TreeNode* search(TreeNode* r, int v) search
• TreeNode* minValueNode(TreeNode node) delete
• TreeNode* deleteNode(TreeNode* r, int v) delete
Insertion Operation
void insertnode(new_node)
if root == null then root = new_node
else
set temp=root
while temp != null
if new node.value == temp.value
then return // no duplicates allowed
else if (new_node.value < temp.value) && (temp.left == null)
then temp.left = new_node // value inserted on left
break // get out of the function
else if (new node.value < temp.value)
then temp = temp. left
else if (new_node.value > temp.value) && (temp.right == null)
then temp.right = new_node // value inserted on right
break // get out of the function,
else temp = temp.right
end while
end if
Add new node in BST using
Recursion
// Recursive function to insert a new node in the BST
Node* insert(Node* root, int key) {
// If the tree is empty, return a new node
if (root == nullptr) {
return new Node(key);
}
// Check for duplicates
if (key == root->key) {
return root;
// No duplicates allowed
}
// Otherwise, recur down the tree
if (key < root->key) {
root->left = insert(root->left, key);
}
else { root->right = insert(
root->right, key);
}
// Return the (unchanged) node pointer
return root;
}
Traversal Techniques
• Tree traversal also known as tree search and walking the tree refers to the
process of visiting (checking and/or updating each node in a tree data
structure, exactly once. Such traversals are classified by the order in which the
nodes are visited.
• Depth-first search/traversal (DFS) These searches are referred to as
depth-first search (DFS), since the search tree is deepened as much as possible
on each child before going to the next sibling.
– Pre-order (NLR)
– In-order (LNR)
– Post-order (LRN)
• Breadth-first search/traversal (BFS) Trees can also be traversed in
level-order, where we visit every node on a level before going to a
lower level. This search is referred to as breadth-first search (BFS), as
the search tree is broadened as much as possible on each depth before
going to the next depth.
Pre-order (NLR) (node - left-right)
• Access the data part of the current node.
• Traverse the left subtree by recursively calling the pre-order function.
• Traverse the right subtree by recursively calling the pre-order function.
Pre-order (Pseudocode)
void printPreorder(TreeNode* r)
{
IF r==NULL THEN return
PRINT r value
printPreorder(r left)
printPreorder(r right)
}
In-order (LNR) (left - node - right)
• Traverse the left subtree by recursively calling the in-order function.
• Access the data part of the current node.
• Traverse the right subtree by recursively calling the in-order function.
– In BST in-order traversal retrieves the keys in ascending sorted order.
In-Order (Pseudocode)
void printinorder(TreeNode*r)
{
IF r==NULL THEN return
printlnorder(r left)
PRINT r value
printlnorder(r right)
}
Inorder Traversal (Loop)
Post-order (LRN) (left-right - node)
• Traverse the left subtree by recursively calling the post-order function.
• Traverse the right subtree by recursively calling the post-order
function.
• Access the data part of the current node.
Post-Order (Pseudocode)
void printPostorder(TreeNode* r)
{
IF r==NULL THEN return
printPostorder(r left)
printPostorder(r right)
PRINT r value
}
Search Operation in (BST)
treenode* iterativesearch(val)
{
if root==null then return root
else
set temp=root
while temp!=null
if val == temp.value
then return temp
else if val<temp.value
then temp = temp.left
else
temp = temp.right
end while
return null
}
Height of (BST)
int height(treenode* r)
{
if r==null then return -1
else
{
lheight = height(r left)
rheight=height(r right)
if lheight>rheight
then return lheight+1
else
then return rheight+1
}
}
Breadth First Search (BFS)
void printLevelOrderBFS(TreeNode *r)
{
h= height(r) // calculate height of tree
FOR i=0 to i<=h
printGivenLevel( r,i )
}
void printGivenLevel(TreeNode *r, int level)
{
IF r==NULL THEN return
ELSE IF level==0
PRINT(r value)
ELSE
printGivenLevel(r left, level-1)
printGivenLevel(r right, level-1)
}
Delete Node - Cases
For leaf node
• Traverse to the leaf node and delete the node.
For node with 1 child
• Traverse to the node with single child to be deleted (lets say n).
• Check if n has left child (n->left).
– If it does not link the right child (n->right) with parent node of n
• Check if n has right child (n->right).
– If it does not, link the left child(n->left) with parent node of n
For Node with 2 Children
• Traverse to the node with 2 children to be deleted (n).
• Find the SMALLEST node(nMin) in the right sub tree of n. OR Find the LARGEST
node(nMax) in the left sub tree of n.
• Replace this node(nMin or nMax) with the node to be deleted (replace n with nMin).
• Now delete nMin (or nMax) using the delete process again
Delete Node in BFS
TreeNode* delete Node(TreeNode* r, int v) TreeNode * minValueNode(TreeNode * node)
{ {
IF r==NULL //Base Condition TreeNode * current = node;
/* loop down to find the leftmost leaf */
THEN return r while (current left != NULL) {
ELSE IF v < r value THEN // if value smaller go left sub tree current = current left;
}
r left = delete Node(r left, v)
return current;
ELSE IF v >r value THEN // if value larger go right sub tree }
r right = delete Node(r right, v)
ELSE // if value matches
IF r left==NULL THEN // node with only right child, //OR no child
temp = r right
delete r
return temp
ELSE IF r right==NULL THEN //node with only left child, //OR no child temp = r
left
delete r
return temp
ELSE // node with TWO children
temp = minValueNode(r right)
r value = temp value
r right = delete Node(r right, temp value)
return
}
Issues of BST
• The main disadvantage is that we should always
implement a balanced binary search tree. Otherwise the
cost of operations may not be logarithmic and degenerate
into a linear search on an array.
• Accessing the element in BST is slightly slower than
array.
• A BST can be imbalanced or degenerated which can
increase the complexity.
• It employs recursive approach which requires more stack
space.
• The interaction of binary search with memory hierarchy
i.e. caching is poor. (because of its random access nature)
Time Complexity
Multi-way Trees/Tries
A multiway tree is a tree that can have more than two children. A multiway tree of order m
(or an m-way tree) is one in which a tree can have m children. As with the other trees that
have been studied, the nodes in an m-way tree will be made up of key fields, in this case m-1
key fields, and pointers to children.
Biggest advantage of m-way tree over binary tree is short height & fast access of nodes, Less
traversal overhead.
max elements : m^(h+1) - 1
h: Height of tree
m: Degree of tree

S
Reference
• https://prepinsta.com/java-program/preorder
-tree-traversal-without-recursion/

You might also like