(Divide and Conquer) - Merge and Quick Sort
(Divide and Conquer) - Merge and Quick Sort
3
Divide and Conquer Approach
● Divide the problems into a number of sub problems.
4
Merge sort
● Merge sort: orders a list of values by recursively dividing the list in half
until each sub-list has one element, then recombining
■ Invented by John von Neumann in 1945
● More specifically:
■ Divide the n element sequence to be sorted into two subsequences of
n/2 elements each.
■ Conquer: Sort the two subsequences to produce the sorted answer.
■ Combine: Merge the two sorted sub sequences to produce the sorted
answer.
mergeSort(0, mergeSort(n/2,
n/2-1) n-1)
5
sor merge(0, n/2, sor
t n-1) t
Merge sort
Base Case: When the sequences to be sorted has length 1.
Unsorted
Sorted 66
12 108
14 56
34 14
56 89
66 12
89 108
34
Divide
Merge Divide
Merge
66
14 108
56 56
66 108
14 89
12 12
34 34
89
Divide
Merge Divide
Merge Divide
Merge Divide
BCase
Merge
66 108 56
14 14
56 89
12 12
89 34
66 108
Divide
BCase
Merge Divide
BCase
Merge Divide
BCase
Merge Divide
BCase
Merge
6
56 89 12
66 108 14
Merge Sort Pseudo Code
7
Merge Sort Pseudo Code (2)
8
Merging Algorithm
● The merge operation:
■ Given two sorted arrays, merge operation produces a
sorted array with all the elements of the two arrays
■ Temporary array is used to store the sorted elements
from the two arrays
A 6 13 18 21 B 4 8 9 20
C 4 6 8 9 13 18 20 21
● It is easy to see that the Merge (A1, A2, A) takes the linear
time. Consequently,
11
Each level O(n) operations & O(log2n) levels 🡪
O(n*log2n)
Mergesort Analysis
● Advantage:
■ Mergesort is an extremely fast algorithm.
● Disadvantage:
■ Mergesort requires a second array as large as the original array.
12
Quick sort
● Key Points:
■ choose one element in the list to be the pivot (= partition
element)
■ organize the elements so that all elements less than the
pivot are to its left and all greater are to its right
■ apply the quick sort algorithm (recursively) to both
partitions
13
Quicksort Outline
● Divide and conquer approach
● Given array S to be sorted
• If size of S < 1 then done;
• Pick any element v in S as the pivot
• Partition S-{v} (remaining elements in S) into two groups
• S1 = {all elements in S-{v} that are smaller than v}
• S2 = {all elements in S-{v} that are larger than v}
• Return {quicksort(S1) followed by v followed by quicksort(S2)
}
● Trick lies in handling the partitioning (step 3).
■ Picking a good pivot
■ Efficiently partitioning in-place
14
Quick sort illustrated
pick a pivot
40 18 37 2
10 32 6 35
12 17
partitio
6 17 n 40 37
10 12 2 18 32 35
quicksort quicksort
2 6 10 12 17 18 32 35 37 40
combine 15
2 6 10 12 17 18 32 35 37 40
Pseudocode
16
Pseudocode
● To partition a[left...right]:
1. Set p = a[left], l = left + 1, r = right;
2. while l < r, do
2.1. while l < right & a[l] < p, set l = l +
1
2.2. while r > left & a[r] >= p, set r = r
-1
2.3. if l < r, swap a[l] and a[r]
3. Set a[left] = a[r], a[r] = p 18
4. Terminate
Example of partitioning
n/2 n/2 n
T(n) = 2 T(n/2) + cn 21
22
O (n lg n)
Quicksort: Worst Case Analysis
● Assume that keys are random, uniformly distributed.
● What is worst case running time?
● Pivot is the smallest (or largest) element all the time.
■ Recursion:
1. Partition splits array in three sub-arrays:
• one sub-array of size 0
• one sub-array with the pivot itself
• the other sub-array of size n-1
2. Quicksort each sub-array
23
Worst Case Intuition
t(n) = n n
- -
0 1 n 1
n
- -
0 2 n 2
n
T(n) = T(n-1) + cn
- -
T(n-1) = T(n-2) + c(n-1)
0 3 n n
3
T(n-2) = T(n-3) + c(n-2) .
- .
.
-
…
4 4
T(2) = T(1) + 2c 0 1 1
24
0 0 0
Picking the Pivot
● How would you pick one?
25
Picking the Pivot (contd.)
● Strategy 2: Pick the pivot randomly
26
Picking the Pivot (contd.)
● Strategy 3: Median-of-three Partitioning
27
Picking the Pivot (contd.)
● Example: Median-of-three Partitioning
■ Pivot
○ = Median of S[left], S[right], and S[center]
○ = median of 6, 8, and 0
○ = S[left] = 6
28
Partitioning Algorithm
● Original input : S = {6, 1, 4, 9, 0, 3, 5, 2, 7, 8}
● Get the pivot out of the way by swapping it with the last element
8 1 4 9 0 3 5 2 7 6
pivot
● Have two ‘iterators’ – i and j
■ i starts at first element and moves forward
■ j starts at last element and moves backwards
8 1 4 9 0 3 5 2 7 6
i j pivot
29
Partitioning Algorithm (contd.)
❑ While (i < j)
■ (The effect is to push larger elements to the right and smaller elements to the
left)
● Quicksort is recursive
■ So it can spend a lot of time sorting small arrays
● Hybrid algorithm:
■ Switch to using insertion sort when problem size is small
(say for N < 20)
32
Special cases
● What happens when the array contains many duplicate
elements?
33
Quick sort: Final Comments
● If the array is sorted to begin with, Quicksort is terrible:
O(n2)
● However, Quicksort is usually O(n log2n)
● The constants are so good that Quicksort is generally the
fastest algorithm known
● Most real-world sorting is done by Quicksort
● For optimum efficiency, the pivot must be chosen
carefully
● “Median of three” is a good technique for choosing the
pivot
● However, no matter what you do, there will be some 34
cases where Quicksort runs in O(n2) time