Sorting is one of the most important concepts in programming.
It helps in organizing data and is used in searching, databases, and many real-world applications.
In this blog, we will explore different sorting algorithms, their working, and their complexities.
š What is Sorting?
Sorting means arranging elements in a specific order:
- Ascending ā smallest to largest
- Descending ā largest to smallest
š¹ 1. Bubble Sort
Bubble Sort repeatedly swaps adjacent elements if they are in the wrong order.
š» Code:
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]
return arr
ā” Complexity:
- Time: O(n²)
- Space: O(1)
š Simple but inefficient for large data
š¹ 2. Selection Sort
Select the smallest element and place it at the correct position.
š» Code:
def selection_sort(arr):
n = len(arr)
for i in range(n):
min_index = i
for j in range(i+1, n):
if arr[j] < arr[min_index]:
min_index = j
arr[i], arr[min_index] = arr[min_index], arr[i]
return arr
ā” Complexity:
- Time: O(n²)
- Space: O(1)
š¹ 3. Insertion Sort
Builds the sorted array one element at a time.
š» Code:
def insertion_sort(arr):
for i in range(1, len(arr)):
key = arr[i]
j = i - 1
while j >= 0 and arr[j] > key:
arr[j+1] = arr[j]
j -= 1
arr[j+1] = key
return arr
ā” Complexity:
- Time: O(n²)
- Best Case: O(n)
š Efficient for small or nearly sorted data
š¹ 4. Merge Sort
Uses divide and conquer:
- Split array
- Sort halves
- Merge
š» Code:
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
ā” Complexity:
- Time: O(n log n)
- Space: O(n)
š Stable and efficient
š¹ 5. Quick Sort
Picks a pivot and partitions the array.
š» Code:
def quick_sort(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 quick_sort(left) + middle + quick_sort(right)
ā” Complexity:
- Average: O(n log n)
- Worst: O(n²)
š Very fast in practice
š¹ 6. Heap Sort
Uses a heap data structure to sort elements.
š» Code:
import heapq
def heap_sort(arr):
heapq.heapify(arr)
return [heapq.heappop(arr) for _ in range(len(arr))]
ā” Complexity:
- Time: O(n log n)
- Space: O(1) (in-place version)
š Comparison Table
Algorithm Time Complexity Space Stable
Bubble Sort O(n²) O(1) Yes
Selection Sort O(n²) O(1) No
Insertion Sort O(n²) O(1) Yes
Merge Sort O(n log n) O(n) Yes
Quick Sort O(n log n)* O(log n) No
Heap Sort O(n log n) O(1) No
š§ Key Takeaways
- Use Bubble/Selection/Insertion for learning
- Use Merge Sort when stability is needed
- Use Quick Sort for speed
- Use Heap Sort when memory is limited
š Conclusion
Sorting algorithms are fundamental to programming.
Understanding their differences helps you choose the right one based on:
- Input size
- Memory constraints
- Performance needs
Top comments (0)