Skip to content

Commit 0fd5436

Browse files
committed
Fixed comments
1 parent 43c76ff commit 0fd5436

File tree

10 files changed

+48
-18
lines changed

10 files changed

+48
-18
lines changed

assets/LectureHoares.jpeg

700 Bytes
Loading

assets/Lomutos.jpeg

26 KB
Loading

assets/QuickSortOverview.jpeg

39.8 KB
Loading
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# QuickSort
2+
3+
This page will provide a high-level overview of the different types of QuickSort and the significance of each
4+
enhancement.
5+
6+
![QuickSort Overview](../../../../assets/QuickSortOverview.jpeg)
7+
8+
We start off with Simple QuickSort, which utilises Hoare's / Lomuto's partitioning with a fixed pivot. But the time
9+
complexity of Simple QuickSort degrades to O(n^2) when pivots chosen are continuously bad. This could be because of
10+
inputs such as sorted arrays, where picking the first element as the pivot will always lead to an extremely imbalanced
11+
partitioning. This could also be because of the presence of duplicates, as we now handle duplicates by putting them to
12+
one side of the pivot.
13+
14+
Therefore, we introduced randomisation in pivot selection to prevent fixed pivot selection from continuously choosing
15+
a bad pivot. We also added a good pivot check (Paranoid) to Simple QuickSort to ensure that the pivots we select are
16+
"good" and will not cause extremely imbalanced partitions. However, the presence of the good pivot checks will cause
17+
infinite recursion when the array contains many duplicates, since any pivot you choose in the array will fail the good
18+
pivot check.
19+
20+
So, we introduced 3-way partitioning to handle duplicates by partitioning the array into three sections: elements less
21+
than the pivot, elements equal to the pivot, and elements greater than the pivot. Now the good pivot check ignores the
22+
size of the segment that comprises elements = to pivot.

src/algorithms/sorting/quickSort/hoares/QuickSort.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
*
88
* Implementation Invariant:
99
* The pivot is in the correct position, with elements to its left being <= it, and elements to its right being > it.
10-
* (We edited the psuedocode a bit to keep the duplicates to the left of the pivot.)
10+
* (We edited the pseudocode a bit to keep the duplicates to the left of the pivot.)
1111
*
12-
* This implementation picks the element at the index 0 as the pivot.
12+
* This implementation picks the first element as the pivot.
1313
*/
1414

1515
public class QuickSort {
@@ -53,18 +53,17 @@ private static void quickSort(int[] arr, int start, int end) {
5353
*/
5454
private static int partition(int[] arr, int start, int end) {
5555
int pivot = arr[start];
56-
int low = start + 1;
57-
int high = end;
56+
int low = start;
57+
int high = end + 1;
5858

59-
while (low <= high) {
60-
while (low <= high && arr[low] <= pivot) {// we use <= as opposed to < to pack duplicates to the left side
61-
// of the pivot
59+
while (low < high) {
60+
do {
6261
low++;
63-
}
64-
65-
while (low <= high && arr[high] > pivot) {
62+
} while (low < high && arr[low] <= pivot); // we use <= as opposed to < to pack duplicates to the left side
63+
// of the pivot
64+
do {
6665
high--;
67-
}
66+
} while (low < high && arr[high] > pivot);
6867

6968
if (low < high) {
7069
swap(arr, low, high);

src/algorithms/sorting/quickSort/hoares/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ However, using a fixed pivot, such as always choosing the first element as the p
3737
especially when the array is already sorted or has a specific pattern. This is because in such cases, the partitioning
3838
might create highly unbalanced sub-arrays, causing the algorithm to degrade to O(n^2) time complexity.
3939

40+
Space:
41+
- O(logn) as the partitioning is done in-place so each partitioning takes O(1) space but depth of QuickSort recursion
42+
is logn, therefore logn * O(1) = O(logn)
43+
4044
## Notes
4145

4246
### Presence of Duplicates

src/algorithms/sorting/quickSort/lomuto/QuickSort.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@
3838
* duplicates in the array leads to extremely unbalanced partitioning, leading to a O(n^2) time complexity.
3939
*
4040
* Space:
41-
* - O(1) since sorting is done in-place
41+
* - O(logn) as the partitioning is done in-place so each partitioning takes O(1) space but depth of QuickSort
42+
* recursion is logn, therefore logn * O(1) = O(logn)
4243
*/
4344

4445
public class QuickSort {

src/algorithms/sorting/quickSort/paranoid/QuickSort.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
* enter an infinite loop of repeating pivot selection.
3030
*
3131
* Space:
32-
* - O(1) since sorting is done in-place
32+
* - O(logn) as the partitioning is done in-place so each partitioning takes O(1) space but depth of QuickSort
33+
* recursion is logn, therefore logn * O(1) = O(logn)
3334
*/
3435

3536
public class QuickSort {

src/algorithms/sorting/quickSort/threeWayPartitioning/QuickSort.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,9 @@
2121
* - Average case: O(nlogn)
2222
* - Best case: O(nlogn)
2323
*
24-
* By isolating the elements equal to the pivot into their correct positions during the partitioning step, three-way
25-
* partitioning efficiently handles duplicates, preventing the presence of many duplicates in the array from causing
26-
* the time complexity of QuickSort to degrade to O(n^2).
27-
*
2824
* Space:
29-
* - O(1) since sorting is done in-place
25+
* - O(logn) as the partitioning is done in-place so each partitioning takes O(1) space but depth of QuickSort
26+
* recursion is logn, therefore logn * O(1) = O(logn)
3027
*/
3128

3229
public class QuickSort {

test/algorithms/quickSort/hoares/QuickSortTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,18 @@ public void test_selectionSort_shouldReturnSortedArray() {
4242
int[] seventhResult = Arrays.copyOf(seventhArray, seventhArray.length);
4343
QuickSort.sort(seventhResult);
4444

45+
int[] eighthArray = new int[] {1,1,1,1,1,1,1,1,1,1,1,1,1,1};
46+
int[] eighthResult = Arrays.copyOf(eighthArray, eighthArray.length);
47+
QuickSort.sort(eighthResult);
48+
4549
Arrays.sort(firstArray); // get expected result
4650
Arrays.sort(secondArray); // get expected result
4751
Arrays.sort(thirdArray); // get expected result
4852
Arrays.sort(fourthArray); // get expected result
4953
Arrays.sort(fifthArray); // get expected result
5054
Arrays.sort(sixthArray); // get expected result
5155
Arrays.sort(seventhArray); // get expected result
56+
Arrays.sort(eighthArray); // get expected result
5257

5358
assertArrayEquals(firstResult, firstArray);
5459
assertArrayEquals(secondResult, secondArray);
@@ -57,5 +62,6 @@ public void test_selectionSort_shouldReturnSortedArray() {
5762
assertArrayEquals(fifthResult, fifthArray);
5863
assertArrayEquals(sixthResult, sixthArray);
5964
assertArrayEquals(seventhResult, seventhArray);
65+
assertArrayEquals(eighthResult, eighthArray);
6066
}
6167
}

0 commit comments

Comments
 (0)