#include <stdio.h>
#include <stdlib.h>
#include <string.h> // Para a função memcpy
// Código do mergesort:
void intercalar(
char *array1,
char *array2,
size_t tamanho_array1,
size_t tamanho_array2,
char *aux,
size_t tamanho_elemento,
int (* comparador)(void *, void *)
) {
int a = 0, b = 0, c = 0;
while (a < tamanho_array1 || b < tamanho_array2) {
int ain = a < tamanho_array1;
int bin = b < tamanho_array2;
char *e1 = ain ? &array1[a * tamanho_elemento] : NULL;
char *e2 = bin ? &array2[b * tamanho_elemento] : NULL;
char *e3 = &aux[c * tamanho_elemento];
char *comp = (e2 == NULL || (e1 != NULL && comparador(e1, e2) <= 0)) ? e1 : e2;
memcpy(e3
, comp
, tamanho_elemento
); if (comp == e1) a++; else b++;
c++;
}
}
void mergesort_aux(
char *array,
char *aux,
size_t tamanho_elemento,
size_t tamanho_array,
int (* comparador)(void *, void *)
) {
if (tamanho_array < 2) return;
int metade1 = tamanho_array / 2;
int metade2 = tamanho_array - metade1;
mergesort_aux(array, aux, tamanho_elemento, metade1, comparador);
char *temp = &array[metade1 * tamanho_elemento];
mergesort_aux(temp, aux, tamanho_elemento, metade2, comparador);
intercalar(array, temp, metade1, metade2, aux, tamanho_elemento, comparador);
memcpy(array
, aux
, tamanho_elemento
* tamanho_array
); }
void mergesort(
void *array,
size_t tamanho_elemento,
size_t tamanho_array,
int (* comparador)(void *, void *)
) {
void *aux
= malloc(tamanho_elemento
* tamanho_array
); mergesort_aux((char *) array, (char *) aux, tamanho_elemento, tamanho_array, comparador);
}
// Seu código de teste:
typedef struct {
int a;
int b;
int c;
} XPTO;
void criar_vetor(XPTO *v, int n) {
for (int i = 0; i < n; i++) {
v[i].a = (i % 3) + 4;
v[i].b = 100 - i % 5;
v[i].c = i;
}
}
void imprimir_vetor(XPTO *v, int n) {
for (int i = 0; i < n; i++) {
printf("(a=%d b=%d c=%d) ", v
[i
].
a, v
[i
].
b, v
[i
].
c); }
}
int por_a(void *p1, void *p2) {
XPTO *pp1 = (XPTO *) p1;
XPTO *pp2 = (XPTO *) p2;
return pp1->a - pp2->a;
}
int por_b(void *p1, void *p2) {
XPTO *pp1 = (XPTO *) p1;
XPTO *pp2 = (XPTO *) p2;
return pp1->b - pp2->b;
}
#define T 20
int main(int argc, char* argv[]) {
XPTO v[T];
criar_vetor(v, T);
imprimir_vetor(v, T);
mergesort(v, sizeof(XPTO), T, por_a);
imprimir_vetor(v, T);
criar_vetor(v, T); // Recria o vetor.
mergesort(v, sizeof(XPTO), T, por_b);
imprimir_vetor(v, T);
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPiAvLyBQYXJhIGEgZnVuw6fDo28gbWVtY3B5CgovLyBDw7NkaWdvIGRvIG1lcmdlc29ydDoKCnZvaWQgaW50ZXJjYWxhcigKICAgIGNoYXIgKmFycmF5MSwKICAgIGNoYXIgKmFycmF5MiwKICAgIHNpemVfdCB0YW1hbmhvX2FycmF5MSwKICAgIHNpemVfdCB0YW1hbmhvX2FycmF5MiwKICAgIGNoYXIgKmF1eCwKICAgIHNpemVfdCB0YW1hbmhvX2VsZW1lbnRvLAogICAgaW50ICgqIGNvbXBhcmFkb3IpKHZvaWQgKiwgdm9pZCAqKQopIHsKICAgIGludCBhID0gMCwgYiA9IDAsIGMgPSAwOwogICAgd2hpbGUgKGEgPCB0YW1hbmhvX2FycmF5MSB8fCBiIDwgdGFtYW5ob19hcnJheTIpIHsKICAgICAgICBpbnQgYWluID0gYSA8IHRhbWFuaG9fYXJyYXkxOwogICAgICAgIGludCBiaW4gPSBiIDwgdGFtYW5ob19hcnJheTI7CiAgICAgICAgY2hhciAqZTEgPSBhaW4gPyAmYXJyYXkxW2EgKiB0YW1hbmhvX2VsZW1lbnRvXSA6IE5VTEw7CiAgICAgICAgY2hhciAqZTIgPSBiaW4gPyAmYXJyYXkyW2IgKiB0YW1hbmhvX2VsZW1lbnRvXSA6IE5VTEw7CiAgICAgICAgY2hhciAqZTMgPSAmYXV4W2MgKiB0YW1hbmhvX2VsZW1lbnRvXTsKICAgICAgICBjaGFyICpjb21wID0gKGUyID09IE5VTEwgfHwgKGUxICE9IE5VTEwgJiYgY29tcGFyYWRvcihlMSwgZTIpIDw9IDApKSA/IGUxIDogZTI7CiAgICAgICAgbWVtY3B5KGUzLCBjb21wLCB0YW1hbmhvX2VsZW1lbnRvKTsKICAgICAgICBpZiAoY29tcCA9PSBlMSkgYSsrOyBlbHNlIGIrKzsKICAgICAgICBjKys7CiAgICB9Cn0KCnZvaWQgbWVyZ2Vzb3J0X2F1eCgKICAgIGNoYXIgKmFycmF5LAogICAgY2hhciAqYXV4LAogICAgc2l6ZV90IHRhbWFuaG9fZWxlbWVudG8sCiAgICBzaXplX3QgdGFtYW5ob19hcnJheSwKICAgIGludCAoKiBjb21wYXJhZG9yKSh2b2lkICosIHZvaWQgKikKKSB7CiAgICBpZiAodGFtYW5ob19hcnJheSA8IDIpIHJldHVybjsKICAgIGludCBtZXRhZGUxID0gdGFtYW5ob19hcnJheSAvIDI7CiAgICBpbnQgbWV0YWRlMiA9IHRhbWFuaG9fYXJyYXkgLSBtZXRhZGUxOwogICAgbWVyZ2Vzb3J0X2F1eChhcnJheSwgYXV4LCB0YW1hbmhvX2VsZW1lbnRvLCBtZXRhZGUxLCBjb21wYXJhZG9yKTsKICAgIGNoYXIgKnRlbXAgPSAmYXJyYXlbbWV0YWRlMSAqIHRhbWFuaG9fZWxlbWVudG9dOwogICAgbWVyZ2Vzb3J0X2F1eCh0ZW1wLCBhdXgsIHRhbWFuaG9fZWxlbWVudG8sIG1ldGFkZTIsIGNvbXBhcmFkb3IpOwogICAgaW50ZXJjYWxhcihhcnJheSwgdGVtcCwgbWV0YWRlMSwgbWV0YWRlMiwgYXV4LCB0YW1hbmhvX2VsZW1lbnRvLCBjb21wYXJhZG9yKTsKICAgIG1lbWNweShhcnJheSwgYXV4LCB0YW1hbmhvX2VsZW1lbnRvICogdGFtYW5ob19hcnJheSk7Cn0KCnZvaWQgbWVyZ2Vzb3J0KAogICAgdm9pZCAqYXJyYXksCiAgICBzaXplX3QgdGFtYW5ob19lbGVtZW50bywKICAgIHNpemVfdCB0YW1hbmhvX2FycmF5LAogICAgaW50ICgqIGNvbXBhcmFkb3IpKHZvaWQgKiwgdm9pZCAqKQopIHsKICAgIHZvaWQgKmF1eCA9IG1hbGxvYyh0YW1hbmhvX2VsZW1lbnRvICogdGFtYW5ob19hcnJheSk7CiAgICBtZXJnZXNvcnRfYXV4KChjaGFyICopIGFycmF5LCAoY2hhciAqKSBhdXgsIHRhbWFuaG9fZWxlbWVudG8sIHRhbWFuaG9fYXJyYXksIGNvbXBhcmFkb3IpOwogICAgZnJlZShhdXgpOwp9CgovLyBTZXUgY8OzZGlnbyBkZSB0ZXN0ZToKCnR5cGVkZWYgc3RydWN0IHsKICAgIGludCBhOwogICAgaW50IGI7CiAgICBpbnQgYzsKfSBYUFRPOwoKdm9pZCBjcmlhcl92ZXRvcihYUFRPICp2LCBpbnQgbikgewogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICB2W2ldLmEgPSAoaSAlIDMpICsgNDsKICAgICAgICB2W2ldLmIgPSAxMDAgLSBpICUgNTsKICAgICAgICB2W2ldLmMgPSBpOwogICAgfQp9Cgp2b2lkIGltcHJpbWlyX3ZldG9yKFhQVE8gKnYsIGludCBuKSB7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewogICAgICAgIHByaW50ZigiKGE9JWQgYj0lZCBjPSVkKSAiLCB2W2ldLmEsIHZbaV0uYiwgdltpXS5jKTsKICAgIH0KICAgIHByaW50ZigiXG4iKTsKfQoKaW50IHBvcl9hKHZvaWQgKnAxLCB2b2lkICpwMikgewogICAgWFBUTyAqcHAxID0gKFhQVE8gKikgcDE7CiAgICBYUFRPICpwcDIgPSAoWFBUTyAqKSBwMjsKICAgIHJldHVybiBwcDEtPmEgLSBwcDItPmE7Cn0KCmludCBwb3JfYih2b2lkICpwMSwgdm9pZCAqcDIpIHsKICAgIFhQVE8gKnBwMSA9IChYUFRPICopIHAxOwogICAgWFBUTyAqcHAyID0gKFhQVE8gKikgcDI7CiAgICByZXR1cm4gcHAxLT5iIC0gcHAyLT5iOwp9CgojZGVmaW5lIFQgMjAKCmludCBtYWluKGludCBhcmdjLCBjaGFyKiBhcmd2W10pIHsKICAgIFhQVE8gdltUXTsKICAgIGNyaWFyX3ZldG9yKHYsIFQpOwoKICAgIHByaW50ZigiQW50ZXM6XG4iKTsKICAgIGltcHJpbWlyX3ZldG9yKHYsIFQpOwoKICAgIHByaW50ZigiXG5Qb3IgQTpcbiIpOwogICAgbWVyZ2Vzb3J0KHYsIHNpemVvZihYUFRPKSwgVCwgcG9yX2EpOwogICAgaW1wcmltaXJfdmV0b3IodiwgVCk7CgogICAgY3JpYXJfdmV0b3IodiwgVCk7IC8vIFJlY3JpYSBvIHZldG9yLgogICAgcHJpbnRmKCJcblBvciBCOlxuIik7CiAgICBtZXJnZXNvcnQodiwgc2l6ZW9mKFhQVE8pLCBULCBwb3JfYik7CiAgICBpbXByaW1pcl92ZXRvcih2LCBUKTsKCiAgICByZXR1cm4gMDsKfQ==