JavaScript Implementation of Classic Array Sorting Algorithms
Quicksort
Quicksort uses a divide-and-conquer approach by selecting a pivot element.
let dataset = [1, 2, 5, 6, 3, 1, 4];
function quickSort(data) {
if (data.length < 2) {
return data;
}
let pivotIdx = Math.floor(data.length / 2);
let pivotValue = data.splice(pivotIdx, 1)[0];
let smaller = [];
let larger = [];
for (let element of data) {
if (pivotValue > element) {
smaller.push(element);
} else {
larger.push(element);
}
}
return [...quickSort(smaller), pivotValue, ...quickSort(larger)];
}
console.log(quickSort(dataset)); // Output: [ 1, 1, 2, 3, 4, 5, 6 ]
Bubble Sort
This algorithm repeatedly steps through the list, comparing adjacent elements and swapping them if they are in the wrong order. The process is repeated until the list is sorted.
Basic Implementation:
function simpleBubble(data) {
for (let i = 0; i < data.length - 1; i++) {
for (let j = 0; j < data.length - 1 - i; j++) {
if (data[j] > data[j + 1]) {
[data[j], data[j + 1]] = [data[j + 1], data[j]];
}
}
}
return data;
}
Optimized Version (with early termination):
function optimizedBubble(data) {
let n = data.length;
let swapped;
do {
swapped = false;
for (let i = 0; i < n - 1; i++) {
if (data[i] > data[i + 1]) {
let hold = data[i];
data[i] = data[i + 1];
data[i + 1] = hold;
swapped = true;
}
}
n--; // The last element is now sorted
} while (swapped);
return data;
}
Insertion Sort
Insertion sort builds the final sorted array one item at a time by comparing each new element too the already-sorted section and inserting it into the correct position.
let numbers = [2, 1, 8, 4, 9, 9, 12, 32, 7, 5];
function insertionSort(data) {
for (let i = 1; i < data.length; i++) {
let key = data[i];
let j = i - 1;
while (j >= 0 && data[j] > key) {
data[j + 1] = data[j];
j--;
}
data[j + 1] = key;
}
return data;
}
console.log(insertionSort(numbers));
Merge Sort
Merge sort recursively splits the array into halves until each sub-array contains a single element, then merges the sub-arrays back together in sorted order.
function mergeSort(data) {
if (data.length <= 1) return data;
const mid = Math.floor(data.length / 2);
const left = mergeSort(data.slice(0, mid));
const right = mergeSort(data.slice(mid));
return merge(left, right);
}
function merge(leftArr, rightArr) {
let merged = [];
let i = 0, j = 0;
while (i < leftArr.length && j < rightArr.length) {
if (leftArr[i] < rightArr[j]) {
merged.push(leftArr[i]);
i++;
} else {
merged.push(rightArr[j]);
j++;
}
}
return [...merged, ...leftArr.slice(i), ...rightArr.slice(j)];
}
Counting Sort
Counting sort works by counting the number of occurrences of each distinct element and calculating their positions.
function countSort(data) {
let countMap = {};
for (let num of data) {
countMap[num] = (countMap[num] || 0) + 1;
}
let sortedResult = [];
let sortedKeys = Object.keys(countMap).sort((a, b) => a - b);
for (let key of sortedKeys) {
while (countMap[key] > 0) {
sortedResult.push(Number(key));
countMap[key]--;
}
}
return sortedResult;
}
Shell Sort
Shell sort is a generalization of insertion sort that starts by sorting elements far apart from each other and progressively reduces the gap.
function shellSort(data) {
let n = data.length;
for (let gap = Math.floor(n / 2); gap > 0; gap = Math.floor(gap / 2)) {
for (let i = gap; i < n; i++) {
let temp = data[i];
let j;
for (j = i; j >= gap && data[j - gap] > temp; j -= gap) {
data[j] = data[j - gap];
}
data[j] = temp;
}
}
return data;
}
Selection Sort
Selection sort divides the array into a sorted and an unsorted region. It repeatedly finds the minimum element from the unsorted region and moves it to the end of the sorted region.
function selectionSort(data) {
for (let i = 0; i < data.length; i++) {
let minIndex = i;
for (let j = i + 1; j < data.length; j++) {
if (data[j] < data[minIndex]) {
minIndex = j;
}
}
if (minIndex !== i) {
[data[i], data[minIndex]] = [data[minIndex], data[i]];
}
}
return data;
}