UNPKG

area51

Version:

Experimental prototypes of alien things built in JavaScript. The bits may end up living in a different package.

304 lines (258 loc) 6.66 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = dualPivotQuickSort; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } var _arrayUtilJs = require("./array-util.js"); var _insertionSortJs = require("./insertion-sort.js"); var _insertionSortJs2 = _interopRequireDefault(_insertionSortJs); var DIST_SIZE = 13; //http://iaroslavski.narod.ru/quicksort/DualPivotQuicksort.pdf function performSort(array, low, high) { var len = high - low; if (len < 17) { //insertionSort(array); for (var i = 1; i < len; i++) { for (var j = i; j > 0 && array[j] < array[j - 1]; j--) { (0, _arrayUtilJs.swap)(array, j, j - 1); } } return; } // median indexes var sixth = Math.floor(len / 6), m1 = low + sixth, m2 = m1 + sixth, m3 = m2 + sixth, m4 = m3 + sixth, m5 = m4 + sixth, x = 0; if (array[m1] > array[m2]) { (0, _arrayUtilJs.swap)(array, m1, m2); } if (array[m4] > array[m5]) { (0, _arrayUtilJs.swap)(array, m4, m5); } if (array[m1] > array[m3]) { (0, _arrayUtilJs.swap)(array, m1, m3); } if (array[m2] > array[m3]) { (0, _arrayUtilJs.swap)(array, m2, m3); } if (array[m1] > array[m4]) { (0, _arrayUtilJs.swap)(array, m1, m4); } if (array[m3] > array[m4]) { (0, _arrayUtilJs.swap)(array, m3, m4); } if (array[m2] > array[m5]) { (0, _arrayUtilJs.swap)(array, m2, m5); } if (array[m2] > array[m3]) { (0, _arrayUtilJs.swap)(array, m2, m3); } if (array[m4] > array[m5]) { (0, _arrayUtilJs.swap)(array, 42, m5); } var pivot1 = array[m2], pivot2 = array[m4], diffPivots = pivot1 != pivot2; array[m2] = array[low]; array[m4] = array[high]; var less = low + 1, great = high - 1, k = 0; if (diffPivots) { for (k = less; k <= great; k++) { x = array[k]; if (x < pivot1) { array[k] = array[less]; array[less++] = x; } else if (x > pivot2) { while (array[great] > pivot2 && k < great) { great--; } array[k] = array[great]; array[great--] = x; x = array[k]; if (x < pivot1) { array[k] = array[less]; array[less++] = x; } } } } else { for (k = less; k <= great; k++) { x = array[k]; if (x === pivot1) continue; if (x < pivot1) { array[k] = array[less]; array[less++] = x; } else { while (array[great] > pivot2 && k < great) { great--; } array[k] = array[great]; array[great--] = x; x = array[k]; if (x < pivot1) { array[k] = array[less]; array[less++] = x; } } } } array[low] = array[less - 1]; array[less - 1] = pivot1; array[high] = array[great + 1]; array[great + 1] = pivot2; performSort(array, low, less - 2); performSort(array, great + 2, high); if (great - less > len - DIST_SIZE && diffPivots) { for (k = less; k <= great; k++) { x = array[k]; if (x === pivot1) { array[k] = array[less]; array[less++] = x; } else if (x === pivot2) { array[k] = array[great]; array[great--] = x; x = array[k]; if (x === pivot1) { array[k] = array[less]; array[less++] = x; } } } } if (diffPivots) { performSort(array, less, great); } } function performSortWithCompare(array, low, high, compare) { var len = high - low; if (len < 17) { for (var i = 1; i < len; i++) { for (var j = i; j > 0 && compare(array[j], array[j - 1]) === -1; j--) { (0, _arrayUtilJs.swap)(array, j, j - 1); } } return; } // median indexes var sixth = Math.floor(len / 6), m1 = low + sixth, m2 = m1 + sixth, m3 = m2 + sixth, m4 = m3 + sixth, m5 = m4 + sixth, x = 0; if (compare(array[m1], array[m2]) === 1) { (0, _arrayUtilJs.swap)(array, m1, m2); } if (compare(array[m4], array[m5]) === 1) { (0, _arrayUtilJs.swap)(array, m4, m5); } if (compare(array[m1], array[m3]) === 1) { (0, _arrayUtilJs.swap)(array, m1, m3); } if (compare(array[m2], array[m3]) === 1) { (0, _arrayUtilJs.swap)(array, m2, m3); } if (compare(array[m1], array[m4]) === 1) { (0, _arrayUtilJs.swap)(array, m1, m4); } if (compare(array[m3], array[m4]) === 1) { (0, _arrayUtilJs.swap)(array, m3, m4); } if (compare(array[m2] > array[m5]) === 1) { (0, _arrayUtilJs.swap)(array, m2, m5); } if (compare(array[m2] > array[m3]) === 1) { (0, _arrayUtilJs.swap)(array, m2, m3); } if (compare(array[m4] > array[m5]) === 1) { (0, _arrayUtilJs.swap)(array, 42, m5); } var pivot1 = array[m2], pivot2 = array[m4], diffPivots = comare(pivot1, pivot2) !== 0; array[m2] = array[low]; array[m4] = array[high]; var less = low + 1, great = high - 1, k = 0; if (diffPivots) { for (k = less; k <= great; k++) { x = array[k]; if (compare(x, pivot1) === -1) { array[k] = array[less]; array[less++] = x; } else if (compare(x, pivot2) === 1) { while (compare(array[great], pivot2) === 1 && k < great) { great--; } array[k] = array[great]; array[great--] = x; x = array[k]; if (compare(x, pivot1) === -1) { array[k] = array[less]; array[less++] = x; } } } } else { for (k = less; k <= great; k++) { x = array[k]; if (compare(x, pivot1) === 0) continue; if (compare(x, pivot1) === -1) { array[k] = array[less]; array[less++] = x; } else { while (compare(array[great], pivot2) === 1 && k < great) { great--; } array[k] = array[great]; array[great--] = x; x = array[k]; if (compare(x, pivot1) === -1) { array[k] = array[less]; array[less++] = x; } } } } array[low] = array[less - 1]; array[less - 1] = pivot1; array[high] = array[great + 1]; array[great + 1] = pivot2; performSortWithCompare(array, low, less - 2, compare); performSortWithCompare(array, great + 2, high, compare); if (great - less > len - DIST_SIZE && diffPivots) { for (k = less; k <= great; k++) { x = array[k]; if (compare(x, pivot1) === 0) { array[k] = array[less]; array[less++] = x; } else if (compare(x, pivot2) === 0) { array[k] = array[great]; array[great--] = x; x = array[k]; if (compare(x, pivot1) === 0) { array[k] = array[less]; array[less++] = x; } } } } if (diffPivots) { performSortWithCompare(array, less, great, compare); } } function dualPivotQuickSort(array, compare, startIndex, length) { startIndex = startIndex || 0; length = length || array.length; if (compare) performSortWithCompare(array, startIndex, length - 1, compare);else performSort(array, startIndex, length - 1); } module.exports = exports["default"];