Skip to content

Commit 3be02b5

Browse files
dubzzztrekhleb
authored andcommittedJul 22, 2018
Fix CountingSort for negative numbers (trekhleb#100)
1 parent eec7f2f commit 3be02b5

File tree

2 files changed

+14
-6
lines changed

2 files changed

+14
-6
lines changed
 

Diff for: ‎src/algorithms/sorting/counting-sort/CountingSort.js

+9-5
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ export default class CountingSort extends Sort {
55
* @param {number[]} originalArray
66
* @param {number} [biggestElement]
77
*/
8-
sort(originalArray, biggestElement = 0) {
8+
sort(originalArray, smallestElement = 0, biggestElement = 0) {
99
// Detect biggest element in array in order to build number bucket array later.
10+
let detectedSmallestElement = smallestElement;
1011
let detectedBiggestElement = biggestElement;
1112
if (!detectedBiggestElement) {
1213
originalArray.forEach((element) => {
@@ -16,17 +17,20 @@ export default class CountingSort extends Sort {
1617
if (this.comparator.greaterThan(element, detectedBiggestElement)) {
1718
detectedBiggestElement = element;
1819
}
20+
if (this.comparator.greaterThan(detectedSmallestElement, element)) {
21+
detectedSmallestElement = element;
22+
}
1923
});
2024
}
2125

2226
// Init buckets array.
2327
// This array will hold frequency of each number from originalArray.
24-
const buckets = Array(detectedBiggestElement + 1).fill(0);
28+
const buckets = Array(detectedBiggestElement - detectedSmallestElement + 1).fill(0);
2529
originalArray.forEach((element) => {
2630
// Visit element.
2731
this.callbacks.visitingCallback(element);
2832

29-
buckets[element] += 1;
33+
buckets[element - detectedSmallestElement] += 1;
3034
});
3135

3236
// Add previous frequencies to the current one for each number in bucket
@@ -53,13 +57,13 @@ export default class CountingSort extends Sort {
5357
this.callbacks.visitingCallback(element);
5458

5559
// Get correct position of this element in sorted array.
56-
const elementSortedPosition = buckets[element];
60+
const elementSortedPosition = buckets[element - detectedSmallestElement];
5761

5862
// Put element into correct position in sorted array.
5963
sortedArray[elementSortedPosition] = element;
6064

6165
// Increase position of current element in the bucket for future correct placements.
62-
buckets[element] += 1;
66+
buckets[element - detectedSmallestElement] += 1;
6367
}
6468

6569
// Return sorted array.

Diff for: ‎src/algorithms/sorting/counting-sort/__test__/CountingSort.test.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ describe('CountingSort', () => {
1818
SortTester.testSort(CountingSort);
1919
});
2020

21+
it('should sort negative numbers', () => {
22+
SortTester.testNegativeNumbersSort(CountingSort);
23+
});
24+
2125
it('should allow to use specify maximum integer value in array to make sorting faster', () => {
2226
const visitingCallback = jest.fn();
2327
const sorter = new CountingSort({ visitingCallback });
@@ -27,7 +31,7 @@ describe('CountingSort', () => {
2731
return element > accumulator ? element : accumulator;
2832
}, 0);
2933

30-
const sortedArray = sorter.sort(notSortedArr, biggestElement);
34+
const sortedArray = sorter.sort(notSortedArr, 0, biggestElement);
3135

3236
expect(sortedArray).toEqual(sortedArr);
3337
// Normally visitingCallback is being called 60 times but in this case

0 commit comments

Comments
 (0)
Please sign in to comment.