Add quick sort.

This commit is contained in:
Oleksii Trekhleb 2018-04-15 06:30:45 +03:00
parent f29bcabffb
commit c8becaf299
4 changed files with 133 additions and 0 deletions

View File

@ -36,6 +36,7 @@
* [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)
* [Quick Sort](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sorting/quick-sort)
## Running Tests

View File

@ -0,0 +1,44 @@
import Sort from '../Sort';
export default class QuickSort extends Sort {
sort(originalArray) {
// Clone original array to prevent it from modification.
const array = originalArray.slice(0);
// If array has less then or equal to one elements then it is already sorted.
if (array.length <= 1) {
return array;
}
// Init left and right arrays.
const leftArray = [];
const rightArray = [];
// Take the first element of array as a pivot.
const pivotElement = array.shift();
const centerArray = [pivotElement];
// Split all array elements between left, center and right arrays.
while (array.length) {
const currentElement = array.shift();
// Call visiting callback.
this.callbacks.visitingCallback(currentElement);
if (this.comparator.equal(currentElement, pivotElement)) {
centerArray.push(currentElement);
} else if (this.comparator.lessThen(currentElement, pivotElement)) {
leftArray.push(currentElement);
} else {
rightArray.push(currentElement);
}
}
// Sort left and right arrays.
const leftArraySorted = this.sort(leftArray);
const rightArraySorted = this.sort(rightArray);
// Let's now join sorted left array with center array and with sorted right array.
return leftArraySorted.concat(centerArray, rightArraySorted);
}
}

View File

@ -0,0 +1,28 @@
# Quicksort
Quicksort is a divide and conquer algorithm.
Quicksort first divides a large array into two smaller
sub-arrays: the low elements and the high elements.
Quicksort can then recursively sort the sub-arrays
The steps are:
1. Pick an element, called a pivot, from the array.
2. Partitioning: reorder the array so that all elements with
values less than the pivot come before the pivot, while all
elements with values greater than the pivot come after it
(equal values can go either way). After this partitioning,
the pivot is in its final position. This is called the
partition operation.
3. Recursively apply the above steps to the sub-array of
elements with smaller values and separately to the
sub-array of elements with greater values.
Animated visualization of the quicksort algorithm.
The horizontal lines are pivot values.
![Quicksort](https://upload.wikimedia.org/wikipedia/commons/6/6a/Sorting_quicksort_anim.gif)
## References
[Wikipedia](https://en.wikipedia.org/wiki/Quicksort)

View File

@ -0,0 +1,60 @@
import QuickSort from '../QuickSort';
import {
equalArr,
notSortedArr,
reverseArr,
sortedArr,
SortTester,
} from '../../SortTester';
// Complexity constants.
const SORTED_ARRAY_VISITING_COUNT = 190;
const NOT_SORTED_ARRAY_VISITING_COUNT = 62;
const REVERSE_SORTED_ARRAY_VISITING_COUNT = 190;
const EQUAL_ARRAY_VISITING_COUNT = 19;
describe('QuickSort', () => {
it('should sort array', () => {
SortTester.testSort(QuickSort);
});
it('should sort array with custom comparator', () => {
SortTester.testSortWithCustomComparator(QuickSort);
});
it('should do stable sorting', () => {
SortTester.testSortStability(QuickSort);
});
it('should visit EQUAL array element specified number of times', () => {
SortTester.testAlgorithmTimeComplexity(
QuickSort,
equalArr,
EQUAL_ARRAY_VISITING_COUNT,
);
});
it('should visit SORTED array element specified number of times', () => {
SortTester.testAlgorithmTimeComplexity(
QuickSort,
sortedArr,
SORTED_ARRAY_VISITING_COUNT,
);
});
it('should visit NOT SORTED array element specified number of times', () => {
SortTester.testAlgorithmTimeComplexity(
QuickSort,
notSortedArr,
NOT_SORTED_ARRAY_VISITING_COUNT,
);
});
it('should visit REVERSE SORTED array element specified number of times', () => {
SortTester.testAlgorithmTimeComplexity(
QuickSort,
reverseArr,
REVERSE_SORTED_ARRAY_VISITING_COUNT,
);
});
});