0% found this document useful (0 votes)
44 views116 pages

Ds Tree1

Uploaded by

Anshu Jayswal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
44 views116 pages

Ds Tree1

Uploaded by

Anshu Jayswal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 116

What is Searching?

In computer science, searching is the process of finding an item with the specified properties from a
collection of items. The items may be stored as records in a database or a simple data element in the
array, text in files, nodes in trees, vertices, and edges in graphs or they may be elements of other
search spaces.

Why do we need searching?


Searching is one of the computer science algorithms. You know that today’s modern computers store
a lot of information. To read this information proficiently, we need very efficient searching
algorithms.
There are certain ways of organizing data that improves the searching process. That means If we keep
the data in proper order it is easy to search the required elements. Sorting is one of the techniques for
making the elements order.
Types of Searching
The following are the types of searching available in computer science.
•Unordered Linear Search
•Sorted/Ordered Linear Search
•Binary Search
•Interpolation Search
•Symbol tables and hashing
•String searching algorithms: Ternary search,Tries and Suffix trees
Linear search is a very basic and simple search algorithm. In Linear search, we search
an element or value in a given array by traversing the array from the starting, till the
desired element or value is found.

Implementing Linear Search


Following are the steps of implementation that we will be following:
1.Traverse the array using a for loop.
3.If no match is found, return -1.

4.In every iteration, compare the target value with the current value of the array.
•If the values match, return the current index of the array.
•If the values do not match, move on to the next array element.
Problem: Given an array arr[] of n elements, write a function to search a given element x in arr[].
Examples :
Input : arr[] = {10, 20, 80, 30, 60, 50, 110, 100, 130, 170} x = 110;
Output : 6 Element x is present at index 6
Input : arr[] = {10, 20, 80, 30, 60, 50, 110, 100, 130, 170} x = 175;
Output : -1 Element x is not present in arr[].

A simple approach is to do a linear search, i.e


•Start from the leftmost element of arr[] and one by one compare x with each element of arr[]
•If x matches with an element, return the index.
•If x doesn’t match with any of elements, return -1.
Algorithm for Linear Search in Data Structure
The algorithm for linear search is as shown below. It is a straightforward algorithm. Go through it and study it
as we shall be building a computer program on the algorithm.
Algorithm:
function linear_search(integer array[], integer n, integer x)
{
integer k;
for (k = 0, k < n, k++)
if (array [k] = x)
return k;
return -1;
}

This program takes input array size & array elements from the user,
afterward calling linearSearch(int[] inputArray, int seachKey) method to
find search key element in the input array. This algorithm scan search key
element in input array if element found then it returns index number else
it returns -1
Linear Search Complexities
Time Complexity: O(n)
Space Complexity: O(1)

Linear Search Applications


1.For searching operations in smaller arrays (<100 items).
How Linear Search Works?
The following steps are followed to search for an element k = 1 in the list below.

Array to be searched for

1.Start from the first element, compare k with each element x. .

Compare with each element


If x == k, return the index.

• Element found

•Else, return not found .


C++ Program to Implement Linear Search –
#include < iostream >
using namespace std;
void linearSearch(int a[], int n)
{ int temp = -1;
for (int i = 0; i < 5; i++)
{ if (a[i] == n)
{ cout << "Element found at position: " << i + 1 << endl;
temp = 0;
break; }
} if (temp == -1)
{ cout << "No Element Found" << endl;
}
} int main()
{
int arr[5];
cout << "Please enter 5 elements of the Array" << endl; for (int i = 0; i < 5; i++)
{ cin >> arr[i];
} cout << "Please enter an element to search" << endl;
int num;
cin >> num;
linearSearch(arr, num);
return 0;
}
#include<iostream>

using namespace std;

int main()
{
int a[20],n,x,i,flag=0;
cout<<"How many elements?";
cin>>n;
cout<<"\nEnter elements of the array\n";
for(i=0;i<n;++i)
cin>>a[i];
cout<<"\nEnter element to search:";
cin>>x;
for(i=0;i<n;++i)
{
if(a[i]==x)
{
flag=1;
break;
}
}
if(flag)
cout<<"\nElement is found at position "<<i;
else
cout<<"\nElement not found";
return 0;
}
Binary Search is applied on the sorted array or list of large size. It's
time complexity of O(log n) makes it very fast as compared to other
sorting algorithms. The only limitation is that the array or list of
elements must be sorted for the binary search algorithm to work on it.

Binary search is one of the search techniques. Which works efficiently


on the sorted arrays or collection. Hence, in order to search an
element in array or collection by using binary search techniques, we
must ensure that the array or collection is sorted.
The binary search uses a divide and conquer algorithm in which, the
arrays or collection is divided into two halves and the item is
compared with the middle element of the collection. If the match is
found for a given searching key then the location of the middle
element is returned. Otherwise, we have to search into either of the
halves depending upon the result produced through the match.
Binary Search: Search a sorted array by repeatedly dividing the search interval in half. Begin with an
interval covering the whole array. If the value of the search key is less than the item in the middle of
the interval, narrow the interval to the lower half. Otherwise, narrow it to the upper half. Repeatedly
check until the value is found or the interval is empty.

