0% found this document useful (0 votes)
16 views12 pages

Chapter9 Part3

The document discusses two sorting algorithms: quicksort and mergesort. Quicksort works by recursively selecting pivots and partitioning the array around those pivots, sorting the subarrays on either side. Mergesort works by recursively dividing the array in half until each subarray contains a single element, then merging the subarrays back together in sorted order. Both algorithms have average case performance of O(n log n) but quicksort's worst case is O(n^2) while mergesort is always O(n log n).

Uploaded by

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

Chapter9 Part3

The document discusses two sorting algorithms: quicksort and mergesort. Quicksort works by recursively selecting pivots and partitioning the array around those pivots, sorting the subarrays on either side. Mergesort works by recursively dividing the array in half until each subarray contains a single element, then merging the subarrays back together in sorted order. Both algorithms have average case performance of O(n log n) but quicksort's worst case is O(n^2) while mergesort is always O(n log n).

Uploaded by

Artemis Zeusborn
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 12

COS 212

Sorting:
Quicksort and Mergesort
Properties of a Sorted Array
 What properties does a sorted array have?
1 2 3 4 5 6 7 8

≤n n ≥n
 For any value n
 All elements to the left of n are less than or equal to n
 All elements to the right of n are greater than or equal to n

Pivot 6 7 2 5 1 8 3 4

 In an unsorted array, pick a pivot called n


 Put all elements ≤ the pivot value to the left of n
 Put all elements ≥ the pivot value to the right of n
 Now 6 is in its sorted position, and does not need to move again

2 5 1 3 4 6 7 8
Quicksort
 Now, apply the same process to the left and right sides of 6

2 5 1 3 4 6 7 8

1 2 5 3 4 6 7 8
 Now 2 and 7 are both in their sorted positions
 There is no need to move either 2 or 7 again
 We repeat this process until every sub-array is of size 1
 When that point is reached, the array will be sorted
 This recursive sorting algorithm is known as quicksort
Quicksort
quicksort(data[])
if data.length > 1
choose pivot;
while there is an element el left in data
if (el ≤ pivot) add el to data1[];
else if (el ≥ pivot) add el to data2[];
quicksort(data1[]); // recursive call
quicksort(data2[]); // recursive call

 Elegant, but a lot of details are unspecified


 How are we going to choose the pivot?
 Are all pivots equally good?
 How are we going to reorder the data?
 Do we need external data structures?
 Middle point is a safer pivot than first or last element
 This results in more evenly sized sub-arrays
 Uneven sub-arrays cause poor performance (more later)
 It is much more memory-efficient to use only one array
Quicksort: Partitioning algorithm
swap(data[first],data[(first + last)/2]); // swap pivot & 1st
lower = first + 1, upper = last; // indices of 1st & last
T pivot = data[first]; // store value of pivot
while (lower <= upper) { // partition the data
while (data[lower] < pivot) lower++; // skip values < pivot
while (data[upper] > pivot) upper--; // skip values > pivot
if (lower < upper) // pair must be swapped
swap(data[lower++],data[upper--]); // perform swap
}
swap(data[upper],data[first]); // place pivot correctly

6 7 2 5 1 8 3 4

Exercise: Apply the


swap process
pivot 5 7 2 6 1 8 3 4 recursively to the
halves on either side of
the pivot
Quicksort: Partitioning algorithm
 Let’s look at a different full array (i.e. not a sub-array)
6 7 2 8 1 5 3 4

8 7 2 6 1 5 3 4
Null pointer
exception
while (pivot > data[lower]) lower++;
 Simple trick to prevent null pointers
 Pre-processing step before the first call to the recursive function
 Find the largest element and swap with the last element

6 7 2 4 1 5 3 8
 Ensures there’s at least one element to stop the while loop
 How does this impact efficiency?
while (pivot > data[lower]) lower++;
Quicksort: Example while (pivot < data[upper]) upper--;

