Skip to content

Commit 642c152

Browse files
committed
Add selection sort.
1 parent 1b8075c commit 642c152

File tree

6 files changed

+122
-3
lines changed

6 files changed

+122
-3
lines changed

src/algorithms/sorting/SortTester.js

+15-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ export class SortTester {
1111
expect(sorter.sort([1])).toEqual([1]);
1212
expect(sorter.sort([1, 2])).toEqual([1, 2]);
1313
expect(sorter.sort([2, 1])).toEqual([1, 2]);
14-
expect(sorter.sort([1, 1, 1])).toEqual([1, 1, 1]);
1514
expect(sorter.sort(sortedArr)).toEqual(sortedArr);
1615
expect(sorter.sort(reverseArr)).toEqual(sortedArr);
1716
expect(sorter.sort(notSortedArr)).toEqual(sortedArr);
@@ -33,6 +32,21 @@ export class SortTester {
3332
expect(sorter.sort([''])).toEqual(['']);
3433
expect(sorter.sort(['a'])).toEqual(['a']);
3534
expect(sorter.sort(['aa', 'a'])).toEqual(['a', 'aa']);
35+
expect(sorter.sort(['aa', 'aa'])).toEqual(['aa', 'aa']);
36+
}
37+
38+
static testSortStability(SortingClass) {
39+
const callbacks = {
40+
compareCallback: (a, b) => {
41+
if (a.length === b.length) {
42+
return 0;
43+
}
44+
return a.length < b.length ? -1 : 1;
45+
},
46+
};
47+
48+
const sorter = new SortingClass(callbacks);
49+
3650
expect(sorter.sort(['bb', 'aa', 'c'])).toEqual(['c', 'bb', 'aa']);
3751
}
3852

src/algorithms/sorting/bubble-sort/BubbleSort.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import Sort from '../Sort';
22

33
export default class BubbleSort extends Sort {
4-
sort(initialArray) {
4+
sort(originalArray) {
55
// Flag that holds info about whether the swap has occur or not.
66
let swapped = false;
77
// Clone original array to prevent its modification.
8-
const array = initialArray.slice(0);
8+
const array = originalArray.slice(0);
99

1010
for (let i = 0; i < array.length; i += 1) {
1111
swapped = false;

src/algorithms/sorting/bubble-sort/__test__/BubbleSort.test.js

+4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ describe('BubbleSort', () => {
1616
SortTester.testSortWithCustomComparator(BubbleSort);
1717
});
1818

19+
it('should do stable sorting', () => {
20+
SortTester.testSortStability(BubbleSort);
21+
});
22+
1923
it('should visit EQUAL array element specified number of times', () => {
2024
const expectedNumberOfVisits = 19;
2125

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Selection Sort
2+
3+
Selection sort is a sorting algorithm, specifically an
4+
in-place comparison sort. It has O(n2) time complexity,
5+
making it inefficient on large lists, and generally
6+
performs worse than the similar insertion sort.
7+
Selection sort is noted for its simplicity, and it has
8+
performance advantages over more complicated algorithms
9+
in certain situations, particularly where auxiliary
10+
memory is limited.
11+
12+
![](https://en.wikipedia.org/wiki/Selection_sort#/media/File:Selection-Sort-Animation.gif)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import Sort from '../Sort';
2+
3+
export default class SelectionSort extends Sort {
4+
sort(originalArray) {
5+
// Clone original array to prevent its modification.
6+
const array = originalArray.slice(0);
7+
8+
for (let i = 0; i < array.length - 1; i += 1) {
9+
let minIndex = i;
10+
11+
// Find minimum element in the rest of array.
12+
for (let j = i + 1; j < array.length; j += 1) {
13+
// Call visiting callback.
14+
this.callbacks.visitingCallback(array[j]);
15+
16+
if (this.comparator.lessThen(array[j], array[minIndex])) {
17+
minIndex = j;
18+
}
19+
}
20+
21+
// If new minimum element has been found then swap it with current i-th element.
22+
if (minIndex !== i) {
23+
const tmp = array[i];
24+
array[i] = array[minIndex];
25+
array[minIndex] = tmp;
26+
}
27+
}
28+
29+
return array;
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import SelectionSort from '../SelectionSort';
2+
import {
3+
equalArr,
4+
notSortedArr,
5+
reverseArr,
6+
sortedArr,
7+
SortTester,
8+
} from '../../SortTester';
9+
10+
describe('SelectionSort', () => {
11+
it('should sort array', () => {
12+
SortTester.testSort(SelectionSort);
13+
});
14+
15+
it('should sort array with custom comparator', () => {
16+
SortTester.testSortWithCustomComparator(SelectionSort);
17+
});
18+
19+
it('should visit EQUAL array element specified number of times', () => {
20+
const expectedNumberOfVisits = 190;
21+
22+
SortTester.testAlgorithmTimeComplexity(
23+
SelectionSort,
24+
equalArr,
25+
expectedNumberOfVisits,
26+
);
27+
});
28+
29+
it('should visit SORTED array element specified number of times', () => {
30+
const expectedNumberOfVisits = 190;
31+
32+
SortTester.testAlgorithmTimeComplexity(
33+
SelectionSort,
34+
sortedArr,
35+
expectedNumberOfVisits,
36+
);
37+
});
38+
39+
it('should visit NOT SORTED array element specified number of times', () => {
40+
const expectedNumberOfVisits = 190;
41+
42+
SortTester.testAlgorithmTimeComplexity(
43+
SelectionSort,
44+
notSortedArr,
45+
expectedNumberOfVisits,
46+
);
47+
});
48+
49+
it('should visit REVERSE SORTED array element specified number of times', () => {
50+
const expectedNumberOfVisits = 190;
51+
52+
SortTester.testAlgorithmTimeComplexity(
53+
SelectionSort,
54+
reverseArr,
55+
expectedNumberOfVisits,
56+
);
57+
});
58+
});

0 commit comments

Comments
 (0)