Example :

The idea of binary search is to use the information that the array is sorted and reduce the time
complexity to O(Log n).
Procedure binary_search
A ← sorted array
n ← size of array
x ← value to be searched
Set lowerBound = 1
Set upperBound = n
while x not found
if upperBound < lowerBound
EXIT:
x does not exists.
set midPoint = lowerBound + ( upperBound - lowerBound ) / 2
if A[midPoint] < x
set lowerBound = midPoint + 1
if A[midPoint] > x
set upperBound = midPoint – 1
if A[midPoint] = x EXIT:
x found at location midPoint
end while
end procedure
1.Compare x with the middle element.
2.If x matches with the middle element, we return the mid index.
3.Else If x is greater than the mid element, then x can only lie in the
right half subarray after the mid element. So we recur for the right
half.
4.Else (x is smaller) recur for the left half.
Implementing Binary Search Algorithm
Following are the steps of implementation that we will be following:
1.Start with the middle element:
•If the target value is equal to the middle element of the array, then return the index of the middle
element.
•If not, then compare the middle element with the target value,
•If the target value is greater than the number in the middle index, then pick the elements to the
right of the middle index, and start with Step 1.
•If the target value is less than the number in the middle index, then pick the elements to the left
of the middle index, and start with Step 1.
2.When a match is found, return the index of the element matched.
3.If no match is found, then return -1
// C++ Program for Binary Search // -----
#include<iostream>
using namespace std;
int main()
{ int i, arr[10], num, first, last, middle;
cout<<"Enter 10 Elements (in ascending order): ";
for(i=0; i<10; i++)
cin>>arr[i];
cout<<"\nEnter Element to be Search: ";
cin>>num;
first = 0;
last = 9;
middle = (first+last)/2;
while(first <= last)
{ if(arr[middle]<num) first = middle+1;
else if(arr[middle]==num)
{ cout<<"\nThe number, "<<num<<" found at
Position "<<middle+1;
break;
}
else
last = middle-1;
middle = (first+last)/2;
} if(first>last)
cout<<"\nThe number, "<<num<<" is not found
in given Array";
cout<<endl;
return 0;
}
#include <iostream>
using namespace std;
int binarySearch(int[], int, int, int);
int main()
{
int num[10] = {10, 22, 37, 55, 92, 118};
int search_num, loc=-1;
cout<<"Enter the number that you want to search: ";
cin>>search_num;
loc = binarySearch(num, 0, 6, search_num);
if(loc != -1)
{
cout<<search_num<<" found in the array at the location: "<<loc;
}
else
{
cout<<"Element not found";
}
return 0;
}
int binarySearch(int a[], int first, int last, int search_num)
{ int middle; if(last >= first)
{ middle = (first + last)/2;
//Checking if the element is present at middle loc
if(a[middle] == search_num) { return middle+1; } //Checking if the search element is
present in greater half
else if(a[middle] < search_num)
{ return binarySearch(a,middle+1,last,search_num);
} //Checking if the search element is present in lower half
else
{
return binarySearch(a,first,middle-1,search_num); }
} return -1;
}
If user enters 10 elements as 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 and element to be search as 8, then dry run of above
program goes like:
•10 elements gets stored in the array arr[] in a way that, arr[0]=1, arr[1]=2, arr[2]=3, and so on

•The number to be search say 8 gets initialized to num. Therefore, num=8

•Initially first=0 and last=9

•(first+last)/2 or 0+9/2 or 4 gets initialized to middle. Therefore middle=4

•Because the value of first (0) is less than the value of last (9), so the condition of while loop evaluates to be
true. Therefore program flow goes inside the loop

•Checks whether arr[middle]<num evaluates to be true or not. On putting the value of


variables middle and num, arr[4]<num or 5<8 evaluates to be true. Therefore program flow goes inside the if
block and middle+1 or 4+1 or 5 gets initialized to first

•Because, the condition of if block evaluates to be true, therefore else if and else block's statement(s) will not
get executed.

•At last, middle = (first+last)/2 or middle = (5+9)/2 or middle=7

•Program flow goes back to the condition of while loop. The condition first <= last or 5<=9 again evaluates to
be true, therefore again program flow goes inside the loop

•Checks the condition of if block, that is arr[middle]<num evaluates to be true or not, that
is arr[7]<num or 8<8 evaluates to be false. Therefore, program flow goes to else if block, and checks its
condition

•The condition arr[middle]==num or 8==8 evaluates to be true. Therefore program flow goes inside this else
if block and executes its statements

•That is, prints the position of number. Because the number is found at index number 7. Therefore I've printed its
position as 8, since indexing in arrays starts from 0, not from 1

