0% found this document useful (0 votes)
10 views51 pages

3 DaC

The document discusses the divide and conquer algorithm design paradigm, explaining how problems can be recursively broken down into simpler sub-problems until they can be solved directly. It includes examples of algorithms such as binary search, Fibonacci calculation, and merge sort, along with their time complexities. Additionally, it covers the Tower of Hanoi problem and methods for solving recurrence relations.

Uploaded by

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

3 DaC

The document discusses the divide and conquer algorithm design paradigm, explaining how problems can be recursively broken down into simpler sub-problems until they can be solved directly. It includes examples of algorithms such as binary search, Fibonacci calculation, and merge sort, along with their time complexities. Additionally, it covers the Tower of Hanoi problem and methods for solving recurrence relations.

Uploaded by

kiyodal984
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

DAC: TIME COMPLEXITY/RECURSIVE

FUNCTIONS
Problem

divide
Smaller Smaller
Problem Problem
divide
Smaller Smaller
Problem Problem
conquer
Sub
Solution
……………………
conquer

Solution
[Link]
1
DIVIDE AND CONQUER
Algorithm design paradigm based on multi-branched recursion.
A divide and conquer algorithm works by recursively breaking down a problem
into two or more sub-problems of the same or related type, until these become
simple enough to be solved directly.
The solutions to the sub-problems are then combined to give a solution to the
original problem.

int expo(int x, int n){ #define ll long long int


int fibo (int n) {
if (n==0) return 1; ll sum(int n)
if (n<2) return 1;
int p=expo(x,n/2); {
// BASE CONDITION
if (n%2) /* n is odd */ if (n == 1)
return fibo (n-1)
return x*p*p; return 1;
+fibo(n-2);
return p*p; else // Recursive call
}
} return
(ll) pow(n, n) + sum(n - 1));
}
2
GETTING THE RECURRENCE RELATION
Binary Search Assume Time
Complexity T(n)

int* bs (int a[ ],int n,int value){


T(1) = constant Or O(1)
if (n==0) return NULL; //BASE CONDITION
int mid=n/2;
if (a[mid] == value ) return &a[mid];
if (a[mid]>value) return bs(a,mid,value); //0 to mid - 1 (mid)
Either
return bs(a+mid+1,n-mid-1,value); //mid+1 to n-1 (n-mid-1) Or
}
// T(n)=T(n/2)+O(1)
// T(0)=1 T(n/2) +c

3
GETTING THE RECURRENCE RELATION
int expo(int x, int n){ //T(n) int fibo (int n) { #define ll long long int
if (n==0) return 1; //T(0)=1 if (n<2) return 1; ll sum(int n)
int p=expo(x,n/2);//T(n/2) // BASE CONDITION {
if (n%2) /* n is odd */ return fibo (n-1) if (n == 1) return 1;
return x*p*p; +fibo(n-2); else // Recursive call
return p*p; } return
} // T(n)=T(n-1)+T(n-2) (ll) n*n + sum(n - 1)); }
// T(n)=T(n/2)+O(1) // T(0)=T(1)=1 // T(n)=T(n-1)+c
// T(0)=1 // T(1)=T(1)
MergeSort(ary) //T(n)
bool isSorted(int *a, int n) {
{ if (n==1) return;
if (n == 1) return true;
ary_start = MergeSort(ary[0:n/2]); //T(n/2)
if (a[n-2] > a[n-1]) return false;
ary_end = MergeSort(ary[n/2:n]); //T(n/2)
else return isSorted(a, n-1);
return MergeArrays(ary_start, ary_end); //O(n)
}
}
// T(n)=T(n-1)+1, T(0)=1
// T(n)=2T(n/2)+O(n) , T(1)=1
4
TOWER OF HANOI
1. Only one disk can be moved at a time.
2. Each move consists of taking the upper disk from one of the stacks and
placing it on top of another stack i.e. a disk can only be moved if it is the
uppermost disk on a stack.
3. No disk may be placed on top of a smaller disk.
Solution: Label the pegs A, B, C, let n be the total number of discs
number the discs from 1 (smallest, topmost) to n (largest, bottommost)
To move n discs from peg A to peg C:
• move n−1 discs from A to B. This leaves disc n alone on peg A
• move disc n from A to C
• move n−1 discs from B to C so they
sit on disc n

