Comparison Based vs Non Comparison Based Sorting in DSA Python - Complexity Comparison
Sorting is a common task where we arrange items in order. Different sorting methods take different amounts of time depending on how they work.
We want to understand how the time needed changes as the list gets bigger for comparison-based and non-comparison-based sorting.
Analyze the time complexity of these two sorting approaches.
# Comparison based sorting example (Bubble Sort)
def bubble_sort(arr):
n = len(arr)
for i in range(n):
for j in range(0, n-i-1):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
# Non-comparison based sorting example (Counting Sort)
def counting_sort(arr, max_val):
count = [0] * (max_val + 1)
for num in arr:
count[num] += 1
index = 0
for i in range(len(count)):
while count[i] > 0:
arr[index] = i
index += 1
count[i] -= 1
Bubble Sort compares elements to sort, Counting Sort uses counting without direct comparisons.
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: Outer loop runs n times, inner loop runs up to n times, so about n x n = n² times.
- Counting Sort primary operation: Counting occurrences of each number, then rebuilding the list.
- Counting Sort how many times: Counting loop runs n times, rebuilding loop runs up to max_val times.
How does the work increase when the list gets bigger?
| Input Size (n) | Bubble Sort Ops (approx.) | Counting Sort Ops (approx.) |
|---|---|---|
| 10 | 100 (10²) | 10 + max_val |
| 100 | 10,000 (100²) | 100 + max_val |
| 1000 | 1,000,000 (1000²) | 1000 + max_val |
Bubble Sort grows very fast as n increases (squares). Counting Sort grows mostly with n plus the range of numbers (max_val).
Time Complexity: O(n²) for comparison-based (Bubble Sort), O(n + k) for non-comparison-based (Counting Sort), where k is the range of input values.
This means comparison-based sorting can get slow quickly as list size grows, while non-comparison sorting can be faster if the number range is small.
[X] Wrong: "All sorting methods take about the same time because they all sort the list."
[OK] Correct: Different sorting methods work differently; some compare items many times, others use counting or special tricks that can be faster depending on the data.
Knowing how sorting methods differ helps you choose the right one and explain your choice clearly. This skill shows you understand how algorithms work under the hood.
"What if the input numbers have a very large range in Counting Sort? How would that affect the time complexity?"
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 counting frequencies and does not compare elements directly.Final Answer:
Counting Sort -> Option CQuick Check:
Non-comparison based = Counting Sort [OK]
- Confusing Counting Sort with Quick Sort
- Thinking Merge Sort is non-comparison based
- Assuming Heap Sort doesn't compare elements
counting_sort(arr) in Python?Solution
Step 1: Recall Python function call syntax
Functions are called with parentheses enclosing arguments, likefunc(args).Step 2: Match syntax with options
Onlycounting_sort(arr)uses correct parentheses syntax.Final Answer:
counting_sort(arr) -> Option AQuick Check:
Function call uses parentheses [OK]
- Using square brackets instead of parentheses
- Omitting parentheses when calling functions
- Using curly braces which are invalid for calls
[4, 2, 2, 8, 3, 3, 1]?
def counting_sort(arr):
max_val = max(arr)
count = [0] * (max_val + 1)
for num in arr:
count[num] += 1
sorted_arr = []
for i in range(len(count)):
sorted_arr.extend([i] * count[i])
return sorted_arr
print(counting_sort([4, 2, 2, 8, 3, 3, 1]))Solution
Step 1: Count frequencies of each number
Count array will have counts: 1->1, 2->2, 3->2, 4->1, 8->1, others 0.Step 2: Build sorted array by repeating each number count times
Sorted array is [1, 2, 2, 3, 3, 4, 8].Final Answer:
[1, 2, 2, 3, 3, 4, 8] -> Option AQuick Check:
Counting Sort output = sorted array [OK]
- Confusing original array with sorted output
- Reversing the sorted order
- Missing duplicates in output
def counting_sort(arr):
max_val = max(arr)
count = [0] * max_val
for num in arr:
count[num] += 1
sorted_arr = []
for i in range(len(count)):
sorted_arr.extend([i] * count[i])
return sorted_arr
print(counting_sort([1, 4, 1, 2, 7, 5]))Solution
Step 1: Check count array size
Count array size is max_val, but should be max_val + 1 to include max element index.Step 2: Identify impact of size error
Missing last index causes IndexError or missing counts for max element.Final Answer:
count array size is too small, missing last element count -> Option BQuick Check:
Count array size = max_val + 1 needed [OK]
- Ignoring off-by-one error in count array size
- Thinking extend causes error
- Confusing max_val with min_val
Solution
Step 1: Analyze input range and size
Input values are integers from 0 to 1000, so k = 1000 is small compared to n (large list).Step 2: Choose sorting algorithm based on time complexity
Counting Sort runs in O(n + k), which is efficient for small k and large n, better than O(n log n).Final Answer:
Counting Sort because it sorts in O(n + k) time where k is max value -> Option DQuick Check:
Small range + large list = Counting Sort best [OK]
- Choosing Quick Sort ignoring input range
- Preferring Bubble Sort despite poor performance
- Ignoring Counting Sort's linear time advantage
Ready to prove it?
Pass the test and this pattern moves unknown