•After printing the position of element, use the break keyword to break out from the while loop
Important Differences
•Input data needs to be sorted in Binary Search and not
in Linear Search
•Linear search does the sequential access whereas
Binary search access data randomly.
•Time complexity of linear search -O(n) , Binary search
has time complexity O(log n).
• Linear search performs equality comparisons and
Binary search performs ordering comparisons
This is the simplest program to implement linear search in C++.
// C++ Program to Implement Linear Search
#include<iostream>
using namespace std;
int main()
{
int arr[10], i, num, index;
cout<<"Enter 10 Numbers: ";
for(i=0; i<10; i++)
cin>>arr[i];
cout<<"\nEnter a Number to Search: ";
cin>>num;
for(i=0; i<10; i++)
{
if(arr[i]==num)
{
index = i; break; }
}
cout<<"\nFound at Index No."<<index; cout<<endl;
return 0; }
Tree Node
A node is a structure that contains a key or value and pointers in its child node in the tree data structure.
In the tree data structure, you can define the tree node as follows.

struct node
{
int data;
struct node *leftchild;
struct node *rightchild;
}
Tree - Terminology

In linear data structure data is organized in sequential order and in non-linear data
structure data is organized in random order. A tree is a very popular non-linear data
structure used in a wide range of applications. A tree data structure can be defined as
follows...

Tree is a non-linear data structure which organizes data in hierarchical structure


and this is a recursive definition.

A tree data structure can also be defined as follows...

Tree data structure is a collection of data (Node) which is organized in


hierarchical structure recursively

In tree data structure, every individual element is called as Node. Node in a tree data
structure stores the actual data of that particular element and link to next element in
hierarchical structure.

In a tree data structure, if we have N number of nodes then we can have a maximum of N-
1 number of links.
Example
Terminology
In a tree data structure, we use the following terminology...
1. Root
In a tree data structure, the first node is called as Root Node. Every tree must
have a root node. We can say that the root node is the origin of the tree data
structure. In any tree, there must be only one root node. We never have multiple
root nodes in a tree.
2. Edge
In a tree data structure, the connecting link between any two nodes is called as EDGE. In a tree with 'N' number of nodes there
will be a maximum of 'N-1' number of edges.
3. Parent
In a tree data structure, the node which is a predecessor of any node is called as PARENT NODE. In simple words, the node
which has a branch from it to any other node is called a parent node. Parent node can also be defined as "The node which has
child / children".
4. Child
In a tree data structure, the node which is descendant of any node is called as CHILD Node. In simple words, the node which
has a link from its parent node is called as child node. In a tree, any parent node can have any number of child nodes. In a
tree, all the nodes except root are child nodes.
5. Siblings
In a tree data structure, nodes which belong to same Parent are called as SIBLINGS. In simple words, the nodes with the same
parent are called Sibling nodes.
6. Leaf
In a tree data structure, the node which does not have a child is called as LEAF Node. In simple words, a leaf is a node with no
child.

In a tree data structure, the leaf nodes are also called as External Nodes. External node is also a node with no child. In a
tree, leaf node is also called as 'Terminal' node.
7. Internal Nodes
In a tree data structure, the node which has atleast one child is called as INTERNAL Node. In simple words, an internal
node is a node with atleast one child.

In a tree data structure, nodes other than leaf nodes are called as Internal Nodes. The root node is also said to be
Internal Node if the tree has more than one node. Internal nodes are also called as 'Non-Terminal' nodes.
8. Degree
In a tree data structure, the total number of children of a node is called as DEGREE of that Node. In simple words, the
Degree of a node is total number of children it has. The highest degree of a node among all the nodes in a tree is called as
'Degree of Tree'
9. Level
In a tree data structure, the root node is said to be at Level 0 and the children of root node are at Level 1 and the children of
the nodes which are at Level 1 will be at Level 2 and so on... In simple words, in a tree each step from top to bottom is called as
a Level and the Level count starts with '0' and incremented by one at each level (Step).
10. Height
In a tree data structure, the total number of edges from leaf node to a particular node in the longest path is called
as HEIGHT of that Node. In a tree, height of the root node is said to be height of the tree. In a tree, height of all
leaf nodes is '0'.
11. Depth
In a tree data structure, the total number of egdes from root node to a particular node is called as DEPTH of that Node. In a
tree, the total number of edges from root node to a leaf node in the longest path is said to be Depth of the tree. In simple
words, the highest depth of any leaf node in a tree is said to be depth of that tree. In a tree, depth of the root node is
'0'.
12. Path
In a tree data structure, the sequence of Nodes and Edges from one node to another node is called as PATH between that two
Nodes. Length of a Path is total number of nodes in that path. In below example the path A - B - E - J has length 4.
13. Sub Tree
In a tree data structure, each child from a node forms a subtree recursively. Every child node will form a subtree on its parent nod
A tree is a nonlinear hierarchical data structure that consists of nodes connected by edges.

Why Tree Data Structure?


