From 30ae3230d11553f711c9df5d35e7f76d6521cf29 Mon Sep 17 00:00:00 2001 From: Oleksii Trekhleb Date: Sun, 27 May 2018 22:23:40 +0200 Subject: [PATCH] Do some code formatting on QuickSort algorithm. --- README.md | 2 +- .../sorting/quick-sort/QuickSort.js | 4 ++ .../sorting/quick-sort/QuickSortInPlace.js | 57 ++++++++++++------- 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index a5f7f05952..9f66468db5 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ a set of rules that precisely defines a sequence of operations. * [Insertion Sort](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sorting/insertion-sort) * [Heap Sort](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sorting/heap-sort) * [Merge Sort](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sorting/merge-sort) - * [Quicksort](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sorting/quick-sort) + * [Quicksort](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sorting/quick-sort) - in-place and non-in-place implementations * [Shellsort](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sorting/shell-sort) * **Tree** * [Depth-First Search](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/tree/depth-first-search) (DFS) diff --git a/src/algorithms/sorting/quick-sort/QuickSort.js b/src/algorithms/sorting/quick-sort/QuickSort.js index 8a9c113fa9..1c63c86e8b 100644 --- a/src/algorithms/sorting/quick-sort/QuickSort.js +++ b/src/algorithms/sorting/quick-sort/QuickSort.js @@ -1,6 +1,10 @@ import Sort from '../Sort'; export default class QuickSort extends Sort { + /** + * @param {*[]} originalArray + * @return {*[]} + */ sort(originalArray) { // Clone original array to prevent it from modification. const array = [...originalArray]; diff --git a/src/algorithms/sorting/quick-sort/QuickSortInPlace.js b/src/algorithms/sorting/quick-sort/QuickSortInPlace.js index fc7bb67d23..7bff025d31 100644 --- a/src/algorithms/sorting/quick-sort/QuickSortInPlace.js +++ b/src/algorithms/sorting/quick-sort/QuickSortInPlace.js @@ -1,27 +1,43 @@ import Sort from '../Sort'; export default class QuickSortInPlace extends Sort { - /* Sorting in place avoids unnecessary use of additional memory, but modifies input array. + /** Sorting in place avoids unnecessary use of additional memory, but modifies input array. * * This process is difficult to describe, but much clearer with a visualization: - * http://www.algomation.com/algorithm/quick-sort-visualization + * @see: http://www.algomation.com/algorithm/quick-sort-visualization + * + * @param {*[]} originalArray + * @param {number} inputLowIndex + * @param {number} inputHighIndex + * @return {*[]} */ - sort(originalArray, inputLow, inputHigh) { + sort(originalArray, inputLowIndex, inputHighIndex) { // Destructures array on initial passthrough, and then sorts in place. - const array = inputLow === undefined ? [...originalArray] : originalArray; - // Partition array segment and return index of last swap - const partition = (l, h) => { - const swap = (left, right) => { - const tempVariable = array[left]; - array[left] = array[right]; - array[right] = tempVariable; + const array = inputLowIndex === undefined ? [...originalArray] : originalArray; + + /** + * Partition array segment and return index of last swap + * + * @param {number} lowIndex + * @param {number} highIndex + * @return {number} + */ + const partition = (lowIndex, highIndex) => { + /** + * @param {number} leftIndex + * @param {number} rightIndex + */ + const swap = (leftIndex, rightIndex) => { + const tempVariable = array[leftIndex]; + array[leftIndex] = array[rightIndex]; + array[rightIndex] = tempVariable; }; - const pivot = array[h]; + const pivot = array[highIndex]; this.callbacks.visitingCallback(array[pivot]); - let firstRunner = l - 1; - for (let secondRunner = l; secondRunner < h; secondRunner += 1) { + let firstRunner = lowIndex - 1; + for (let secondRunner = lowIndex; secondRunner < highIndex; secondRunner += 1) { if (this.comparator.lessThan(array[secondRunner], pivot)) { firstRunner += 1; swap(firstRunner, secondRunner); @@ -29,7 +45,7 @@ export default class QuickSortInPlace extends Sort { } if (this.comparator.lessThan(pivot, array[firstRunner + 1])) { - swap(firstRunner + 1, h); + swap(firstRunner + 1, highIndex); } return firstRunner + 1; @@ -40,20 +56,21 @@ export default class QuickSortInPlace extends Sort { * still have to set `high`'s default within the function as we * don't have access to `array.length - 1` when declaring paramaters */ - const low = inputLow === undefined ? 0 : inputLow; - const high = inputHigh === undefined ? array.length - 1 : inputHigh; + const lowIndex = inputLowIndex === undefined ? 0 : inputLowIndex; + const highIndex = inputHighIndex === undefined ? array.length - 1 : inputHighIndex; // Base case is when low and high converge - if (low < high) { - const partitionIndex = partition(low, high); + if (lowIndex < highIndex) { + const partitionIndex = partition(lowIndex, highIndex); /* * `partition()` swaps elements of the array based on their comparison to the `hi` parameter, * and then returns the index where swapping is no longer necessary, which can be best thought * of as the pivot used to split an array in a non-in-place quicksort */ - this.sort(array, low, partitionIndex - 1); - this.sort(array, partitionIndex + 1, high); + this.sort(array, lowIndex, partitionIndex - 1); + this.sort(array, partitionIndex + 1, highIndex); } + return array; } }