Bubble Sort
Bubble sort operates by repeatedly stepping through the list, comparing adjacent elements, and swapping them if they are in the wrong order. The pass through the list is repeated until no swaps are needed, which indicates that the list is sorted.
C++ Implementation
#include <vector>
#include <iostream>
void bubbleSort(std::vector<int>& arr) {
int n = arr.size();
bool swapped;
for (int i = 0; i < n - 1; ++i) {
swapped = false;
for (int j = 0; j < n - i - 1; ++j) {
if (arr[j] > arr[j + 1]) {
std::swap(arr[j], arr[j + 1]);
swapped = true;
}
}
if (!swapped) break;
}
}
Python Implementation
def bubble_sort(arr):
n = len(arr)
for i in range(n):
swapped = False
for j in range(0, n - i - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
swapped = True
if not swapped:
break
Selection Sort
Selection sort divides the input list into two parts: a sorted sublist built up from left to right, and an unsorted sublist occupying the rest of the array. Initially, the sorted sublist is empty. The algorithm proceeds by finding the smallest element in the unsorted sublist, exchanging it with the leftmost unsorted element, and moving the sublist boundaries one element to the right.
C++ Implementation
#include <vector>
#include <iostream>
void selectionSort(std::vector<int>& arr) {
int n = arr.size();
for (int i = 0; i < n - 1; ++i) {
int min_idx = i;
for (int j = i + 1; j < n; ++j) {
if (arr[j] < arr[min_idx]) {
min_idx = j;
}
}
if (min_idx != i) {
std::swap(arr[i], arr[min_idx]);
}
}
}
Python Implementation
def selection_sort(arr):
n = len(arr)
for i in range(n):
min_idx = i
for j in range(i + 1, n):
if arr[j] < arr[min_idx]:
min_idx = j
arr[i], arr[min_idx] = arr[min_idx], arr[i]
Insertion Sort
Insertion sort builds the final sorted array one item at a time. It iterates through the input, growing a sorted sublist. For each element, it scans backward through the sorted sublist to find the correct position to insert the new element, shifting larger elements to the right to make room.
C++ Implementation
#include <vector>
#include <iostream>
void insertionSort(std::vector<int>& arr) {
int n = arr.size();
for (int i = 1; i < n; ++i) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
}
Python Implementation
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
Shell Sort
Shell sort is an optimization of insertion sort that allows the exchange of items that are far apart. The idea is to arrange the list of elements so that, starting anywhere, taking every h-th element produces a sorted list. Such a list is said to be h-sorted. The algorithm uses decreasing increment sequences to sort the array, culminating in an increment of 1, which guarantees a fully sorted array.
C++ Implementation
#include <vector>
#include <iostream>
void shellSort(std::vector<int>& arr) {
int n = arr.size();
for (int gap = n / 2; gap > 0; gap /= 2) {
for (int i = gap; i < n; ++i) {
int temp = arr[i];
int j;
for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
arr[j] = arr[j - gap];
}
arr[j] = temp;
}
}
}
Python Implementation
def shell_sort(arr):
n = len(arr)
gap = n // 2
while gap > 0:
for i in range(gap, n):
temp = arr[i]
j = i
while j >= gap and arr[j - gap] > temp:
arr[j] = arr[j - gap]
j -= gap
arr[j] = temp
gap //= 2
Quick Sort
Quicksort is a divide-and-conquer algorithm. It works by selecting a pivot element from the array and partitioning the other elements into two sub-arrays, according to whether they are less than or greater than the pivot. The sub-arrays are then sorted recursively.
C++ Implementation
#include <vector>
#include <iostream>
int partition(std::vector<int>& arr, int low, int high) {
int pivot = arr[high];
int i = low - 1;
for (int j = low; j < high; ++j) {
if (arr[j] < pivot) {
++i;
std::swap(arr[i], arr[j]);
}
}
std::swap(arr[i + 1], arr[high]);
return i + 1;
}
void quickSort(std::vector<int>& arr, int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
Python Implementation
def partition(arr, low, high):
pivot = arr[high]
i = low - 1
for j in range(low, high):
if arr[j] < pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[i + 1], arr[high] = arr[high], arr[i + 1]
return i + 1
def quick_sort(arr, low, high):
if low < high:
pi = partition(arr, low, high)
quick_sort(arr, low, pi - 1)
quick_sort(arr, pi + 1, high)
Merge Sort
Merge sort is an efficient, stable, divide-and-conquer algorithm. It divides the unsorted list into n sublists, each containing one element, and then repeatedly merges sublists to produce new sorted sublists until there is only one sublist remaining, which is the sorted list.
C++ Implementation
#include <vector>
#include <iostream>
void merge(std::vector<int>& arr, int left, int mid, int right) {
std::vector<int> temp(right - left + 1);
int i = left, j = mid + 1, k = 0;
while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++];
}
}
while (i <= mid) temp[k++] = arr[i++];
while (j <= right) temp[k++] = arr[j++];
for (int l = 0; l < k; ++l) {
arr[left + l] = temp[l];
}
}
void mergeSort(std::vector<int>& arr, int left, int right) {
if (left >= right) return;
int mid = left + (right - left) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
Python Implementation
def merge(arr, left, mid, right):
temp = []
i, j = left, mid + 1
while i <= mid and j <= right:
if arr[i] <= arr[j]:
temp.append(arr[i])
i += 1
else:
temp.append(arr[j])
j += 1
while i <= mid:
temp.append(arr[i])
i += 1
while j <= right:
temp.append(arr[j])
j += 1
for k in range(len(temp)):
arr[left + k] = temp[k]
def merge_sort(arr, left, right):
if left >= right:
return
mid = left + (right - left) // 2
merge_sort(arr, left, mid)
merge_sort(arr, mid + 1, right)
merge(arr, left, mid, right)
Bucket Sort
Bucket sort works by distributing the elements of an array into a number of buckets. Each bucket is then sorted individually, either using a different sorting algorithm or by recursively applying the bucket sorting algorithm. Finally, the sorted buckets are concatenated to form the final sorted array.
C++ Implementation
#include <vector>
#include <algorithm>
#include <iostream>
void bucketSort(std::vector<int>& arr) {
if (arr.empty()) return;
int max_val = *std::max_element(arr.begin(), arr.end());
int min_val = *std::min_element(arr.begin(), arr.end());
int bucket_count = (max_val - min_val) / arr.size() + 1;
std::vector<std::vector<int>> buckets(bucket_count);
for (int val : arr) {
int idx = (val - min_val) / arr.size();
buckets[idx].push_back(val);
}
int index = 0;
for (auto& bucket : buckets) {
std::sort(bucket.begin(), bucket.end());
for (int val : bucket) {
arr[index++] = val;
}
}
}
Python Implementation
def bucket_sort(arr):
if not arr:
return
max_val = max(arr)
min_val = min(arr)
bucket_count = (max_val - min_val) // len(arr) + 1
buckets = [[] for _ in range(bucket_count)]
for val in arr:
idx = (val - min_val) // len(arr)
buckets[idx].append(val)
index = 0
for bucket in buckets:
bucket.sort()
for val in bucket:
arr[index] = val
index += 1
Heap Sort
Heap sort involves building a max heap from the input data, and then repeatedly extracting the maximum element from the heap and rebuilding the heap until all elements have been extracted. The extracted elements form a sorted array.
C++ Implementation
#include <vector>
#include <iostream>
void heapify(std::vector<int>& arr, int n, int i) {
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && arr[left] > arr[largest])
largest = left;
if (right < n && arr[right] > arr[largest])
largest = right;
if (largest != i) {
std::swap(arr[i], arr[largest]);
heapify(arr, n, largest);
}
}
void heapSort(std::vector<int>& arr) {
int n = arr.size();
for (int i = n / 2 - 1; i >= 0; --i)
heapify(arr, n, i);
for (int i = n - 1; i > 0; --i) {
std::swap(arr[0], arr[i]);
heapify(arr, i, 0);
}
}
Python Implementation
def heapify(arr, n, i):
largest = i
left = 2 * i + 1
right = 2 * i + 2
if left < n and arr[left] > arr[largest]:
largest = left
if right < n and arr[right] > arr[largest]:
largest = right
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i]
heapify(arr, n, largest)
def heap_sort(arr):
n = len(arr)
for i in range(n // 2 - 1, -1, -1):
heapify(arr, n, i)
for i in range(n - 1, 0, -1):
arr[0], arr[i] = arr[i], arr[0]
heapify(arr, i, 0)
Algorithm Performance Comparison
| Algorithm | Time Complexity | Space Complexity | Stable |
|---|---|---|---|
| Bubble Sort | O(n^2) | O(1) | Yes |
| Selection Sort | O(n^2) | O(1) | No |
| Insertion Sort | O(n^2) | O(1) | Yes |
| Shell Sort | O(n^1.5) | O(1) | No |
| Quick Sort | O(n log n) | O(log n) | No |
| Merge Sort | O(n log n) | O(n) | Yes |
| Bucket Sort | O(n + k) | O(n + k) | Depends |
| Heap Sort | O(n log n) | O(1) | No |