2 4 9 5 5 6 3 7 8 2 Pivot
Largest
to to
thethe
first
lastcell
cell

5 4 2 5 2 6 3 7 8 9 Pivot to upper’s cell


Partitioning

2 4 2 3 Pivot to the first cell 6 5 7 8


4 2 2 3 Pivot to upper’s cell
Partitioning 5 6 7 8

3 2 2 Pivot to the first cell 6 7 8

2 3 2 Partitioning
Pivot to upper’s cell 7 6 8

2 3 6 8

2 2 3 4 5 5 6 7 8 9
Quicksort: Efficiency
Best case: Selected pivots create Worst case: Selected pivots create
two even-size arrays at every one empty array at every
partitioning partitioning

n n
n/2 n/2 n–1
n/4 n/4 n/4 n/4 n–2
? ?
……………………………….. …………………………..

1 1 ………………. 1 1 1

(n–1) n n2 – n
n + n + … + n = n lg n (n–1) + (n–2) + … + 1 = =
2 2
How many times can we Quicksort
divide n by 2?
Best Average Worst
lg n times
Therefore (lg n) + 1 total subsets O(n lg n) O(n lg n) O(n2)
Mergesort
 Quicksort is efficient, but rarely performs optimally
 This is because perfect pivots are hard to find
 Quicksort partitions the array, then sorts each partition
 Can we partition perfectly, then merge partitions while sorting?

n=8 If we always
halve the
4 4 arrays, we
2 2 2 2 ensure
logarithmic
Merge! 1 1 1 1 1 1 1 1 performance

sorted 2 2 2 2
How are we
going to merge
sorted 4 4 the sub-arrays
so that they’re
sorted?
sorted 8
Mergesort Can we do this
without the temp
array?
array

2 5 6 8 1 5 7 9 Look at 1, which is
copied to the 1st array
position

temp If this happens in the


original array, it
1 2 5 5 6 7 8 9 overwrites 2 and
leaves two copies of 1
in the array

merge(array[], first, last) // first and last are positions in array


mid = (first + last) / 2; // midpoint of array
it1 = 0; // 1st element in temp
it2 = first; // 1st element in 1st subset of array
it3 = mid + 1; // 1st element in 2nd subset of array
while both left and right sub-arrays contain elements
if array[it2] < array[it3]
temp[it1++] = array[it2++];
else temp[it1++] = array[it3++];
load remaining array[] elements into temp[];
replace array[] with temp[];
Mergesort
4
Recursive calls to Merge sets, then
mergeSort split 2 2 unwind the stack
sets
1 1 1 1
mergeSort(array[], first, last)
if first < last // stops at singleton set
mid = (first + last) / 2; // find middle of array
mergeSort(array, first, mid); // sort left half
mergeSort(array, mid + 1, last); // sort right half
merge(data, first, last); // merge and sort halves

merge(array[], first, last)


mid = (first + last) / 2;
it1 = 0;
it2 = first;
it3 = mid + 1;
while both left and right sub-arrays contain elements
if array[it2] < array[it3]
temp[it1++] = array[it2++];
else temp[it1++] = array[it3++];
load remaining array[] elements into temp[];
replace array[] with temp[];
Mergesort 2 4 9 5 5 7 3 6 2

Mergesort 2 4 9 5 5 7 3 6 2
Best O(n lg n)
Average O(n lg n)
2 4 9 5 5 7 3 6 2

Worst O(n lg n) 2 4 9 5 5 7 3 6 2

2 4
Unfortunately,
mergesort is 2 4
memory-wasteful
2 4 9 5 5 3 7 2 6

2 4 5 5 9 2 3 6 7
mergeSort(array[], first, last)
if first < last
mid = (first + last) / 2; 2 2 3 4 5 5 6 7 9
mergeSort(array, first, mid);
mergeSort(array, mid + 1, last);
merge(data, first, last);

You might also like