Other data structures such as arrays, linked list, stack, and queue are linear data
structures that store data sequentially. In order to perform any operation in a
linear data structure, the time complexity increases with the increase in the data
size. But, it is not acceptable in today's computational world.
Different tree data structures allow quicker and easier access to the data as it is a
non-linear data structure.
Degree of a Node
The degree of a node is the total number of branches of that node.
Forest
A collection of disjoint trees is called a forest.

Creating forest from a tree

You can create a forest by cutting the root of a tree.


Advantages of trees
Trees are so useful and frequently used, because they have some
very serious advantages:
•Trees reflect structural relationships in the data
•Trees are used to represent hierarchies
•Trees provide an efficient insertion and searching
•Trees are very flexible data, allowing to move subtrees around
with minumum effort
Applications of tree
•Trees are used to store simple as well as complex data. Here
simple means an integer value, character value and complex data
means a structure or a record.
•Trees are often used for implementing other types of data
structures like hash tables, sets, and maps.
•Trees are an important data structure used for compiler
construction.
•Trees are also used in database design.
•Trees are used in file system directories.
•Trees are also widely used for information storage and retrieval in
symbol tables.
Main applications of trees include:
1. Manipulate hierarchical data.
2. Make information easy to search (see tree traversal).
3. Manipulate sorted lists of data.
4. As a workflow for compositing digital images for visual effects.
5. Router algorithms
6. Form of a multi-stage decision-making (see business chess).
Trees in Data Science
A Tree structure is used in predictive modelling. It is usually called a Decision tree. In the Decision tree, each
internal node represents a test or condition on a predictive variable, and edge gives various possible answers to
this test. Leaf node gives the outcome of all tests on a path. Decision tree for accepting or rejecting job offer is
as follows:

Deciding whether to accept or reject a job is based on two parameters: salary and commute time. Nodes specify
conditions on which these two parameters are tested. The priority of the condition depends on how close it is to
root. The most affecting parameter is tested first, in this case, salary. So that is the 1st split at the root. Then
the next relevant condition. Hence, decision trees not only help in finding the decisions, but it also does in the
fastest way.
There are many algorithms like CART (Classification And Regression Tree), Random forest, which helps in
building models.
In a normal tree, every node can have any number of children. A binary tree is a special
type of tree data structure in which every node can have a maximum of 2 children. One
is known as a left child and the other is known as right child.
A tree in which every node can have a maximum of two children is called Binary
Tree.
In a binary tree, every node can have either 0 children or 1 child or 2 children but not
more than 2 children.
Binary Tree Representations
A binary tree data structure is represented using
two methods. Those methods are as follows...
1. Array Representation
2. Linked List Representation

Consider the following binary tree...


1. Array Representation of Binary Tree
In array representation of a binary tree, we use one-dimensional array (1-D Array) to represent a binary tree.
Consider the above example of a binary tree and it is represented as follows...

To represent a binary tree of depth 'n' using array representation, we need one dimensional array with a maximum size of 2n + 1.

2. Linked List Representation of Binary Tree


We use a double linked list to represent a binary tree. In a double linked list, every node consists of three fields. First field for storing left child address,
second for storing actual data and third for storing right child address.
In this linked list representation, a node has the following structure...

The above example of the binary tree represented using Linked list representation is shown as follows...
There are different types of binary trees and they are...
1. Strictly Binary Tree
In a binary tree, every node can have a maximum of two children. But in strictly binary tree, every node should have exactly two children or none. That means
every internal node must have exactly two children. A strictly Binary Tree can be defined as follows...
A binary tree in which every node has either two or zero number of children is called Strictly Binary Tree

Strictly binary tree is also called as Full Binary Tree or Proper Binary Tree or 2-Tree

Strictly binary tree data structure is used to represent mathematical expressions.


2. Complete Binary Tree
In a binary tree, every node can have a maximum of two children. But in strictly binary tree,
every node should have exactly two children or none and in complete binary tree all the
nodes must have exactly two children and at every level of complete binary tree there must
be 2 number of nodes. For example at level 2 there must be 2 = 4 nodes and at level 3
level 2

there must be 2 = 8 nodes.


3

A binary tree in which every internal node has exactly two children and all leaf nodes
are at same level is called Complete Binary Tree.
Complete binary tree is also called as Perfect Binary Tree
3. Extended Binary Tree
A binary tree can be converted into Full Binary tree by adding dummy nodes to existing nodes wherever required.
The full binary tree obtained by adding dummy nodes to a binary tree is called as Extended Binary Tree.

In above figure, a normal binary tree is converted into full binary tree by adding dummy nodes (In pink colour).
Common operations
Following is a list of common operations that can be performed on a
binary tree:
1. Insertion
2. Deletion
3. Tree Traversal

Properties of Binary Tree


