First, I set up a test for your code:
void mergeSort(int v[], int tamanho) {
mergeSortInt(v, 0, tamanho);
}
int main() {
int a[] = {10, 2, 7, 1, 4, 9, 3, 8, 0, 5, 6};
mergeSort(a, 11);
for (int i = 0; i < 11; i++) {
printf("%d ", a[i]);
}
}
See here it working on ideone.
Before transforming the mergeInt
from iterative to recursive, some changes need to be made to resolve some things that would prevent the recursive version from working:
Attack your malloc
and free
. Even in iterative version, use a lot of malloc
s and free
s is somewhat inefficient, it would be better to use only one in the whole mergesort process.
We remove from inside the mergeInt
, the last for
which copies of aux
for v
.
Within the while
, we change the if
to have only two possible paths instead of four.
The code goes like this:
void mergeInt(int v[], int inicio, int fim, int aux[]) {
int meio = (inicio + fim) / 2;
int i = inicio;
int j = meio + 1;
int k = 0;
while (i <= meio || j <= fim) {
if (i <= meio && (j > fim || v[i] < v[j])) {
aux[k] = v[i];
i++;
} else {
aux[k] = v[j];
j++;
}
k++;
}
}
void mergeSortInt(int v[], int inicio, int fim, int aux[]) {
int meio = (inicio + fim) / 2;
if (inicio < fim) {
mergeSortInt(v, inicio, meio, aux);
mergeSortInt(v, meio + 1, fim, aux);
mergeInt(v, inicio, fim, aux);
for (int l = 0; l < fim - inicio + 1; l++) {
v[inicio + l] = aux[l];
}
}
}
void mergeSort(int v[], int tamanho) {
int *aux = malloc(sizeof(int) * tamanho);
mergeSortInt(v, 0, tamanho, aux);
free(aux);
}
int main() {
int a[] = {10, 2, 7, 1, 4, 9, 3, 8, 0, 5, 6};
mergeSort(a, 11);
for (int i = 0; i < 11; i++) {
printf("%d ", a[i]);
}
}
See here working on ideone.
At this point, note that the function mergeInt
reduced to being little more than just a noose while
. So now we can make it recursive.
The parameters inicio
and fim
are exchanged for i
, meio
, j
and fim
. The logic is that i
and meio
correspond to one of the intervals that will be merged into aux
and j
and fim
corresponds to the other range. O k
also becomes a parameter to indicate at which point of aux
the intercalation between the two intervals is happening.
The code goes like this:
void mergeInt(int v[], int i, int meio, int j, int fim, int k, int aux[]) {
if (i <= meio && (j > fim || v[i] < v[j])) {
aux[k] = v[i];
mergeInt(v, i + 1, meio, j, fim, k + 1, aux);
} else if (j <= fim) {
aux[k] = v[j];
mergeInt(v, i, meio, j + 1, fim, k + 1, aux);
}
}
void mergeSortInt(int v[], int inicio, int fim, int aux[]) {
int meio = (inicio + fim) / 2;
if (inicio < fim) {
mergeSortInt(v, inicio, meio, aux);
mergeSortInt(v, meio + 1, fim, aux);
mergeInt(v, inicio, meio, meio + 1, fim, 0, aux);
for (int l = 0; l < fim - inicio + 1; l++) {
v[inicio + l] = aux[l];
}
}
}
void mergeSort(int v[], int tamanho) {
int *aux = malloc(sizeof(int) * tamanho);
mergeSortInt(v, 0, tamanho, aux);
free(aux);
}
int main() {
int a[] = {10, 2, 7, 1, 4, 9, 3, 8, 0, 5, 6};
mergeSort(a, 11);
for (int i = 0; i < 11; i++) {
printf("%d ", a[i]);
}
}
See here working on ideone.
Why do you want to implement the
merge
recursively?– Victor Stafusa
It’s an exercise I was trying to do, but I couldn’t imagine the recursion, I guess the way the code was written.
– Erik Jhonatta