G DAA-Unit-II
G DAA-Unit-II
G DAA-Unit-II
}
}
The Time Complexity of many divide-and-conquer
algorithms is given by recurrences of the form
c n small
T(n) = aT(n/b)+f(n) Otherwise
Unsuccessful search:
O(log n)
2. Merge Sort
1. Base Case, solve the problem directly if it is
small enough(only one element).
Merge
A is sorted!
Merge-Sort(A, 0, 7)
Divide A 6 2 8 4 3 7 5 1
A: 6 2 8 4 3 7 5 1
Merge-Sort(A, 0, 7)
Merge-Sort(A, 0, 3) , divide
A: 3 7 5 1
6 2 88 4
4
Merge-Sort(A, 0, 7)
Merge-Sort(A, 0, 1) , divide
A: 3 7 5 1
8 4
6 2
2
Merge-Sort(A, 0, 7)
Merge-Sort(A, 0, 0) , base case
A: 3 7 5 1
8 4
6
Merge-Sort(A, 0, 7)
Merge-Sort(A, 0, 0), return
A: 3 7 5 1
8 4
6 2
Merge-Sort(A, 0, 7)
Merge-Sort(A, 1, 1) , base case
A: 3 7 5 1
8 4
2
Merge-Sort(A, 0, 7)
Merge-Sort(A, 1, 1), return
A: 3 7 5 1
8 4
6 2
Merge-Sort(A, 0, 7)
Merge(A, 0, 0, 1)
A: 3 7 5 1
8 4
2 6
Merge-Sort(A, 0, 7)
Merge-Sort(A, 0, 1), return
A: 3 7 5 1
2 6 8 4
Merge-Sort(A, 0, 7)
Merge-Sort(A, 2, 3) , divide
A: 3 7 5 1
2 6
8 4
Merge-Sort(A, 0, 7)
Merge-Sort(A, 2, 2), base case
A: 3 7 5 1
2 6
8
Merge-Sort(A, 0, 7)
Merge-Sort(A, 2, 2), return
A: 3 7 5 1
2 6
8 4
Merge-Sort(A, 0, 7)
Merge-Sort(A, 3, 3), base case
A:
2 6
4
Merge-Sort(A, 0, 7)
Merge-Sort(A, 3, 3), return
A: 3 7 5 1
2 6
8 4
Merge-Sort(A, 0, 7)
Merge(A, 2, 2, 3)
A: 3 7 5 1
2 6
4 8
Merge-Sort(A, 0, 7)
Merge-Sort(A, 2, 3), return
A: 3 7 5 1
2 6 4 8
Merge-Sort(A, 0, 7)
Merge(A, 0, 1, 3)
A: 3 7 5 1
2 4 6 8
Merge-Sort(A, 0, 7)
Merge-Sort(A, 0, 3), return
A: 2 4 6 8 3 7 5 1
Merge-Sort(A, 0, 7)
Merge-Sort(A, 4, 7)
A: 2 4 6 8
3 7 5 1
Merge-Sort(A, 0, 7)
Merge (A, 4, 5, 7)
A: 2 4 6 8
1 3 5 7
Merge-Sort(A, 0, 7)
Merge-Sort(A, 4, 7), return
A: 2 4 6 8 1 3 5 7
Merge-Sort(A, 0, 7)
Merge-Sort(A,
Merge(A, 0, 3, 0,
7) 7), done!
A: 1 2 3 4 5 6 7 8
Ex:- [179, 254, 285, 310, 351, 423, 450, 520, 652, 861]
1,10
1,5 6,10
{
mid ← (low+high)/2; Recursive Calls
MergeSort(low,mid);
MergeSort(mid+1, high);
Merge(low, mid, high);
}
}
Merge-Sort: Merge Example
low mid high
A: 2
5 3
5 7 28
15 8 30
1 4
6 5 14
10 6
B: 5 5 15 28 30 6 10 14
L: R:
3 5 15 28 6 10 14 22
Merge-Sort: Merge Example
A: 5 5 15 28 30 6 10 14
B:
3
1 5 15 28 30 6 10 14
i=low
3
2 15
3 28
7 30
8 6
1 10
4 14
5 22
6
h=low j=mid+1
Merge-Sort: Merge Example
A: 5 5 15 28 30 6 10 14
B:
1 2
5 15 28 30 6 10 14
3
2 5
3 15
7 28
8 6
1 10
4 14
5 22
6
h j
Merge-Sort: Merge Example
A: 5 5 15 28 30 6 10 14
B:
1 2 3 28 30
15 6 10 14
2 3 7 8 6
1 10
4 14
5 22
6
h j
Merge-Sort: Merge Example
A: 5 5 15 28 30 6 10 14
B:
1 2 3 4 6 10 14
2 3 7 8 6
1 10
4 14
5 22
6
h j
Merge-Sort: Merge Example
A: 5 5 15 28 30 6 10 14
B:
1 2 3 4 5 6 10 14
2 3 7 8 6
1 10
4 14
5 22
6
h j
Merge-Sort: Merge Example
A: 5 5 15 28 30 6 10 14
B:
1 2 3 4 5 6 10 14
2 3 7 8 6
1 10
4 14
5 22
6
h j
Merge-Sort: Merge Example
A: 5 5 15 28 30 6 10 14
B:
1 2 3 4 5 6 7 14
2 3 7 8 6
1 10
4 14
5 22
6
h j
Merge-Sort: Merge Example
A: 5 5 15 28 30 6 10 14
B:
1 2 3 4 5 6 7 8
14
3
2 5
3 15
7 28
8 6
1 10
4 14
5 22
6
h j
Merge-Sort: Merge Example
A: 5 5 15 28 30 6 10 14
B:
1 2 3 4 5 6 7 8
3
2 5
3 15
7 28
8 6
1 10
4 14
5 22
6
h j
A:
5 5 15 28 30 6 10 14
B: 1 2 3 4 5 6 7 8
Algorithm Merge(low,mid,high)
// a[low:high] is a global array containing two sorted subsets in a[low:mid]
// and in a[mid+1:high]. The goal is to merge these two sets into a single
// set residing in a[low:high]. b[ ] is a temporary global array.
{
h:=low; j:=mid+1; i:=low;
while( h ≤ mid ) and ( j ≤ high ) do
{
if( a[h] ≤ a[j] ) then
{
b[i]:=a[h]; h:=h+1;
}
else
{
b[i]:=a[j]; j:=j+1;
}
i:=i+1;
}
if( h > mid ) then
for k:=j to high do
{
b[i] := a[k]; i:= i+1;
}
else
for k:=h to mid do
{
b[i] := a[k]; i:= i+1;
}
for k:= low to high do a[k]:=b[k];
}
Merge-Sort Analysis
n
n/2 n/2
2 2 2
Merge-Sort Time Complexity
If the time for the merging operation is proportional to n, then the
computing time for merge sort is described by the recurrence relation
c1 n=1, c1 is a constant
T(n) =
2T(n/2) + c2n n>1, c2 is a constant
…..
…..
=2k T(1)+ kc2n
= c1n+c2nlogn = = O(nlogn)
Summary
• Merge-Sort
– Most of the work done in combining the
solutions.
– Best case takes o(n log(n)) time
– Average case takes o(n log(n)) time
– Worst case takes o(n log(n)) time
3. Quick Sort
• Divide:
• Pick any element as the pivot, e.g, the first
element
• Partition the remaining elements into
FirstPart, which contains all elements < pivot
SecondPart, which contains all elements > pivot
4 2 7 8 1 9 3 6 5
pivot
x y
The whole process
4 2 7 8 1 9 3 6 5
2 1 3 4 7 8 9 6 5
1 2 3 6 5 7 8 9
1 3 5 6 8 9
5 9
Process:
Keep going from left side as long as a[ i ]<pivot and from the right
side as long as a[ j ]>pivot
pivot 85 24 63 95 17 31 45 98
i j
85 24 63 95 17 31 45 98
i j
85 24 63 95 17 31 45 98
i j
85 24 63 95 17 31 45 98
i j
If i<j interchange ith and j th elements and
then Continue the process.
85 24 63 45 17 31 95 98
i j
85 24 63 45 17 31 95 98
i j
85 24 63 45 17 31 95 98
i
85 24 63 45 17 31 95 98
85 24 63 45 17 31 95 98
j i
Two sublists:
35 24 63 45 17 95 98
85
Recursively sort
FirstPart and SecondPart
QickSort( low, j-1 ) QickSort( j+1,high )
Quick Sort Algorithm :
Algorithm QuickSort(low,high)
//Sorts the elements a[low],…..,a[high] which resides
//in the global array a[1:n] into ascending order;
// a[n+1] is considered to be defined and must ≥ all the
// elements in a[1:n].
{
if( low< high ) // if there are more than one element
{ // divide p into two subproblems.
j :=Partition(low,high);
// j is the position of the partitioning element.
QuickSort(low,j-1);
QuickSort(j+1,high);
// There is no need for combining solutions.
}
}
Algorithm Partition(low, high)
{
pivot:= a[ low ]; i:=low; j:= high+1;
while( i < j ) do
{
i++;
while( a[ i ] < pivot ) do
i++;
j--;
while( a[ j ] > pivot ) do
j--;
c1 n=1, c1 is a constant
T(n) =
T(k) + T(n-k-1) +c2n n>1, c2 is a constant
A worst/bad case
It occurs if the list is already in sorted order
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9
3 4 5 6 7 8 9
4 5 6 7 8 9
5 6 7 8 9 O(n2)
6 7 8 9
7 8 9
8 9
9
Worst/bad Case
n cn
n-1 c(n-1)
n-2 c(n-2)
3c
3
2 2c
1c
1
contd...
• In the worst case, the list is always partitioned into
two sublists in which one of them is always empty.
Thus , for the worst case analysis,
= T(n-1) +c2n
= T(n-2) + c2 ( n -1)+ c2n
= T(n-3) + c2 ( n -2) + c2( n -1)+c2n
…..
…..
= n(n+1)/2 = ( n2+n)/2= O(n2)
A Best/Good case
• It occurs only if each partition divides the list into two
equal size sublists.
O(n logn)
Best/Good Case
n
n/2 n/2
2 2 2
c1 n=1, c1 is a constant
T(n) =
2T(n/2) + c2n n>1, c2 is a constant
…..
…..
=2k T(1)+ kc2n
= c1n+c2nlogn = = O(nlogn)
Summary
• Quick-Sort
– Most of the work done in partitioning
– Best case takes O(n log(n)) time
– Average case takes O(n log(n)) time
– Worst case takes O(n2) time
4.Strassen’s Matrix Multiplication
Basic Matrix Multiplication
Let A an B two n×n matrices. The product C=AB is also an n×n matrix.
c11 c12
1 1 2 2 5 5 6 6
C11=A11B11+A12B21
C11 C12 1 1 2 2 5 5 6 6
C12=A11B12+A12B22 C
C 21 C 22 3 3 4 4 7 7 8 8
C21=A21B11+A22B21 c21 c22 3 3 4 4 7 7 8 8
C22=A21B12+A22B22 A
21 22 21A B22 B
T(n)= c1 if n<=2
8T(n/2)+ c2n2 if n>2
T(n) = O(n3)
= 82 T(n/4)+ c22n2 + c 2 n2
= 8log n c + c 2 n2
2 1
.
8
log
=n 2 c1 + c n2 = n3 c1+ c2n2 = O(n3 )
Strassen’s method
• Matrix multiplications are more expensive than matrix
additions or subtractions( O(n3) versus O(n2)).
C11=M1 + M4 - M5 + M7
C12= M3 + M5
C21= M2 + M4
C22=M1 + M3 - M2 + M6
C11 C12 A11 A12 B11 B12
= *
C21 C22 A21 A22 B21 B22
M1 + M4 - M5 + M7 M3 + M5
=
M2 + M4 M1 + M3 - M2 + M6
T(n)= c1 n<=2
7T(n/2) +c2n2 n>2
T(n)= 7kT(1) + c2n2 1+ 7/4 + (7/4)2 + (7/4) 3+……………..+ (7/4)k-1
..
.