Today, we'll discuss one of the fastest sorting algorithms. However, there's beauty here for sure but no magic it only works for numbers.
Numbers only? Yes, because our algorithm relies solely on numbers. We will use each digit of each number to place the number into the corresponding bucket, ranging from 0 to 9. For each iteration, we will return an array that is partially sorted until we've looped over every digit.
But what if there is no value for the current digit? In that case, it will go to the first bucket (0), meaning it was previously sorted.
To make this more manageable, we will create some utility functions.
The first one will be getDigit which takes two parameters: the number and the index of the digit we are examining. For example, getDigit(193, 2) returns 1.
We have two ways of doing this:
function getDigit(number, digit) {
return Math.floor(number / Math.pow(10, digit)) % 10;
};
Here, we divide by the nth place (for example, if the digit parameter is 2, we divide by 100), then we floor the result and apply modulo 10 to find out how many times 10 fits into the resulting number.
Next, we need to determine where to stop iterating or the maximum number of digits in the provided array:
function getMaxDigits(arr) {
let max_digits = 0;
for (let num of arr) {
max_digits = Math.max((""+num).length, max_digits);
}
return max_digits;
};
getMaxDigits([1234, 5, 67]) // 4
This is quite straightforward. We define a maxDigits variable starting at 0 and then we loop over each provided number, reassigning our variable to the maximum value between the current maxDigits and the length of the number.
Finally, we create our radixSort function, which essentially puts our previously defined functions to good use:
function radixSort(arr) {
const max_digits = getMaxDigits(arr);
for (let i = 0; i < max_digits; i++) {
let buckets = Array.from({length: 10}, () =>
[]);
for (let j = 0; j < arr.length; j++) {
buckets[getDigit(arr[j], i)].push(arr[j]);
};
arr = [].concat(...buckets);
}
return arr;
};
As you can see, once you have all your utility functions, it's pretty straightforward:
So, after the first iteration, our arr parameter will look like this: 7890, 1, 23, 456. After the second iteration, our arr would look like this: 1, 23, 456, 7890, which already makes more sense.
As you can see, this algorithm is straightforward and fast. Yes, it is almost O(n). Why almost?
Well, because we have a loop inside a loop, which should mean O(n²). However, since the outer loop's length is based on the maximum digits, it usually is a rather small number. By small, I mean less than 1000. So, we generally agree that it should be O(nk), where n is the number of items in the provided parameter and k is the number of digits of the largest number.
Here are some key points to consider:
Radix sort is particularly suitable for sorting arrays of numbers.
Radix sort stands out as an exceptionally efficient algorithm for sorting numbers, often outperforming many other sorting algorithms in terms of performance. Its unique approach of leveraging individual digits to sort numbers makes it particularly efficient for large datasets where numerical sorting is required. However, what makes it so efficient also makes so specialized, only applicable to numerical data, which limits its versatility compared to more general-purpose sorting algorithms.
Happy coding!
Honestly i am no one, i've just been coding for 3 years now and i like to document every solutions to every problem i encounter. Extracting as much code snippets and tutorials i can so that if i ever need it again i just have to pop back here and get a quick refresher.
Feel free to me through this learning journey by providing any feedback and if you wanna support me: