A very common and efficient in-place, comparison sorting algorithm, usually implemented with recursion, swaps elements around a pivot. For best performance the choice of pivot is important.
Runtime: \(O (n Log n)\) average case, worst case \(O(n^2)\).
Where n is the number of elements to sort.
If the pivot selected in Partition is at the start or end of the array we will get worst case performance on an already sort a sorted array, something that happens more than might be expected.
We also get poor performance when trying to sort an array with a large number of repeated elements.
In the below I have tried to highlight the depth of call stack to give an appreciation of the fact that despite the multiple while loops this implementation heavily relies on recursion.
Individual’s learning styles are different, there are a huge verity of choices out there, this is what worked for me.
I have re-created one of a number of solutions to Quick Sort below and stepped through the code using a unit test, also provided, this detailed step through example is how I originally got to grips with Quick Sort, I recommend doing it yourself, reading the below might be useful as a refresher, but to really embed the understanding take the time to write it yourself, write a test and give it your best shot, once you have struggled for a good while then check back against an example, then walk through it like I have below, and to really cement the understanding write out what is happening as you step through.
We pick the middle of the array for our partition as this reduces the risk of the worst case performance O(n^2) ie: int left = 0, right = arr.Length -1.
while (left <= right) Check that the pointers that we will use to choose elements to swap are still valid. Quick Sort will work with values around the current pivot until this is not longer satisfied, then partition again, selecting a new pivot in the process.
while (_arr[left] < pivot) left++ Find a value on the LHS of the pivot that should be on the RHS. ie greater than 1000 for our first pass, the first is left = 1, arr[1] = 1500.
while (_arr[right] > pivot) right-- Does the same for the value on the RHS that should be on the LHS. ie take the first value that is less than 1000, in this case arr[8] = 14.
if (left <= right) We only swap the values chosen if the index in left, is equal to or lower than the index in right. This is the same test as the earlier while (left <= right)
Swap(left, right) Simply swaps the values in 1 and 8 their respective places.
Index
0
1
2
3
4
5
6
7
8
arr
22
14
2001
2002
1000
2000
2003
10
1500
Increment left, moving it from 1 to 2.
Decrement right, moving it from 8 to 7.
while (left <= right) 2 < 7 == true, we continue iterating:
_arr[left] is 2001 < pivot 1000 == false, so left remains 2.
_arr[right] == _arr[7] is 10 > pivot 1000 == false, so it remains 7.
2 <= 7 so we swap the values:
Index
0
1
2
3
4
5
6
7
8
arr
22
14
10
2002
1000
2000
2003
2001
1500
Increment left and decrement right, left=3, right=6.
while (left <= right) 3 < 6 == true, we continue iterating:
_arr[left] is 2002 < pivot 1000 == false, so left remains 3.