Основная проблема в вашем коде - вы вообще не инициализируете R
. В инициализации l oop есть простая опечатка, вероятно, ошибка вырезания и вставки: L[j] = a[m + 1 + j];
должно быть
R[j] = a[m + 1 + j];
Обратите внимание, что в C ++ идиоматически c указать фрагмент с помощью индекс первого включенного элемента и индекс последнего исключенного элемента. Это соглашение, используемое в C, Python и многих других языках, позволяет использовать более простой и универсальный код c, вы можете указать пустой фрагмент с помощью l == h
. Это также менее подвержено ошибкам, поскольку +1
/ -1
корректировки не требуются, и можно безопасно использовать типы индексов без знака, такие как size_t
.
Наконец, int L[n1], R[n2];
- это объявление C99, которое является расширение до C ++. Даже в средах, где поддерживаются VLA, автоматическое выделение c хранилища вызовет переполнение стека для достаточно больших наборов. Вы должны использовать vector
для этих временных массивов.
Эти векторы могут быть инициализированы непосредственно из векторного среза, что позволяет избежать циклов копирования, подверженных ошибкам:
vector<int> L(a.begin() + l, a.begin() + m);
vector<int> R(a.begin() + m, a.begin() + r);
Вот измененный версия:
#include <iostream>
#include <vector>
using namespace std;
void merge(vector<int> &a, size_t l, size_t m, size_t r) {
vector<int> L(a.begin() + l, a.begin() + m);
vector<int> R(a.begin() + m, a.begin() + r);
size_t i = 0;
size_t j = 0;
size_t k = l; // index into the merged vector slice
size_t n1 = m - l;
size_t n2 = r - m;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
a[k++] = L[i++];
} else {
a[k++] = R[j++];
}
}
while (i < n1) {
a[k++] = L[i++];
}
// the last loop in redundant as the remaining elements from R are already at
// the end of a
}
void mergeSort(vector<int> &a, size_t l, size_t r) {
if (r - l >= 2) {
size_t m = l + (r - l) / 2;
mergeSort(a, l, m);
mergeSort(a, m, r);
merge(a, l, m, r);
}
}
int main() {
size_t n;
std::cin >> n;
vector<int> a(n);
for (size_t i = 0; i < a.size(); i++) {
cin >> a[i];
}
mergeSort(a, 0, a.size());
for (size_t i = 0; i < a.size(); i++) {
cout << a[i];
}
return 0;
}