•At each level of i, the maximum number of nodes is 2i.
•The height of the tree is defined as the longest path from the root node
to the leaf node. The tree which is shown above has a height equal to 3.
Therefore, the maximum number of nodes at height 3 is equal to
(1+2+4+8) = 15. In general, the maximum number of nodes possible at
height h is (20 + 21 + 22+….2h) = 2h+1 -1.
•The minimum number of nodes possible at height h is equal to h+1.
•If the number of nodes is minimum, then the height of the tree would be
maximum. Conversely, if the number of nodes is maximum, then the
height of the tree would be minimum.
If there are 'n' number of nodes in the binary tree.
Binary Tree Traversals
When we wanted to display a binary tree, we need to follow some order in which all the nodes of that binary tree
must be displayed. In any binary tree, displaying order of nodes depends on the traversal method.
Displaying (or) visiting order of nodes in a binary tree is called as Binary Tree Traversal.
Tree Traversal
Traversal of the tree in data structures is a process of visiting each node and prints their value. There are three
ways to traverse tree data structure.

 Pre-order Traversal
 In-Order Traversal
 Post-order Traversal

In-Order Traversal

In the in-order traversal, the left subtree is visited first, then the root, and later the right subtree.

Algorithm:

Step 1- Recursively traverse the left subtree

Step 2- Visit root node

Step 3- Recursively traverse right subtree


Pre-Order Traversal
In pre-order traversal, it visits the root node first, then the left subtree, and lastly right subtree.
Algorithm:
Step 1- Visit root node
Step 2- Recursively traverse the left subtree
Step 3- Recursively traverse right subtree
Post-Order Traversal
It visits the left subtree first in post-order traversal, then the right subtree, and finally the root node.
Algorithm:
Step 1- Recursively traverse the left subtree
Step 2- Visit root node
Step 3- Recursively traverse right subtree
.
#include <bits/stdc++.h>
using namespace std;

struct Node {
int data;
struct Node* left;
struct Node* right;

// val is the key or the value that


// has to be added to the data part
Node(int val)
{
data = val;

// Left and right child for node


// will be initialized to null
left = NULL;
right = NULL;
}
};

int main()
{

/*create root*/
struct Node* root = new Node(1);
/* following is the tree after above statement

1
/\
NULL NULL
*/

root->left = new Node(2);


root->right = new Node(3);
/* 2 and 3 become left and right children of 1
1
/\
2 3
/\ /\
NULL NULL NULL NULL
*/

root->left->left = new Node(4);


/* 4 becomes left child of 2
1
/ \
2 3
/\ /\
4 NULL NULL NULL
/\
NULL NULL
*/

return 0;
}
Binary Search Tree
A binary search tree is a useful data structure for fast addition and removal of data.

It is composed of nodes, which stores data and also links to upto two other child nodes.
It is the relationship between the leaves linked to and the linking leaf, also known as
the parent node, which makes the binary tree such an efficient data structure.
For a binary tree to be a binary search tree, the data of all the nodes in the left sub-tree
of the root node should be less than the data of the root. The data of all the nodes in the
right subtree of the root node should be greater than equal to the data of the root. As a
result, the leaves on the farthest left of the tree have the lowest values, whereas the
leaves on the right of the tree have the greatest values.
A representation of binary search tree looks like the following:

Consider the root node 20. All elements to the left of subtree(10, 5) are less than 20
and all elements to the right of subtree(25, 30, 35) are greater than 20.
Attributes of Binary Search Tree
A BST is made of multiple nodes and consists of the following attributes:
•Nodes of the tree are represented in a parent-child relationship
•Every sub-tree, also known as a binary search tree, has sub-branches on
the right and left of themselves.
•All the nodes are linked with key-value pairs.
•The keys of the nodes present on the left subtree are smaller than the keys
of their parent node
•Similarly, The left subtree nodes' keys have lesser values than their parent
node's keys.
•Each parent node can have zero child nodes or a maximum of two
subnodes or subtrees on the left and right sides.
BST primarily offers the following three types of operations for your usage:
Search: searches the element from the binary tree
Insert: adds an element to the binary tree
Delete: delete the element from a binary tree
Each operation has its own structure and method of execution/analysis, but the most
complex of all is the Delete operation.
Search Operation
Always initiate analyzing tree at the root node and then move further to either the right or
left subtree of the root node depending upon the element to be located is either less or
greater than the root.
The element to be searched is 10
Compare the element with the root node 12, 10 < 12, hence you move to the left subtree.
No need to analyze the right-subtree
Now compare 10 with node 7, 10 > 7, so move to the right-subtree
Then compare 10 with the next node, which is 9, 10 > 9, look in the right subtree child
10 matches with the value in the node, 10 = 10, return the value to the user.

Insert Operation
This is a very straight forward operation. First, the root node is inserted, then the next
value is compared with the root node. If the value is greater than root, it is added to
the right subtree, and if it is lesser than the root, it is added to the left subtree.
There is a list of 6 elements that need to be inserted in a BST in order from left to
right
Insert 12 as the root node and compare next values 7 and 9 for inserting accordingly
into the right and left subtree
Compare the remaining values 19, 5, and 10 with the root node 12 and place them
accordingly. 19 > 12 place it as the right child of 12, 5 < 12 & 5 < 7, hence place it as
left child of 7.
Now compare 10, 10 is < 12 & 10 is > 7 & 10 is > 9, place 10 as right subtree of 9.

