智慧水务管理系统 - 精河县供水工程综合管理平台

index.js 2.0KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /**
  2. * Rearranges items so that all items in the [left, k] are the smallest.
  3. * The k-th element will have the (k - left + 1)-th smallest value in [left, right].
  4. *
  5. * @template T
  6. * @param {T[]} arr the array to partially sort (in place)
  7. * @param {number} k middle index for partial sorting (as defined above)
  8. * @param {number} [left=0] left index of the range to sort
  9. * @param {number} [right=arr.length-1] right index
  10. * @param {(a: T, b: T) => number} [compare = (a, b) => a - b] compare function
  11. */
  12. export default function quickselect(arr, k, left = 0, right = arr.length - 1, compare = defaultCompare) {
  13. while (right > left) {
  14. if (right - left > 600) {
  15. const n = right - left + 1;
  16. const m = k - left + 1;
  17. const z = Math.log(n);
  18. const s = 0.5 * Math.exp(2 * z / 3);
  19. const sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
  20. const newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
  21. const newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));
  22. quickselect(arr, k, newLeft, newRight, compare);
  23. }
  24. const t = arr[k];
  25. let i = left;
  26. /** @type {number} */
  27. let j = right;
  28. swap(arr, left, k);
  29. if (compare(arr[right], t) > 0) swap(arr, left, right);
  30. while (i < j) {
  31. swap(arr, i, j);
  32. i++;
  33. j--;
  34. while (compare(arr[i], t) < 0) i++;
  35. while (compare(arr[j], t) > 0) j--;
  36. }
  37. if (compare(arr[left], t) === 0) swap(arr, left, j);
  38. else {
  39. j++;
  40. swap(arr, j, right);
  41. }
  42. if (j <= k) left = j + 1;
  43. if (k <= j) right = j - 1;
  44. }
  45. }
  46. /**
  47. * @template T
  48. * @param {T[]} arr
  49. * @param {number} i
  50. * @param {number} j
  51. */
  52. function swap(arr, i, j) {
  53. const tmp = arr[i];
  54. arr[i] = arr[j];
  55. arr[j] = tmp;
  56. }
  57. /**
  58. * @template T
  59. * @param {T} a
  60. * @param {T} b
  61. * @returns {number}
  62. */
  63. function defaultCompare(a, b) {
  64. return a < b ? -1 : a > b ? 1 : 0;
  65. }