5
TOWER OF HANOI AND RECURSION
void Hanoi (int n, char source, char dest, char aux){
//Base condition
if (n==1) printf("Move a disc from Peg %c TO %c\n",source,dest);
else {
Hanoi(n-1,source,aux,dest);
Hanoi(1,source,dest,-1);
Hanoi(n-1,aux,dest,source); Move a disc from Peg a TO b
Move a disc from Peg a TO c
} Move a disc from Peg b TO c
} Move a disc from Peg a TO b
int main(){ Move a disc from Peg c TO a
Hanoi(3,'a','b','c'); Move a disc from Peg c TO b
} Move a disc from Peg a TO b

6
TOWER OF HANOI AND RECURSION Assume Time
Complexity T(n)
void Hanoi (int n, char source, char dest, char aux){
//Base condition T(1) = Or O(1) constant
if (n==1) printf("Move a disc from Peg %c TO %c\n",source,dest);
else { T(n-1)
Hanoi(n-1,source,aux,dest); +
Hanoi(1,source,dest,-1); constant
Hanoi(n-1,aux,dest,source);
} +
T(n-1)
}
int main(){
Hanoi(3,'a','b','c');
}
T (n)  2T (n  1)  1, T (1)  1

7
MERGE SORT
void mergeSort(int n) // +ARRAY[n] // T(n)=
{
if () // BASE CONDITION
h1=mergeSort(n/2); Sort first half // T(n/2) +
h2=mergeSort(n/2); Sort second half // T(n/2) +
merge(h1,h2); // O(n)
}
// T(n) = 2T(n/2) +O(n),

8
MERGESORT EXAMPLE 8 3 2 9 7 1 5 4

8 3 2 9 7 1 5 4

The non-recursive (bottom-up)


version of Mergesort starts 8 3 2 9 71 5 4

from merging single elements


into sorted pairs. 8 3 2 9 7 1 5 4

Merge((8),(3))->(3,8)
Merge((2),(9))->(2,9) 3 8 2 9 1 7 4 5


2 3 8 9 1 4 5 7
Merge((3,8),(2,9)->(2,3,8,9)
… 1 2 3 4 5 7 8 9

9
def mergeSort(myList): #Recursive : T(n),
if len(myList) > 1: #T(0)=c
mid = len(myList) // 2
MERGESORT IN PYTHON
left = myList[:mid]
right = myList[mid:]
# Recursive call on each half 2*T(n/2)
mergeSort(left)
mergeSort(right)
i,j,k= 0,0,0
#### O(n)
while i < len(left) and j < len(right): Before [6, 2, 9, 5]
if left[i] < right[j]: myList[k] = left[i];i += 1 After [2, 5, 6, 9]
else: myList[k] = right[j]; j += 1 Before [100,14,119,26,127,31,133,35, 142,44]
k += 1
After [14,26,31,35,44,100,119,127,133,142]
while i < len(left): myList[k] = left[i];i += 1;k += 1
while j < len(right): myList[k]=right[j];j += 1;k += 1
myList = [6,2,9,5];print("Before",myList);
mergeSort(myList);print('After',myList)
myList=[100,14,119,26,127,31,133,35,142,44]
print("Before",myList);mergeSort(myList);print('After',myList)

10
def mergeSort(a): #Iterative
current_size = 1
while current_size <= len(a) - 1:
MERGESORT IN PYTHON
left = 0
while left < len(a)-1:
mid = min((left + current_size - 1),(len(a)-1))
right =min(len(a)-1,2 * current_size + left - 1)
merge(a, left, mid, right)
left += current_size*2
current_size *= 2
def merge(a, l, m, r): #left from l to m, right from m+1 to r SO:
n1 = m - l + 1;n2 = r - m
L=a[l:m+1];R=a[m+1:r+1]
i, j, k = 0, 0, l
while i < n1 and j < n2: #Do Merge a=[8,3,2,9,7,1,5,4]
if L[i] > R[j]:a[k] = R[j];j += 1 print("Before:",a)
else: a[k] = L[i];i += 1 mergeSort(a)
k += 1
print("After :",a)
while i < n1: a[k] = L[i];i += 1;k += 1 #Remaining parts
while j < n2: a[k] = R[j];j += 1;k += 1 #Remaining parts Before: [8, 3, 2, 9, 7, 1, 5, 4]
After : [1, 2, 3, 4, 5, 7, 8, 9]
11
MERGESORT() - C
#include <stdio.h>
#define max 10
int a[10] = { 100,14,119,26,127,31,133,35, 142, 44 };
int b[10];// Bad Global Arrays ! void sort(int low, int high) {
void merging(int low, int mid, int high) { int mid;
int l1, l2, i;
for(l1 = low, l2 = mid + 1, i = low; if(low < high) {
l1 <= mid && l2 <= high; i++) {
if(a[l1] <= a[l2]) mid = (low + high) / 2;
b[i] = a[l1++]; sort(low, mid);
else sort(mid+1, high);
b[i] = a[l2++]; merging(low, mid, high);
} } else {
while(l1 <= mid) b[i++] = a[l1++];
while(l2 <= high) b[i++] = a[l2++]; return;
for(i = low; i <= high; i++) }
a[i] = b[i]; }
}

