Usa quicksort (o l'algoritmo di ordinamento di tua scelta) per ordinare un elenco di indici di array in base ai tempi intermedi corrispondenti. La matrice di indici è un proxy per l'array di tempi intermedi. Non vogliamo cambiare l'ordine dei tempi, ma vogliamo sapere quale sarebbe l'ordine dei tempi se lo ordinassimo.
Array split time: splits[] = {4.2, 3.9, 4.1, 3.8, 3.7}
Iniziamo con una serie di indici: indexes[] = {0, 1, 2, 3, 4}
Ora ordiniamo l'array indexes
usando i valori di splits
. Qualsiasi algoritmo di ordinamento richiede una funzione di confronto e la nostra è:
compare(i, j) := if splits[i] < splits[j], i is smaller,
else if splits[i] > splits[j], i is larger,
else they're equal
Quindi, ad esempio, compare(0, 1)
dovrebbe restituire i > j
perché 4.2 > 3.9
.
Di seguito è riportato un codice C che illustra la soluzione utilizzando un codice abbastanza piccolo. Si basa sulla funzione di libreria standard qsort_r()
C, che è una versione di quicksort, ma è possibile utilizzare qualsiasi algoritmo di ordinamento. Un importante dettaglio di implementazione è che la routine qsort_r()
ci consente di passare un parametro aggiuntivo fornito alla funzione di confronto; questo ci consente di passare l'array splits
alla funzione di confronto.
void sortSplits(float splits[], int index[], int count)
{
// initialize the index array
for (int i = 0; i < count; i++) {
index[i] = i;
}
qsort_r(index, count, sizeof(int), splits, compareSplits);
}
int compareSplits(void *thunk, const void *item1, const void *item2)
{
float *splits = (float*)thunk;
int i = *(int*)item1;
int j = *(int*)item2;
if (splits[i] < splits[j])
return -1; // less than
else if (splits[i] > splits[j])
return 1; // greater than
else
return 0; // equal
}
Per usare questo codice, chiama sortSplits()
che passa nell'array di tempi intermedi, una matrice di ints che è lunga almeno quanto l'array di volte e il numero di volte. Al ritorno, la matrice index
conterrà la lista ordinata di indici. In altre parole, se la matrice risultante assomiglia a:
{3, 0, 1, 2}
significa che il tempo parziale all'indice 3 è il più piccolo, seguito dal tempo all'indice 0, seguito dal tempo all'indice 1, seguito dal tempo all'indice 2.
Gli indici qui funzionano davvero come dei puntatori. Potresti anche dire che sono indicatori in un certo senso. In effetti, è possibile implementare esattamente lo stesso algoritmo descritto sopra utilizzando una serie di puntatori al posto della serie di indici che eliminerebbe la necessità di passare l'array splits
come parametro separato.