Comparison Based vs Non Comparison Based Sorting in DSA C++ - Complexity Comparison
Sorting is a common task, and how fast it runs depends on the method used.
We want to see how time grows when sorting gets bigger with different sorting types.
Analyze the time complexity of these two sorting approaches.
// Comparison based sorting example (Bubble Sort)
void bubbleSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
std::swap(arr[j], arr[j + 1]);
}
}
}
}
// Non-comparison based sorting example (Counting Sort)
void countingSort(int arr[], int n, int maxVal) {
int count[maxVal + 1] = {0};
for (int i = 0; i < n; i++) count[arr[i]]++;
int index = 0;
for (int i = 0; i <= maxVal; i++) {
while (count[i]-- > 0) arr[index++] = i;
}
}
Bubble Sort compares elements repeatedly; Counting Sort counts occurrences to sort.
Look at the loops and repeated steps in each method.
- Bubble Sort primary operation: Comparing and swapping pairs inside nested loops.
- Bubble Sort how many times: About n x n times (nested loops).
- Counting Sort primary operation: Counting each element once, then placing them back.
- Counting Sort how many times: Counting loop runs n times; placement loop runs maxVal times.
See how operations increase as input size grows.
| Input Size (n) | Bubble Sort Ops (approx.) | Counting Sort Ops (approx.) |
|---|---|---|
| 10 | 100 | 10 + maxVal |
| 100 | 10,000 | 100 + maxVal |
| 1000 | 1,000,000 | 1000 + maxVal |
Bubble Sort grows very fast (square of n), Counting Sort grows mostly with n plus max value range.
Time Complexity: O(n²) for comparison based (Bubble Sort), O(n + k) for non comparison based (Counting Sort)
Bubble Sort gets much slower as n grows; Counting Sort depends on n and the range of values (k).
[X] Wrong: "All sorting methods take about the same time because they all sort the list."
[OK] Correct: Some methods compare items many times, others use counting or special tricks that can be faster depending on data.
Knowing these differences helps you pick the right sorting method and explain your choice clearly in interviews.
"What if the input values are very large but n is small? How would Counting Sort's time complexity be affected?"
Practice
Solution
Step 1: Understand comparison based sorting
Comparison based sorting algorithms decide order by comparing elements pairwise, like Merge Sort, Quick Sort, and Heap Sort.Step 2: Identify non-comparison based sorting
Counting Sort uses element values as indices to count occurrences, not comparisons.Final Answer:
Counting Sort -> Option CQuick Check:
Counting Sort is non-comparison based [OK]
- Confusing Quick Sort as non-comparison
- Thinking Heap Sort is non-comparison
- Assuming all sorts use counting
radixSort on an integer array arr of size n in C++?Solution
Step 1: Understand typical function parameters
Sorting functions usually take the array and its size as parameters, in that order.Step 2: Match syntax with parameters
radixSort(arr, n); passes array and size correctly. radixSort(n, arr); reverses order, C misses size, D passes address incorrectly.Final Answer:
radixSort(arr, n); -> Option AQuick Check:
Array then size is standard [OK]
- Swapping parameter order
- Omitting size parameter
- Passing address of array incorrectly
int arr[] = {4, 2, 7, 1};
int n = 4;
// Using Counting Sort
void countingSort(int arr[], int n) {
int max_val = 7;
int count[8] = {0};
for (int i = 0; i < n; i++) count[arr[i]]++;
int index = 0;
for (int i = 0; i <= max_val; i++) {
while (count[i]-- > 0) {
arr[index++] = i;
}
}
}
countingSort(arr, n);
for (int i = 0; i < n; i++) std::cout << arr[i] << " ";Solution
Step 1: Count frequencies of each element
Count array records: count[1]=1, count[2]=1, count[4]=1, count[7]=1, others 0.Step 2: Rebuild array in sorted order
Loop from 0 to 7, placing elements according to counts: 1, 2, 4, 7.Final Answer:
1 2 4 7 -> Option DQuick Check:
Counting Sort outputs sorted array [OK]
- Confusing counting array indices
- Not rebuilding array correctly
- Assuming original order remains
void countingSort(int arr[], int n, int exp) {
int output[n];
int count[10] = {0};
for (int i = 0; i < n; i++)
count[(arr[i] / exp) % 10]++;
for (int i = 1; i < 10; i++)
count[i] += count[i - 1];
for (int i = 0; i < n; i++) {
output[count[(arr[i] / exp) % 10]] = arr[i];
count[(arr[i] / exp) % 10]--;
}
for (int i = 0; i < n; i++)
arr[i] = output[i];
}Solution
Step 1: Analyze output array indexing in third loop
Indexing uses count[...] directly, but count array is cumulative, so index should be count[...] - 1.Step 2: Identify correct fix
Subtract 1 from count[...] when indexing output to avoid skipping first position.Final Answer:
The output array index is off by one in the third loop -> Option AQuick Check:
Output index = count[...] - 1 needed [OK]
- Ignoring off-by-one in output indexing
- Changing count array size unnecessarily
- Not initializing count array
Solution
Step 1: Analyze input size and range
Array size n=1,000,000; range k=1001 (0 to 1000).Step 2: Compare sorting complexities
Counting Sort runs in O(n + k) which is about 1,001,000 steps, faster than O(n log n) for comparison sorts.Final Answer:
Counting Sort, because it sorts in O(n + k) where k is small -> Option BQuick Check:
Small range + large n favors Counting Sort [OK]
- Choosing Quick Sort ignoring range
- Preferring stable sort without need
- Ignoring Counting Sort efficiency on small range
Ready to prove it?
Pass the test and this pattern moves unknown
