Advertisement
Neveles

© 2020 Neveles. All rights reserved.

Oct 14th, 2020
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.77 KB | None | 0 0
  1. #include <cstdlib>
  2. #include <ctime>
  3. #include <iostream>
  4. #include <vector>
  5.  
  6. // вход:
  7. // массив целых чисел `a`
  8. // индекс начала подмассива `begin` и размер этого подмассива `n`,
  9. // задающие подмассив, над которым необходимо провести разбиение
  10. // индекс `j` его элемента `p = a[j]`
  11.  
  12. // выход:
  13. // массив `a` изменен: в заданном его подмассиве сначала идут элементы,
  14. // меньшие `p`, затем равные `p`, затем большие `p`
  15. // структура borders_t с двумя полями left и right - соответственно
  16. // наименьший и наибольший индексы элементов массива `a` после
  17. // перестановки, равных p
  18.  
  19. void divide(std::vector<int>& a, int begin, int end, int j, int &left, int &right)
  20. {
  21. int p = a[j];
  22. // элементы с индексами меньше left или больше right стоят
  23. // на правильных местах
  24. left = begin;
  25. right = end - 1;
  26. int i = begin;
  27. // на каждой итерации цикла мы либо увелечиваем `i`, либо уменьшаем right.
  28. // Поэтому, если в массиве `a` `n` элементов, цикл выполнится
  29. // ровно `n` раз
  30. while (i <= right)
  31. {
  32. if (a[i] < p)
  33. {
  34. // если i-й элемент меньше `p`, то помещаем его в левую часть
  35. // массива на "правильное" место
  36. // при этом элемент останется на том же месте, если элементов,
  37. // равных `p`, еще не было. В противном случае он заменит
  38. // собой элемент, равный `p`, либо элемент, который уже был
  39. // скопирован на "правильное" место
  40. int temp = a[left];
  41. a[left] = a[i];
  42. a[i] = temp;
  43. i++;
  44. left++;
  45. }
  46. else if (a[i] > p)
  47. {
  48. // если i-й элемент больше `p`, то обмениваем его местами с самым
  49. // правым непроверенным элементом
  50. // теперь элемент, который только что переставили вправо, стоит на
  51. // "правильном" месте, а элемент, переставленный влево, будет
  52. // проверен на следующей итерации
  53. int temp = a[right];
  54. a[right] = a[i];
  55. a[i] = temp;
  56. right--;
  57. }
  58. else if (a[i] == p)
  59. {
  60. // если i-й элемент равен `p`, то пропускаем его
  61. i++;
  62. }
  63. }
  64. }
  65. // вход:
  66. // массив целых чисел `a`
  67. // индекс начала подмассива `begin` и размер этого подмассива `n`,
  68. // задающие подмассив, порядковую статистику которого нужно найти
  69. // номер `k` порядковой статистики
  70. // выход:
  71. // `k`-я порядковая статистика заданного подмассива
  72.  
  73. int select(std::vector<int>& a, int begin, int end, int k)
  74. {
  75. // выбираем индекс j случайно
  76. int j = begin + std::rand() % (end - begin);
  77. int left = begin;
  78. int right = end;
  79. // осуществляем разбиение заданного подмассива
  80. divide(a, begin, end, j, left, right);
  81. // в зависимости от того, в каком отрезке лежит искомая порядковая
  82. // статистика, вызвать select для подмассива или вернуть значение
  83. if (k < left)
  84. {
  85. return select(a, begin, left - 1, k);
  86. }
  87. else if (k <= right)
  88. {
  89. return a[k];
  90. }
  91.  
  92. return select(a, right + 1, end, k);
  93. }
  94.  
  95. int main()
  96. {
  97. std::srand(std::time(nullptr));
  98.  
  99. std::cout << "Input size: ";
  100. int n = 0;
  101. std::cin >> n;
  102.  
  103. if (n < 1)
  104. {
  105. return -1;
  106. }
  107.  
  108. std::vector<int> a;
  109.  
  110. int val;
  111. for (int i = 0; i < n; i++)
  112. {
  113. std::cin >> val;
  114. a.push_back(val);
  115. }
  116.  
  117. // считываем индекс j
  118. int j = 0;
  119. std::cin >> j;
  120. if (j < 0 || j >= n) return 1;
  121. int left = 0;
  122. int right = n;
  123. // вызываем "разделяющую" процедуру divide
  124. divide(a, 0, n, j, left, right);
  125. // выводим изменённый массив и индексы
  126. for (int element : a) std::cout << element << ' ';
  127. std::cout << '\n' << left << ' ' << right << '\n';
  128.  
  129. int median = select(a, 0, n, n - n / 2 - 1);
  130. std::cout << "Median = " << median;
  131. }
  132.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement