Bucket Sort: Mechanism, Complexity Analysis & Interactive Visualizer
Bucket Sort
A distribution-based sorting algorithm that partitions elements into a finite number of buckets, sorts each bucket individually (using Insertion Sort), and then merges them.
How it works
Bucket Sort works by dividing the interval of input values into equal-sized sub-intervals (buckets). Each input value is placed into its corresponding bucket, sorted, and then gathered sequentially.
- Create an array of empty buckets.
- Distribute the elements from the input array into the buckets based on their values relative to the range (minimum and maximum).
- Sort each non-empty bucket using a simple sorting algorithm like Insertion Sort.
- Visit all buckets in order and copy their sorted elements back into the original array.
Complexity
Interactive visualization
Pseudocode
procedure bucketSort(A): n ← length(A) min, max ← findMinMax(A) numBuckets ← floor(n / 2) buckets ← array of numBuckets empty lists range ← max - min for i from 0 to n - 1: bucketIdx ← floor(((A[i] - min) / range) * (numBuckets - 1)) buckets[bucketIdx].append(A[i]) idx ← 0 for i from 0 to numBuckets - 1: insertionSort(buckets[i]) for j from 0 to length(buckets[i]) - 1: A[idx] ← buckets[i][j] idx ← idx + 1
JavaScript implementation
function bucketSort(arr) { const n = arr.length; if (n <= 1) return arr; let min = arr[0]; let max = arr[0]; for (let i = 1; i < n; i++) { if (arr[i] < min) min = arr[i]; if (arr[i] > max) max = arr[i]; } if (min === max) return arr; const numBuckets = Math.max(2, Math.floor(n / 2)); const buckets = Array.from({ length: numBuckets }, () => []); const range = max - min; for (let i = 0; i < n; i++) { const bucketIdx = Math.floor(((arr[i] - min) / range) * (numBuckets - 1)); buckets[bucketIdx].push(arr[i]); } let idx = 0; for (let i = 0; i < numBuckets; i++) { insertionSort(buckets[i]); for (let j = 0; j < buckets[i].length; j++) { arr[idx++] = buckets[i][j]; } } return arr; } function insertionSort(arr) { const len = arr.length; for (let i = 1; i < len; i++) { const key = arr[i]; let j = i - 1; while (j >= 0 && arr[j] > key) { arr[j + 1] = arr[j]; j--; } arr[j + 1] = key; } }
Pros and cons
Pros
- Extremely fast O(n + k) linear-time execution on uniformly distributed data.
- Highly effective when input elements are floating-point numbers distributed uniformly over a range.
- Stable sorting algorithm (using a stable inner sort like Insertion Sort).
Cons
- Not an in-place sort, requires auxiliary memory.
- Performance degrades to O(n²) if keys cluster into a single bucket.
- Requires knowledge of range (min/max) beforehand.
When to use it
- Uniformly Distributed Data: when elements are evenly spread over an interval (such as percentage values or decimal probabilities).
- Float Sorting: ideal for sorting floats in the range [0, 1).
Related reading
Sleep Sort: Mechanism, Complexity Analysis & Interactive Visualizer
A unique concurrency-based sorting algorithm: spawns a separate thread for each element, sleeping for a duration proportional to the element value before writing it to the output.
By Md. Harun-Or-Roshid
Cube Sort: Mechanism, Complexity Analysis & Interactive Visualizer
A parallel dimension sorting algorithm: organizes elements in a 3D coordinate cube and sorts vectors along the height, width, and depth axes sequentially to achieve sorted order.
By Md. Harun-Or-Roshid
Patience Sort: Mechanism, Complexity Analysis & Interactive Visualizer
A card-game inspired sorting algorithm: distributes elements onto a series of piles such that each pile's top is \(\ge\) the incoming value, then performs a multi-way merge across pile tops.
By Md. Harun-Or-Roshid
Library Sort: Mechanism, Complexity Analysis & Interactive Visualizer
A gapped variation of Insertion Sort: leaves empty slots (gaps) in the array, allowing elements to be inserted in \(O(1)\) shift time on average by avoiding massive shifts.
By Md. Harun-Or-Roshid