12
SOLVING A RECURRENT RELATION
1: SUBSTITUTION METHOD
• Guess the Solution.
• Use the mathematical induction method

Binary Search Merge Sort


T (n)  T (n / 2)  1, T (1)  1 T (n)  2T (n / 2)  n, T (1)  1
 Assume T(n)=O(log(n)) is true for n/2  Assume T(n)=O(n log(n)) is true for n/2
So T(n/2)≤c * log(n/2) So T(n/2)≤c * n/2 log(n/2)
Substituting in the RR: Substituting in the RR:
T(n)=T(n/2)+1 ≤ c * log(n/2) +1 T(n)=T(n/2)+n ≤ c * n log(n/2) +n
≤ cnlog(n)-c n log(2)+n
≤ clog(n)-clog(2)+1(assume c>1) ≤ cnlog(n)
≤ clog(n)

13
SOLVING A RECURRENT RELATION
2: ITERATION METHOD Tower of Hanoi

 Re-Substitute till reaching base condition


T (n)  2T (n  1)  1 T(n) r=0
2T(n-1)+1 r=1
T (1)  1 22T(n-2)+21+1 r=2
23T(n-3)+22+21+1 r=3
--------------------
2rT(n-r)+(2r-1 -1) r
--------------------
Hence
𝑑𝑒𝑝𝑡ℎ 𝑛−2 𝑖
2depth T(1)
T(n)=2 + 0 2 depth d=?
=2𝑛−1 + 𝑛−2 𝑖
0 2 n-depth=1
depth=n-1
= 2𝑛 −1
14
SOLVING A RECURRENT RELATION
2: ITERATION METHOD
 Re-Substitute till reaching base condition

Binary Search Merge Sort

T (n)  T (n / 2)  1, T (1)  1 T (n)  2T (n / 2)  n, T (1)  1


 =T(n/4)+1+1  =22T(n/4)+n+n
*T(n/2)=T(n/4)+1 *T(n/2)=2T(n/4)+n/2
 =T(n/8)+1+1+1  =23T(n/8)+3n
… …
 =T(n/2r )+r  =2rT(n/2r )+rn
Depth when 2=1,i.e, r=log2(n) Depth when 2=1,i.e, r=log2(n)
T(n)=T(1)+log2(n)=(log2 n) T(n)=2 log2 n T(1)+nlog2(n)=(nlog2 n)

15
SOLVING A RECURRENT RELATION T ( n)  3T ( n / 2)  n;T( 1 )  1
2: ITERATION METHOD (TELESCOPING) [T(n/ 2 )  3T(n/ 4 )  cn/ 2 ]
n
T ( n)  2T ( n / 2)  cn 3 T( 1 )  32 T( 2n2 )  n * 3 / 2
1

2
[T(n/ 2 )  2T(n/ 4 )  cn/ 2 ] n
32 T( 2 )  33 T( 2n3 )  n * (3 / 2) 2
n 2
2 T( 1 )  2 2 T( 2n2 )  cn
1 ..........
2 n
3d 1T( d 1 )  3d T( 2nd )  n * (3 / 2) d 1
n 2
2 2 T( 2 )  23 T( 2n3 )  cn n
Merge Sort

2 3 T( d )  3 T( 1 )  3 O( 1 )  n log 2 3O (1)
d d log n2

2
.......... 
log 2 ( n )
d 1 n n[ 3  1]
2 T( d 1
)  2 d T( n
2d
)  cn   n(3 / 2)  i 2 
2 i  0 , log 2 n 1
3 1
n 2
2 d T( d )  2 d T( 1 )  2 log 2 O( 1 )  cn
n log 2 ( n )
 2n( 3  1)  2n( n log 2 ( 3 / 2 )  1) 
2 2
log 2 3 log 2 2
 2n( n  1)  2n( n log 2 3 / n  1)
  Erat
