The following solution will not work in a multi-threaded context, as it uses a global variable. It is also assumed that the arguments to the function have a well-defined distance, which can be expressed as an integer.
#include <stdio.h> #include <stdlib.h> static int p_distance = 0; /* * Compares not just p1 and p2, but the floats i and j, then p1 and p2 are swapped * by the qsort algorithm internally. */ static int indexed_compare(const void *p1, const void *p2) { float i = *((float *)(p1 - p_distance)); float j = *((float *)(p2 - p_distance)); if (i > j) return (1); if (i < j) return (-1); return (0); } /* * The data can be const, we will only sort the indices through qsort. */ void order(int n, const float *data, int *indices) { p_distance = (void*)indices - (void*)data; qsort((void*)indices, n, sizeof(float), indexed_compare); } /* * Test procedure. Result will be printed as sorted values of test. The array test * itself will be kept in-tact. The array indices will be updated to point to values * in test from small to large. That is, indices[0] becomes 3. */ int main() { float test[5] = {0.3, 0.5, 0.2, 0.1, 0.4}; int indices[5] = {0, 1, 2, 3, 4}; for (int i = 0; i < 5; ++i ) { printf("%f ", test[i]); } printf("\n"); order(5, test, indices); for (int i = 0; i < 5; ++i ) { printf("%i ", indices[i]); } printf("\n"); for (int i = 0; i < 5; ++i ) { printf("%f ", test[indices[i]]); } printf("\n"); return 0; }
It also has its advantages. No structures are required. No copying around. There are no temporary variables. Just an array of indexes with incremental 1: N values โโto start with and
Anne van rossum
source share