Download presentation
Presentation is loading. Please wait.
Published byTerence Boyd Modified over 9 years ago
1
Divide-and-Conquer The most-well known algorithm design strategy: 1. Divide instance of problem into two or more smaller instances 2.Solve smaller instances recursively 3.Obtain solution to original (larger) instance by combining these solutions
2
Divide-and-Conquer Technique subproblem 2 of size n/2 subproblem 1 of size n/2 a solution to subproblem 1 a solution to the original problem a solution to subproblem 2 a problem of size n (instance) It general leads to a recursive algorithm!
3
Divide-and-Conquer Examples Sorting: merge sort and quicksort Binary tree traversals Binary search Multiplication of large integers Matrix multiplication: Strassen’s algorithm Closest-pair and convex-hull algorithms
4
General Divide-and-Conquer Recurrence T(n) = aT(n/b) + f (n) where f(n) (n d ), d 0 Master Theorem: If a < b d, T(n) (n d ) If a = b d, T(n) (n d log n) If a = b d, T(n) (n d log n) If a > b d, T(n) ( n log b a ) If a > b d, T(n) ( n log b a ) Note: The same results hold with O instead of . Examples: T(n) = 4T(n/2) + n T(n) ? T(n) = 4T(n/2) + n 2 T(n) ? T(n) = 4T(n/2) + n 2 T(n) ? T(n) = 4T(n/2) + n 3 T(n) ? T(n) = 4T(n/2) + n 3 T(n) ? (n^2) (n^2log n) (n^3)
5
Mergesort Split array A[0..n-1] into about equal halves and make copies of each half in arrays B and C Sort arrays B and C recursively Merge sorted arrays B and C into array A as follows: –Repeat the following until no elements remain in one of the arrays: compare the first elements in the remaining unprocessed portions of the arrays copy the smaller of the two into A, while incrementing the index indicating the unprocessed portion of that array –Once all elements in one of the arrays are processed, copy the remaining unprocessed elements from the other array into A.
6
Mergesort Example
7
Quicksort Select a pivot (partitioning element) – here, the first element Rearrange the list so that all the elements in the first s positions are smaller than or equal to the pivot and all the elements in the remaining n-s positions are larger than or equal to the pivot (see next slide for an algorithm) Exchange the pivot with the last element in the first (i.e., ) subarray — the pivot is now in its final position Sort the two subarrays recursively p A[i] p A[i] p
8
Quicksort Algorithm Given an array of n elements (e.g., integers): If array only contains one element, return Else –pick one element to use as pivot. –Partition elements into two sub-arrays: Elements less than or equal to pivot Elements greater than pivot –Quicksort two sub-arrays –Return results
9
Example We are given array of n integers to sort: 402010806050730100
10
Pick Pivot Element There are a number of ways to pick the pivot element. In this example, we will use the first element in the array: 402010806050730100
11
Partitioning Array Given a pivot, partition the elements of the array such that the resulting array consists of: 1.One sub-array that contains elements >= pivot 2.Another sub-array that contains elements < pivot The sub-arrays are stored in the original data array. Partitioning loops through, swapping elements below/above pivot.
12
402010806050730100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index
13
402010806050730100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index
14
402010806050730100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index
15
402010806050730100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index
16
402010806050730100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index
17
402010806050730100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index
18
402010806050730100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index]
19
402010306050780100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index]
20
402010306050780100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1.
21
402010306050780100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1.
22
402010306050780100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1.
23
402010306050780100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1.
24
402010306050780100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1.
25
402010306050780100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index 1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1.
26
1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 402010307506080100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index
27
1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 402010307506080100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index
28
1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 402010307506080100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index
29
1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 402010307506080100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index
30
1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 402010307506080100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index
31
1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 402010307506080100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index
32
1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 402010307506080100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index
33
1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 402010307506080100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index
34
1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 402010307506080100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index
35
1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] 402010307506080100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index
36
1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] 720103040506080100 pivot_index = 4 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index
37
Partition Result 720103040506080100 [0] [1] [2] [3] [4] [5] [6] [7] [8] <= data[pivot]> data[pivot]
38
Recursion: Quicksort Sub-arrays 720103040506080100 [0] [1] [2] [3] [4] [5] [6] [7] [8] <= data[pivot]> data[pivot]
39
Quicksort Analysis Assume that keys are random, uniformly distributed. What is best case running time?
40
Quicksort Analysis Assume that keys are random, uniformly distributed. What is best case running time? –Recursion: 1.Partition splits array in two sub-arrays of size n/2 2.Quicksort each sub-array
41
Quicksort Analysis Assume that keys are random, uniformly distributed. What is best case running time? –Recursion: 1.Partition splits array in two sub-arrays of size n/2 2.Quicksort each sub-array –Depth of recursion tree?
42
Quicksort Analysis Assume that keys are random, uniformly distributed. What is best case running time? –Recursion: 1.Partition splits array in two sub-arrays of size n/2 2.Quicksort each sub-array –Depth of recursion tree? O(log 2 n)
43
Quicksort Analysis Assume that keys are random, uniformly distributed. What is best case running time? –Recursion: 1.Partition splits array in two sub-arrays of size n/2 2.Quicksort each sub-array –Depth of recursion tree? O(log 2 n) –Number of accesses in partition?
44
Quicksort Analysis Assume that keys are random, uniformly distributed. What is best case running time? –Recursion: 1.Partition splits array in two sub-arrays of size n/2 2.Quicksort each sub-array –Depth of recursion tree? O(log 2 n) –Partition? O(n)
45
Quicksort Analysis Assume that keys are random, uniformly distributed. Best case running time: O(n log 2 n)
46
Quicksort Analysis Assume that keys are random, uniformly distributed. Best case running time: O(n log 2 n) Worst case running time?
47
Quicksort: Worst Case Assume first element is chosen as pivot. Assume we get array that is already in order: 24101213505763100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_index too_small_index
48
1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] 24101213505763100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_indextoo_small_index
49
1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] 24101213505763100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_indextoo_small_index
50
1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] 24101213505763100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_indextoo_small_index
51
1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] 24101213505763100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_indextoo_small_index
52
1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] 24101213505763100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_indextoo_small_index
53
1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] 24101213505763100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] too_big_indextoo_small_index
54
1.While data[too_big_index] <= data[pivot] ++too_big_index 2.While data[too_small_index] > data[pivot] --too_small_index 3.If too_big_index < too_small_index swap data[too_big_index] and data[too_small_index] 4.While too_small_index > too_big_index, go to 1. 5.Swap data[too_small_index] and data[pivot_index] 24101213505763100 pivot_index = 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] > data[pivot]<= data[pivot]
55
Quicksort Analysis Assume that keys are random, uniformly distributed. Best case running time: O(n log 2 n) Worst case running time? –Recursion: 1.Partition splits array in two sub-arrays: one sub-array of size 0 the other sub-array of size n-1 2.Quicksort each sub-array –Depth of recursion tree?
56
Quicksort Analysis Assume that keys are random, uniformly distributed. Best case running time: O(n log 2 n) Worst case running time? –Recursion: 1.Partition splits array in two sub-arrays: one sub-array of size 0 the other sub-array of size n-1 2.Quicksort each sub-array –Depth of recursion tree? O(n)
57
Quicksort Analysis Assume that keys are random, uniformly distributed. Best case running time: O(n log 2 n) Worst case running time? –Recursion: 1.Partition splits array in two sub-arrays: one sub-array of size 0 the other sub-array of size n-1 2.Quicksort each sub-array –Depth of recursion tree? O(n) –partition?
58
Quicksort Analysis Assume that keys are random, uniformly distributed. Best case running time: O(n log 2 n) Worst case running time? –Recursion: 1.Partition splits array in two sub-arrays: one sub-array of size 0 the other sub-array of size n-1 2.Quicksort each sub-array –Depth of recursion tree? O(n) –Partition? O(n)
59
Quicksort Analysis Assume that keys are random, uniformly distributed. Best case running time: O(n log 2 n) Worst case running time: O(n 2 )!!!
60
Quicksort Analysis Assume that keys are random, uniformly distributed. Best case running time: O(n log 2 n) Worst case running time: O(n 2 )!!! What can we do to avoid worst case?
61
Improved Pivot Selection Pick median value of three elements from data array: data[0], data[n/2], and data[n-1]. Use this median value as pivot.
62
Improving Performance of Quicksort Improved selection of pivot. For sub-arrays of size 3 or less, apply brute force search: –Sub-array of size 1: trivial –Sub-array of size 2: if(data[first] > data[second]) swap them –Sub-array of size 3: left as an exercise.
63
Quicksort Example 2 3 1 4 5 8 9 7 1 2 3 4 5 7 8 9
64
Analysis of Quicksort Best case: split in the middle — Θ (n log n) Worst case: sorted array! — Θ (n 2 ) Average case: random arrays — Θ (n log n)
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.