Sorting Algorithms – Bubble Sort, QuickSort, and Merge Sort
CQH103: Sorting Algorithms – Bubble Sort, QuickSort, and Merge Sort
Sorting is one of the most fundamental operations in programming. Whether you’re organizing numbers, names, or any kind of data, efficient sorting is crucial for performance. In this lesson, we’ll explore three key sorting algorithms: Bubble Sort, QuickSort, and Merge Sort—each with unique approaches and trade-offs.
Why Sorting Matters
Sorting is essential for many applications, from searching for data quickly to optimizing storage and display. It directly ties back to arrays and linked lists, the core data structures we covered in CQH102. The way data is structured impacts the efficiency of sorting, and choosing the right algorithm can make a huge difference in performance.
Bubble Sort – The Simple But Slow Approach
Bubble Sort repeatedly steps through the list, compares adjacent elements, and swaps them if they are in the wrong order. It continues until the list is fully sorted.
How It Works
- Compare the first two elements and swap if necessary.
- Move to the next pair and repeat.
- Continue until the largest element bubbles to the end.
- Repeat the process for the remaining elements.
Example in Python
# Bubble Sort Implementation
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]
numbers = [5, 3, 8, 4, 2]
bubble_sort(numbers)
print(numbers) # Output: [2, 3, 4, 5, 8]
Performance
- Time Complexity: O(n²) – very slow for large datasets.
- Best For: Small datasets or when simplicity matters.
QuickSort – The Efficient Divide & Conquer Method
QuickSort is a divide and conquer algorithm that selects a pivot, partitions the array, and recursively sorts the subarrays.
How It Works
- Pick a pivot element.
- Partition the array so that elements smaller than the pivot go left, and larger ones go right.
- Recursively apply QuickSort to the left and right partitions.
Example in Python
# QuickSort Implementation
def quicksort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quicksort(left) + middle + quicksort(right)
numbers = [5, 3, 8, 4, 2]
print(quicksort(numbers)) # Output: [2, 3, 4, 5, 8]
Performance
- Time Complexity: O(n log n) on average.
- Best For: Large datasets where speed matters.
Merge Sort – The Reliable and Stable Approach
Merge Sort also follows the divide and conquer strategy but ensures stability (preserving order of equal elements).
How It Works
- Divide the array into halves until each half contains a single element.
- Merge the halves back together in sorted order.
Example in Python
# Merge Sort Implementation
def merge_sort(arr):
if len(arr) <= 1:
return arr
mid = len(arr) // 2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
return merge(left, right)
def merge(left, right):
result = []
i = j = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
result.extend(left[i:])
result.extend(right[j:])
return result
numbers = [5, 3, 8, 4, 2]
print(merge_sort(numbers)) # Output: [2, 3, 4, 5, 8]
Performance
- Time Complexity: O(n log n), but requires extra space.
- Best For: Sorting linked lists or when stability matters.
Choosing the Right Sorting Algorithm
Algorithm | Best Case | Average Case | Worst Case | Space Complexity | Use Case |
---|---|---|---|---|---|
Bubble Sort | O(n) | O(n²) | O(n²) | O(1) | Small datasets, simple needs |
QuickSort | O(n log n) | O(n log n) | O(n²) | O(log n) | Fast sorting, large datasets |
Merge Sort | O(n log n) | O(n log n) | O(n log n) | O(n) | Stable sorting, linked lists |
Key Takeaways
- Use Bubble Sort for simplicity or small datasets.
- Use QuickSort for general-purpose fast sorting.
- Use Merge Sort when stability is required or for linked lists.
Sorting is a foundational topic in computer science, and different sorting techniques work best for different data structures. Arrays work well with QuickSort due to fast random access, while linked lists benefit from Merge Sort’s stability.
Next Steps
Sorting is just the beginning! Next, we’ll dive into Searching Algorithms like Binary Search and Linear Search, showing how sorted data can make searching lightning-fast.
Want to try it yourself? Modify the above sorting algorithms to handle descending order sorting and post your solution in the comments! 🚀