-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathradix-sort.js
93 lines (79 loc) · 2.24 KB
/
radix-sort.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/**
* @module lib/radix-sort
* @license MIT Copyright 2015 Daniel Imms (http://www.growingwiththeweb.com)
*/
'use strict';
/**
* Stable sorts an array by a particular digit using counting sort.
* @param {Array} array The array to sort.
* @param {number} radix The base/radix to use to sort.
* @param {number} exponent The exponent of the significant digit to sort.
* @param {number} minValue The minimum value within the array.
* @returns The sorted array.
*/
function countingSortByDigit(array, radix, exponent, minValue) {
var i;
var bucketIndex;
var buckets = new Array(radix);
var output = new Array(array.length);
// Initialize bucket
for (i = 0; i < radix; i++) {
buckets[i] = 0;
}
// Count frequencies
for (i = 0; i < array.length; i++) {
bucketIndex = Math.floor(((array[i] - minValue) / exponent) % radix);
buckets[bucketIndex]++;
}
// Compute cumulates
for (i = 1; i < radix; i++) {
buckets[i] += buckets[i - 1];
}
// Move records
for (i = array.length - 1; i >= 0; i--) {
bucketIndex = Math.floor(((array[i] - minValue) / exponent) % radix);
output[--buckets[bucketIndex]] = array[i];
}
// Copy back
for (i = 0; i < array.length; i++) {
array[i] = output[i];
}
return array;
}
/**
* Sorts an array using radix sort.
* @param {Array} array The array to sort.
* @param {number} [radix=10] The base/radix to use.
* @returns The sorted array.
*/
function sort(array, radix) {
if (array.length === 0) {
return array;
}
radix = radix || 10;
// Determine minimum and maximum values
var minValue = array[0];
var maxValue = array[0];
for (var i = 1; i < array.length; i++) {
if (array[i] < minValue) {
minValue = array[i];
} else if (array[i] > maxValue) {
maxValue = array[i];
}
}
// Perform counting sort on each exponent/digit, starting at the least
// significant digit
var exponent = 1;
while ((maxValue - minValue) / exponent >= 1) {
array = countingSortByDigit(array, radix, exponent, minValue);
exponent *= radix;
}
return array;
}
/**
* Sorts an array using radix sort.
* @param {Array} array The array to sort.
* @param {number} [radix=10] The base/radix to use.
* @returns The sorted array.
*/
module.exports = sort;