Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Prompt: Can you write an industrial strength quicksort algorithm in JavaScript?
- ___
- Below is an **industrial-strength Quicksort** implementation in JavaScript.
- It includes the techniques normally required for high-performance, production-grade behavior:
- ### ✔️ Features
- * **Median-of-three pivot selection** (reduces worst-case risk)
- * **Cutoff to insertion sort** for small partitions (improves speed)
- * **Tail-recursion elimination / iterative partitioning** (prevents deep recursion)
- * **In-place sorting**
- * **Stable performance across partially sorted / adversarial data**
- ---
- # Industrial-Strength Quicksort (JavaScript)
- ```js
- /**
- * Industrial-strength in-place quicksort.
- * Uses:
- * - Median-of-three pivoting
- * - Insertion sort for small partitions
- * - Tail recursion elimination
- */
- function quicksort(arr) {
- if (!Array.isArray(arr) || arr.length < 2) return arr;
- quicksortInternal(arr, 0, arr.length - 1);
- return arr;
- }
- const INSERTION_SORT_THRESHOLD = 16;
- // ------------------ Helper: Insertion Sort ------------------
- function insertionSort(arr, left, right) {
- for (let i = left + 1; i <= right; i++) {
- const tmp = arr[i];
- let j = i - 1;
- while (j >= left && arr[j] > tmp) {
- arr[j + 1] = arr[j];
- j--;
- }
- arr[j + 1] = tmp;
- }
- }
- // ------------------ Helper: Median-of-Three Pivot ------------------
- function medianOfThree(arr, a, b, c) {
- const A = arr[a], B = arr[b], C = arr[c];
- if (A < B) {
- if (B < C) return b;
- return A < C ? c : a;
- } else {
- if (A < C) return a;
- return B < C ? c : b;
- }
- }
- // ------------------ Main Quicksort Logic ------------------
- function quicksortInternal(arr, left, right) {
- while (left < right) {
- // Use insertion sort for small segments
- if (right - left < INSERTION_SORT_THRESHOLD) {
- insertionSort(arr, left, right);
- return;
- }
- // Median-of-three pivot selection
- const mid = left + ((right - left) >> 1);
- const pivotIndex = medianOfThree(arr, left, mid, right);
- const pivot = arr[pivotIndex];
- // Move pivot out of the way
- swap(arr, pivotIndex, right);
- // Partitioning (Lomuto variant)
- let i = left;
- for (let j = left; j < right; j++) {
- if (arr[j] <= pivot) {
- swap(arr, i, j);
- i++;
- }
- }
- swap(arr, i, right);
- // Tail recursion elimination:
- // Recurse into smaller part; iterate on the larger.
- const leftSize = i - 1 - left;
- const rightSize = right - (i + 1);
- if (leftSize < rightSize) {
- quicksortInternal(arr, left, i - 1);
- left = i + 1; // eliminate tail-recursion
- } else {
- quicksortInternal(arr, i + 1, right);
- right = i - 1; // eliminate tail-recursion
- }
- }
- }
- // ------------------ Utility ------------------
- function swap(arr, i, j) {
- const tmp = arr[i];
- arr[i] = arr[j];
- arr[j] = tmp;
- }
- // ------------------ Usage ------------------
- let data = [9, 2, 7, 4, 1, 3, 8, 6, 5];
- console.log(quicksort(data)); // sorted output
- ```
- ---
- # Why This Is “Industrial-Strength”
- ### 1. **Median-of-three pivoting**
- Greatly reduces the chance that nearly sorted or reverse-sorted data cause O(n²).
- ### 2. **Insertion sort threshold**
- For small partitions (≤16 elements), insertion sort is faster than recursion + partitioning.
- ### 3. **Tail recursion elimination**
- Ensures the algorithm never blows the call stack on large arrays; maximum recursion depth is O(log n).
- ### 4. **In-place**
- No extra allocations, cache-friendly, and suitable for large datasets.
- ---
- If you'd like, I can also provide:
- ✅ A stable version (slow but stable)
- ✅ A version optimized for V8 (Chrome/Node) performance quirks
- ✅ A fully iterative (stack-based) version
- ✅ A TypeScript version
- Just tell me!
- ____
- Prompt: Could you generate test cases for this code?
- ____
- Here are **comprehensive, industrial-strength test cases** for the Quicksort implementation you asked for.
- They cover correctness, edge cases, randomized stress testing, adversarial inputs, and comparisons with the built-in `.sort()` for verification.
- You can run these in Node.js, a browser, or a test framework like Jest/Mocha.
- ---
- # ✅ **Test Suite (Plain JavaScript)**
- ```js
- // Import or paste your quicksort() implementation here
- function deepEqual(a, b) {
- return JSON.stringify(a) === JSON.stringify(b);
- }
- function runTest(name, fn) {
- try {
- fn();
- console.log(`✔️ ${name}`);
- } catch (err) {
- console.error(`❌ ${name}`);
- console.error(err);
- }
- }
- /* ===============================
- * BASIC FUNCTIONALITY TESTS
- * =============================== */
- runTest("Sort already sorted list", () => {
- const arr = [1, 2, 3, 4, 5];
- const sorted = quicksort([...arr]);
- if (!deepEqual(sorted, arr)) throw new Error("Mismatch");
- });
- runTest("Sort reverse sorted list", () => {
- const arr = [5, 4, 3, 2, 1];
- const sorted = quicksort([...arr]);
- if (!deepEqual(sorted, [1,2,3,4,5])) throw new Error("Mismatch");
- });
- runTest("Sort random small list", () => {
- const arr = [9, 1, 5, 3, 2, 8];
- const expected = [...arr].sort((a, b) => a - b);
- const sorted = quicksort([...arr]);
- if (!deepEqual(sorted, expected)) throw new Error("Mismatch");
- });
- runTest("Sort with duplicates", () => {
- const arr = [5, 3, 5, 2, 2, 9, 1, 5];
- const expected = [...arr].sort((a, b) => a - b);
- const sorted = quicksort([...arr]);
- if (!deepEqual(sorted, expected)) throw new Error("Mismatch");
- });
- runTest("Sort an array with all identical elements", () => {
- const arr = new Array(20).fill(7);
- const sorted = quicksort([...arr]);
- if (!deepEqual(sorted, arr)) throw new Error("Mismatch");
- });
- runTest("Sort array with negative numbers", () => {
- const arr = [-5, -1, 0, 3, -2, 8];
- const expected = [...arr].sort((a, b) => a - b);
- const sorted = quicksort([...arr]);
- if (!deepEqual(sorted, expected)) throw new Error("Mismatch");
- });
- runTest("Sort array with floats", () => {
- const arr = [1.1, 0.1, 3.5, 2.2, -1.8];
- const expected = [...arr].sort((a, b) => a - b);
- const sorted = quicksort([...arr]);
- if (!deepEqual(sorted, expected)) throw new Error("Mismatch");
- });
- /* ===============================
- * EDGE CASE TESTS
- * =============================== */
- runTest("Empty array", () => {
- const arr = [];
- const sorted = quicksort([]);
- if (!deepEqual(sorted, [])) throw new Error("Mismatch");
- });
- runTest("Single-element array", () => {
- const arr = [42];
- const sorted = quicksort([42]);
- if (!deepEqual(sorted, arr)) throw new Error("Mismatch");
- });
- runTest("Two-element array", () => {
- const arr = [2, 1];
- const sorted = quicksort([...arr]);
- if (!deepEqual(sorted, [1, 2])) throw new Error("Mismatch");
- });
- runTest("Handles extremely large numbers", () => {
- const arr = [Number.MAX_SAFE_INTEGER, -999999999999, 0, 500, 42];
- const expected = [...arr].sort((a, b) => a - b);
- const sorted = quicksort([...arr]);
- if (!deepEqual(sorted, expected)) throw new Error("Mismatch");
- });
- /* ===============================
- * STRESS + ADVERSE CASES
- * =============================== */
- runTest("Random large array (10k elements)", () => {
- const arr = Array.from({ length: 10000 }, () => Math.floor(Math.random() * 1e6));
- const expected = [...arr].sort((a, b) => a - b);
- const sorted = quicksort([...arr]);
- if (!deepEqual(sorted, expected)) throw new Error("Mismatch");
- });
- runTest("Adversarial input: already sorted with repetition", () => {
- const arr = [];
- for (let i = 0; i < 5000; i++) arr.push(i % 50);
- const expected = [...arr].sort((a, b) => a - b);
- const sorted = quicksort([...arr]);
- if (!deepEqual(sorted, expected)) throw new Error("Mismatch");
- });
- runTest("Adversarial input: descending order with duplicates", () => {
- const arr = [];
- for (let i = 5000; i >= 0; i--) arr.push(i % 10);
- const expected = [...arr].sort((a, b) => a - b);
- const sorted = quicksort([...arr]);
- if (!deepEqual(sorted, expected)) throw new Error("Mismatch");
- });
- /* ===============================
- * VERY LARGE STRESS TEST (optional)
- * =============================== */
- // Only run this if you want to test for real industrial loads
- /*
- runTest("Very large array (100k elements)", () => {
- const arr = Array.from({ length: 100000 }, () => Math.floor(Math.random() * 1e6));
- const expected = [...arr].sort((a, b) => a - b);
- const sorted = quicksort([...arr]);
- if (!deepEqual(sorted, expected)) throw new Error("Mismatch");
- });
- */
- ```
- ---
- # 📌 What These Tests Cover
- ### ✔ Correctness
- Comparisons against JavaScript’s built-in `.sort()` ensure accuracy.
- ### ✔ Edge Cases
- * Empty arrays
- * Single element
- * Two elements
- * All elements identical
- * Negative / floating numbers
- * Very large values
- ### ✔ Adversarial Cases
- Designed to trigger worst-case patterns in naive quicksort:
- * Already sorted arrays
- * Reverse sorted arrays
- * Duplicates-heavy arrays
- ### ✔ Stress Tests
- 10,000–100,000 item random arrays to ensure performance and stack stability.
- ---
- # Want a version for Jest / Mocha?
- I can generate a fully structured Jest or Mocha test file with `describe()` and `it()` blocks as well — just tell me your preferred framework.
Advertisement
Add Comment
Please, Sign In to add comment