Radix Sort
Example Problem
Given an array arr = [a1,a2,a3,a4,a5...,an]
, we need to sort the array the array with the help of Radix Sort algorithm.
Discussion
Since you are reading this , I assume that you have already gone through most of the comparison sorts that is Merge Sort , Quick Sort , etc
. Problem with comparison based algorithm is that the lower bound complexity for them is nlogn
. They cannot do better than that.
Counting Sort , Bin Bucket Sort
can be used to tackle this problem , but problem with counting sort is that if the maximum number in the array is of the order n2 , then the running time complexity would be of the order O(n2). Also the extra space required increases with the maximum number.
The idea of Radix Sort
is to do digit by digit sort starting from least significant digit to most significant digit. Radix sort uses counting sort as a subroutine to sort.
Working of the Algorithm
Do following for each digit i where i varies from least significant digit to the most significant digit.
- Sort input array using counting sort (or any stable sort) according to the i’th digit.
- Update The array.
Illustration
Let us look at the following illustration :
23 20 15 5 61 301 17 33
Let's look at the one's position for each of the numbers.
23 20 15 5 61 301 17 33
_ _ _ _ _ _ _ _
Sort them according to the marked digits. If there are same digits put them from left to right according to the array.
20 61 301 23 33 15 05 17
_ _ _ _ _ _ _ _
Sort them again according to Ten's place.
301 005 015 017 020 023 033 061
_ _ _ _ _ _ _ _
Sort them again according to Hundred's place.
005 015 017 020 023 033 061 301
We get the final sorted array.
5 15 17 20 23 33 61 301
Code
Code For Sorting according to digits
void digit_sort(int a[],int n,int exp)
{
// declaring vector array of size 10. Since there are 10 digits.
vector <int> arr[10];
// pushing each number in their respective buckets.
for(int i=0;i<n;i++){
arr[ (a[i]/exp) % 10 ].push_back(a[i]);
}
int j = 0;
// Updating the main array.
for(int i=0;i<10;i++)
{
for(auto x:arr[i]){
a[j] = x;
j++;
}
}
// deleting the extra space.
for(int i=0;i<10;i++)
arr[i].clear();
}
Code for Radix Sort.
void RadixSort(int a[],int n)
{
// function for finding the max digit
int m = max_digit(a,n);
for(int i=1;i<=m;i++)
{
// digit_sort for each place
digit_sort(a,n,int(pow(10,i-1)+0.5));
}
}
Code for finding maximum number of digits.
int max_digit(int a[], int n)
{
int res = 0;
for(int i=0;i<n;i++)
{
int temp = a[i] , count = 0;
while(temp)
{
temp/=10;
count++;
}
res = max(res,count);
}
return res;
}
Time Complexity
What is the running time of Radix Sort?
Let there be d digits in input integers. Radix Sort takes O(d*(n+b))
time where b
is the base for representing numbers, for example, for the decimal system, b is 10. What is the value of d? If k is the maximum possible value, then d would be O(logb(k))
. So overall time complexity is O((n+b) * logb(k))
. Which looks more than the time complexity of comparison-based sorting algorithms for a large k. Let us first limit k. Let k <= nc where c is a constant. In that case, the complexity becomes O(nLogb(n)). But it still doesn’t beat comparison-based sorting algorithms.
What if we make the value of b larger?.
What should be the value of b to make the time complexity linear? If we set b as n, we get the time complexity as O(n)
. In other words, we can sort an array of integers with a range from 1 to nc if the numbers are represented in base n (or every digit takes log2(n)
bits).
Other Resources : GFG Blog