Allora, ho modificato il codice in questo modo:
void insertion_sort(void* base, size_t n, size_t size, sort_comparator_t cmp)
{
size_t i;
int j;
int p = 0; /*Indice del minimo*/
void* tmp = malloc(size);
long* ptr_base = (long *)base;
for(i=1; i<n; i++)
if(cmp(&ptr_base[p], &ptr_base[i]) > 0) p = i;
/*Mettiamo il minimo nella prima posizione ptr_base[0], lo usiamo come sentinella per non sforare l'array a sinistra*/
/**tmp = ptr_base[0];
ptr_base[0] = ptr_base[p];
ptr_base[p] = *tmp;*/
memmove(tmp, &ptr_base[0], size);
memmove(&ptr_base[0], &ptr_base[p], size);
memmove(&ptr_base[p], tmp, size);
/*Partiamo dalla posizione 2 perchè non c'è bisogno di confrontare con la posizione 0 inizialmente*/
for(i=2; i<n; i++)
{
j = i;
/*Muove gli elementi di ptr_base[0...i-1], che sono maggiori di dptr, in una posizione prima di quella corrente*/
while(cmp(&ptr_base[j], &ptr_base[j-1]) <= 0)
{
/**tmp = ptr_base[j];
ptr_base[j] = ptr_base[j-1];
ptr_base[j-1] = *tmp;*/
memmove(tmp, &ptr_base[j], size);
memmove(&ptr_base[j], &ptr_base[j-1], size);
memmove(&ptr_base[j-1], tmp, size);
j--;
}
}
return;
}
E le funzioni comparator per i vari tipi di dato sono queste:
int double_comparator(const void* a, const void* b)
{
const double* aa = a;
const double* bb = b;
return (*aa > *bb) - (*aa < *bb);
}
int string_comparator(const void* a, const void* b)
{
const char** aa = (const char**) a;
const char** bb = (const char**) b;
return strcmp(*aa, *bb);
}
int item_comparator(const void* a, const void* b)
{
const item_t* aa = a;
const item_t* bb = b;
return (aa->id > bb->id) - (aa->id < bb->id);
}
I double e le stringhe li ordina correttamente, ma ho ancora problemi ad ordinare la struttura item_t, non mi trova il valore minimo corretto e mi dà un segmentation fault ma non capisco perchè. Questo è il codice che sto utilizzando per testarla:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 9
struct item_s
{
long id;
char* name;
};
typedef struct item_s item_t;
static item_t ca[] = {{9,"john"},{8,"jane"},{7,"mary"},{6,"anthony"},{5,"stevie"},{4,"bob"},{3,"ann"},{2,"claire"},{1,"alice"}};
static int item_comparator(const void* a, const void* b);
int item_comparator(const void* a, const void* b)
{
const item_t* aa = a;
const item_t* bb = b;
return (aa->id > bb->id) - (aa->id < bb->id);
}
void insertion_sort(void* base, size_t n, size_t size, int (*item_comparator)(const void *a, const void *b))
{
size_t i;
int j;
int p = 0; /*Indice del minimo*/
void* tmp = malloc(size);
long* ptr_base = (long *)base;
for(i=1; i<n; i++)
if(item_comparator(&ptr_base[p], &ptr_base[i]) > 0) p = i;
/*Mettiamo il minimo nella prima posizione ptr_base[0], lo usiamo come sentinella per non sforare l'array a sinistra*/
/**tmp = ptr_base[0];
ptr_base[0] = ptr_base[p];
ptr_base[p] = *tmp;*/
memmove(tmp, &ptr_base[0], size);
memmove(&ptr_base[0], &ptr_base[p], size);
memmove(&ptr_base[p], tmp, size);
/*Partiamo dalla posizione 2 perchè non c'è bisogno di confrontare con la posizione 0 inizialmente*/
for(i=2; i<n; i++)
{
j = i;
/*Muove gli elementi di ptr_base[0...i-1], che sono maggiori di dptr, in una posizione prima di quella corrente*/
while(item_comparator(&ptr_base[j], &ptr_base[j-1]) <= 0)
{
/**tmp = ptr_base[j];
ptr_base[j] = ptr_base[j-1];
ptr_base[j-1] = *tmp;*/
memmove(tmp, &ptr_base[j], size);
memmove(&ptr_base[j], &ptr_base[j-1], size);
memmove(&ptr_base[j-1], tmp, size);
j--;
}
}
return;
}
int main()
{
int i;
item_t* ca_clone = NULL;
ca_clone = malloc(N*sizeof(item_t));
assert( ca_clone != NULL );
memcpy(ca_clone, ca, N*sizeof(item_t));
printf("Array di struct da ordinare:\n");
for(i=0; i<N; i++)
{
printf("%ld %s\n", ca_clone[i].id, ca_clone[i].name);
}
insertion_sort(ca_clone, N, sizeof(item_t), item_comparator);
printf("Ordinato:\n");
for(i=0; i<N; i++)
{
printf("%ld %s\n", ca_clone[i].id, ca_clone[i].name);
}
}