|
| 1 | +import Sort from '../Sort'; |
| 2 | + |
| 3 | +export default class QuickSortInPlace extends Sort { |
| 4 | + /* Sorting in place avoids unnecessary use of additional memory, but modifies input array. |
| 5 | + * |
| 6 | + * This process is difficult to describe, but much clearer with a visualization: |
| 7 | + * http://www.algomation.com/algorithm/quick-sort-visualization |
| 8 | + */ |
| 9 | + sort(originalArray, inputLow, inputHigh) { |
| 10 | + // Destructures array on initial passthrough, and then sorts in place. |
| 11 | + const array = inputLow === undefined ? [...originalArray] : originalArray; |
| 12 | + // Partition array segment and return index of last swap |
| 13 | + const partition = (l, h) => { |
| 14 | + const swap = (left, right) => { |
| 15 | + const tempVariable = array[left]; |
| 16 | + array[left] = array[right]; |
| 17 | + array[right] = tempVariable; |
| 18 | + }; |
| 19 | + |
| 20 | + const pivot = array[h]; |
| 21 | + this.callbacks.visitingCallback(array[pivot]); |
| 22 | + let firstRunner = l - 1; |
| 23 | + |
| 24 | + for (let secondRunner = l; secondRunner < h; secondRunner += 1) { |
| 25 | + if (this.comparator.lessThan(array[secondRunner], pivot)) { |
| 26 | + firstRunner += 1; |
| 27 | + swap(firstRunner, secondRunner); |
| 28 | + } |
| 29 | + } |
| 30 | + |
| 31 | + if (this.comparator.lessThan(pivot, array[firstRunner + 1])) { |
| 32 | + swap(firstRunner + 1, h); |
| 33 | + } |
| 34 | + |
| 35 | + return firstRunner + 1; |
| 36 | + }; |
| 37 | + |
| 38 | + /* |
| 39 | + * While we can use a default parameter to set `low` to 0, we would |
| 40 | + * still have to set `high`'s default within the function as we |
| 41 | + * don't have access to `array.length - 1` when declaring paramaters |
| 42 | + */ |
| 43 | + const low = inputLow === undefined ? 0 : inputLow; |
| 44 | + const high = inputHigh === undefined ? array.length - 1 : inputHigh; |
| 45 | + |
| 46 | + // Base case is when low and high converge |
| 47 | + if (low < high) { |
| 48 | + const partitionIndex = partition(low, high); |
| 49 | + /* |
| 50 | + * `partition()` swaps elements of the array based on their comparison to the `hi` parameter, |
| 51 | + * and then returns the index where swapping is no longer necessary, which can be best thought |
| 52 | + * of as the pivot used to split an array in a non-in-place quicksort |
| 53 | + */ |
| 54 | + this.sort(array, low, partitionIndex - 1); |
| 55 | + this.sort(array, partitionIndex + 1, high); |
| 56 | + } |
| 57 | + return array; |
| 58 | + } |
| 59 | +} |
0 commit comments