Quod  Demonstrandum

T ( n)  O ( n log 2 3  n)   ( n log 2 3 )   ( n log 2 3 )
T ( n)  dcn  cn  O ( n log(n)  n) Q.E.D
16
SOLVING A RECURRENT RELATION d  depth  log b n

3: RECURRENCE TREE # leaves  a depth  a logb n


# leaves  n logb a
T(N)=aT(n/b)+f(n), T(1)=(1)

n
T ( n)   ( n log b a
  a f ( i ))
i

17 i  0 , d 1 b
ab2
SOLVING A RECURRENT RELATION depth  log 2 n
3: RECURRENCE TREE # leaves  2 depth  2 log 2 n
# leaves  n log 2 2  n
T(N)=2T(n/2)+1, T(1)=1 Tn

Tn/2 1 Tn/2 1
af(n/b)=2
Tn/4 1 Tn/4 Tn/4 1 Tn/4 2

Tn/8 1 Tn/8 Tn/8 1 Tn/8 Tn/8 1 Tn/8 Tn/8 1 Tn/8 4 d


sum=
1+2+…2log(d)-1=
2log(d) -1=n-1
(1) (1) (1) (1) T (n)   (n  n  1)   (n) (1) (1) (1) (1)

2d
sum=2d =n
18
ab2
SOLVING A RECURRENT RELATION depth  log 2 n
3: RECURRENCE TREE # leaves  2 depth  2 log 2 n
# leaves  n log 2 2  n
Merge Sort: T(N)=2T(n/2)+n,T(1)=1
Tn

Tn/2 n Tn/2 n
2(n/2)
Tn/4 n/2 Tn/4 Tn/4 n/2 Tn/4 n
4(n/4)
Tn/8 n/4 Tn/8 Tn/8 n/4 Tn/8 Tn/8 n/4 Tn/8 Tn/8 n/4 Tn/8 n d
sum=
n*d=
n*log(n)
(1) (1) (1) (1) T(n)  θ(n  n log 2 n)  θ(n log 2 n) (1) (1) (1) (1)

2d
sum=2d = 2log(n) = n
19
SOLVING A RECURRENT RELATION
4: MASTER THEOREM
Let c crit  log b a
1. If f(n)  O(n crit - ) then T(n)  (n crit )
2. If f(n)  (n crit log k n) where k  0 then T(n)  (n crit log kb 1n)
[Link] f(n)  (n crit  ) then T(n)  (f(n))
c1) for cases 1,3 : ε is a constant such that ε  0.
c2) for case 3 : (regularity condition) There must exist a constant
c  1 such that af(n/b)  cf(n) for large n.

20
MASTER METHOD, EXAMPLE 1
Example (Binary search): T (n)  T (n / 2)  1
Let c crit  log b a
1. If f(n)  O(n crit - ) then T(n)  (n crit )
2. If f(n)  (n crit log k n) where k  0 then T(n)  (n crit log kb 1n)
[Link] f(n)  (n crit  ) then T(n)  (f(n))
c1) for cases 1,3 : ε is a constant such that ε  0.
c2) for case 3 : (regularity condition) There must exist a constant
c  1 such that af(n/b)  cf(n) for large n.

a=1,b=2
Solution:c crit  log b a  0
Case 2: with k=0, hence T(n) is ( log2 n).
21
MASTER METHOD, EXAMPLE 2
Example: T (n)  2T (n / 2)  n log n
Let c crit  log b a
1. If f(n)  O(n crit - ) then T(n)  (n crit )
2. If f(n)  (n crit log k n) where k  0 then T(n)  (n crit log kb 1n)
[Link] f(n)  (n crit  ) then T(n)  (f(n))
c1) for cases 1,3 : ε is a constant such that ε  0.
c2) for case 3 : (regularity condition) There must exist a constant
c  1 such that af(n/b)  cf(n) for large n.

a=b=2
Solution:c crit  log b a  1
Case 2: with k=1, hence T(n) is (n log2 n).
22
MASTER METHOD, EXAMPLE 3
Example: T (n)  T (n / 3)  n log n
Let c crit  log b a
1. If f(n)  O(n crit - ) then T(n)  (n crit )
2. If f(n)  (n crit log k n) where k  0 then T(n)  (n crit log kb 1n)
[Link] f(n)  (n crit  ) then T(n)  (f(n))
c1) for cases 1,3 : ε is a constant such that ε  0.
c2) for case 3 : (regularity condition) There must exist a constant
c  1 such that af(n/b)  cf(n) for large n.

