В вашей реализации левый и правый массивы определяются с помощью автоматического c хранилища, поэтому освобождение автоматически c, когда функция возвращается, но это создает 2 проблемы:
- достаточно большой Массив вызовет неопределенное поведение, поскольку выделение слишком большого пространства с помощью автоматического c хранилища приведет к переполнению стека .
- массивов переменного размера не являются стандартным C ++. Вы полагаетесь на расширение c, определяемое компилятором.
Максимальное пространство в стеке, используемое вашей функцией, пропорционально N
, поэтому сложность пространства составляет O (N) как и ожидалось. Вы могли бы выделить эти массивы с помощью new
, и, конечно, вам пришлось бы затем освободить их с помощью delete , иначе бы у вас возникли утечки памяти, а объем потерянной памяти был бы пропорционален N * log2 (N) .
Альтернативный подход будет использовать временный массив, выделенный при первоначальном вызове и переданный рекурсивной функции.
Обратите внимание также на то, что имена для левого и правого массивы очень запутанные. rarr
фактически слева от larr
!
Вот модифицированная версия:
#include <iostream>
using namespace std;
void mergeArr(int *larr, int *rarr, int *arr, int lsize, int rsize) {
int i = 0, r = 0, l = 0;
while (l < lsize && r < rsize) {
if (larr[l] <= rarr[r]) {
arr[i++] = larr[l++];
} else {
arr[i++] = rarr[r++];
}
}
while (l < lsize) {
arr[i++] = larr[l++];
}
while (r < rsize) {
arr[i++] = rarr[r++];
}
}
void mergeSort(int *arr, int length) {
if (length > 1) {
int l1 = length / 2;
int l2 = length - l1;
int *larr = new int[l1];
int *rarr = new int[l2];
for (int i = 0; i < l1; i++) {
larr[i] = arr[i];
}
for (int i = l1; i < length; i++) {
rarr[i - l1] = arr[i];
}
mergeSort(larr, l1);
mergeSort(rarr, l2);
mergeArr(larr, rarr, arr, l1, l2);
delete[] larr;
delete[] rarr;
}
}
int main() {
int arr[] = { 1, 10, 2, 7, 5 };
int length = sizeof arr / sizeof *arr;
mergeSort(arr, length);
for (int i = 0; i < length; i++) {
cout << arr[i] << " ";
}
return 0;
}