2. Divide and Conquer
• Using this method each recursive subproblem is
about one-half the size of the original problem
• If we could define power so that each subproblem
was based on computing kn/2
instead of kn – 1
we
could use the divide and conquer principle
• Recursive divide and conquer algorithms are often
more efficient than iterative algorithms
3. Evaluating Exponents Using
Divide and Conquer
int power(int k, int n) {
// raise k to the power n
if (n == 0)
return 1;
else{
int t = power(k, n/2);
if ((n % 2) == 0)
return t * t;
else
return k * t * t;
}
4. Stacks
• Every recursive function can be
implemented using a stack and iteration.
• Every iterative function which uses a stack
can be implemented using recursion.
10. Analysis
• To sort the halves (n/2)2
+(n/2)2
• To merge the two halves n
• So, for n=100, divide and conquer takes:
= (100/2)2
+ (100/2)2
+ 100
= 2500 + 2500 + 100
= 5100 (n2
= 10,000)
11. Divide and Conquer
• Why not divide the halves in half?
• The quarters in half?
• And so on . . .
• When should we stop?
At n = 1
15. Mergesort
• Mergesort is a divide and conquer algorithm
that does exactly that.
• It splits the list in half
• Mergesorts the two halves
• Then merges the two sorted halves together
• Mergesort can be implemented recursively
16. Mergesort
• The mergesort algorithm involves three
steps:
– If the number of items to sort is 0 or 1, return
– Recursively sort the first and second halves
separately
– Merge the two sorted halves into a sorted group
21. Mergesort
8 12 11 2 7 5
4
10
Split the list in half.
8 12
4
10
Mergesort the left half.
Split the list in half. Mergesort the left half.
4
10
Split the list in half. Mergesort the left half.
10
Mergesort the right.
4
22. Mergesort
8 12 11 2 7 5
4
10
8 12
4
10
4
10
Mergesort the right half.
Merge the two halves.
10
4 8 12
12
8
Merge the two halves.
8
8 12
23. Mergesort
8 12 11 2 7 5
4
10
8 12
4
10
Merge the two halves.
4
10
Mergesort the right half. Merge the two halves.
10
4 8 12
10 12
8
4
10
4 8 12
45. Mergesort Analysis
Merging the two lists of size n/2:
O(n)
Merging the four lists of size n/4:
O(n)
.
.
.
Merging the n lists of size 1:
O(n)
O (lg n)
times
Mergesort is O(n lg n)
Space?
The other sorts we have looked at (insertion,
selection) are in-place (only require a constant
amount of extra space)
Mergesort requires O(n) extra space for merging
46. Mergesort Analysis
• Mergesort is O(n lg n)
• Space?
• The other sorts we have looked at
(insertion, selection) are in-place (only
require a constant amount of extra space)
• Mergesort requires O(n) extra space for
merging
47. Quicksort
• Quicksort is another divide and conquer
algorithm
• Quicksort is based on the idea of
partitioning (splitting) the list around a
pivot or split value
48. Quicksort
First the list is partitioned around a pivot
value. Pivot can be chosen from the beginning,
end or middle of list):
8 3
2 11 7
5
4 10
12
4 5
5
pivot value
49. Quicksort
The pivot is swapped to the last position and
the
remaining elements are compared starting at
the
ends.
8 3 2 11 7 5
4 10
12
4 5
low high
5
pivot value
50. Quicksort
Then the low index moves right until it is at an
element
that is larger than the pivot value (i.e., it is on the
wrong side)
8 6 2 11 7 5
10
12
4 6
low high
5
pivot value
3
12
51. Quicksort
Then the high index moves left until it is at an
element that is smaller than the pivot value (i.e., it
is on the wrong side)
8 6 2 11 7 5
4 10
12
4 6
low high
5
pivot value
3 2
52. Quicksort
Then the two values are swapped and the
index values are updated:
8 6 2 11 7 5
4 10
12
4 6
low high
5
pivot value
3
2 12
53. Quicksort
This continues until the two index values pass
each other:
8 6 12 11 7 5
4
2
4 6
low high
5
pivot value
3
10
3 10
57. void quickSort(int array[], int size)
{
int index;
if (size > 1)
{
index = partition(array, size);
quickSort(array, index);
quickSort(array+index+1, size - index-1);
}
}
Quicksort
58. int partition(int array[], int size)
{
int k;
int mid = size/2;
int index = 0;
swap(array, array+mid);
for (k = 1; k < size; k++){
if (array[k] < array[0]){
index++;
swap(array+k, array+index);
}
}
swap(array, array+index);
return index;
}
Quicksort