Professional Documents
Culture Documents
Module 2 Daa
Module 2 Daa
Module 2 Daa
DISJOINT SETS : Sets are represented by pair wise disjoint sets. If S i and Sj are two sets and i # j, then
there is no common elements for Si and Sj .
Example : When N = 10 elements. That can be partitioned into three disjoint sets i.e, S1, S2 and S3.
S1 = { 1, 7, 8, 9 } S2 = { 2, 5, 10 } S3 = { 3, 4, 6 }
S1 S2 S3
2: Data Representation: We need to maintain the name of each set. So, we require one more data
structure to store the set names. The data structure contains two fields. One is the set name and the other
one is the pointer to root. The data representation for S1, S2 and S3.
Example: S1 = { 1, 7, 8, 9 } S2 = { 2, 5, 10 } S3 = { 3, 4, 6 }
lOMoAR cPSD| 29148908
3 : Array Representation : To represent the sets, we use an array of 1 to n elements where n is the
maximum value among the elements of all sets. The index values represent the nodes (elements of set)
and the entries represent the parent node. For the root value the entry will be‘-1’.
Array Representation of the sets S1, S2 and S3
Example: S1 = { 1, 7, 8, 9 } S2 = { 2, 5, 10 } S3 = { 3, 4, 6 }
S1 S2 S3
i 1 2 3 4 5 6 7 8 9 10
p -1 5 -1 3 -1 3 1 1 1 5
lOMoAR cPSD| 29148908
To perform disjoint set union between two sets Si and Sj can take any one root and make it sub-tree of the
other.
Example : S1 = { 1, 7, 8, 9 } S2 = { 2, 5, 10 } ,Then S1 U S2 can be represented as any one of the following.
Example: S1 = { 1, 7, 8, 9 } S2 = { 2, 5, 10 } S3 = { 3, 4, 6 }
Find ( 4 ) = 4 is in set S3
Find ( 9 ) = 9 is in set S1
Find ( 10 ) = 10 is in set S2
lOMoAR cPSD| 29148908
( or )
The SimpleUnion(i,j), algorithm is very easy to state, their performance characteristics are not very good.
10 20 30 40 50 Initially
We can improve the performance of our union algorithm by avoiding the creation of degenerate trees.
We can use Weighted Union rule.
lOMoAR cPSD| 29148908
1 2 3 4 -------------------------- n
i 1 2 3 4 n
----------------------------------
p -1 -1 -1 -1 -1
Step1 : Initially
1 2 3 4 ------------------------- n
lOMoAR cPSD| 29148908
Step2 : Union(1,2)
i 1 2 3 4 N
----------------------------------
p -2 1 -1 -1 -1
[ -2 ]
1 3 4 ------------------------ n
2
Step3 : Union(1,3)
i 1 2 3 4 n
----------------------------------
p -3 1 1 -1 -1
[ -3 ]
1 4 ------------------------ n
2 3 I = 1, j = 3 p[i]=-count[i]=p[1]=--2 p[j]=-count[j]=p[3]=-
Step4 : Union(1,4)
i 1 2 3 4 n
----------------------------------
p -4 1 1 1 -1
[-4]
1 ------------- n
2 3 4
Step4 : Union(1,n)
2 3 4 ---------------------------- n
Example : Consider the behavior of Weighted union on the following sequences of unions.
Union ( 1,2 ), Union ( 3,4 ), Union ( 5,6 ), Union ( 7,8 ), Union ( 1,3 ), Union ( 5,7 ), Union ( 1,5 ),
Solution: The sequence of unions starting from the initial configuration p[i] = -count[i]=-1
[ -1 ] [ -1 ] [ -1 ] [ -1 ] [ -1 ] [ -1 ] [ -1 ] [ -1 ]
union ( 5,7 )
union ( 1,3 )
[ -4 ] [ -4 ]
lOMoAR cPSD| 29148908
union ( 1,5 )
[ -4 ] [ -4 ] [ -8 ]
Find Algorithm : FIND(i), means it finds the root node of ith node, in other words, it returns the name of set i.
Algorithm SimpleFind(i)
{
while ( p[i] >= 0 ) do
i = p[i];
return i;
}
Example : Consider a tree
p -8 1 1 3 1 5 5 7
i=8
while ( p[i]>=0) – true
i=p[8], i.e 7
while ( p[i]>=0) – true
i=p[7], i.e 5
while ( p[i]>=0) – true
i=p[5], i.e 1
while ( p[i]>=0) – false
return i, i.e i = 1
So 1 is the root node of node 8
Find algorithm Time complexity : O ( N2 )
lOMoAR cPSD| 29148908
Algorithm : Collapse_find( i )
{
// Problem Description : This algorithm Collapse all nodes from i to root node.
r = i;
while ( p[r] > 0 ) do
r := p[r]; //Find the root.
while ( i # r) do //Collapse nodes from i to root r
{
s =p[i];
p[i] =r;
i =s;
}
return r;
}
p -8 1 1 3 1 5 5 7
Step1 : i = 8, r = 8
while ( p[r]>0) – true
r=p[8], i.e 7
while ( p[r]>0) – true
r=p[7], i.e 5
while ( p[r]>0) – true
r=p[5], i.e 1
while ( p[r]>0) – false
Step2 : Collapse nodes from I to root r.
while ( i # r )
8 # 1 – true
s=p[i],
s=p[8]
s=7
p[i]=r
p[8]=1 // means for 8th node 1 is the root node
i=7
again while ( i # r )
7 # 1 – true
s=p[i],
s=p[7]
s=5
p[i]=r
p[7]=1 // means for 7th node 1 is the root node
i=5
again while ( i # r )
5 # 1 – true
s=p[i],
s=p[5]
s=1
p[i]=r
p[5]=1 // means for 5th node 1 is the root node
i=1
lOMoAR cPSD| 29148908
again while ( i # r )
1 # 1 – false return r, i.e r=1
p -8 1 1 3 1 5 1 1
General Method:
In divide and conquer approach, a problem is divided into smaller problems, then the smaller
problems are solved independently, and finally the solutions of smaller problems are combined
into a solution for the large problem.
1. Divide the original problem into a set of subproblems.
2. Conquer: Solve every subproblem individually, recursively.
3. Combine: Put together the solutions of the subproblems to get the solution to the whole
problem.
Given a function to compute on ‘n’ inputs the divide-and-conquer strategy suggests splitting the inputs into ‘k’
distinct subsets, 1<k<=n, yielding ‘k’ sub problems.
These sub problems must be solved, and then a method must be found to combine sub solutions into a
solution of the whole.
lOMoAR cPSD| 29148908
If the sub problems are still relatively large, then the divide-and-conquer strategy can possibly be
reapplied.
Often the sub problems resulting from a divide-and-conquer design are of the same type as the original
problem.
For those cases the re application of the divide-and-conquer principle is naturally expressed by a
recursive algorithm.
D And C(Algorithm) is initially invoked as D and C(P), where ‘p’ is the problem to be solved.
Small(P) is a Boolean-valued function that determines whether the i/p size is small enough that the
answer can be computed without splitting
If this so, the function ‘S’ is invoked.
These sub problems P1, P2 …Pk are solved by recursive application of D And C.
Combine is a function that determines the solution to p using the solutions to the ‘k’ sub problems.
If the size of ‘p’ is n and the sizes of the ‘k’ sub problems are n1, n2 ….nk, respectively, then the
computing time of D And C is described by the recurrence relation.
f(n) is the time for dividing P & combining the solution to sub problems.
Defective chessboard
GIVEN CONDITIONS:-
1.We have a chessboard of size n x n , where n =2k
2.Exactly one square is defective in the chessboard.
3.The tiles(trominoes) are in L-shape i.e. 3 squares.
Cover all the chessboard with L-shape tiles(trominoes), except the defective square.
1x1 2 x2 2 x2
2 x2 2 x2
As the Size of these chessboards displayed here, 1x1 and 2x2 we don’t have to place any L-shape tile in
the first and rest can be filled by just using 1 L-shaped tile.
For 4x 4 chessboard
Step-5 As we have finally divided the problem Step-6 The procedure will continue until all
into 2x2 board we will put the tiles. the sub board are covered with the tiles.
lOMoAR cPSD| 29148908
Step-7 The final chess board covered Step-7 Here we will cover the defectives
with all the titles and only left with the which we have created as in the last, there
defectives which we created. should be only one defective left.
else
{
// No defect in this quadrant
//Place a tile in bottom-right corner
board[topRow + quadrantSize - 1][topColumn + quadrantSize - 1] := tileToUse;
// Tile the rest
TileBoard (topRow, topColumn, topRow + quadrantSize, topColumn + quadrantSize - 1, quadrantSize)
//Code for remaining three quadrants is similar
TileBoard(topRow + quadrantSize, topColumn, topRow + quadrantSize, topColumn + quadrantSize,
quadrantSize)
TileBoard(topRow, topColumn + quadrantSize, topRow + quadrantSize - 1, topColumn + quadrantSize - 1,
quadrantSize)
TileBoard(topRow + quadrantSize, topColumn + quadrantSize, topRow + quadrantSize, topColumn +
quadrantSize, quadrantSize)
}
}
lOMoAR cPSD| 29148908
BINARY SEARCH:
Binary Search is a searching algorithm for finding an element's position in a sorted array. In this approach,
the element is always searched in the middle of a portion of an array.
Binary search can be implemented only on a sorted list of items. If the elements are not sorted already, we need
to sort them first.
Problem definition: Let ai, 1 ≤ i ≤ n be a list of elements that are sorted in non-decreasing order.The problem
is to find whether a given element x is present in the list or not. If x is present we have to determine a value j
(element’s position) such that aj=x. If x is not in the list, then j is set to zero.
ANALYSIS:
In binary search the basic operation is key comparison. Binary Search can be analyzed with the best, worst, and
average case number of comparisons. The numbers of comparisons for the recursive and iterative versions of
Binary Search are the same, if comparison counting is relaxed slightly. For Recursive Binary Search, count each
pass through the if-then-else block as one comparison. For Iterative Binary Search, count each pass through the
while block as one comparison. Let us find out how many such key comparison does the algorithm make on an
array of n elements.
Best case – Θ(1) In the best case, the key is the middle in the array. A constant number of comparisons
(actually just 1) are required.
Worst case - Θ(log2 n) In the worst case, the key does not exist in the array at all. Through each recursion or
iteration of Binary Search, the size of the admissible range is halved. This halving can be done ceiling(log2n )
times. Thus, [ log2 n ] comparisons are required. Sometimes, in case of the successful search, it may take
lOMoAR cPSD| 29148908
maximum number of comparisons. [ log2 n ]. So worst case complexity of successful binary search is Θ (log2
n).
Average case - Θ (log2n) To find the average case, take the sum of the product of number of comparisons
required to find each element and the probability of searching for that element. To simplify the analysis, assume
that no item which is not in array will be searched for, and that the probabilities of searching for each element
are uniform.
Space Complexity –
The space requirements for the recursive and iterative versions of binary search are different.Iterative Binary
Search requires only a constant amount of space, while Recursive Binary Search requires space proportional to
the number of comparisons to maintain the recursion stack.
Max-Min problem is to find a maximum and minimum element from the given array. We can effectively solve
it using divide and conquer approach.
lOMoAR cPSD| 29148908
Explanation:
Straight MaxMin requires 2(n-1) comparisons in the best, average & worst cases.
By realizing the comparison of a[i]>max is false, improvement in a algorithm can be done. Hence we
can replace the contents of the for loop by,
If(a[i]>Max) then Max = a[i]; Else if (a[i]<min) min=a[i]
On the average a[i] is > max half the time. So, the avg. no. of comparison is 3n/2-1.
Divide and conquer approach for Max. Min problem works in three stages.
If a1 is the only element in the array, a1 is the maximum and minimum.
If the array contains only two elements a1 and a2, then the single comparison between two elements can
decide the minimum and maximum of them.
If there are more than two elements, the algorithm divides the array from the middle and creates two sub
problems. Both sub problems are treated as an independent problem and the same recursive process is
applied to them. This division continues until sub problem size becomes one or two.
lOMoAR cPSD| 29148908
lOMoAR cPSD| 29148908
lOMoAR cPSD| 29148908
Space Complexity:
Compared to the straight forward method, the MaxMin method requires extra stack space for i, j,
max, min, max1 and min1. Given n elements there will be [log2n] + 1 levels of recursion and we
need to save seven values for each recursive call. (6 + 1 for return address).
lOMoAR cPSD| 29148908
MERGE SORT
Merge sort is similar to the quick sort algorithm as it uses the divide and conquer approach to sort the elements.
It is one of the most popular and efficient sorting algorithm.
It divides the given list into two equal halves, calls itself for the two halves and then merges the two sorted
halves. We have to define the merge() function to perform the merging.
The sub-lists are divided again and again into halves until the list cannot be divided further. Then we combine
the pair of one element lists into two-element lists, sorting them in the process. The sorted two-element pairs is
merged into the four-element lists, and so on until we get the sorted list.
The time complexity of merge mort in the best case, worst case and average case is O(n log n)
and the number of comparisons used is nearly optimal.
Algorithm:
After that, the index of the smaller element is incremented to point to its immediate successor in
the array it was copied from. This operation is repeated until one of the two given arrays is
exhausted, and then the remaining elements of the other array are copied to the end of the new
array.
Example:
lOMoAR cPSD| 29148908
Let A and B be the 2 n*n Matrix. The product matrix C=AB is calculated by using the formula,
Divide and conquer method suggest another way to compute the product of n*n matrix.
We assume that N is a power of 2 .In the case N is not a power of 2 ,then enough rows and columns of zero
can be added to both A and B .SO that the resulting dimension are the powers of two.
If n=2 then the following formula as a computed using a matrix multiplication operation for the elements of
A & B.
If n>2,Then the elements are partitioned into sub matrix n/2*n/2..since ‘n’ is a power of 2 these product can
be recursively computed using the same formula .This Algorithm will continue applying itself to smaller sub
matrix until ‘N” become suitable small(n=2) so that the product is computed directly .
lOMoAR cPSD| 29148908
Divide and Conquer Following is simple Divide and Conquer method to multiply two square matrices.
1) Divide matrices A and B in 4 sub-matrices of size N/2 x N/2 as shown in the below diagram.
2) Calculate following values recursively. ae + bg, af + bh, ce + dg and cf + dh
Simple Divide and Conquer also leads to O(N3), can there be a better way?
In the above divide and conquer method, the main component for high time complexity is 8 recursive
calls. The idea of Strassen’s method is to reduce the number of recursive calls to 7. Strassen’s method is
similar to above simple divide and conquer method in the sense that this method also divides matrices to
sub-matrices of size N/2 x N/2 as shown in the above diagram, but in Strassen’s method, the four sub-
matrices of result are calculated using following formulae.
lOMoAR cPSD| 29148908