timsort.js
/**
 * Sorts the specified portion of the specified array using a binary
 * insertion sort.  This is the best method for sorting small numbers
 * of elements.  It requires O(n log n) compares, but O(n^2) data
 * movement (worst case).
 *
 * If the initial part of the specified range is already sorted,
 * this method can take advantage of it: the method assumes that the
 * elements from index {@code lo}, inclusive, to {@code start},
 * exclusive are already sorted. 
 * @param {Array} a 
 * @param {Number} lo 
 * @param {Number} hi 
 * @param {Number} start 
 * @param {Function} c 
 */
Sorts the specified portion of the specified array using a binary
insertion sort.  This is the best method for sorting small numbers
of elements.  It requires O(n log n) compares, but O(n^2) data
movement (worst case).

If the initial part of the specified range is already sorted,
this method can take advantage of it: the method assumes that the
elements from index  lo, inclusive, to  start,
exclusive are already sorted.
Sorts the specified portion of the specified array using a binary insertion sort . This is the best method for sorting small numbers of elements . It requires O ( n log n ) compares but O ( n^2 ) data movement ( worst case ) . If the initial part of the specified range is already sorted this method can take advantage of it : the method assumes that the elements from index lo inclusive to start exclusive are already sorted .
function binarySort(a, lo, hi, start, c) {
    if (start === lo){
        start++;
    } 
    for ( ; start < hi; start++) {
        let pivot = a[start];
        let left = lo,
            right = start;
        while (left < right) {
            let mid = (left + right) >>> 1;
            if (c(pivot, a[mid]) < 0){ 
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        let n = start - left;  
        switch(n) {
            case 2:  a[left + 2] = a[left + 1];
            case 1:  a[left + 1] = a[left]; break;
            default: arrayCopy(a, left, a, left + 1, n);
        }
        a[left] = pivot;
    }
}
function binarySort ( a , lo , hi , start , c ) { if ( start === lo ) { start ++ ; } for ( ; start < hi ; start ++ ) { let pivot = a [ start ] ; let left = lo , right = start ; while ( left < right ) { let mid = ( left + right ) >>> 1 ; if ( c ( pivot , a [ mid ] ) < 0 ) { right = mid ; } else { left = mid + 1 ; } } let n = start - left ; switch ( n ) { case 2 : a [ left + 2 ] = a [ left + 1 ] ; case 1 : a [ left + 1 ] = a [ left ] ; break ; default : arrayCopy ( a , left , a , left + 1 , n ) ; } a [ left ] = pivot ; } }
Sorts the specified portion of the specified array using a binary
 insertion sort.
Sorts the specified portion of the specified array using a binary insertion sort .
//assert lo <= start && start <= hi;
 // Set left (and right) to the index where a[start] (pivot) belongs
 // assert left <= right;
 /*
         * Invariants:
         *   pivot >= all in [lo, left).
         *   pivot <  all in [right, start).
         */ //assert left == right;
 /*
         * The invariants still hold: pivot >= all in [lo, left) and
         * pivot < all in [left, start), so pivot belongs at left.  Note
         * that if there are elements equal to pivot, left points to the
         * first slot after them -- that's why this sort is stable.
         * Slide elements over to make room to make room for pivot.
         */ // The number of elements to move
 // Switch is just an optimization for arraycopy in default case
