Title: Quicksort
1- Sorting
- Arrange keys in ascending or descending order.
- One of the most fundamental problems. First
computer program was a sorting program (ENIAC,
Univ. of Penn.) - Studied selection sort, insertion sort, merge
sort (?) and heap sort
2- Recall two basic sorting algorithms
- selection sorting
- insertion sorting
- We will revisit the applet at
- http//math.hws.edu/TMCM/java/xSortLab/
3Merge sorting In lecture 2, we studied the
merging step. Merging Take two sorted arrays
and combine them into one sorted array. Merge
sorting and heap sorting are two algorithms that
take O(n log n) time in the worst-case. (best
possible)
4Code for merging step void merge(
vectorltComparablegt a, vectorltComparablegt
tmpArray,int leftPos, int rightPos, int rightEnd
) int leftEnd rightPos - 1 int
tmpPos leftPos int numElements rightEnd
- leftPos 1 // Main loop while(
leftPos lt leftEnd rightPos lt rightEnd )
if( a leftPos lt a rightPos )
tmpArray tmpPos a leftPos
else tmpArray tmpPos a
rightPos
5while( leftPos lt leftEnd )// Copy rest of first
half tmpArray tmpPos a leftPos
while( rightPos lt rightEnd )//Copy rest of
right half tmpArray tmpPos a
rightPos // Copy tmpArray back for( int i
0 i lt numElements i, rightEnd-- ) a
rightEnd tmpArray rightEnd
6Merge sorting algorithm Recursive version of
merge sorting To sort the array A between
indices low and high if (high low) return
mid (low high) /2 recursively sort A
between indices low and mid recursively sort A
between indices mid1 and high merge the two
sorted halves.
7Merge sorting - Code
void mergeSort( vectorltComparablegt a,
vectorltComparablegt tmpArray, int left, int
right ) if( left lt right )
int center ( left right ) / 2
mergeSort( a, tmpArray, left, center )
mergeSort( a, tmpArray, center 1, right )
merge( a, tmpArray, left, center 1, right
)
8Quicksort - Introduction
- Fastest known sorting algorithm in practice
- Average case O(N log N)
- Worst case O(N2)
- But, the worst case rarely occurs.
- Another divide-and-conquer recursive algorithm
like mergesort
9Quicksort
S
- Divide step
- Pick any element (pivot) v in S
- Partition S v into two disjoint groups
- S1 x ? S v x ? v
- S2 x ? S v x ? v
- Conquer step recursively sort S1 and S2
- Combine step combine the sorted S1, followed by
v, followed by the sorted S2
v
v
S1
S2
10Example Quicksort
11Example Quicksort...
12Pseudocode
- Input an array Ap, r
- Quicksort (A, p, r)
- if (p lt r)
- q Partition (A, p, r) //q is the position
of the pivot element - Quicksort (A, p, q-1)
- Quicksort (A, q1, r)
-
-
-
13Partitioning
- Partitioning
- Key step of quicksort algorithm
- Goal given the picked pivot, partition the
remaining elements into two smaller sets - Many ways to implement
- Even the slightest deviations may cause
surprisingly bad results. - We will learn an easy and efficient partitioning
strategy here. - How to pick a pivot will be discussed later
14Partitioning Strategy
- Want to partition an array Aleft .. right
- First, get the pivot element out of the way by
swapping it with the last element. (Swap pivot
and Aright) - Let i start at the first element and j start at
the next-to-last element (i left, j right
1)
swap
5
6
4
6
3
12
19
5
6
4
3
12
pivot
15Partitioning Strategy
- Want to have
- Ap lt pivot, for p lt i
- Ap gt pivot, for p gt j
- When i lt j
- Move i right, skipping over elements smaller than
the pivot - Move j left, skipping over elements greater than
the pivot - When both i and j have stopped
- Ai gt pivot
- Aj lt pivot
12
5
6
4
3
5
6
4
3
12
16Partitioning Strategy
- When i and j have stopped and i is to the left of
j - Swap Ai and Aj
- The large element is pushed to the right and the
small element is pushed to the left - After swapping
- Ai lt pivot
- Aj gt pivot
- Repeat the process until i and j cross
swap
5
6
4
3
12
5
3
4
6
12
17Partitioning Strategy
- When i and j have crossed
- Swap Ai and pivot
- Result
- Ap lt pivot, for p lt i
- Ap gt pivot, for p gt i
5
3
4
6
12
5
3
4
6
12
5
3
4
6
12
http//math.hws.edu/TMCM/java/xSortLab/
18Implementation of partitioning step
- int partition(A, left, right)
- int pivot Aright
- int i left, j right-1
- for ( )
- while (ai lt pivot i lt right) i
- while (pivot lt aj j gt left) j--
- if (i lt j)
- swap(ai, aj)
- i j--
-
- else break
-
- swap(Ai, Aright)
- return i
-
19Small arrays
- For very small arrays, quicksort does not perform
as well as insertion sort - how small depends on many factors, such as the
time spent making a recursive call, the compiler,
etc - Do not use quicksort recursively for small arrays
- Instead, use a sorting algorithm that is
efficient for small arrays, such as insertion
sort
20Picking the Pivot
- Use the first element as pivot
- if the input is random, then we can choose the
key in position Aright as pivot. - if the input is sorted (straight or reverse)
- all the elements go into S2 (or S1)
- this happens consistently throughout the
recursive calls - Results in O(n2) behavior (Analyze this case
later) - Choose the pivot randomly
- generally safe
- random number generation can be expensive
21Picking the Pivot
- Use the median of the array
- Partitioning always cuts the array into roughly
half - An optimal quicksort (O(N log N))
- However, hard to find the exact median
22Pivot median of three
- We will use median of three
- Compare just three elements the leftmost,
rightmost and center - Swap these elements if necessary so that
- Aleft Smallest
- Aright Largest
- Acenter Median of three
- Pick Acenter as the pivot
- Swap Acenter and Aright 1 so that pivot is
at second last position (why?)
median3
23Pivot median of three
- Code for partitioning with median of three pivot
24Pivot median of three
Aleft 2, Acenter 13, Aright 6
6
4
3
12
19
Swap Acenter and Aright
6
4
3
12
19
6
4
3
12
19
Choose Acenter as pivot
Swap pivot and Aright 1
6
4
3
12
Note we only need to partition Aleft 1, ,
right 2. Why?
25Implementation of partitioning step
- Works only if pivot is picked as median-of-three.
- Aleft lt pivot and Aright gt pivot
- Thus, only need to partition Aleft 1, , right
2 - j will not run past the end
- because aleft lt pivot
- i will not run past the end
- because aright-1 pivot
26Main Quicksort Routine
Choose pivot
Partitioning
Recursion
For small arrays
27Quicksort Faster than Mergesort
- Both quicksort and mergesort take O(N log N) in
the average case. - Why is quicksort faster than mergesort?
- The inner loop consists of an increment/decrement
(by 1, which is fast), a test and a jump. - Mergesort involves a large number of data
movements. - Quicksort is done in-place.
28Performance of quicksort
- Worst-case takes O(n2) time.
- Average-case takes O(n log n) time.
- On typical inputs, quicksort runs faster than
other algorithms. - Compare various sorting algorithms at
- http//www.geocities.com/siliconvalley/network/185
4/Sort1.html