Delete Operations
Delete is the most advanced and complex among all other operations. There are multiple cases handled for deletion
in the BST.
•Case 1- Node with zero children: this is the easiest situation, you just need to delete the node which has no further
children on the right or left.
•Case 2 - Node with one child: once you delete the node, simply connect its child node with the parent node of the
deleted value.
•Case 3 Node with two children: this is the most difficult situation, and it works on the following two rules
•3a - In Order Predecessor: you need to delete the node with two children and replace it with the largest value
on the left-subtree of the deleted node
•3b - In Order Successor: you need to delete the node with two children and replace it with the largest value
on the right-subtree of the deleted node
This is the first case of deletion in which you delete a node that has no children. As you
can see in the diagram that 19, 10 and 5 have no children. But we will delete 19.
Delete the value 19 and remove the link from the node.
View the new structure of the BST without 19
This is the second case of deletion in which you delete a node that has 1 child, as you can
see in the diagram that 9 has one child.
Delete the node 9 and replace it with its child 10 and add a link from 7 to 10
View the new structure of the BST without 9
Here you will be deleting the node 12 that has two children
The deletion of the node will occur based upon the in order predecessor rule, which
means that the largest element on the left subtree of 12 will replace it.
Delete the node 12 and replace it with 10 as it is the largest value on the left subtree
View the new structure of the BST after deleting 12
1 Delete a node 12 that has two children
2 The deletion of the node will occur based upon the In Order Successor rule, which
means that the largest element on the right subtree of 12 will replace it
3 Delete the node 12 and replace it with 19 as it is the largest value on the right
subtree
4 View the new structure of the BST after deleting 12

The algorithm is utilized in real-world solutions like games, autocomplete data, and
graphics.
Insertion in a BST
To insert data into a binary tree involves a function searching for an unused node in the
proper position in the tree in which to insert the key value. The insert function is
generally a recursive function that continues moving down the levels of a binary tree
until there is an unused leaf in a position which follows the following rules of placing
nodes.
Compare data of the root node and element to be inserted.
If the data of the root node is greater, and if a left subtree exists, then repeat step 1
with root = root of left subtree. Else,
Insert element as left child of current root.
If the data of the root node is greater, and if a right subtree exists, then repeat step 1
with root = root of right subtree.
Else, insert element as right child of current root.
Since the root node is a private member, we also write a public member function which
is available to non-members of the class. It calls the private recursive function to insert
an element and also takes care of the case when root node is NULL.
Searching in a BST
The search function works in a similar fashion as insert. It will check if the key value of
the current node is the value to be searched. If not, it should check to see if the value
to be searched for is less than the value of the node, in which case it should be
recursively called on the left child node, or if it is greater than the value of the node, it
should be recursively called on the right child node.
Compare data of the root node and the value to be searched.
If the data of the root node is greater, and if a left subtree exists, then repeat step 1
with root = root of left subtree. Else,
If the data of the root node is greater, and if a right subtree exists, then repeat step 1
with root = root of right subtree. Else,
If the value to be searched is equal to the data of root node, return true.
Else, return false.

Since the root node is a private member, we also write a public member function which
is available to non-members of the class. It calls the private recursive function to search
an element and also takes care of the case when root node is NULL.
Traversing in a BST
There are mainly three types of tree traversals:
1. Pre-order Traversal:
In this technique, we do the following :
Process data of root node.
First, traverse left subtree completely.
Then, traverse right subtree.

2. Post-order Traversal
In this traversal technique we do the following:
First traverse left subtree completely.
Then, traverse right subtree completely.
Then, process data of node.

3. In-order Traversal
In in-order traversal, we do the following:
•First process left subtree.
•Then, process current root node.
•Then, process right subtree.
Complexity Analysis

The time complexity of search and insert rely on the height of the
tree. On average, binary search trees with n nodes have O(log
n) height. However in the worst case the tree can have a height
of O(n) when the unbalanced tree resembles a linked list. For
example in this case :

Traversal requires O(n) time, since every node must be visited.


Heap data structure is a specialized binary tree-based data structure. Heap is a
binary tree with special characteristics. In a heap data structure, nodes are
arranged based on their values. A heap data structure some times also called as
Binary Heap.

There are two types of heap data structures and they are as follows...
1. Max Heap
2. Min Heap
Every heap data structure has the following properties...
Property #1 (Ordering): Nodes must be arranged in an order
according to their values based on Max heap or Min heap.
Property #2 (Structural): All levels in a heap must be full except the
last level and all nodes must be filled from left to right strictly.
Based on this criteria, a heap can be of two types −
For Input → 35 33 42 10 14 19 27 44 26 31

