490fbceac87b5a4d415df647394c9dc8c2e7798dc1916ee96b15452501f9748c334d457038e801a20aaacf9f62d8d7e4e32b7cb79f6ea37c2eb24421c83544 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. 'use strict';
  2. exports.__esModule = true;
  3. exports.default = mergeSort;
  4. exports.merge = merge;
  5. var _linkedList = require('../dataStructures/linkedList');
  6. var _linkedList2 = _interopRequireDefault(_linkedList);
  7. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  8. /**
  9. * Refactored implementation of mergeSort (part of javascript-algorithms project) by Github users:
  10. * mgechev, AndriiHeonia and lekkas (part of javascript-algorithms project - all project contributors
  11. * at repository website)
  12. *
  13. * Link to repository: https://github.com/mgechev/javascript-algorithms
  14. */
  15. /**
  16. * Specifies a function that defines the sort order. The array is sorted according to each
  17. * character's Unicode code point value, according to the string conversion of each element.
  18. *
  19. * @param a {*} first compared element.
  20. * @param b {*} second compared element.
  21. * @returns {Number}
  22. */
  23. var defaultCompareFunction = function defaultCompareFunction(a, b) {
  24. // sort lexically
  25. var firstValue = a.toString();
  26. var secondValue = b.toString();
  27. if (firstValue === secondValue) {
  28. return 0;
  29. } else if (firstValue < secondValue) {
  30. return -1;
  31. }
  32. return 1;
  33. };
  34. /**
  35. * Mergesort method which is recursively called for sorting the input array.
  36. *
  37. * @param {Array} array The array which should be sorted.
  38. * @param {Function} compareFunction Compares two items in an array. If compareFunction is not supplied,
  39. * elements are sorted by converting them to strings and comparing strings in Unicode code point order.
  40. * @param {Number} startIndex Left side of the subarray.
  41. * @param {Number} endIndex Right side of the subarray.
  42. * @returns {Array} Array with sorted subarray.
  43. */
  44. function mergeSort(array) {
  45. var compareFunction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultCompareFunction;
  46. var startIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
  47. var endIndex = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : array.length;
  48. if (Math.abs(endIndex - startIndex) <= 1) {
  49. return [];
  50. }
  51. var middleIndex = Math.ceil((startIndex + endIndex) / 2);
  52. mergeSort(array, compareFunction, startIndex, middleIndex);
  53. mergeSort(array, compareFunction, middleIndex, endIndex);
  54. return merge(array, compareFunction, startIndex, middleIndex, endIndex);
  55. }
  56. /**
  57. * Devides and sort merges two subarrays of given array
  58. *
  59. * @param {Array} array The array which subarrays should be sorted.
  60. * @param {Number} startIndex The start of the first subarray.
  61. * This subarray is with end middle - 1.
  62. * @param {Number} middleIndex The start of the second array.
  63. * @param {Number} endIndex end - 1 is the end of the second array.
  64. * @returns {Array} The array with sorted subarray.
  65. */
  66. function merge(array, compareFunction, startIndex, middleIndex, endIndex) {
  67. var leftElements = new _linkedList2.default();
  68. var rightElements = new _linkedList2.default();
  69. var leftSize = middleIndex - startIndex;
  70. var rightSize = endIndex - middleIndex;
  71. var maxSize = Math.max(leftSize, rightSize);
  72. var size = endIndex - startIndex;
  73. for (var _i = 0; _i < maxSize; _i += 1) {
  74. if (_i < leftSize) {
  75. leftElements.push(array[startIndex + _i]);
  76. }
  77. if (_i < rightSize) {
  78. rightElements.push(array[middleIndex + _i]);
  79. }
  80. }
  81. var i = 0;
  82. while (i < size) {
  83. if (leftElements.first && rightElements.first) {
  84. if (compareFunction(leftElements.first.data, rightElements.first.data) > 0) {
  85. array[startIndex + i] = rightElements.shift().data;
  86. } else {
  87. array[startIndex + i] = leftElements.shift().data;
  88. }
  89. } else if (leftElements.first) {
  90. array[startIndex + i] = leftElements.shift().data;
  91. } else {
  92. array[startIndex + i] = rightElements.shift().data;
  93. }
  94. i += 1;
  95. }
  96. return array;
  97. };