Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: trekhleb/javascript-algorithms
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: yavorski/javascript-algorithms
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: quick-sort-refactor
Choose a head ref
Can’t automatically merge. Don’t worry, you can still create the pull request.
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Oct 27, 2018

  1. Refactor QuickSortInPlace

    * Sort in place without copying the orignal input
    * Remove `recursiveCall` param from `sort` method as not needed anymore
    * Extract `partitionArray` function to class method
    * Remove `swap` function - use destructuring instead
    * Call `visitingCallback` with the right arguments - in this case with `pivot`
    yavorski committed Oct 27, 2018
    Copy the full SHA
    a324712 View commit details

Commits on Nov 12, 2018

  1. Merge branch 'master' into quick-sort-refactor

    Yavorski authored Nov 12, 2018

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    eaa274c View commit details
Showing with 43 additions and 61 deletions.
  1. +42 −60 src/algorithms/sorting/quick-sort/QuickSortInPlace.js
  2. +1 −1 src/algorithms/sorting/quick-sort/__test__/QuickSortInPlace.test.js
102 changes: 42 additions & 60 deletions src/algorithms/sorting/quick-sort/QuickSortInPlace.js
Original file line number Diff line number Diff line change
@@ -6,73 +6,55 @@ export default class QuickSortInPlace extends Sort {
* This process is difficult to describe, but much clearer with a visualization:
* @see: http://www.algomation.com/algorithm/quick-sort-visualization
*
* @param {*[]} originalArray - Not sorted array.
* @param {*[]} array - Not sorted array.
* @param {number} inputLowIndex
* @param {number} inputHighIndex
* @param {boolean} recursiveCall
* @return {*[]} - Sorted array.
* @return {*[]} array - Sorted array.
*/
sort(
originalArray,
inputLowIndex = 0,
inputHighIndex = originalArray.length - 1,
recursiveCall = false,
) {
// Copies array on initial call, and then sorts in place.
const array = recursiveCall ? originalArray : [...originalArray];

/**
* The partitionArray() operates on the subarray between lowIndex and highIndex, inclusive.
* It arbitrarily chooses the last element in the subarray as the pivot.
* Then, it partially sorts the subarray into elements than are less than the pivot,
* and elements that are greater than or equal to the pivot.
* Each time partitionArray() is executed, the pivot element is in its final sorted position.
*
* @param {number} lowIndex
* @param {number} highIndex
* @return {number}
*/
const partitionArray = (lowIndex, highIndex) => {
/**
* Swaps two elements in array.
* @param {number} leftIndex
* @param {number} rightIndex
*/
const swap = (leftIndex, rightIndex) => {
const temp = array[leftIndex];
array[leftIndex] = array[rightIndex];
array[rightIndex] = temp;
};

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

let partitionIndex = lowIndex;
for (let currentIndex = lowIndex; currentIndex < highIndex; currentIndex += 1) {
if (this.comparator.lessThan(array[currentIndex], pivot)) {
swap(partitionIndex, currentIndex);
partitionIndex += 1;
}
}

// The element at the partitionIndex is guaranteed to be greater than or equal to pivot.
// All elements to the left of partitionIndex are guaranteed to be less than pivot.
// Swapping the pivot with the partitionIndex therefore places the pivot in its
// final sorted position.
swap(partitionIndex, highIndex);

return partitionIndex;
};

sort(array, inputLowIndex = 0, inputHighIndex = array.length - 1) {
// Base case is when low and high converge.
if (inputLowIndex < inputHighIndex) {
const partitionIndex = partitionArray(inputLowIndex, inputHighIndex);
const RECURSIVE_CALL = true;
this.sort(array, inputLowIndex, partitionIndex - 1, RECURSIVE_CALL);
this.sort(array, partitionIndex + 1, inputHighIndex, RECURSIVE_CALL);
const partitionIndex = this.partitionArray(array, inputLowIndex, inputHighIndex);
this.sort(array, inputLowIndex, partitionIndex - 1);
this.sort(array, partitionIndex + 1, inputHighIndex);
}

return array;
}

/**
* The partitionArray() operates on the subarray between lowIndex and highIndex, inclusive.
* It arbitrarily chooses the last element in the subarray as the pivot.
* Then, it partially sorts the subarray into elements than are less than the pivot,
* and elements that are greater than or equal to the pivot.
* Each time partitionArray() is executed, the pivot element is in its final sorted position.
*
* @param {*[]} array - Array for partitioning
* @param {number} lowIndex
* @param {number} highIndex
* @return {number} - Partition index
*/
partitionArray(array, lowIndex, highIndex) {
const pivot = array[highIndex];

// visitingCallback is used for time-complexity analysis.
this.callbacks.visitingCallback(pivot);

let partitionIndex = lowIndex;
for (let currentIndex = lowIndex; currentIndex < highIndex; currentIndex += 1) {
if (this.comparator.lessThan(array[currentIndex], pivot)) {
/* eslint no-param-reassign: ["error", { "props": false }] */
[array[partitionIndex], array[currentIndex]] = [array[currentIndex], array[partitionIndex]];
partitionIndex += 1;
}
}

// The element at the partitionIndex is guaranteed to be greater than or equal to pivot.
// All elements to the left of partitionIndex are guaranteed to be less than pivot.
// Swapping the pivot with the partitionIndex therefore places the pivot in its
// final sorted position.
[array[partitionIndex], array[highIndex]] = [array[highIndex], array[partitionIndex]];

return partitionIndex;
}
}
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ import {

// Complexity constants.
const SORTED_ARRAY_VISITING_COUNT = 19;
const NOT_SORTED_ARRAY_VISITING_COUNT = 12;
const NOT_SORTED_ARRAY_VISITING_COUNT = 19;
const REVERSE_SORTED_ARRAY_VISITING_COUNT = 19;
const EQUAL_ARRAY_VISITING_COUNT = 19;