a=1,b=3 c1)f(n)/ncrit=n log(n)>n


Solution: c crit  log b a  0 or: n log(n)/n0> n
Case 3: hence T(n) is (n log2 n). c2)n log(n/b) <log(n)
23
MASTER METHOD, EXAMPLE 4
Example: T (n)  8T (n / 2)  n 2

Let c crit  log b a


1. If f(n)  O(n crit - ) then T(n)  (n crit )
2. If f(n)  (n crit log k n) where k  0 then T(n)  (n crit log kb 1n)
[Link] f(n)  (n crit  ) then T(n)  (f(n))
c1) for cases 1,3 : ε is a constant such that ε  0.
c2) for case 3 : (regularity condition) There must exist a constant
c  1 such that af(n/b)  cf(n) for large n.

a=8,b=2 c1) f(n)/ncrit=n-1=O(n-)


Solution: c crit  log b a  3 or: n2/ n3 <n-
Case 1: hence T(n) is (n 3).
24
MASTER METHOD, EXAMPLE 5
Example: T (n)  9T (n / 3)  n 3

Let c crit  log b a


1. If f(n)  O(n crit - ) then T(n)  (n crit )
2. If f(n)  (n crit log k n) where k  0 then T(n)  (n crit log kb 1n)
[Link] f(n)  (n crit  ) then T(n)  (f(n))
c1) for cases 1,3 : ε is a constant such that ε  0.
c2) for case 3 : (regularity condition) There must exist a constant
c  1 such that af(n/b)  cf(n) for large n.

a=9,b=3 c1) f(n)/ncrit=n=(n+)


Solution: c crit  log b a  2 or: n 3 /n2> n
Case 3: hence T(n) is (n 3). c2) 9(n/3)3 <9/26 n3
25
MASTER METHOD, EXAMPLE 5
Example: T (n)  9T (n / 3)  n
Let c crit  log b a
1. If f(n)  O(n crit - ) then T(n)  (n crit )
2. If f(n)  (n crit log k n) where k  0 then T(n)  (n crit log kb 1n)
[Link] f(n)  (n crit  ) then T(n)  (f(n))
c1) for cases 1,3 : ε is a constant such that ε  0.
c2) for case 3 : (regularity condition) There must exist a constant
c  1 such that af(n/b)  cf(n) for large n.

a=9,b=3 c1) f(n)/ncrit=n-1


=O(n-)
Solution: c crit  log b a  2
Case 1: hence T(n) is (n 2).
26
MASTER METHOD, EXAMPLE 6
Example: T (n)  4T (n / 2)  n
Let c crit  log b a
1. If f(n)  O(n crit - ) then T(n)  (n crit )
2. If f(n)  (n crit log k n) where k  0 then T(n)  (n crit log kb 1n)
[Link] f(n)  (n crit  ) then T(n)  (f(n))
c1) for cases 1,3 : ε is a constant such that ε  0.
c2) for case 3 : (regularity condition) There must exist a constant
c  1 such that af(n/b)  cf(n) for large n.

a=4,b=2

27
MASTER METHOD, EXAMPLE 6
Example: T (n)  4T (n / 2)  n
Let c crit  log b a
1. If f(n)  O(n crit - ) then T(n)  (n crit )
2. If f(n)  (n crit log k n) where k  0 then T(n)  (n crit log kb 1n)
[Link] f(n)  (n crit  ) then T(n)  (f(n))
c1) for cases 1,3 : ε is a constant such that ε  0.
c2) for case 3 : (regularity condition) There must exist a constant
c  1 such that af(n/b)  cf(n) for large n.

a=4,b=2 c1) f(n)/ncrit=n-1


Solution: c crit  log b a  2 <O(n-)
Case 1: hence T(n) is (n 2).
28
MASTER METHOD, EXAMPLE 7
Example: T (n)  3T (n / 2)  n;T( 1 )  1
Let c crit  log b a
1. If f(n)  O(n crit - ) then T(n)  (n crit )
2. If f(n)  (n crit log k n) where k  0 then T(n)  (n crit log kb 1n)
[Link] f(n)  (n crit  ) then T(n)  (f(n))
c1) for cases 1,3 : ε is a constant such that ε  0.
c2) for case 3 : (regularity condition) There must exist a constant
c  1 such that af(n/b)  cf(n) for large n.

