问题
I am supposed to write an algorithm in C that takes an array of integers in any base (radix) and use Radix Sort to put them in ascending order. My algorithm can not impose any limit for the length of the array, the number of digits and the base. When I say integers I do not mean I will always receive an array of int
s, it can be an array of long int
s, char
s, char
pointers, etc.
Seen that, I though the best way to deal with that imposing as little as possible limitations to my algorithm was to just deal with the vector by accessing it's positions and type casting the value there to long unsigned int
so the limitation this approach has is that the user must use a digit "weight" that complies with the encoding option the code was compiled with, i.e., in the ASCII encoding x
in decimal base is 120 and a
is 97, so if the given base uses the digits x
and a
, x
must be greater than a
.
Here is my algorithm:
/*!
* @function radixSort
* @abstract Sort a vector using Radix Sort.
* @discussion This function take a vector of positive
* integers in any base (radix) and sorts
* it in ascending order using the Radix
* Sort algorithm.
* @param v the vector with elements to sort
* @param n the length of the vector v
* @param getMax the function to get the maximum element of v
*/
void radixSort(void *v[], long unsigned int n, long unsigned int (*getMax)(void*[], long unsigned int)) {
long unsigned int i;
void* semiSorted[n];
long unsigned int significantDigit = 1;
long unsigned int max = (*getMax)(v, n);
while (max / significantDigit > 0){
long unsigned int intermediate[10] = {0};
for(i=0; i<n; i++)
intermediate[(long unsigned int)v[i]/significantDigit % 10]++;
for(i=1; i<10; i++)
intermediate[i] += intermediate[i-1];
for(i=n; i>0; i--)
semiSorted[--intermediate[(long unsigned int)v[i-1]/significantDigit % 10]] = v[i-1];
for(i=0; i<n; i++)
v[i] = semiSorted[i];
significantDigit *= 10;
}
}
This algorithm works with all types I tested, but a string array. If I have something like:
int main() {
char *b36v[7] = {"014", "000", "8f6", "080", "056", "00a", "080"};
printf("b36v unsorted: "); for(i=0; i<7; i++) printf("%s ", b36v[i]); printf("\n");
radixSort(b36v, 7, getMaxFunc);
printf("b36v sorted : "); for(i=0; i<7; i++) printf("%s ", b36v[i]); printf("\n");
return 0;
}
The result output will be:
b36v unsorted: 014 000 8f6 080 056 00a 080
b36v sorted : 014 000 8f6 080 080 056 00a
So it doesn't work as expected, I expected the sorted vector to be:
000 00a 014 056 080 080 8f6
I can only see that equal entries are grouped together as expected. Changing the values and observing the outputs I think probably the algorithm is taking the memory addresses and sorting them because at a given position of the original vector there is no actual value, but an array of char
's.
I just want to know if there is someway I can handle these cases of 2D (or even 3D, 4D, ...) arrays writing an universal code which handle from int
/char
arrays to arrays of arrays of arrays... of long unsigned int
s and without asking for too much parameters. I can't figure out how to manage this situation in C.
来源:https://stackoverflow.com/questions/30719811/sort-integers-in-any-base-radix