Skip to content

Commit 66f19d6

Browse files
appleJaxtrekhleb
authored andcommittedSep 14, 2018
Minor refactor of QuickSortInPlace for simplification (trekhleb#187)
1 parent 92b9e6a commit 66f19d6

File tree

1 file changed

+32
-32
lines changed

1 file changed

+32
-32
lines changed
 

‎src/algorithms/sorting/quick-sort/QuickSortInPlace.js

+32-32
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,21 @@ export default class QuickSortInPlace extends Sort {
1111
* @param {number} inputHighIndex
1212
* @return {*[]}
1313
*/
14-
sort(originalArray, inputLowIndex, inputHighIndex) {
15-
// Destructures array on initial passthrough, and then sorts in place.
16-
const array = inputLowIndex === undefined ? [...originalArray] : originalArray;
14+
sort(
15+
originalArray,
16+
inputLowIndex = 0,
17+
inputHighIndex = originalArray.length - 1,
18+
recursiveCall = false,
19+
) {
20+
// Copies array on initial call, and then sorts in place.
21+
const array = recursiveCall ? originalArray : [...originalArray];
1722

1823
/**
19-
* Partition array segment and return index of last swap
24+
* `partition` operates on the subarray between lowIndex and highIndex, inclusive.
25+
* it arbitrarily chooses the last element in the subarray as the pivot.
26+
* then, it partially sorts the subarray into elements than are less than the pivot,
27+
* and elements that are greater than or equal to the pivot.
28+
* each time `partition` is executed, the pivot element is in its final sorted position.
2029
*
2130
* @param {number} lowIndex
2231
* @param {number} highIndex
@@ -28,47 +37,38 @@ export default class QuickSortInPlace extends Sort {
2837
* @param {number} rightIndex
2938
*/
3039
const swap = (leftIndex, rightIndex) => {
31-
const tempVariable = array[leftIndex];
40+
const temp = array[leftIndex];
3241
array[leftIndex] = array[rightIndex];
33-
array[rightIndex] = tempVariable;
42+
array[rightIndex] = temp;
3443
};
3544

3645
const pivot = array[highIndex];
46+
// visitingCallback is used for time-complexity analysis
3747
this.callbacks.visitingCallback(array[pivot]);
3848

39-
let firstRunner = lowIndex - 1;
40-
for (let secondRunner = lowIndex; secondRunner < highIndex; secondRunner += 1) {
41-
if (this.comparator.lessThan(array[secondRunner], pivot)) {
42-
firstRunner += 1;
43-
swap(firstRunner, secondRunner);
49+
let partitionIndex = lowIndex;
50+
for (let currentIndex = lowIndex; currentIndex < highIndex; currentIndex += 1) {
51+
if (this.comparator.lessThan(array[currentIndex], pivot)) {
52+
swap(partitionIndex, currentIndex);
53+
partitionIndex += 1;
4454
}
4555
}
4656

47-
if (this.comparator.lessThan(pivot, array[firstRunner + 1])) {
48-
swap(firstRunner + 1, highIndex);
49-
}
57+
// The element at the partitionIndex is guaranteed to be greater than or equal to pivot.
58+
// All elements to the left of partitionIndex are guaranteed to be less than pivot.
59+
// Swapping the pivot with the partitionIndex therefore places the pivot in its
60+
// final sorted position.
61+
swap(partitionIndex, highIndex);
5062

51-
return firstRunner + 1;
63+
return partitionIndex;
5264
};
5365

54-
/*
55-
* While we can use a default parameter to set `low` to 0, we would
56-
* still have to set `high`'s default within the function as we
57-
* don't have access to `array.length - 1` when declaring parameters
58-
*/
59-
const lowIndex = inputLowIndex === undefined ? 0 : inputLowIndex;
60-
const highIndex = inputHighIndex === undefined ? array.length - 1 : inputHighIndex;
61-
6266
// Base case is when low and high converge
63-
if (lowIndex < highIndex) {
64-
const partitionIndex = partition(lowIndex, highIndex);
65-
/*
66-
* `partition()` swaps elements of the array based on their comparison to the `hi` parameter,
67-
* and then returns the index where swapping is no longer necessary, which can be best thought
68-
* of as the pivot used to split an array in a non-in-place quicksort
69-
*/
70-
this.sort(array, lowIndex, partitionIndex - 1);
71-
this.sort(array, partitionIndex + 1, highIndex);
67+
if (inputLowIndex < inputHighIndex) {
68+
const partitionIndex = partition(inputLowIndex, inputHighIndex);
69+
const RECURSIVE_CALL = true;
70+
this.sort(array, inputLowIndex, partitionIndex - 1, RECURSIVE_CALL);
71+
this.sort(array, partitionIndex + 1, inputHighIndex, RECURSIVE_CALL);
7272
}
7373

7474
return array;

0 commit comments

Comments
 (0)
Please sign in to comment.