Skip to content

Commit 66f19d6

Browse files
appleJaxtrekhleb
authored andcommitted
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

Lines changed: 32 additions & 32 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy