UNPKG

introsort

Version:
121 lines (118 loc) 2.75 kB
'use strict'; /* * Intro sort ported from Java to Javascript * * original Copyright Ralph Unden, * http://ralphunden.net/content/tutorials/a-guide-to-introsort/?q=a-guide-to-introsort * Modifications: Bernhard Pfahringer * changes include: local insertion sort, no global array * * Javascript port: Arnor Heidar Sigurdsson <arnorhs@gmail.com> */ const SIZE_THRESHOLD = 16; const sort = (a) => { introsort_loop(a, 0, a.length, 2 * floor_lg(a.length)); }; /* * Quicksort algorithm modified for Introsort */ const introsort_loop = (a, lo, hi, depth_limit) => { while (hi - lo > SIZE_THRESHOLD) { if (depth_limit === 0) { heapsort(a, lo, hi); return; } depth_limit = depth_limit - 1; var p = partition(a, lo, hi, medianof3(a, lo, lo + (hi - lo) / 2 + 1, hi - 1)); introsort_loop(a, p, hi, depth_limit); hi = p; } insertionsort(a, lo, hi); }; const partition = (a, lo, hi, x) => { let i = lo; let j = hi; while (true) { while (a[i] < x) i++; j = j - 1; while (x < a[j]) j = j - 1; if (i >= j) return i; exchange(a, i, j); i++; } }; const medianof3 = (a, lo, mid, hi) => { if (a[mid] < a[lo]) { if (a[hi] < a[mid]) { return a[mid]; } else { return a[hi] < a[lo] ? a[hi] : a[lo]; } } else { if (a[hi] < a[mid]) { return a[hi] < a[lo] ? a[lo] : a[hi]; } else { return a[mid]; } } }; /* * Heapsort algorithm */ const heapsort = (a, lo, hi) => { var n = hi - lo, i; for (i = n / 2; i >= 1; i--) { downheap(a, i, n, lo); } for (i = n; i > 1; i--) { exchange(a, lo, lo + i - 1); downheap(a, 1, i - 1, lo); } }; const downheap = (a, i, n, lo) => { var d = a[lo + i - 1]; var child; while (i <= n / 2) { child = 2 * i; if (child < n && a[lo + child - 1] < a[lo + child]) { child++; } if (d >= a[lo + child - 1]) break; a[lo + i - 1] = a[lo + child - 1]; i = child; } a[lo + i - 1] = d; }; /* * Insertion sort algorithm */ const insertionsort = (a, lo, hi) => { var i, j; var t; for (i = lo; i < hi; i++) { j = i; t = a[i]; while (j != lo && t < a[j - 1]) { a[j] = a[j - 1]; j--; } a[j] = t; } }; /* * Common methods for all algorithms */ const exchange = (a, i, j) => { var t = a[i]; a[i] = a[j]; a[j] = t; }; const floor_lg = (a) => Math.floor(Math.log(a) / Math.log(2)) << 0; module.exports = sort;