Min-Heap − Where the value of the root node is less than or equal to either of its children.
Max Heap
Max heap data structure is a specialized full binary tree data structure. In a max heap nodes
are arranged based on node value.

Max heap is defined as follows...


Max heap is a specialized full binary tree in which every parent node contains
greater or equal value than its child nodes.

Max-Heap − Where the value of the root node is greater than or equal to either of its children.
Max Heap Construction Algorithm
We shall use the same example to demonstrate how a Max Heap is created. The
procedure to create Min Heap is similar but we go for min values instead of max
values.
We are going to derive an algorithm for max heap by inserting one element at a
time. At any point of time, heap must maintain its property. While insertion, we
also assume that we are inserting a node in an already heapified tree.

Step 1 − Create a new node at the end of heap.


Step 2 − Assign new value to the node.
Step 3 − Compare the value of this child node with its parent.
Step 4 − If value of parent is less than child, then swap them.
Step 5 − Repeat step 3 & 4 until Heap property holds.
Operations on Max Heap
The following operations are performed on a Max heap data structure...
1. Finding Maximum
2. Insertion
3. Deletion

Finding Maximum Value Operation in Max Heap


Finding the node which has maximum value in a max heap is very simple. In a max heap,
the root node has the maximum value than all other nodes. So, directly we can display root
node value as the maximum value in max heap.

Insertion Operation in Max Heap


Insertion Operation in max heap is performed as follows...
 Step 1 - Insert the newNode as last leaf from left to right.
 Step 2 - Compare newNode value with its Parent node.
 Step 3 - If newNode value is greater than its parent, then swap both of them.
 Step 4 - Repeat step 2 and step 3 until newNode value is less than its parent node (or)
newNode reaches to root.
Example

Above tree is satisfying both Ordering property and Structural property according to the Max Heap data structure.
Example
Consider the above max heap. Insert a new node with value 85.
•Step 1 - Insert the newNode with value 85 as last leaf from left to right. That means newNode is added as a right child of
node with value 75. After adding max heap is as follows...
•Step 2 - Compare newNode value (85) with its Parent node value (75). That means 85 > 75

•Step 3 - Here newNode value (85) is greater than its parent value (75), then swap both of them. After swapping, max heap is as foll
•Step 4 - Now, again compare newNode value (85) with its parent node value (89).

Here, newNode value (85) is smaller than its parent node value (89). So, we stop insertion process. Finally, max heap after
insertion of a new node with value 85 is as follows...
Deletion Operation in Max Heap
In a max heap, deleting the last node is very simple as it does not disturb max heap properties.

Deleting root node from a max heap is little difficult as it disturbs the max heap properties. We
use the following steps to delete the root node from a max heap...
 Step 1 - Swap the root node with last node in max heap
 Step 2 - Delete last node.
 Step 3 - Now, compare root value with its left child value.
 Step 4 - If root value is smaller than its left child, then compare left child with its right
sibling. Else goto Step 6
 Step 5 - If left child value is larger than its right sibling, then swap root with left
child otherwise swap root with its right child.
 Step 6 - If root value is larger than its left child, then compare root value with its right
child value.
 Step 7 - If root value is smaller than its right child, then swap root with right
child otherwise stop the process.
 Step 8 - Repeat the same until root node fixes at its exact position.
Example
Consider the above max heap. Delete root node (90) from the max heap.
 Step 1 - Swap the root node (90) with last node 75 in max heap. After swapping max
heap is as follows...
•Step 2 - Delete last node. Here the last node is 90. After deleting node with value 90 from heap, max heap is as follows...

•Step 3 - Compare root node (75) with its left child (89).
Here, root value (75) is smaller than its left child value (89). So, compare left child (89) with its right sibling (70).

•Step 4 - Here, left child value (89) is larger than its right sibling (70), So, swap root (75) with left child (89).
•Step 5 - Now, again compare 75 with its left child (36).

Here, node with value 75 is larger than its left child. So, we compare node 75 with its right child 85.
•Step 6 - Here, node with value 75 is smaller than its right child (85). So, we swap both of them. After swapping max heap is as fo
•Step 7 - Now, compare node with value 75 with its left child (15).

Here, node with value 75 is larger than its left child (15) and it does not have right child. So we stop the process.

Finally, max heap after deleting root node (90) is as follows...


A spanning tree is a subset of Graph G, which has all the vertices covered with minimum possible
number of edges. Hence, a spanning tree does not have cycles and it cannot be disconnected..
By this definition, we can draw a conclusion that every connected and undirected Graph G has at least
one spanning tree. A disconnected graph does not have any spanning tree, as it cannot be spanned to
all its vertices.

We found three spanning trees off one complete graph. A complete undirected
graph can have maximum nn-2 number of spanning trees, where n is the number of
nodes. In the above addressed example, n is 3, hence 33−2 = 3 spanning trees are
possible.
General Properties of Spanning Tree

