Do some code formatting on QuickSort algorithm.

This commit is contained in:
Oleksii Trekhleb 2018-05-27 22:23:40 +02:00
parent bf5d7b338c
commit 30ae3230d1
3 changed files with 42 additions and 21 deletions

View File

@ -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) * [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) * [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) * [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) * [Shellsort](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sorting/shell-sort)
* **Tree** * **Tree**
* [Depth-First Search](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/tree/depth-first-search) (DFS) * [Depth-First Search](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/tree/depth-first-search) (DFS)

View File

@ -1,6 +1,10 @@
import Sort from '../Sort'; import Sort from '../Sort';
export default class QuickSort extends Sort { export default class QuickSort extends Sort {
/**
* @param {*[]} originalArray
* @return {*[]}
*/
sort(originalArray) { sort(originalArray) {
// Clone original array to prevent it from modification. // Clone original array to prevent it from modification.
const array = [...originalArray]; const array = [...originalArray];

View File

@ -1,27 +1,43 @@
import Sort from '../Sort'; import Sort from '../Sort';
export default class QuickSortInPlace extends 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: * 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. // Destructures array on initial passthrough, and then sorts in place.
const array = inputLow === undefined ? [...originalArray] : originalArray; const array = inputLowIndex === undefined ? [...originalArray] : originalArray;
// Partition array segment and return index of last swap
const partition = (l, h) => { /**
const swap = (left, right) => { * Partition array segment and return index of last swap
const tempVariable = array[left]; *
array[left] = array[right]; * @param {number} lowIndex
array[right] = tempVariable; * @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]); 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)) { if (this.comparator.lessThan(array[secondRunner], pivot)) {
firstRunner += 1; firstRunner += 1;
swap(firstRunner, secondRunner); swap(firstRunner, secondRunner);
@ -29,7 +45,7 @@ export default class QuickSortInPlace extends Sort {
} }
if (this.comparator.lessThan(pivot, array[firstRunner + 1])) { if (this.comparator.lessThan(pivot, array[firstRunner + 1])) {
swap(firstRunner + 1, h); swap(firstRunner + 1, highIndex);
} }
return firstRunner + 1; 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 * still have to set `high`'s default within the function as we
* don't have access to `array.length - 1` when declaring paramaters * don't have access to `array.length - 1` when declaring paramaters
*/ */
const low = inputLow === undefined ? 0 : inputLow; const lowIndex = inputLowIndex === undefined ? 0 : inputLowIndex;
const high = inputHigh === undefined ? array.length - 1 : inputHigh; const highIndex = inputHighIndex === undefined ? array.length - 1 : inputHighIndex;
// Base case is when low and high converge // Base case is when low and high converge
if (low < high) { if (lowIndex < highIndex) {
const partitionIndex = partition(low, high); const partitionIndex = partition(lowIndex, highIndex);
/* /*
* `partition()` swaps elements of the array based on their comparison to the `hi` parameter, * `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 * 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 * of as the pivot used to split an array in a non-in-place quicksort
*/ */
this.sort(array, low, partitionIndex - 1); this.sort(array, lowIndex, partitionIndex - 1);
this.sort(array, partitionIndex + 1, high); this.sort(array, partitionIndex + 1, highIndex);
} }
return array; return array;
} }
} }