a=3,b=2 c1) f(n)/ncrit= n-.585


Solution:c crit  log 2 3  1.585 <O(n-)
Case 1: hence T(n) is (n 1.585).
29
MASTER METHOD, EXAMPLE 8
Example: T (n)  2T (n / 2)  log(n);T( 1 )  1
Let c crit  log b a
1. If f(n)  O(n crit - ) then T(n)  (n crit )
2. If f(n)  (n crit log k n) where k  0 then T(n)  (n crit log kb 1n)
[Link] f(n)  (n crit  ) then T(n)  (f(n))
c1) for cases 1,3 : ε is a constant such that ε  0.
c2) for case 3 : (regularity condition) There must exist a constant
c  1 such that af(n/b)  cf(n) for large n.

a=2,b=2 c1) f(n)/ncrit=log(n)/n


Solution: c crit  log 2 2  1 <O(n-), 0<<1
Case 1: hence T(n) is (n).
30
HOWEVER
MASTER THEOREM EXCEPTIONALITY
Gap between cases 1 and 2 : f (n)  n crit : f(n) is asymptotically smaller
but not polynomially smaller, i.e., does not satisfy :
f ( n) 
crit
 n ( for some positive constant  )
n
Gap between cases 3 and 2 : f (n)  n crit : f(n) is asymptotically larger
but not polynomially larger, i.e., does not satisfy :
f ( n) 
crit
 n ( for some positive constant  )
n
or regularity condition fails to hold

31
MASTER METHOD, GAP EXAMPLE 9
Example:T ( n)  2T ( n / 2)  n log(n);T( 1 )  1
Let c crit  log b a
1. If f(n)  O(n crit - ) then T(n)  (n crit )
2. If f(n)  (n crit log k n) where k  0 then T(n)  (n crit log kb 1n)
[Link] f(n)  (n crit  ) then T(n)  (f(n))
c1) for cases 1,3 : ε is a constant such that ε  0.
c2) for case 3 : (regularity condition) There must exist a constant
c  1 such that af(n/b)  cf(n) for large n.
c1) f(n)/ncrit=log(n)
a=2,b=2 >O(n)
Solution: c crit  log 2 2  1 f(n) is asymptotically
Case 3: wrong larger ,but not
32
polynomially larger
MASTER METHOD, EXAMPLE 10
Example: T (n)  3T (n / 4)  nlog (n)
Let c crit  log b a
1. If f(n)  O(n crit - ) then T(n)  (n crit )
2. If f(n)  (n crit log k n) where k  0 then T(n)  (n crit log kb 1n)
[Link] f(n)  (n crit  ) then T(n)  (f(n))
c1) for cases 1,3 : ε is a constant such that ε  0.
c2) for case 3 : (regularity condition) There must exist a constant
c  1 such that af(n/b)  cf(n) for large n.

a=3,b=4

33
MASTER METHOD, EXAMPLE 10
Example: T (n)  3T (n / 4)  nlog (n)
Let c crit  log b a
1. If f(n)  O(n crit - ) then T(n)  (n crit )
2. If f(n)  (n crit log k n) where k  0 then T(n)  (n crit log kb 1n)
[Link] f(n)  (n crit  ) then T(n)  (f(n))
c1) for cases 1,3 : ε is a constant such that ε  0.
c2) for case 3 : (regularity condition) There must exist a constant
c  1 such that af(n/b)  cf(n) for large n.
c1) f(n)/ncrit=n0.2log(n)
a=3,b=4
=(n+) or: > n
Solution:c crit  log b a  0.793
c2) 3(n/4)log(n/4)
Case 3: hence T(n) is (n log(n))
≤(3/4)n log n=cf(n)
34
EXAMPLE 1: NAÏVE MATRIX MULTIPLY
//implementation C = A*B
for i = 1 to n C(i,j) C(i,j) A(i,:)
for j = 1 to n = + B(:,j)
*
for k = 1 to n
C(i,j) = C(i,j) + A(i,k) * B(k,j)

Clearly T(n)=O(n3); complexity of


matrix addition is O(n2)

EXAMPLE 1: DAC
A  B = R
•Divide matrices into sub-
matrices: A0 , A1, A2 etc
A0 A1 B0 B1 A0B0+A1B2 A0B1+A1B3
 =
•Use blocked matrix
multiply equations
A2 A3 B2 B3 A2B0+A3B2 A2B1+A3B3 •Recursively multiply sub-
matrices

