mirror of
https://github.com/trekhleb/javascript-algorithms.git
synced 2025-07-05 16:36:41 +08:00
Add insertion sort.
This commit is contained in:
@ -33,6 +33,7 @@
|
||||
* Sorting
|
||||
* [Bubble Sort](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sorting/bubble-sort)
|
||||
* [Selection Sort](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sorting/selection-sort)
|
||||
* [Insertion Sort](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/sorting/insertion-sort)
|
||||
|
||||
## Running Tests
|
||||
|
||||
@ -98,4 +99,5 @@ Source: [Big O Cheat Sheet](http://bigocheatsheet.com/).
|
||||
| Name | Best | Average | Worst | Memory | Stable | Method | Notes |
|
||||
| --------------------- | :-----: | :-------: | :-----: | :-------: | :-------: | :------------ | :-------------- |
|
||||
| **Bubble sort** | n | n^2 | n^2 | 1 | Yes | Exchanging | Tiny code size |
|
||||
| **Insertion sort** | n | n^2 | n^2 | 1 | Yes | Insertion | O(n + d), in the worst case over sequences that have d inversions |
|
||||
| **Selection sort** | n^2 | n^2 | n^2 | 1 | No | Selection | Stable with O(n) extra space, for example using lists |
|
||||
|
@ -10,6 +10,9 @@ export default class BubbleSort extends Sort {
|
||||
for (let i = 0; i < array.length; i += 1) {
|
||||
swapped = false;
|
||||
|
||||
// Call visiting callback.
|
||||
this.callbacks.visitingCallback(array[i]);
|
||||
|
||||
for (let j = 0; j < array.length - 1; j += 1) {
|
||||
// Call visiting callback.
|
||||
this.callbacks.visitingCallback(array[j]);
|
||||
|
@ -21,7 +21,7 @@ describe('BubbleSort', () => {
|
||||
});
|
||||
|
||||
it('should visit EQUAL array element specified number of times', () => {
|
||||
const expectedNumberOfVisits = 19;
|
||||
const expectedNumberOfVisits = 20;
|
||||
|
||||
SortTester.testAlgorithmTimeComplexity(
|
||||
BubbleSort,
|
||||
@ -31,7 +31,7 @@ describe('BubbleSort', () => {
|
||||
});
|
||||
|
||||
it('should visit SORTED array element specified number of times', () => {
|
||||
const expectedNumberOfVisits = 19;
|
||||
const expectedNumberOfVisits = 20;
|
||||
|
||||
SortTester.testAlgorithmTimeComplexity(
|
||||
BubbleSort,
|
||||
@ -41,7 +41,7 @@ describe('BubbleSort', () => {
|
||||
});
|
||||
|
||||
it('should visit NOT SORTED array element specified number of times', () => {
|
||||
const expectedNumberOfVisits = 266;
|
||||
const expectedNumberOfVisits = 280;
|
||||
|
||||
SortTester.testAlgorithmTimeComplexity(
|
||||
BubbleSort,
|
||||
@ -51,7 +51,7 @@ describe('BubbleSort', () => {
|
||||
});
|
||||
|
||||
it('should visit REVERSE SORTED array element specified number of times', () => {
|
||||
const expectedNumberOfVisits = 380;
|
||||
const expectedNumberOfVisits = 400;
|
||||
|
||||
SortTester.testAlgorithmTimeComplexity(
|
||||
BubbleSort,
|
||||
|
35
src/algorithms/sorting/insertion-sort/InsertionSort.js
Normal file
35
src/algorithms/sorting/insertion-sort/InsertionSort.js
Normal file
@ -0,0 +1,35 @@
|
||||
import Sort from '../Sort';
|
||||
|
||||
export default class InsertionSort extends Sort {
|
||||
sort(originalArray) {
|
||||
const array = originalArray.slice(0);
|
||||
|
||||
// Go through all array elements...
|
||||
for (let i = 0; i < array.length; i += 1) {
|
||||
let currentIndex = i;
|
||||
|
||||
// Call visiting callback.
|
||||
this.callbacks.visitingCallback(array[i]);
|
||||
|
||||
// Go and check if previous elements and greater then current one.
|
||||
// If this is the case then swap that elements.
|
||||
while (
|
||||
array[currentIndex - 1] &&
|
||||
this.comparator.lessThen(array[currentIndex], array[currentIndex - 1])
|
||||
) {
|
||||
// Call visiting callback.
|
||||
this.callbacks.visitingCallback(array[currentIndex - 1]);
|
||||
|
||||
// Swap the elements.
|
||||
const tmp = array[currentIndex - 1];
|
||||
array[currentIndex - 1] = array[currentIndex];
|
||||
array[currentIndex] = tmp;
|
||||
|
||||
// Shift current index left.
|
||||
currentIndex -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
}
|
12
src/algorithms/sorting/insertion-sort/README.md
Normal file
12
src/algorithms/sorting/insertion-sort/README.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Insertion Sort
|
||||
|
||||
Insertion sort is a simple sorting algorithm that builds
|
||||
the final sorted array (or list) one item at a time.
|
||||
It is much less efficient on large lists than more
|
||||
advanced algorithms such as quicksort, heapsort, or merge
|
||||
sort.
|
||||
|
||||

|
||||
|
||||

|
||||
|
@ -0,0 +1,62 @@
|
||||
import InsertionSort from '../InsertionSort';
|
||||
import {
|
||||
equalArr,
|
||||
notSortedArr,
|
||||
reverseArr,
|
||||
sortedArr,
|
||||
SortTester,
|
||||
} from '../../SortTester';
|
||||
|
||||
describe('InsertionSort', () => {
|
||||
it('should sort array', () => {
|
||||
SortTester.testSort(InsertionSort);
|
||||
});
|
||||
|
||||
it('should sort array with custom comparator', () => {
|
||||
SortTester.testSortWithCustomComparator(InsertionSort);
|
||||
});
|
||||
|
||||
it('should do stable sorting', () => {
|
||||
SortTester.testSortStability(InsertionSort);
|
||||
});
|
||||
|
||||
it('should visit EQUAL array element specified number of times', () => {
|
||||
const expectedNumberOfVisits = 20;
|
||||
|
||||
SortTester.testAlgorithmTimeComplexity(
|
||||
InsertionSort,
|
||||
equalArr,
|
||||
expectedNumberOfVisits,
|
||||
);
|
||||
});
|
||||
|
||||
it('should visit SORTED array element specified number of times', () => {
|
||||
const expectedNumberOfVisits = 20;
|
||||
|
||||
SortTester.testAlgorithmTimeComplexity(
|
||||
InsertionSort,
|
||||
sortedArr,
|
||||
expectedNumberOfVisits,
|
||||
);
|
||||
});
|
||||
|
||||
it('should visit NOT SORTED array element specified number of times', () => {
|
||||
const expectedNumberOfVisits = 101;
|
||||
|
||||
SortTester.testAlgorithmTimeComplexity(
|
||||
InsertionSort,
|
||||
notSortedArr,
|
||||
expectedNumberOfVisits,
|
||||
);
|
||||
});
|
||||
|
||||
it('should visit REVERSE SORTED array element specified number of times', () => {
|
||||
const expectedNumberOfVisits = 210;
|
||||
|
||||
SortTester.testAlgorithmTimeComplexity(
|
||||
InsertionSort,
|
||||
reverseArr,
|
||||
expectedNumberOfVisits,
|
||||
);
|
||||
});
|
||||
});
|
@ -8,6 +8,9 @@ export default class SelectionSort extends Sort {
|
||||
for (let i = 0; i < array.length - 1; i += 1) {
|
||||
let minIndex = i;
|
||||
|
||||
// Call visiting callback.
|
||||
this.callbacks.visitingCallback(array[i]);
|
||||
|
||||
// Find minimum element in the rest of array.
|
||||
for (let j = i + 1; j < array.length; j += 1) {
|
||||
// Call visiting callback.
|
||||
|
@ -17,7 +17,7 @@ describe('SelectionSort', () => {
|
||||
});
|
||||
|
||||
it('should visit EQUAL array element specified number of times', () => {
|
||||
const expectedNumberOfVisits = 190;
|
||||
const expectedNumberOfVisits = 209;
|
||||
|
||||
SortTester.testAlgorithmTimeComplexity(
|
||||
SelectionSort,
|
||||
@ -27,7 +27,7 @@ describe('SelectionSort', () => {
|
||||
});
|
||||
|
||||
it('should visit SORTED array element specified number of times', () => {
|
||||
const expectedNumberOfVisits = 190;
|
||||
const expectedNumberOfVisits = 209;
|
||||
|
||||
SortTester.testAlgorithmTimeComplexity(
|
||||
SelectionSort,
|
||||
@ -37,7 +37,7 @@ describe('SelectionSort', () => {
|
||||
});
|
||||
|
||||
it('should visit NOT SORTED array element specified number of times', () => {
|
||||
const expectedNumberOfVisits = 190;
|
||||
const expectedNumberOfVisits = 209;
|
||||
|
||||
SortTester.testAlgorithmTimeComplexity(
|
||||
SelectionSort,
|
||||
@ -47,7 +47,7 @@ describe('SelectionSort', () => {
|
||||
});
|
||||
|
||||
it('should visit REVERSE SORTED array element specified number of times', () => {
|
||||
const expectedNumberOfVisits = 190;
|
||||
const expectedNumberOfVisits = 209;
|
||||
|
||||
SortTester.testAlgorithmTimeComplexity(
|
||||
SelectionSort,
|
||||
|
Reference in New Issue
Block a user