We now understand that one graph can have more than one spanning tree. Following are a few properties
of the spanning tree connected to graph G −
•A connected graph G can have more than one spanning tree.
•All possible spanning trees of graph G, have the same number of edges and vertices.
•The spanning tree does not have any cycle (loops).
•Removing one edge from the spanning tree will make the graph disconnected, i.e. the spanning tree
is minimally connected.
•Adding one edge to the spanning tree will create a circuit or loop, i.e. the spanning tree is maximally
acyclic.

Mathematical Properties of Spanning Tree

•Spanning tree has n-1 edges, where n is the number of nodes (vertices).
•From a complete graph, by removing maximum e - n + 1 edges, we can construct a spanning tree.
•A complete graph can have maximum nn-2 number of spanning trees.
Thus, we can conclude that spanning trees are a subset of connected Graph G and disconnected graphs
do not have spanning tree. Application of Spanning Tree
Spanning tree is basically used to find a minimum path to connect all nodes in a graph. Common application of
spanning trees are −
Civil Network Planning
Computer Network Routing Protocol
Cluster Analysis
Let us understand this through a small example. Consider, city network as a huge graph and now plans to deploy
telephone lines in such a way that in minimum lines we can connect to all city nodes. This is where the spanning tree
comes into picture.
Minimum Spanning Tree (MST)
In a weighted graph, a minimum spanning tree is a spanning tree that has
minimum weight than all other spanning trees of the same graph. In real-world
situations, this weight can be measured as distance, congestion, traffic load or
any arbitrary value denoted to the edges.
Minimum Spanning-Tree Algorithm
We shall learn about two most important spanning tree algorithms here −
•Kruskal's Algorithm
•Prim's Algorithm
Both are greedy algorithms.
Kruskal's algorithm to find the minimum cost spanning tree uses the greedy approach. This
algorithm treats the graph as a forest and every node it has as an individual tree. A tree
connects to another only and only if, it has the least cost among all available options and does
not violate MST properties.
To understand Kruskal's algorithm let us consider the following example −

Step 1 - Remove all loops and Parallel Edges


Remove all loops and parallel edges from the given graph.
In case of parallel edges, keep the one which has the least cost associated and remove all others.

Step 2 - Arrange all edges in their increasing order of weight


The next step is to create a set of edges and weight, and arrange them in an ascending order of weightage (cost).

Step 3 - Add the edge which has the least weightage


Now we start adding edges to the graph beginning from the one which has the least weight. Throughout, we shall
keep checking that the spanning properties remain intact. In case, by adding one edge, the spanning tree property
does not hold then we shall consider not to include the edge in the graph.
The least cost is 2 and edges involved are B,D and D,T. We add them. Adding them does not violate spanning tree
properties, so we continue to our next edge selection.
Next cost is 3, and associated edges are A,C and C,D. We add them again −
Next cost in the table is 4, and we observe that adding it will create a circuit in the graph. −

We ignore it. In the process we shall ignore/avoid all edges that create a
circuit.
We observe that edges with cost 5 and 6 also create circuits. We ignore them and move on.

Now we are left with only one node to be added. Between the two least cost
edges available 7 and 8, we shall add the edge with cost 7.

By adding edge S,A we have included all the nodes of the graph and we now have
minimum cost spanning tree.
Prim's algorithm to find minimum cost spanning tree (as Kruskal's algorithm) uses the greedy
approach. Prim's algorithm shares a similarity with the shortest path first algorithms.
Prim's algorithm, in contrast with Kruskal's algorithm, treats the nodes as a single tree and keeps on
adding new nodes to the spanning tree from the given graph.
To contrast with Kruskal's algorithm and to understand Prim's algorithm better, we shall use the same
example −

Step 1 - Remove all loops and parallel edges


Step 2 - Choose any arbitrary node as root node
In this case, we choose S node as the root node of Prim's spanning tree. This node is arbitrarily chosen, so any
node can be the root node. One may wonder why any video can be a root node. So the answer is, in the spanning
tree all the nodes of a graph are included and because it is connected then there must be at least one edge, which
will join it to the rest of the tree.
Step 3 - Check outgoing edges and select the one with less cost
After choosing the root node S, we see that S,A and S,C are two edges with weight 7 and 8, respectively. We
choose the edge S,A as it is lesser than the other.
Now, the tree S-7-A is treated as one node and we check for all edges going out from it. We select the one which
has the lowest cost and include it in the tree.
After this step, S-7-A-3-C tree is formed. Now we'll again treat it as a node and will check all the edges again.
However, we will choose only the least cost edge. In this case, C-3-D is the new edge, which is less than other edges'
cost 8, 6, 4, etc.
After adding node D to the spanning tree, we now have two edges going out of it having the same cost, i.e. D-2-T
and D-2-B. Thus, we can add either one. But the next step will again yield edge 2 as the least cost. Hence, we are
showing a spanning tree with both edges included.

You might also like