35
EXAMPLE 1: DIVIDE AND CONQUER MATRIX MULTIPLY
A  B = C
A0 A1 B0 B1 A0B0+A1B2 A0B1+A1B3
 =
A2 A3 B2 B3 A2B0+A3B2 A2B1+A3B3

T (n)  8T (n / 2)  n , T (1)  1
2
T ( n)   n  log2 8

T ( n)  n 3

this no better than the original, direct


algorithm; however …
36
EXAMPLE 1: STRASSENS’S MATRIX MULTIPLICATION
C11 C12 A11 A12 B11 B12
= *
C21 C22 A21 A22 B21 B22

P1 = (A11+ A22)(B11+B22)
P2 = (A21 + A22) * B11
C11 = P1 + P4 - P5 + P7
P3 = A11 * (B12 - B22)
C12 = P3 + P5
P4 = A22 * (B21 - B11)
C21 = P2 + P4 T ( n)  7 T (n / 2)  n 2 , T (1)  1
P5 = (A11 + A12) * B22
C22 = P1 + P3 - P2 + P6
P6 = (A21 - A11) * (B11 + B12)
P7 = (A12 - A22) * (B21 + B22)
a  7; b  2; d  2; a  b ; so 2

T ( n )  ( n log b a
)  ( n log 2 7
)
T (n)  (n 2.58 )
37
EXAMPLE 2: QUICKSORT
Efficient sorting algorithm
 Discovered by C.A.R. Hoare
Example of Divide and Conquer algorithm
Two phases
 Partition phase
 Divides the work into half < pivot pivot > pivot
 Choose a pivot
 Find the position for the pivot so that
 all elements to the left are less
 all elements to the right are greater
< pivot > pivot

 Sort phase < p’ p’ > p’ pivot < p” p” > p”


 Conquers the halves!
 Apply the same algorithm to each half
38
EXAMPLE 2: QUICKSORT
quicksort( void *a, int low, int high )
{
int pivot;
/* Termination condition! */
if ( high > low )
{
pivot = partition( a, low, high ); Divide

quicksort( a, low, pivot-1 );


quicksort( a, pivot+1, high ); Conquer

}
}
39
QUICKSORT - PARTITION
int partition( int *a, int low, int high ) {
int left, right;
int pivot_item;
pivot_item = a[low];
pivot = left = low;
right = high;
while ( left < right ) {
/* Move left while item < pivot */
while( a[left] <= pivot_item ) left++;
/* Move right while item > pivot */
while( a[right] >= pivot_item ) right--;
if ( left < right ) SWAP(a,left,right);
}
/* right is final position for the pivot */
a[low] = a[right];
a[right] = pivot_item;
return right;
}
40
QUICKSORT - PARTITION
int partition( int *a, int low, int high ) {
This example
uses int’s
int left, right; to keep things
int pivot_item; simple!
pivot_item = a[low];
pivot = left = low;
right = high; Any item will do as the pivot,
while ( left < right ) { choose the leftmost one!
/* Move left while item < pivot */
while( a[left] <= pivot_item ) left++;
/* Move right while item > pivot */
while( a[right] >= pivot_item ) right--;
if ( left < right ) SWAP(a,left,right);
}
23 12 15 38 42 18 36 29 27
/* right is final position for the pivot */
a[low] = a[right];
a[right] = pivot_item;
return right;
} low high

41
QUICKSORT - PARTITION
int partition( int *a, int low, int high ) {
int left, right;
int pivot_item;
pivot_item = a[low];
pivot = left = low; Set left and right markers
right = high;
while ( left < right ) {
/* Move left while item < pivot */
while(
left a[left] <= pivot_item ) left++;right
/* Move right while item > pivot */
while( a[right] >= pivot_item ) right--;
if (23left12 < right
15 38) SWAP(a,left,right);
42 18 36 29 27
}
/* right is final position for the pivot */
a[low] = a[right];
low pivot: 23 high
a[right] = pivot_item;
return right;
}

42
QUICKSORT - PARTITION
int partition( int *a, int low, int high ) {
int left, right;
int pivot_item;
pivot_item = a[low];
pivot = left = low; Move the markers
right = high; until they cross over
while ( left < right ) {
/* Move left while item < pivot */
while( a[left] <= pivot_item ) left++;
/* Move right while item > pivot */
while( a[right] >= pivot_item ) right--;
if ( left < right ) SWAP(a,left,right);
} left right
/* right is final position for the pivot */
a[low] = a[right];
23 12 15 38 42 18 36 29 27
a[right] = pivot_item;
return right;
} low pivot: 23 high

