void *mergeSort(void *base, size_t nmeb, size_t size, int(*compar)(const void *, const void *)) { if (nmeb < 2) return; mergeSort(base, nmeb / 2, size, compar); mergeSort(base + (nmeb / 2) * size, nmeb - nmeb / 2, size, compar); int i, j; void * hold; hold = calloc(nmeb, size); if (hold == NULL) { exit(EXIT_FAILURE); } i = j = 0; while (i < nmeb / 2 && j < nmeb - nmeb / 2) { if (compar(base + i * size, base + (nmeb / 2 + j) * size) > 0) { memcpy(hold + (i + j) * size, base + (nmeb / 2 + j) * size, size); ++j; } else { memcpy(hold + (i + j) * size, base + i * size, size); ++i; } } if (i == nmeb / 2) { memcpy(hold + (i + j) * size, base + (nmeb / 2 + j) * size, (nmeb - nmeb / 2 - j) * size); } else { memcpy(hold + (i + j) * size, base + i * size, (nmeb / 2 - i) * size); } memcpy(base, hold, nmeb * size); free(hold); }
void swap(void *p1, void *p2, size_t size) { void *temp; temp = malloc(size); if (temp == NULL) { exit(EXIT_FAILURE); } memcpy(temp, p1, size); memcpy(p1, p2, size); memcpy(p2, temp, size); free(temp); } int comparStr(const void *p1, const void *p2) { return strcmp(* (char * const *) p1, * (char * const *) p2); } int comparInt(const void *p1, const void *p2) { return (*(const int *) p1 - *(const int *) p2); }
int main(int argc, char *argv[]) { int i; int arr[5] = {4, 2, 1, 3, 5}; printf("Integer Sort\n"); printf("Original: "); for (i = 0; i < 5; i++) printf("%d ", arr[i]); printf("\n"); mergeSort(arr, 5, sizeof(int), comparInt); printf("Sorted : "); for (i = 0; i < 5; i++) printf("%d ", arr[i]); printf("\n\n"); if (argc < 2) exit(EXIT_SUCCESS); printf("String Sort\n"); printf("Original: "); for (i = 1; i < argc; i++) printf("%s ", argv[i]); printf("\n"); mergeSort(&argv[1], argc - 1, sizeof(argv[1]), comparStr); printf("Sorted : "); for (i = 1; i < argc; i++) printf("%s ", argv[i]); printf("\n"); exit(EXIT_SUCCESS); }
roo@ubuntu:~$ ./a.out linux windows mac Integer Sort Original: 4 2 1 3 5 Sorted : 1 2 3 4 5 String Sort Original: linux windows mac Sorted : linux mac windows