Introduction
Sorting is a fundamental operation in computer science, and while QuickSort is often preferred due to its average-case efficiency of O(n log n), there are cases where Radix Sort outperforms it. Unlike comparison-based sorting algorithms, Radix Sort takes advantage of number digit processing, making it highly efficient for sorting integers and fixed-length strings.
In this guide, weβll explore:
- What is Radix Sort?
- How does it work?
- Radix Sort vs. QuickSort
- Advantages and disadvantages
- Implementations in JavaScript and Python
- When to use Radix Sort?
- FAQs
Letβs dive in! π
What is Radix Sort?
Radix Sort is a non-comparative sorting algorithm that processes numbers digit by digit, starting from the least significant digit (LSD) to the most significant digit (MSD). It groups numbers into "buckets" based on their digit values and sorts them progressively.
Unlike comparison-based sorting algorithms like QuickSort or Merge Sort, Radix Sort leverages digit-based sorting to achieve an optimal time complexity of O(nk), where:
- n is the number of elements
- k is the number of digits in the largest number
How Radix Sort Works
Step-by-Step Explanation
Radix Sort follows these steps:
- Find the maximum number in the list to determine the number of digits (k).
- Start sorting from the least significant digit (LSD) to the most significant digit (MSD).
- Place numbers into buckets (0-9) based on the current digit.
- Reassemble the numbers in order from bucket 0 to 9.
- Repeat for the next digit position until all digits are sorted.
Illustration of Radix Sort
Letβs sort the array [170, 45, 75, 90, 802, 24, 2, 66] using Radix Sort:
Step 1: Sorting by Least Significant Digit (LSD)
Buckets:
0 -> [170]
2 -> [802, 2]
4 -> [24]
5 -> [75, 45]
6 -> [66]
9 -> [90]
Rearrange β [170, 802, 2, 24, 75, 45, 66, 90]
Step 2: Sorting by Second Digit
Buckets:
0 -> [2]
2 -> [24]
4 -> [45]
6 -> [66]
7 -> [75, 170]
8 -> [802]
9 -> [90]
Rearrange β [2, 24, 45, 66, 75, 170, 802, 90]
Step 3: Sorting by Most Significant Digit
Buckets:
0 -> [2, 24, 45, 66, 75, 90]
1 -> [170]
8 -> [802]
Final Sorted Array β [2, 24, 45, 66, 75, 90, 170, 802]
Radix Sort vs. QuickSort
Features | Radix Sort | QuickSort |
---|---|---|
Type | Non-comparative | Comparative |
Time Complexity (Best/Average) | O(nk) | O(n log n) |
Worst Case | O(nk) | O(nΒ²) |
Space Complexity | O(n + k) | O(log n) |
Stable Sort? | Yes | No |
Best for? | Large integers, fixed-length strings | General-purpose sorting |
When is Radix Sort Faster?
- Sorting large integers (e.g., phone numbers, IDs)
- When k (number of digits) is small compared to n
- Fixed-length string sorting
Radix Sort Implementation in JavaScript
function getMax(arr) {
let max = arr[0];
for (let num of arr) {
if (num > max) max = num;
}
return max;
}
function countingSort(arr, exp) {
let output = new Array(arr.length).fill(0);
let count = new Array(10).fill(0);
for (let i = 0; i < arr.length; i++) {
let index = Math.floor(arr[i] / exp) % 10;
count[index]++;
}
for (let i = 1; i < 10; i++) {
count[i] += count[i - 1];
}
for (let i = arr.length - 1; i >= 0; i--) {
let index = Math.floor(arr[i] / exp) % 10;
output[count[index] - 1] = arr[i];
count[index]--;
}
for (let i = 0; i < arr.length; i++) {
arr[i] = output[i];
}
}
function radixSort(arr) {
let max = getMax(arr);
for (let exp = 1; Math.floor(max / exp) > 0; exp *= 10) {
countingSort(arr, exp);
}
}
let arr = [170, 45, 75, 90, 802, 24, 2, 66];
radixSort(arr);
console.log(arr);
Radix Sort Implementation in Python
def counting_sort(arr, exp):
n = len(arr)
output = [0] * n
count = [0] * 10
for i in range(n):
index = (arr[i] // exp) % 10
count[index] += 1
for i in range(1, 10):
count[i] += count[i - 1]
i = n - 1
while i >= 0:
index = (arr[i] // exp) % 10
output[count[index] - 1] = arr[i]
count[index] -= 1
i -= 1
for i in range(n):
arr[i] = output[i]
def radix_sort(arr):
max_num = max(arr)
exp = 1
while max_num // exp > 0:
counting_sort(arr, exp)
exp *= 10
arr = [170, 45, 75, 90, 802, 24, 2, 66]
radix_sort(arr)
print(arr)
When Should You Use Radix Sort?
Use Radix Sort when:
β
Sorting large datasets of integers
β
The number of digits (k) is small compared to n
β
Stability is important
β
Sorting fixed-length strings (e.g., dates, IDs)
Avoid Radix Sort if:
β You have floating-point numbers
β Memory efficiency is a priority
β You're working with small datasets
Frequently Asked Questions (FAQs) About Radix Sort
Q1. What is Radix Sort in simple terms?
Radix Sort is a non-comparative sorting algorithm that sorts numbers by processing them digit by digit from the least significant digit (LSD) to the most significant digit (MSD). It works efficiently for sorting large integers and fixed-length strings, unlike QuickSort, which relies on element comparisons.
Q2. Why is Radix Sort faster than QuickSort?
Radix Sort is faster than QuickSort when k (the number of digits in the largest number) is small because it sorts numbers in O(nk) time, whereas QuickSort operates in O(n log n) on average. If the number of digits is significantly smaller than the number of elements, Radix Sort outperforms QuickSort.
Q3. What is the time complexity of Radix Sort?
The time complexity of Radix Sort is O(nk), where:
- n = number of elements in the list
- k = number of digits in the largest number
This makes it highly efficient for large numbers but less optimal for floating-point numbers or small datasets.
Q4. Is Radix Sort better than Merge Sort?
Radix Sort can be better than Merge Sort in cases where numbers have a fixed number of digits and k is small. However, Merge Sort (O(n log n)) is more versatile and performs well across various data types, including floating-point numbers and large datasets with variable-length strings.
Q5. What are the applications of Radix Sort?
Radix Sort is used in:
- Sorting large datasets of integers (e.g., phone numbers, zip codes)
- Fixed-length string sorting (e.g., dates, IP addresses)
- Processing large financial transactions (e.g., banking systems)
- Sorting large-scale data in scientific computing
Q6. Can Radix Sort be used for negative numbers?
Radix Sort, in its standard form, does not handle negative numbers directly because it sorts based on individual digits. However, you can modify the algorithm by:
- Separating negative and positive numbers
- Sorting them separately
- Merging them after sorting (negative numbers in descending order, positives in ascending order)
Q7. Is Radix Sort stable?
Yes, Radix Sort is a stable sorting algorithm, meaning it preserves the relative order of elements with equal keys. This makes it ideal for cases where stability is required, such as sorting database records.
Q8. Why is Radix Sort not always used?
Radix Sort is not always preferred because:
- It requires extra memory (O(n + k) space complexity).
- It cannot efficiently handle floating-point numbers.
- It is not efficient for small datasets.
- It depends on fixed-length keys, making it unsuitable for variable-length strings.
Q9. Does Radix Sort work for floating-point numbers?
No, Radix Sort is not ideal for floating-point numbers because it relies on integer-based digit grouping. Floating-point numbers have decimal points, making them harder to process using this approach. Instead, comparison-based sorting algorithms like QuickSort or Merge Sort are preferred for floating-point numbers.
Q10. What is the space complexity of Radix Sort?
Radix Sort has a space complexity of O(n + k), as it requires additional memory for temporary buckets used in digit-wise sorting. This makes it less memory-efficient than in-place sorting algorithms like QuickSort (O(log n) space).
Q11. What is the difference between LSD and MSD Radix Sort?
- LSD (Least Significant Digit) Radix Sort: Starts sorting from the rightmost (least significant) digit and moves left. This is the most commonly used method.
- MSD (Most Significant Digit) Radix Sort: Starts sorting from the leftmost (most significant) digit and moves right. This is useful for sorting variable-length numbers.
Q12. How does Radix Sort compare to Counting Sort?
Radix Sort uses Counting Sort as a subroutine to sort digits. The key differences are:
- Counting Sort works best when numbers fall within a limited range.
- Radix Sort is more efficient for large numbers and works even when numbers have a wide range.
Q13. Can Radix Sort be used for string sorting?
Yes! Radix Sort can be modified to sort strings if they have fixed lengths (e.g., sorting dates, IP addresses, or airline codes). Each character is treated as a "digit" in a given radix (e.g., ASCII values, Unicode values), making it possible to sort strings efficiently.
Q14. What is the best-case and worst-case scenario for Radix Sort?
- Best-case time complexity: O(nk) (when k is small and numbers are uniformly distributed).
- Worst-case time complexity: O(nk) (when k is large, making the sorting process inefficient).
Q15. What is the best alternative to Radix Sort?
If Radix Sort is not efficient for your use case, consider these alternatives:
- QuickSort β Best for general-purpose sorting
- Merge Sort β Best for stability and floating-point numbers
- Counting Sort β Best when numbers fall within a small range
- Heap Sort β Best when minimal space usage is required
Conclusion
Radix Sort is a powerful non-comparative sorting algorithm that can be faster than QuickSort in specific scenarios. By sorting numbers digit by digit, it efficiently handles large integers and fixed-length strings. If you're dealing with huge datasets where QuickSort struggles, Radix Sort is a great alternative. π
Related Blogs
- Master JavaScript Sorting Algorithms: Efficiency & Analysis
- QuickSort Algorithm Explained in JavaScript & Python
- Merge Sort vs Quick Sort: Key Differences, Pros, & Use Cases
- Bucket Sort Algorithm: How It Works & When to Use It
- Counting Sort Algorithm: Fastest Non-Comparison Sorting
- Heap Sort Algorithm: Efficient Sorting Using a Binary Heap
- Shell Sort Algorithm: Fastest Sorting Method Explained
Bucket Sort Algorithm: How It Works & When to Use It
Counting Sort Algorithm: Fastest Non-Comparison Sorting
About Muhaymin Bin Mehmood
Front-end Developer skilled in the MERN stack, experienced in web and mobile development. Proficient in React.js, Node.js, and Express.js, with a focus on client interactions, sales support, and high-performance applications.