quickSelect.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. /*
  20. * Licensed to the Apache Software Foundation (ASF) under one
  21. * or more contributor license agreements. See the NOTICE file
  22. * distributed with this work for additional information
  23. * regarding copyright ownership. The ASF licenses this file
  24. * to you under the Apache License, Version 2.0 (the
  25. * "License"); you may not use this file except in compliance
  26. * with the License. You may obtain a copy of the License at
  27. *
  28. * http://www.apache.org/licenses/LICENSE-2.0
  29. *
  30. * Unless required by applicable law or agreed to in writing,
  31. * software distributed under the License is distributed on an
  32. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  33. * KIND, either express or implied. See the License for the
  34. * specific language governing permissions and limitations
  35. * under the License.
  36. */
  37. /**
  38. * Quick select n-th element in an array.
  39. *
  40. * Note: it will change the elements placement in array.
  41. */
  42. function defaultCompareFunc(a, b) {
  43. return a - b;
  44. }
  45. function swapElement(arr, idx0, idx1) {
  46. var tmp = arr[idx0];
  47. arr[idx0] = arr[idx1];
  48. arr[idx1] = tmp;
  49. }
  50. function select(arr, left, right, nth, compareFunc) {
  51. var pivotIdx = left;
  52. var pivotValue;
  53. while (right > left) {
  54. pivotIdx = Math.round((right + left) / 2);
  55. pivotValue = arr[pivotIdx]; // Swap pivot to the end
  56. swapElement(arr, pivotIdx, right);
  57. pivotIdx = left;
  58. for (var i = left; i <= right - 1; i++) {
  59. if (compareFunc(pivotValue, arr[i]) >= 0) {
  60. swapElement(arr, i, pivotIdx);
  61. pivotIdx++;
  62. }
  63. }
  64. swapElement(arr, right, pivotIdx);
  65. if (pivotIdx === nth) {
  66. return pivotIdx;
  67. } else if (pivotIdx < nth) {
  68. left = pivotIdx + 1;
  69. } else {
  70. right = pivotIdx - 1;
  71. }
  72. } // Left == right
  73. return left;
  74. }
  75. /**
  76. * @alias module:echarts/core/quickSelect
  77. * @param {Array} arr
  78. * @param {number} [left]
  79. * @param {number} [right]
  80. * @param {number} nth
  81. * @param {Function} [compareFunc]
  82. * @example
  83. * var quickSelect = require('echarts/core/quickSelect');
  84. * var arr = [5, 2, 1, 4, 3]
  85. * quickSelect(arr, 3);
  86. * quickSelect(arr, 0, 3, 1, function (a, b) {return a - b});
  87. *
  88. * @return {number}
  89. */
  90. function _default(arr, left, right, nth, compareFunc) {
  91. if (arguments.length <= 3) {
  92. nth = left;
  93. if (arguments.length === 2) {
  94. compareFunc = defaultCompareFunc;
  95. } else {
  96. compareFunc = right;
  97. }
  98. left = 0;
  99. right = arr.length - 1;
  100. }
  101. return select(arr, left, right, nth, compareFunc);
  102. }
  103. module.exports = _default;