quicksort the content for these slides was originally created by gerard harrison. ported to c# by...
TRANSCRIPT
QuickSort
The content for these slides was originally created by Gerard Harrison.Ported to C# by Mike Panitz
Divide and Conquer
Reduce the problem by reducing the data set. A smaller data will easier to solve.
Ideally, subdivide the data set into two equal parts Solve each part recursively
Divide and Conquer
Very similar to MergeSort
DIFFERENCE: MergeSort sorts things ‘on the way back up’, while QuickSort puts things into semi-sorted order on the way down So once we reach the base case(s),
we’re done – we don’t need to merge stuff
QuickSort outline First choose some key from the array.
This key the pivot. Ideally, about half the keys will come before
and half after.
Then partition the items so that all those with items less than the pivot are at the front of the array, and all those with greater values are at the back of the array. Put the pivot in between them
Then sort the two reduced lists separately, and the whole list will be in order.
Algorithm
Public void QSort( int [] A ){ QSort_private( A, 0, A.length – 1 ); }
Private void QSort_private( int [] A, int left, int right )
{int pivotIndex = Partition(A, left, right);
if( pivotIndex - 1 > left )QSort( A, left, pivotIndex - 1);
if( pivotIndex +1 < right )QSort( A, pivotIndex + 1, right );
}
Partition
Partition determines the pivot. Everything before pivot is less than. Everything after pivot is greater
than.
Pivot... ...
These elements are all less than or equal to the pivot
These elements are all greater than the pivot
Choosing the pivot
Algorithm will work for any value we choose for pivot. Choose the first element (arbitrarily) as the
pivot.
Move all values less than or equal to pivot towards the beginning of array.
Move all values greater towards the end.
Where is the dividing line?
Moving the elements
Work indeces inwards from both ends of the array. Start from "left" and look for first element
greater than pivot. Start from "right" and look for first element
less than pivot. Swap the two items. They will now be in the
correct ends of the array.
Repeat until searching indeces "meet".
Searching
2040 10 80 60 50 7 30
Pivot
leftIndex rightIndex
2040 10 30 60 50 7 80 100 90
[7][3]
When indexes cross each other, we stop.
70
100 90 70
Indeces “Meet” (Cross Over)
Low becomes new pivot Exchange old pivot with new pivot
2040 10 30 7 50 60 80Pivot
leftIndexrightIndex[4] [5]
207 10 30 40 50 60 80
100 90 70
100 90 70
int Partition(int[] A, int left, int right ) {
int pivot = A[left];int indexLeft = left; int indexRight = right;
while( indexLeft < indexRight ) {
while (A[indexRight] > pivot) indexRight--;
while(indexLeft < indexRight && A[indexLeft]<=pivot)
indexLeft++;
if (indexLeft < indexRight)Swap (A, indexLeft, indexRight);
}
Swap(A, left, indexRight); //swap pivot & right indexreturn indexRight; // new location of pivot
}
Analysis: Average/Expected Case
The list is divided in half each time, Resulting in O(log2 n)
Original list N elements
N/2 N/2
N/4 N/4 N/4 N/4 }Log2(N) levels deep
Analysis: Average/Expected Case So how much time at each level?
Partition will take O(N) time on each array (N = # elements)
Partition will be run on all the sub-arrays of each level
Therefore, on each level, all the calls to partition will take a total of O(N) time
N = size of given array
Original list N elements
N/2 N/2
N/4 N/4 N/4 N/4 }Log2(N) levels deep
Analysis: Average/Expected Case Therefore, the expected time is
O(N • log2(N) )
In the average case
What is the worst case?Original list N elements
N/2 N/2
N/4 N/4 N/4 N/4 }Log2(N) levels deep
Analysis: Space
O(log2(N) )
In the average case
What is the worst case?Original list N elements
N/2 N/2
N/4 N/4 N/4 N/4 }Log2(N) levels deep
Analysis: Worst Case Worst possible situation: we call
partition, and split off a SINGLE element, leaving N-1 to be recursively sorted
Original list N elements
1 N-1
1 N-2 }N levels deep
Analysis: Worst Case Therefore, the expected time is
O(N • N ) = O(N2)
In the WORST case