43
QUICKSORT - PARTITION
int partition( int *a, int low, int high ) {
int left, right;
int pivot_item;
pivot_item = a[low];
pivot = left = low;
right = high; Move the left pointer while
while ( left < right ) { it points to items <= pivot
/* Move left while item < pivot */
while( a[left] <= pivot_item ) left++;
/* Move right while item > pivot */
while( a[right] >= pivot_item ) right--;
if ( left < right ) SWAP(a,left,right);
} left right
Move right
/* right is final position for the pivot */ similarly
a[low] = a[right];
23 12 15
a[right] 38 42 18 36 29 27
= pivot_item;
return right;
}
low pivot: 23 high

44
QUICKSORT - PARTITION
int partition( int *a, int low, int high ) {
int left, right;
int pivot_item;
pivot_item = a[low];
pivot = left = low;
Swap the two items
right = high; on the wrong side of the pivot
while ( left < right ) {
/* Move left while item < pivot */
while( a[left] <= pivot_item ) left++;
/* Move right while item > pivot */
while( a[right] >= pivot_item ) right--;
if ( left < right ) SWAP(a,left,right);
}
left
/* right is final right for the pivot */
position
a[low] = a[right];
a[right]
23 12 15= pivot_item;
38 42 18 36 29 27
return right;
pivot: 23
}
low high

45
QUICKSORT - PARTITION
int partition( int *a, int low, int high ) {
int left, right;
int pivot_item; left and right
pivot_item = a[low]; have swapped over,
pivot = left = low;
right = high; so stop
while ( left < right ) {
/* Move left while item < pivot */
while( a[left] <= pivot_item ) left++;
/* Move right while item > pivot */
while( a[right] >= pivot_item ) right--;
if ( left < right ) SWAP(a,left,right);
}
/* right isright left
final position for the pivot */
a[low] = a[right];
a[right]
23 12 15= pivot_item;
18 42 38 36 29 27
return right;
}
low pivot: 23 high

46
QUICKSORT - PARTITION
int partition( int *a, int low, int high ) {
int left, right;
int pivot_item;
pivot_item = a[low];
pivot = left = low;
right = high;
right left
while ( left < right ) {
/* Move left while item < pivot */

23 12while(
15 a[left]
18 42 <=
38 pivot_item
36 29 ) 27left++;
/* Move right while item > pivot */
while( a[right] >= pivot_item ) right--;
low if ( left < right
pivot: 23 ) SWAP(a,left,right);
high
}
/* right is final position for the pivot */
a[low] = a[right];
Finally, swap the pivot
a[right] = pivot_item; and right
return right;
}

47
QUICKSORT - PARTITION
int partition( int *a, int low, int high ) {
int left, right;
int pivot_item;
pivot_item = a[low];
pivot = left = low;
right
right = high;
while ( left < right ) { pivot: 23
/* Move left while item < pivot */
18 12while(
15 a[left]
23 42<= pivot_item
38 36 29 27
) left++;
/* Move right while item > pivot */
while( a[right] >= pivot_item ) right--;
low high
if ( left < right ) SWAP(a,left,right);
}
/* right is final position for the pivot */
a[low] = a[right]; Return the position
a[right] = pivot_item; of the pivot
return right;
}

48
QUICKSORT - CONQUER
pivot: 23 Time Performance Worst Case
T (n)  T (n  1)  T (1)   (n), T (1)  1
18 12 15 23 42 38 36 29 27 T ( n)   ( n 2 )

Time Performance Best Case


Recursively
sort left half
Recursively T (n)  2T (n / 2)   (n), T (1)  1
sort right half
T (n)   (nlog (n))

Time Performance Constant proportion 10 / 9


T (n)  T (9n / 10)  T (n / 10)   (n), T (1)  1
49
T (n)   (nlog (n))
QUICKSORT - WHY BOTHER?
Quicksort is generally faster
 Fewer comparisons and exchanges
 Some empirical data
Average Time Performance
1
T (n)  [ p 1 T ( p  1)   p 1 T (n  p )]  n  1, T (1)  1
n n

n
T (n)   (nlog (n))

Quick Heap Insert


n
Comp Exch Comp Exch Comp Exch
100 712 148 2842 581 2595 899
200 1682 328 9736 9736 10307 3503
500 5102 919 53113 4042 62746 21083
50
THANKS

51

You might also like